From aa05cdc653bc15ca2406b11afd66bc618ac26104 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Mon, 9 Feb 2015 20:19:00 -0800 Subject: [PATCH 01/83] initial work on new tree mesh implementation --- SimPEG/Mesh/NewTreeMesh.py | 416 +++++++++++++++++++++++++++++++++++++ 1 file changed, 416 insertions(+) create mode 100644 SimPEG/Mesh/NewTreeMesh.py diff --git a/SimPEG/Mesh/NewTreeMesh.py b/SimPEG/Mesh/NewTreeMesh.py new file mode 100644 index 00000000..f3ecf4dc --- /dev/null +++ b/SimPEG/Mesh/NewTreeMesh.py @@ -0,0 +1,416 @@ +import numpy as np, scipy.sparse as sp +from SimPEG.Utils import ndgrid, mkvc + + +NUM, PARENT, ACTIVE, EDIR, ENODE0, ENODE1 = range(6) +NUM, PARENT, ACTIVE, FDIR, FEDGE0, FEDGE1, FEDGE2, FEDGE3 = range(8) +NUM, PARENT, ACTIVE, CFACE0, CFACE1, CFACE2, CFACE3, CFACE4, CFACE5 = range(9) + +def SortByX0(grid): + dtype=[('x',float),('y',float)] + grid2 = np.zeros(grid.shape[0], dtype=dtype) + grid2['x'][:] = grid[:,0] + grid2['y'][:] = grid[:,1] + P = np.argsort(grid2, order=['y','x']) + return P + + +class TreeMesh(object): + + def __init__(self, hx, hy): + nx = np.r_[0,hx.cumsum()] + ny = np.r_[0,hy.cumsum()] + vnC = [nx.size-1, ny.size-1] + vnN = [nx.size, ny.size] + + XY = ndgrid(nx, ny) + N = np.c_[np.arange(XY.shape[0]), XY] + + N.astype([('num',int),('x',float),('y',float),('z',float)]) + + I = np.arange(nx.size * ny.size, dtype=int).reshape(vnN, order='F') + + vEx = np.c_[mkvc(I[:-1,:]), mkvc(I[1:,:])] + vEy = np.c_[mkvc(I[:,:-1]), mkvc(I[:,1:])] + + nEx = np.arange(vEx.shape[0], dtype=int).reshape(nx.size-1, ny.size, order='F') + nEy = np.arange(vEy.shape[0], dtype=int).reshape(nx.size, ny.size-1, order='F') + vEx.shape[0] + + zEx = np.zeros(nEx.size, dtype=int) + zEy = np.zeros(nEy.size, dtype=int) + + # # parent active dir, n1,n2 + Ex = np.c_[mkvc(nEx), zEx-1, zEx+1, zEx+0, vEx] + Ey = np.c_[mkvc(nEy), zEy-1, zEy+1, zEy+1, vEy] + + nC = np.arange(np.prod(vnC), dtype=int) + + C = np.c_[nC, nC*0-1, nC*0+1, nC*0+2, mkvc(nEx[:,:-1]), mkvc(nEx[:,1:]), mkvc(nEy[:-1,:]), mkvc(nEy[1:,:])] + + self._nodes = N + self._edges = np.r_[Ex, Ey] + self._faces = C + + self.isNumbered = False + + @property + def isNumbered(self): + return self._numberedCC and self._numberedFx and self._numberedFy + @isNumbered.setter + def isNumbered(self, value): + assert value is False, 'Can only set to False.' + self._numberedCC = False + self._numberedEx = False + self._numberedEy = False + + @property + def dim(self): + return 2 + + def _push(self, attr, rows): + self.isNumbered = False + rows = np.atleast_2d(rows) + X = getattr(self, attr) + offset = X.shape[0] + rowNumer = np.arange(rows.shape[0], dtype=int) + offset + rows[:,0] = rowNumer*0-1 + setattr(self, attr, np.vstack((X, rows)).astype(X.dtype)) + if rows.shape[0] == 1: + return offset, rows.flatten() + return rowNumer, rows + + def addNode(self, between): + """Add a node between the node in list between""" + between = np.array(between).flatten() + nodes = self._nodes[between.astype(int), :] + newNode = np.mean(nodes, axis=0) + return self._push('_nodes', newNode) + + def refineEdge(self, index): + e = self._edges[index,:] + self._edges[index, ACTIVE] = 0 + + newNode, node = self.addNode(e[[ENODE0, ENODE1]]) + + Es = np.zeros((2, 6)) + Es[:, ACTIVE] = 1 + Es[:, PARENT] = index + Es[:, EDIR] = e[EDIR] + Es[0, ENODE0] = e[ENODE0] + Es[0, ENODE1] = newNode + Es[1, ENODE0] = newNode + Es[1, ENODE1] = e[ENODE1] + return self._push('_edges', Es) + + def refineFace(self, index): + f = self._faces[index,:] + nodeNums = self._edges[f[[FEDGE0, FEDGE1]],:][:,[ENODE0, ENODE1]] + + self._faces[index, ACTIVE] = 0 + + # new faces and edges + # 2_______________3 _______________ + # | e1--> | | | | + # ^ | | ^ | 2 3 3 | y z z + # | | | | | | | ^ ^ ^ + # | | x | | ---> |---0---+---1---| | | | + # e2 | | e3 | | | | | | + # | | | 0 2 1 | z-----> x y-----> x x-----> y + # |_______________| |_______|_______| + # 0 e0--> 1 + + # Refine the outer edges + E0i, E0 = self.refineEdge(f[FEDGE0]) + E1i, E1 = self.refineEdge(f[FEDGE1]) + E2i, E2 = self.refineEdge(f[FEDGE2]) + E3i, E3 = self.refineEdge(f[FEDGE3]) + + newNode, node = self.addNode(nodeNums) + + # Refine the inner edges + nE = np.zeros((4,6)) + nE[:, ACTIVE] = 1 + nE[:, PARENT] = -1 + nE[:, EDIR] = [0,0,1,1] if f[FDIR] == 2 else [0,0,2,2] if f[FDIR] == 1 else [1,1,2,2] + nE[0, ENODE0] = E2[0, ENODE1] + nE[0, ENODE1] = newNode + nE[1, ENODE0] = newNode + nE[1, ENODE1] = E3[0, ENODE1] + nE[2, ENODE0] = E0[0, ENODE1] + nE[2, ENODE1] = newNode + nE[3, ENODE0] = newNode + nE[3, ENODE1] = E1[0, ENODE1] + nEi, nE = self._push('_edges', nE) + + # Add four new faces + Fs = np.zeros((4,8)) + Fs[:, ACTIVE] = 1 + Fs[:, PARENT] = index + Fs[:, FDIR] = f[FDIR] + + fInds = [FEDGE0,FEDGE1,FEDGE2,FEDGE3] + Fs[0, fInds] = [E0i[0], nEi[0], E2i[0], nEi[2]] + Fs[1, fInds] = [E0i[1], nEi[1], nEi[2], E3i[0]] + Fs[2, fInds] = [nEi[0], E1i[0], E2i[1], nEi[3]] + Fs[3, fInds] = [nEi[1], E1i[1], nEi[3], E3i[1]] + + return self._push('_faces', Fs) + + @property + def nC(self): + if self.dim == 2: + return np.sum(self._faces[:,ACTIVE] == 1) + return np.sum(self._cells[:,ACTIVE] == 1) + + @property + def nE(self): + return np.sum(self._edges[:,ACTIVE] == 1) + + @property + def nF(self): + return np.sum(self._faces[:,ACTIVE] == 1) + + @property + def nEx(self): + return np.sum((self._edges[:,ACTIVE] == 1) & (self._edges[:,EDIR] == 0)) + + @property + def nEy(self): + return np.sum((self._edges[:,ACTIVE] == 1) & (self._edges[:,EDIR] == 1)) + + @property + def nEz(self): + if self.dim == 2: + return None + return np.sum((self._edges[:,ACTIVE] == 1) & (self._edges[:,EDIR] == 2)) + + @property + def nFx(self): + if self.dim == 2: + return self.nEy + return np.sum((self._faces[:,ACTIVE] == 1) & (self._faces[:,FDIR] == 0)) + + @property + def nFy(self): + if self.dim == 2: + return self.nEx + return np.sum((self._faces[:,ACTIVE] == 1) & (self._faces[:,FDIR] == 1)) + + @property + def nFz(self): + if self.dim == 2: + return None + return np.sum((self._faces[:,ACTIVE] == 1) & (self._faces[:,FDIR] == 1)) + + @property + def area(self): + if getattr(self, '_area', None) is None: + + N = self._nodes + E = self._edges + activeEdges = E[:,ACTIVE] == 1 + e0xy = N[E[activeEdges,ENODE0],:][:,[1,2]] + e1xy = N[E[activeEdges,ENODE1],:][:,[1,2]] + + self._area = np.sum((e1xy - e0xy)**2,axis=1)**0.5 + + return self._area + + + @property + def vol(self): + if getattr(self, '_vol', None) is None: + + N = self._nodes + E = self._edges + C = self._faces + activeCells = C[:,ACTIVE] == 1 + nInds1 = E[C[activeCells,FEDGE0],:][:,[ENODE0,ENODE1]] + nInds2 = E[C[activeCells,FEDGE1],:][:,[ENODE0,ENODE1]] + n0 = N[nInds1[:,0],:][:,[1,2]] # 2------3 3------2 + n1 = N[nInds1[:,1],:][:,[1,2]] # | | --> | | + n3 = N[nInds2[:,0],:][:,[1,2]] # | | | | + n2 = N[nInds2[:,1],:][:,[1,2]] # 0------1 0------1 + + a = np.sum((n1 - n0)**2,axis=1)**0.5 + b = np.sum((n2 - n1)**2,axis=1)**0.5 + c = np.sum((n3 - n2)**2,axis=1)**0.5 + d = np.sum((n0 - n3)**2,axis=1)**0.5 + p = np.sum((n2 - n0)**2,axis=1)**0.5 + q = np.sum((n3 - n1)**2,axis=1)**0.5 + + # Area of an arbitrary quadrilateral (in a plane) + self._vol = 0.25 * (4.0*(p**2)*(q**2) - (a**2 + c**2 - b**2 - d**2))**0.5 + + return self._vol + + @property + def gridCC(self): + N = self._nodes + E = self._edges + C = self._faces + activeCells = C[:,ACTIVE] == 1 + nInds1 = E[C[activeCells,FEDGE0],:][:,[ENODE0,ENODE1]] + nInds2 = E[C[activeCells,FEDGE1],:][:,[ENODE0,ENODE1]] + Cx = (N[nInds1[:,0],1] + N[nInds1[:,1],1] + N[nInds2[:,0],1] + N[nInds2[:,1],1])/4.0 + Cy = (N[nInds1[:,0],2] + N[nInds1[:,1],2] + N[nInds2[:,0],2] + N[nInds2[:,1],2])/4.0 + + P = SortByX0(np.c_[N[nInds1[:,0],1], N[nInds1[:,0],2]]) + if not self._numberedCC: + cnt = np.zeros(P.size, dtype=int) + cnt[P] = np.arange(P.size) + self._faces[activeCells, NUM] = cnt + self._numberedCC = True + + return np.c_[Cx,Cy][P, :] + + @property + def gridEx(self): + N = self._nodes + E = self._edges + C = self._faces + activeEdges = (E[:,ACTIVE] == 1) & (E[:,EDIR] == 0) + nInds = E[activeEdges,:][:,[ENODE0,ENODE1]] + Ex = (N[nInds[:,0],1] + N[nInds[:,1],1])/2.0 + Ey = (N[nInds[:,0],2] + N[nInds[:,1],2])/2.0 + + P = SortByX0(np.c_[N[nInds[:,0],1], N[nInds[:,0],2]]) + if not self._numberedEx: + cnt = np.zeros(P.size, dtype=int) + cnt[P] = np.arange(P.size) + self._edges[activeEdges, NUM] = cnt + self._numberedEx = True + + return np.c_[Ex,Ey][P, :] + + @property + def gridEy(self): + N = self._nodes + E = self._edges + C = self._faces + activeEdges = (E[:,ACTIVE] == 1) & (E[:,EDIR] == 1) + nInds = E[activeEdges,:][:,[ENODE0,ENODE1]] + Ex = (N[nInds[:,0],1] + N[nInds[:,1],1])/2.0 + Ey = (N[nInds[:,0],2] + N[nInds[:,1],2])/2.0 + + P = SortByX0(np.c_[N[nInds[:,0],1], N[nInds[:,0],2]]) + if not self._numberedEy: + cnt = np.zeros(P.size, dtype=int) + cnt[P] = np.arange(P.size) + self._edges[activeEdges, NUM] = cnt + self.nEx + self._numberedEy = True + + return np.c_[Ex,Ey][P, :] + + def _index(self, attr, index): + index = [index] if type(index) in [int, long] else list(index) + C = getattr(self, attr) + cSub = [] + iSub = [] + for I in index: + if C[I, ACTIVE] == 1: + iSub += [I] + cSub += [C[I, :]] + else: + subInds = np.argwhere(C[:,PARENT] == I).flatten() + i, c = self._index(attr, subInds) + iSub += i + cSub += [c] + return iSub, np.vstack(cSub) + + @property + def faceDiv(self): + if getattr(self, '_faceDiv', None) is None: + self.number() + # TODO: Preallocate! + I, J, V = [], [], [] + for cell in self.sortedCells: + faces = cell.faceDict + for face in faces: + j = faces[face].index + I += [cell.num]*len(j) + J += j + V += [-1 if 'm' in face else 1]*len(j) + VOL = self.vol + D = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.nF)) + S = self.area + self._faceDiv = Utils.sdiag(1/VOL)*D*Utils.sdiag(S) + return self._faceDiv + + def number(self): + self._nodes[:,NUM] = -1 + self._edges[:,NUM] = -1 + self._faces[:,NUM] = -1 + # self._cells[:,NUM] = -1 + self.gridCC + self.gridEx + self.gridEy + + def plotGrid(self, ax=None, text=True, showIt=False): + import matplotlib.pyplot as plt + + + axOpts = {'projection':'3d'} if self.dim == 3 else {} + if ax is None: ax = plt.subplot(111, **axOpts) + + N = self._nodes + E = self._edges + C = self._faces + + plt.plot(N[:,1], N[:,2], 'b.') + activeCells = C[:,ACTIVE] == 1 + for FEDGE in [FEDGE0, FEDGE1, FEDGE2, FEDGE3]: + nInds = E[C[activeCells,FEDGE],:][:,[ENODE0,ENODE1]] + eX = np.c_[N[nInds[:,0],1], N[nInds[:,1],1], [np.nan]*nInds.shape[0]] + eY = np.c_[N[nInds[:,0],2], N[nInds[:,1],2], [np.nan]*nInds.shape[0]] + plt.plot(eX.flatten(), eY.flatten(), 'b-') + + gridCC = self.gridCC + # if text: + # [ax.text(cc[0], cc[1],i) for i, cc in enumerate(gridCC)] + plt.plot(gridCC[:,0], gridCC[:,1], 'r.') + gridFx = self.gridEy + gridFy = self.gridEx + # if text: + # [ax.text(cc[0], cc[1],i) for i, cc in enumerate(np.vstack((gridFx,gridFy)))] + gridEx = self.gridEx + gridEy = self.gridEy + # if text: + # [ax.text(cc[0], cc[1],i) for i, cc in enumerate(np.vstack((gridEx,gridEy)))] + + for E in self._edges: + if E[ACTIVE] == 0: continue + ex = N[E[[ENODE0,ENODE1]],1] + ey = N[E[[ENODE0,ENODE1]],2] + ax.plot(ex, ey, 'b-') + ax.text(ex.mean(), ey.mean(), E[NUM]) + + if showIt: + plt.show() + +if __name__ == '__main__': + from SimPEG import Mesh, Utils + import matplotlib.pyplot as plt + + tM = TreeMesh(np.ones(3),np.ones(2)) + + tM.refineFace(0) + tM.refineFace(9) + + # print tM._faces + # print tM._edges[0,:] + # print tM.area + + + tM.number() + print tM._index('_edges',3)[1] + + # print tM._edges[:,[0,1,3, 4,5 ]] + + tM.plotGrid() + # plt.figure(2) + # plt.plot(SortByX0(tM.gridCC),'b.') + plt.show() + + + From a7a6671ad427b484c6eb01ab524995c0711934fe Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Mon, 9 Feb 2015 20:52:26 -0800 Subject: [PATCH 02/83] updates to tree mesh. faceDiv kinda working. --- SimPEG/Mesh/NewTreeMesh.py | 60 ++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 22 deletions(-) diff --git a/SimPEG/Mesh/NewTreeMesh.py b/SimPEG/Mesh/NewTreeMesh.py index f3ecf4dc..f7282c10 100644 --- a/SimPEG/Mesh/NewTreeMesh.py +++ b/SimPEG/Mesh/NewTreeMesh.py @@ -168,6 +168,8 @@ class TreeMesh(object): @property def nF(self): + if self.dim == 2: + return self.nFx + self.nFy return np.sum(self._faces[:,ACTIVE] == 1) @property @@ -240,7 +242,9 @@ class TreeMesh(object): q = np.sum((n3 - n1)**2,axis=1)**0.5 # Area of an arbitrary quadrilateral (in a plane) - self._vol = 0.25 * (4.0*(p**2)*(q**2) - (a**2 + c**2 - b**2 - d**2))**0.5 + V = 0.25 * (4.0*(p**2)*(q**2) - (a**2 + c**2 - b**2 - d**2))**0.5 + P = np.argsort(C[activeCells,NUM]) + self._vol = V[P] return self._vol @@ -303,7 +307,7 @@ class TreeMesh(object): return np.c_[Ex,Ey][P, :] def _index(self, attr, index): - index = [index] if type(index) in [int, long] else list(index) + index = [index] if np.isscalar(index) else list(index) C = getattr(self, attr) cSub = [] iSub = [] @@ -324,13 +328,21 @@ class TreeMesh(object): self.number() # TODO: Preallocate! I, J, V = [], [], [] - for cell in self.sortedCells: - faces = cell.faceDict - for face in faces: - j = faces[face].index - I += [cell.num]*len(j) - J += j - V += [-1 if 'm' in face else 1]*len(j) + nEx, nFx = self.nEx, self.nFx + + offset = np.r_[nFx, -nEx] + N = self._nodes + E = self._edges + C = self._faces + activeCells = C[:,ACTIVE] == 1 + for cell in C[activeCells]: + for sign, face in zip([-1,1,-1,1],[FEDGE0, FEDGE1, FEDGE2, FEDGE3]): + ij, jrow = self._index('_edges', cell[face]) + I += [cell[NUM]]*len(ij) + print jrow + J += list(jrow[:,0] + offset[jrow[:,EDIR]])# + nFx) + # J += list(jrow[:,0] - nEx) + V += [sign]*len(ij) VOL = self.vol D = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.nF)) S = self.area @@ -366,24 +378,24 @@ class TreeMesh(object): plt.plot(eX.flatten(), eY.flatten(), 'b-') gridCC = self.gridCC - # if text: - # [ax.text(cc[0], cc[1],i) for i, cc in enumerate(gridCC)] + if text: + [ax.text(cc[0], cc[1],i) for i, cc in enumerate(gridCC)] plt.plot(gridCC[:,0], gridCC[:,1], 'r.') gridFx = self.gridEy gridFy = self.gridEx - # if text: - # [ax.text(cc[0], cc[1],i) for i, cc in enumerate(np.vstack((gridFx,gridFy)))] + if text: + [ax.text(cc[0], cc[1],i) for i, cc in enumerate(np.vstack((gridFx,gridFy)))] gridEx = self.gridEx gridEy = self.gridEy # if text: # [ax.text(cc[0], cc[1],i) for i, cc in enumerate(np.vstack((gridEx,gridEy)))] - for E in self._edges: - if E[ACTIVE] == 0: continue - ex = N[E[[ENODE0,ENODE1]],1] - ey = N[E[[ENODE0,ENODE1]],2] - ax.plot(ex, ey, 'b-') - ax.text(ex.mean(), ey.mean(), E[NUM]) + # for E in self._edges: + # if E[ACTIVE] == 0: continue + # ex = N[E[[ENODE0,ENODE1]],1] + # ey = N[E[[ENODE0,ENODE1]],2] + # ax.plot(ex, ey, 'b-') + # ax.text(ex.mean(), ey.mean(), E[NUM]) if showIt: plt.show() @@ -402,12 +414,16 @@ if __name__ == '__main__': # print tM.area - tM.number() - print tM._index('_edges',3)[1] + # tM.number() + # print tM._index('_edges',3)[1] + + print tM.vol # print tM._edges[:,[0,1,3, 4,5 ]] - tM.plotGrid() + plt.subplot(211) + plt.spy(tM.faceDiv) + tM.plotGrid(ax=plt.subplot(212)) # plt.figure(2) # plt.plot(SortByX0(tM.gridCC),'b.') plt.show() From 310f327b5ad1313c63242d7acb639e32067bf437 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Mon, 9 Feb 2015 21:30:54 -0800 Subject: [PATCH 03/83] updates to edges and areas --- SimPEG/Mesh/NewTreeMesh.py | 120 ++++++++++++++++++++++++------------- 1 file changed, 77 insertions(+), 43 deletions(-) diff --git a/SimPEG/Mesh/NewTreeMesh.py b/SimPEG/Mesh/NewTreeMesh.py index f7282c10..a8741c0f 100644 --- a/SimPEG/Mesh/NewTreeMesh.py +++ b/SimPEG/Mesh/NewTreeMesh.py @@ -2,9 +2,10 @@ import numpy as np, scipy.sparse as sp from SimPEG.Utils import ndgrid, mkvc -NUM, PARENT, ACTIVE, EDIR, ENODE0, ENODE1 = range(6) -NUM, PARENT, ACTIVE, FDIR, FEDGE0, FEDGE1, FEDGE2, FEDGE3 = range(8) -NUM, PARENT, ACTIVE, CFACE0, CFACE1, CFACE2, CFACE3, CFACE4, CFACE5 = range(9) +NUM, ACTIVE, NX, NY, NZ = range(5) +NUM, ACTIVE, PARENT, EDIR, ENODE0, ENODE1 = range(6) +NUM, ACTIVE, PARENT, FDIR, FEDGE0, FEDGE1, FEDGE2, FEDGE3 = range(8) +NUM, ACTIVE, PARENT, CFACE0, CFACE1, CFACE2, CFACE3, CFACE4, CFACE5 = range(9) def SortByX0(grid): dtype=[('x',float),('y',float)] @@ -24,9 +25,7 @@ class TreeMesh(object): vnN = [nx.size, ny.size] XY = ndgrid(nx, ny) - N = np.c_[np.arange(XY.shape[0]), XY] - - N.astype([('num',int),('x',float),('y',float),('z',float)]) + N = np.c_[np.arange(XY.shape[0]), np.ones(XY.shape[0]), XY] I = np.arange(nx.size * ny.size, dtype=int).reshape(vnN, order='F') @@ -39,13 +38,13 @@ class TreeMesh(object): zEx = np.zeros(nEx.size, dtype=int) zEy = np.zeros(nEy.size, dtype=int) - # # parent active dir, n1,n2 - Ex = np.c_[mkvc(nEx), zEx-1, zEx+1, zEx+0, vEx] - Ey = np.c_[mkvc(nEy), zEy-1, zEy+1, zEy+1, vEy] + # # active parent dir, n1,n2 + Ex = np.c_[mkvc(nEx), zEx+1, zEx-1, zEx+0, vEx] + Ey = np.c_[mkvc(nEy), zEy+1, zEy-1, zEy+1, vEy] nC = np.arange(np.prod(vnC), dtype=int) - C = np.c_[nC, nC*0-1, nC*0+1, nC*0+2, mkvc(nEx[:,:-1]), mkvc(nEx[:,1:]), mkvc(nEy[:-1,:]), mkvc(nEy[1:,:])] + C = np.c_[nC, nC*0+1, nC*0-1, nC*0+2, mkvc(nEx[:,:-1]), mkvc(nEx[:,1:]), mkvc(nEy[:-1,:]), mkvc(nEy[1:,:])] self._nodes = N self._edges = np.r_[Ex, Ey] @@ -55,13 +54,16 @@ class TreeMesh(object): @property def isNumbered(self): - return self._numberedCC and self._numberedFx and self._numberedFy + return self._numberedCC and self._numberedEx and self._numberedEy @isNumbered.setter def isNumbered(self, value): assert value is False, 'Can only set to False.' self._numberedCC = False self._numberedEx = False self._numberedEy = False + for name in ['vol', 'area', 'edge', 'gridCC', 'gridN', 'gridEx', 'gridEy', 'gridEz', 'gridFx', 'gridFy', 'gridFz']: + if hasattr(self, '_'+name): + delattr(self, '_'+name) @property def dim(self): @@ -84,6 +86,7 @@ class TreeMesh(object): between = np.array(between).flatten() nodes = self._nodes[between.astype(int), :] newNode = np.mean(nodes, axis=0) + newNode[ACTIVE] = 1 return self._push('_nodes', newNode) def refineEdge(self, index): @@ -162,6 +165,10 @@ class TreeMesh(object): return np.sum(self._faces[:,ACTIVE] == 1) return np.sum(self._cells[:,ACTIVE] == 1) + @property + def nN(self): + return np.sum(self._cells[:,ACTIVE] == 1) + @property def nE(self): return np.sum(self._edges[:,ACTIVE] == 1) @@ -205,16 +212,29 @@ class TreeMesh(object): return np.sum((self._faces[:,ACTIVE] == 1) & (self._faces[:,FDIR] == 1)) @property - def area(self): - if getattr(self, '_area', None) is None: + def edge(self): + if getattr(self, '_edge', None) is None: + self.number() N = self._nodes E = self._edges activeEdges = E[:,ACTIVE] == 1 - e0xy = N[E[activeEdges,ENODE0],:][:,[1,2]] - e1xy = N[E[activeEdges,ENODE1],:][:,[1,2]] + e0xy = N[E[activeEdges,ENODE0],:][:,[NX,NY]] + e1xy = N[E[activeEdges,ENODE1],:][:,[NX,NY]] - self._area = np.sum((e1xy - e0xy)**2,axis=1)**0.5 + A = np.sum((e1xy - e0xy)**2,axis=1)**0.5 + + P = np.argsort(E[activeEdges,NUM]) + self._edge = A[P] + + return self._edge + + @property + def area(self): + if getattr(self, '_area', None) is None: + self.number() + if self.dim == 2: + self._area = np.r_[self.edge[self.nEx:], self.edge[:self.nEx]] return self._area @@ -222,6 +242,7 @@ class TreeMesh(object): @property def vol(self): if getattr(self, '_vol', None) is None: + self.number() N = self._nodes E = self._edges @@ -229,10 +250,10 @@ class TreeMesh(object): activeCells = C[:,ACTIVE] == 1 nInds1 = E[C[activeCells,FEDGE0],:][:,[ENODE0,ENODE1]] nInds2 = E[C[activeCells,FEDGE1],:][:,[ENODE0,ENODE1]] - n0 = N[nInds1[:,0],:][:,[1,2]] # 2------3 3------2 - n1 = N[nInds1[:,1],:][:,[1,2]] # | | --> | | - n3 = N[nInds2[:,0],:][:,[1,2]] # | | | | - n2 = N[nInds2[:,1],:][:,[1,2]] # 0------1 0------1 + n0 = N[nInds1[:,0],:][:,[NX,NY]] # 2------3 3------2 + n1 = N[nInds1[:,1],:][:,[NX,NY]] # | | --> | | + n3 = N[nInds2[:,0],:][:,[NX,NY]] # | | | | + n2 = N[nInds2[:,1],:][:,[NX,NY]] # 0------1 0------1 a = np.sum((n1 - n0)**2,axis=1)**0.5 b = np.sum((n2 - n1)**2,axis=1)**0.5 @@ -256,10 +277,10 @@ class TreeMesh(object): activeCells = C[:,ACTIVE] == 1 nInds1 = E[C[activeCells,FEDGE0],:][:,[ENODE0,ENODE1]] nInds2 = E[C[activeCells,FEDGE1],:][:,[ENODE0,ENODE1]] - Cx = (N[nInds1[:,0],1] + N[nInds1[:,1],1] + N[nInds2[:,0],1] + N[nInds2[:,1],1])/4.0 - Cy = (N[nInds1[:,0],2] + N[nInds1[:,1],2] + N[nInds2[:,0],2] + N[nInds2[:,1],2])/4.0 + Cx = (N[nInds1[:,0],NX] + N[nInds1[:,1],NX] + N[nInds2[:,0],NX] + N[nInds2[:,1],NX])/4.0 + Cy = (N[nInds1[:,0],NY] + N[nInds1[:,1],NY] + N[nInds2[:,0],NY] + N[nInds2[:,1],NY])/4.0 - P = SortByX0(np.c_[N[nInds1[:,0],1], N[nInds1[:,0],2]]) + P = SortByX0(np.c_[N[nInds1[:,0],NX], N[nInds1[:,0],NY]]) if not self._numberedCC: cnt = np.zeros(P.size, dtype=int) cnt[P] = np.arange(P.size) @@ -275,10 +296,10 @@ class TreeMesh(object): C = self._faces activeEdges = (E[:,ACTIVE] == 1) & (E[:,EDIR] == 0) nInds = E[activeEdges,:][:,[ENODE0,ENODE1]] - Ex = (N[nInds[:,0],1] + N[nInds[:,1],1])/2.0 - Ey = (N[nInds[:,0],2] + N[nInds[:,1],2])/2.0 + Ex = (N[nInds[:,0],NX] + N[nInds[:,1],NX])/2.0 + Ey = (N[nInds[:,0],NY] + N[nInds[:,1],NY])/2.0 - P = SortByX0(np.c_[N[nInds[:,0],1], N[nInds[:,0],2]]) + P = SortByX0(np.c_[N[nInds[:,0],NX], N[nInds[:,0],NY]]) if not self._numberedEx: cnt = np.zeros(P.size, dtype=int) cnt[P] = np.arange(P.size) @@ -294,10 +315,10 @@ class TreeMesh(object): C = self._faces activeEdges = (E[:,ACTIVE] == 1) & (E[:,EDIR] == 1) nInds = E[activeEdges,:][:,[ENODE0,ENODE1]] - Ex = (N[nInds[:,0],1] + N[nInds[:,1],1])/2.0 - Ey = (N[nInds[:,0],2] + N[nInds[:,1],2])/2.0 + Ex = (N[nInds[:,0],NX] + N[nInds[:,1],NX])/2.0 + Ey = (N[nInds[:,0],NY] + N[nInds[:,1],NY])/2.0 - P = SortByX0(np.c_[N[nInds[:,0],1], N[nInds[:,0],2]]) + P = SortByX0(np.c_[N[nInds[:,0],NX], N[nInds[:,0],NY]]) if not self._numberedEy: cnt = np.zeros(P.size, dtype=int) cnt[P] = np.arange(P.size) @@ -306,6 +327,17 @@ class TreeMesh(object): return np.c_[Ex,Ey][P, :] + + @property + def gridFx(self): + if self.dim == 2: + return self.gridEy + + @property + def gridFy(self): + if self.dim == 2: + return self.gridEx + def _index(self, attr, index): index = [index] if np.isscalar(index) else list(index) C = getattr(self, attr) @@ -328,20 +360,15 @@ class TreeMesh(object): self.number() # TODO: Preallocate! I, J, V = [], [], [] - nEx, nFx = self.nEx, self.nFx - offset = np.r_[nFx, -nEx] - N = self._nodes - E = self._edges + offset = np.r_[self.nFx, -self.nEx] # this switches from edge to face numbering C = self._faces activeCells = C[:,ACTIVE] == 1 for cell in C[activeCells]: for sign, face in zip([-1,1,-1,1],[FEDGE0, FEDGE1, FEDGE2, FEDGE3]): ij, jrow = self._index('_edges', cell[face]) I += [cell[NUM]]*len(ij) - print jrow - J += list(jrow[:,0] + offset[jrow[:,EDIR]])# + nFx) - # J += list(jrow[:,0] - nEx) + J += list(jrow[:,0] + offset[jrow[:,EDIR]]) V += [sign]*len(ij) VOL = self.vol D = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.nF)) @@ -350,6 +377,8 @@ class TreeMesh(object): return self._faceDiv def number(self): + if self.isNumbered: + return self._nodes[:,NUM] = -1 self._edges[:,NUM] = -1 self._faces[:,NUM] = -1 @@ -373,16 +402,16 @@ class TreeMesh(object): activeCells = C[:,ACTIVE] == 1 for FEDGE in [FEDGE0, FEDGE1, FEDGE2, FEDGE3]: nInds = E[C[activeCells,FEDGE],:][:,[ENODE0,ENODE1]] - eX = np.c_[N[nInds[:,0],1], N[nInds[:,1],1], [np.nan]*nInds.shape[0]] - eY = np.c_[N[nInds[:,0],2], N[nInds[:,1],2], [np.nan]*nInds.shape[0]] + eX = np.c_[N[nInds[:,0],NX], N[nInds[:,1],NX], [np.nan]*nInds.shape[0]] + eY = np.c_[N[nInds[:,0],NY], N[nInds[:,1],NY], [np.nan]*nInds.shape[0]] plt.plot(eX.flatten(), eY.flatten(), 'b-') gridCC = self.gridCC if text: [ax.text(cc[0], cc[1],i) for i, cc in enumerate(gridCC)] plt.plot(gridCC[:,0], gridCC[:,1], 'r.') - gridFx = self.gridEy - gridFy = self.gridEx + gridFx = self.gridFx + gridFy = self.gridFy if text: [ax.text(cc[0], cc[1],i) for i, cc in enumerate(np.vstack((gridFx,gridFy)))] gridEx = self.gridEx @@ -392,8 +421,8 @@ class TreeMesh(object): # for E in self._edges: # if E[ACTIVE] == 0: continue - # ex = N[E[[ENODE0,ENODE1]],1] - # ey = N[E[[ENODE0,ENODE1]],2] + # ex = N[E[[ENODE0,ENODE1]],NX] + # ey = N[E[[ENODE0,ENODE1]],NY] # ax.plot(ex, ey, 'b-') # ax.text(ex.mean(), ey.mean(), E[NUM]) @@ -417,13 +446,18 @@ if __name__ == '__main__': # tM.number() # print tM._index('_edges',3)[1] - print tM.vol # print tM._edges[:,[0,1,3, 4,5 ]] plt.subplot(211) plt.spy(tM.faceDiv) tM.plotGrid(ax=plt.subplot(212)) + + + print tM.vol + print tM.area + print tM.edge + # plt.figure(2) # plt.plot(SortByX0(tM.gridCC),'b.') plt.show() From 5e5a3221e8431b54d5d0624c5efc70e43f22fc3c Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Mon, 9 Feb 2015 21:48:42 -0800 Subject: [PATCH 04/83] test simple grid functions add Nodal Grid --- SimPEG/Mesh/NewTreeMesh.py | 29 +++++++++++++--- SimPEG/Tests/test_NewTreeMesh.py | 59 ++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 5 deletions(-) create mode 100644 SimPEG/Tests/test_NewTreeMesh.py diff --git a/SimPEG/Mesh/NewTreeMesh.py b/SimPEG/Mesh/NewTreeMesh.py index a8741c0f..6e068b87 100644 --- a/SimPEG/Mesh/NewTreeMesh.py +++ b/SimPEG/Mesh/NewTreeMesh.py @@ -18,7 +18,8 @@ def SortByX0(grid): class TreeMesh(object): - def __init__(self, hx, hy): + def __init__(self, h): + hx, hy = h nx = np.r_[0,hx.cumsum()] ny = np.r_[0,hy.cumsum()] vnC = [nx.size-1, ny.size-1] @@ -54,11 +55,12 @@ class TreeMesh(object): @property def isNumbered(self): - return self._numberedCC and self._numberedEx and self._numberedEy + return self._numberedCC and self._numberedN and self._numberedEx and self._numberedEy @isNumbered.setter def isNumbered(self, value): assert value is False, 'Can only set to False.' self._numberedCC = False + self._numberedN = False self._numberedEx = False self._numberedEy = False for name in ['vol', 'area', 'edge', 'gridCC', 'gridN', 'gridEx', 'gridEy', 'gridEz', 'gridFx', 'gridFy', 'gridFz']: @@ -269,6 +271,22 @@ class TreeMesh(object): return self._vol + @property + def gridN(self): + N = self._nodes + activeNodes = N[:,ACTIVE] == 1 + Nx = N[activeNodes,NX] + Ny = N[activeNodes,NY] + + P = SortByX0(np.c_[Nx, Ny]) + if not self._numberedN: + cnt = np.zeros(P.size, dtype=int) + cnt[P] = np.arange(P.size) + self._nodes[activeNodes, NUM] = cnt + self._numberedN = True + + return np.c_[Nx, Ny][P, :] + @property def gridCC(self): N = self._nodes @@ -287,7 +305,7 @@ class TreeMesh(object): self._faces[activeCells, NUM] = cnt self._numberedCC = True - return np.c_[Cx,Cy][P, :] + return np.c_[Cx, Cy][P, :] @property def gridEx(self): @@ -306,7 +324,7 @@ class TreeMesh(object): self._edges[activeEdges, NUM] = cnt self._numberedEx = True - return np.c_[Ex,Ey][P, :] + return np.c_[Ex, Ey][P, :] @property def gridEy(self): @@ -325,7 +343,7 @@ class TreeMesh(object): self._edges[activeEdges, NUM] = cnt + self.nEx self._numberedEy = True - return np.c_[Ex,Ey][P, :] + return np.c_[Ex, Ey][P, :] @property @@ -384,6 +402,7 @@ class TreeMesh(object): self._faces[:,NUM] = -1 # self._cells[:,NUM] = -1 self.gridCC + self.gridN self.gridEx self.gridEy diff --git a/SimPEG/Tests/test_NewTreeMesh.py b/SimPEG/Tests/test_NewTreeMesh.py new file mode 100644 index 00000000..430766ca --- /dev/null +++ b/SimPEG/Tests/test_NewTreeMesh.py @@ -0,0 +1,59 @@ +from SimPEG.Mesh import TensorMesh +from SimPEG.Mesh.NewTreeMesh import TreeMesh +import numpy as np +import unittest +import matplotlib.pyplot as plt + +TOL = 1e-10 + +class TestQuadTreeMesh(unittest.TestCase): + + def setUp(self): + M = TreeMesh([np.ones(x) for x in [3,2]]) + M.refineFace(0) + self.M = M + M.number() + # M.plotGrid(showIt=True) + + def test_MeshSizes(self): + self.assertTrue(self.M.nC==9) + self.assertTrue(self.M.nF==25) + self.assertTrue(self.M.nFx==12) + self.assertTrue(self.M.nFy==13) + self.assertTrue(self.M.nE==25) + self.assertTrue(self.M.nEx==13) + self.assertTrue(self.M.nEy==12) + + def test_gridCC(self): + x = np.r_[0.25,0.75,1.5,2.5,0.25,0.75,0.5,1.5,2.5] + y = np.r_[0.25,0.25,0.5,0.5,0.75,0.75,1.5,1.5,1.5] + self.assertTrue(np.linalg.norm((np.c_[x,y]-self.M.gridCC).flatten()) == 0) + + def test_gridN(self): + x = np.r_[0,0.5,1,2,3,0,0.5,1,0,0.5,1,2,3,0,1,2,3] + y = np.r_[0,0,0,0,0,.5,.5,.5,1,1,1,1,1,2,2,2,2] + self.assertTrue(np.linalg.norm((np.c_[x,y]-self.M.gridN).flatten()) == 0) + + def test_gridFx(self): + x = np.r_[0.0,0.5,1.0,2.0,3.0,0.0,0.5,1.0,0.0,1.0,2.0,3.0] + y = np.r_[0.25,0.25,0.25,0.5,0.5,0.75,0.75,0.75,1.5,1.5,1.5,1.5] + self.assertTrue(np.linalg.norm((np.c_[x,y]-self.M.gridFx).flatten()) == 0) + + def test_gridFy(self): + x = np.r_[0.25,0.75,1.5,2.5,0.25,0.75,0.25,0.75,1.5,2.5,0.5,1.5,2.5] + y = np.r_[0,0,0,0,0.5,0.5,1,1,1,1,2,2,2] + self.assertTrue(np.linalg.norm((np.c_[x,y]-self.M.gridFy).flatten()) == 0) + + def test_gridEx(self): + x = np.r_[0.25,0.75,1.5,2.5,0.25,0.75,0.25,0.75,1.5,2.5,0.5,1.5,2.5] + y = np.r_[0,0,0,0,0.5,0.5,1,1,1,1,2,2,2] + self.assertTrue(np.linalg.norm((np.c_[x,y]-self.M.gridEx).flatten()) == 0) + + def test_gridEy(self): + x = np.r_[0.0,0.5,1.0,2.0,3.0,0.0,0.5,1.0,0.0,1.0,2.0,3.0] + y = np.r_[0.25,0.25,0.25,0.5,0.5,0.75,0.75,0.75,1.5,1.5,1.5,1.5] + self.assertTrue(np.linalg.norm((np.c_[x,y]-self.M.gridEy).flatten()) == 0) + + +if __name__ == '__main__': + unittest.main() From 9a8f4d60f75ceab3ef10d89af1a59ea87aa6bc53 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Mon, 9 Feb 2015 21:59:28 -0800 Subject: [PATCH 05/83] test area edge vol --- SimPEG/Tests/test_NewTreeMesh.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/SimPEG/Tests/test_NewTreeMesh.py b/SimPEG/Tests/test_NewTreeMesh.py index 430766ca..21a44220 100644 --- a/SimPEG/Tests/test_NewTreeMesh.py +++ b/SimPEG/Tests/test_NewTreeMesh.py @@ -54,6 +54,20 @@ class TestQuadTreeMesh(unittest.TestCase): y = np.r_[0.25,0.25,0.25,0.5,0.5,0.75,0.75,0.75,1.5,1.5,1.5,1.5] self.assertTrue(np.linalg.norm((np.c_[x,y]-self.M.gridEy).flatten()) == 0) + def test_vol(self): + v = np.r_[0.25,0.25,1,1,0.25,0.25,1,1,1] + self.assertTrue(np.linalg.norm((v-self.M.vol)) < TOL) + + def test_edge(self): + ex = np.r_[0.5,0.5,1,1,0.5,0.5,0.5,0.5,1,1,1,1,1] + ey = np.r_[0.5,0.5,0.5,1,1,0.5,0.5,0.5,1,1,1,1] + self.assertTrue(np.linalg.norm((np.r_[ex,ey]-self.M.edge)) < TOL) + + def test_area(self): + ax = np.r_[0.5,0.5,0.5,1,1,0.5,0.5,0.5,1,1,1,1] + ay = np.r_[0.5,0.5,1,1,0.5,0.5,0.5,0.5,1,1,1,1,1] + self.assertTrue(np.linalg.norm((np.r_[ax,ay]-self.M.area)) < TOL) + if __name__ == '__main__': unittest.main() From 006dcf393d1667ab1bd43c3c9e20d4b9365b0134 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Mon, 9 Feb 2015 22:12:22 -0800 Subject: [PATCH 06/83] updates to area calculation --- SimPEG/Mesh/NewTreeMesh.py | 12 +++++------ SimPEG/Tests/test_NewTreeMesh.py | 34 ++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/SimPEG/Mesh/NewTreeMesh.py b/SimPEG/Mesh/NewTreeMesh.py index 6e068b87..38aa375c 100644 --- a/SimPEG/Mesh/NewTreeMesh.py +++ b/SimPEG/Mesh/NewTreeMesh.py @@ -1,5 +1,5 @@ import numpy as np, scipy.sparse as sp -from SimPEG.Utils import ndgrid, mkvc +from SimPEG.Utils import ndgrid, mkvc, sdiag NUM, ACTIVE, NX, NY, NZ = range(5) @@ -265,7 +265,7 @@ class TreeMesh(object): q = np.sum((n3 - n1)**2,axis=1)**0.5 # Area of an arbitrary quadrilateral (in a plane) - V = 0.25 * (4.0*(p**2)*(q**2) - (a**2 + c**2 - b**2 - d**2))**0.5 + V = 0.25 * (4.0*(p**2)*(q**2) - (a**2 + c**2 - b**2 - d**2)**2)**0.5 P = np.argsort(C[activeCells,NUM]) self._vol = V[P] @@ -391,7 +391,7 @@ class TreeMesh(object): VOL = self.vol D = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.nF)) S = self.area - self._faceDiv = Utils.sdiag(1/VOL)*D*Utils.sdiag(S) + self._faceDiv = sdiag(1/VOL)*D*sdiag(S) return self._faceDiv def number(self): @@ -452,10 +452,10 @@ if __name__ == '__main__': from SimPEG import Mesh, Utils import matplotlib.pyplot as plt - tM = TreeMesh(np.ones(3),np.ones(2)) + tM = TreeMesh([np.ones(3),np.ones(2)]) - tM.refineFace(0) - tM.refineFace(9) + # tM.refineFace(0) + # tM.refineFace(9) # print tM._faces # print tM._edges[0,:] diff --git a/SimPEG/Tests/test_NewTreeMesh.py b/SimPEG/Tests/test_NewTreeMesh.py index 21a44220..3d9807e5 100644 --- a/SimPEG/Tests/test_NewTreeMesh.py +++ b/SimPEG/Tests/test_NewTreeMesh.py @@ -69,5 +69,39 @@ class TestQuadTreeMesh(unittest.TestCase): self.assertTrue(np.linalg.norm((np.r_[ax,ay]-self.M.area)) < TOL) + +class SimpleOctreeOperatorTests(unittest.TestCase): + + def setUp(self): + h1 = np.random.rand(5) + h2 = np.random.rand(7) + h3 = np.random.rand(3) + # self.tM = TensorMesh([h1,h2,h3]) + # self.oM = TreeMesh([h1,h2,h3]) + self.tM2 = TensorMesh([h1,h2]) + self.oM2 = TreeMesh([h1,h2]) + # self.oM2.plotGrid(showIt=True) + + def test_faceDiv(self): + # self.assertAlmostEqual((self.tM.faceDiv - self.oM.faceDiv).toarray().sum(), 0) + self.assertAlmostEqual((self.tM2.faceDiv - self.oM2.faceDiv).toarray().sum(), 0) + + # def test_nodalGrad(self): + # self.assertAlmostEqual((self.tM.nodalGrad - self.oM.nodalGrad).toarray().sum(), 0) + # self.assertAlmostEqual((self.tM2.nodalGrad - self.oM2.nodalGrad).toarray().sum(), 0) + + # def test_edgeCurl(self): + # self.assertAlmostEqual((self.tM.edgeCurl - self.oM.edgeCurl).toarray().sum(), 0) + # # self.assertAlmostEqual((self.tM2.edgeCurl - self.oM2.edgeCurl).toarray().sum(), 0) + + # def test_InnerProducts(self): + # self.assertAlmostEqual((self.tM.getFaceInnerProduct() - self.oM.getFaceInnerProduct()).toarray().sum(), 0) + # self.assertAlmostEqual((self.tM2.getFaceInnerProduct() - self.oM2.getFaceInnerProduct()).toarray().sum(), 0) + # self.assertAlmostEqual((self.tM2.getEdgeInnerProduct() - self.oM2.getEdgeInnerProduct()).toarray().sum(), 0) + # self.assertAlmostEqual((self.tM.getEdgeInnerProduct() - self.oM.getEdgeInnerProduct()).toarray().sum(), 0) + + + + if __name__ == '__main__': unittest.main() From 156b85319c672b390146b098201364da024a4f21 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Mon, 9 Feb 2015 22:51:52 -0800 Subject: [PATCH 07/83] updates to multiple edge refinement --- SimPEG/Mesh/NewTreeMesh.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/SimPEG/Mesh/NewTreeMesh.py b/SimPEG/Mesh/NewTreeMesh.py index 38aa375c..42848992 100644 --- a/SimPEG/Mesh/NewTreeMesh.py +++ b/SimPEG/Mesh/NewTreeMesh.py @@ -93,6 +93,11 @@ class TreeMesh(object): def refineEdge(self, index): e = self._edges[index,:] + if e[ACTIVE] == 0: + # search for the children up to one level deep + subInds = np.argwhere(self._edges[:,PARENT] == index).flatten() + return subInds, self._edges[subInds,:] + self._edges[index, ACTIVE] = 0 newNode, node = self.addNode(e[[ENODE0, ENODE1]]) @@ -454,8 +459,10 @@ if __name__ == '__main__': tM = TreeMesh([np.ones(3),np.ones(2)]) - # tM.refineFace(0) - # tM.refineFace(9) + tM.refineFace(0) + tM.refineFace(1) + tM.refineFace(3) + tM.refineFace(9) # print tM._faces # print tM._edges[0,:] From e0303b8dffc72ca5173608b2ba9461bf394bc677 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Mon, 9 Feb 2015 22:52:08 -0800 Subject: [PATCH 08/83] multi face refinement --- SimPEG/Mesh/NewTreeMesh.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/SimPEG/Mesh/NewTreeMesh.py b/SimPEG/Mesh/NewTreeMesh.py index 42848992..7bc904c2 100644 --- a/SimPEG/Mesh/NewTreeMesh.py +++ b/SimPEG/Mesh/NewTreeMesh.py @@ -114,7 +114,10 @@ class TreeMesh(object): def refineFace(self, index): f = self._faces[index,:] - nodeNums = self._edges[f[[FEDGE0, FEDGE1]],:][:,[ENODE0, ENODE1]] + if f[ACTIVE] == 0: + # search for the children up to one level deep + subInds = np.argwhere(self._faces[:,PARENT] == index).flatten() + return subInds, self._faces[subInds,:] self._faces[index, ACTIVE] = 0 @@ -135,6 +138,7 @@ class TreeMesh(object): E2i, E2 = self.refineEdge(f[FEDGE2]) E3i, E3 = self.refineEdge(f[FEDGE3]) + nodeNums = self._edges[f[[FEDGE0, FEDGE1]],:][:,[ENODE0, ENODE1]] newNode, node = self.addNode(nodeNums) # Refine the inner edges @@ -479,11 +483,6 @@ if __name__ == '__main__': plt.spy(tM.faceDiv) tM.plotGrid(ax=plt.subplot(212)) - - print tM.vol - print tM.area - print tM.edge - # plt.figure(2) # plt.plot(SortByX0(tM.gridCC),'b.') plt.show() From 1c40cbb9721222cb47fcbe98e7796237c61243f5 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Tue, 10 Feb 2015 12:34:48 -0800 Subject: [PATCH 09/83] init3D --- SimPEG/Mesh/NewTreeMesh.py | 394 +++++++++++++++++++++++++------------ 1 file changed, 264 insertions(+), 130 deletions(-) diff --git a/SimPEG/Mesh/NewTreeMesh.py b/SimPEG/Mesh/NewTreeMesh.py index 7bc904c2..233630db 100644 --- a/SimPEG/Mesh/NewTreeMesh.py +++ b/SimPEG/Mesh/NewTreeMesh.py @@ -1,5 +1,6 @@ import numpy as np, scipy.sparse as sp from SimPEG.Utils import ndgrid, mkvc, sdiag +from BaseMesh import BaseMesh NUM, ACTIVE, NX, NY, NZ = range(5) @@ -16,42 +17,172 @@ def SortByX0(grid): return P -class TreeMesh(object): +class TreeMesh(BaseMesh): - def __init__(self, h): - hx, hy = h - nx = np.r_[0,hx.cumsum()] - ny = np.r_[0,hy.cumsum()] - vnC = [nx.size-1, ny.size-1] - vnN = [nx.size, ny.size] + def __init__(self, h_in, x0=None): + assert type(h_in) in [list, tuple], 'h_in must be a list' + assert len(h_in) > 1, "len(h_in) must be greater than 1" - XY = ndgrid(nx, ny) - N = np.c_[np.arange(XY.shape[0]), np.ones(XY.shape[0]), XY] + h = range(len(h_in)) + for i, h_i in enumerate(h_in): + if type(h_i) in [int, long, float]: + # This gives you something over the unit cube. + h_i = np.ones(int(h_i))/int(h_i) + assert isinstance(h_i, np.ndarray), ("h[%i] is not a numpy array." % i) + assert len(h_i.shape) == 1, ("h[%i] must be a 1D numpy array." % i) + h[i] = h_i[:] # make a copy. + self.h = h - I = np.arange(nx.size * ny.size, dtype=int).reshape(vnN, order='F') + if x0 is None: + x0 = np.zeros(len(h)) + else: + assert type(x0) in [list, tuple, np.ndarray], 'x0 must be an array' + x0 = np.array(x0, dtype=float) + assert len(x0) == self.dim, 'x0 must have the same dimensions as the mesh' - vEx = np.c_[mkvc(I[:-1,:]), mkvc(I[1:,:])] - vEy = np.c_[mkvc(I[:,:-1]), mkvc(I[:,1:])] + # TODO: this has a lot of stuff which doesn't work for this style of mesh... + BaseMesh.__init__(self, np.array([x.size for x in h]), x0) + if self.dim == 2: + self._init2D() + else: + self._init3D() - nEx = np.arange(vEx.shape[0], dtype=int).reshape(nx.size-1, ny.size, order='F') - nEy = np.arange(vEy.shape[0], dtype=int).reshape(nx.size, ny.size-1, order='F') + vEx.shape[0] + self.isNumbered = False - zEx = np.zeros(nEx.size, dtype=int) - zEy = np.zeros(nEy.size, dtype=int) + def _init2D(self): + XY = ndgrid(*[np.r_[0, h.cumsum()] for h in self.h]) - # # active parent dir, n1,n2 - Ex = np.c_[mkvc(nEx), zEx+1, zEx-1, zEx+0, vEx] - Ey = np.c_[mkvc(nEy), zEy+1, zEy-1, zEy+1, vEy] + nCx, nCy = [len(h) for h in self.h] - nC = np.arange(np.prod(vnC), dtype=int) + vnC = [nCx , nCy ] + vnN = [nCx+1, nCy+1] - C = np.c_[nC, nC*0+1, nC*0-1, nC*0+2, mkvc(nEx[:,:-1]), mkvc(nEx[:,1:]), mkvc(nEy[:-1,:]), mkvc(nEy[1:,:])] + vnEx = [nCx , nCy+1] + vnEy = [nCx+1, nCy ] + + vnFx = [nCx+1, nCy ] + vnFy = [nCx , nCy+1] + + nC = np.prod(vnC) + nN = np.prod(vnN) + nFx = np.prod(vnFx) + nFy = np.prod(vnFy) + nF = nFx + nFy + nEx = np.prod(vnEx) + nEy = np.prod(vnEy) + nE = nEx + nEy + + N = np.c_[np.arange(nN), np.ones(nN), XY] + + iN = np.arange(nN, dtype=int).reshape(vnN, order='F') + + # Pointers to the nodes for the edges + pnEx = np.c_[mkvc(iN[:-1,:]), mkvc(iN[1:,:])] + pnEy = np.c_[mkvc(iN[:,:-1]), mkvc(iN[:,1:])] + + iEx = np.arange(nEx, dtype=int).reshape(*vnEx, order='F') + iEy = np.arange(nEy, dtype=int).reshape(*vnEy, order='F') + nEx + + zEx = np.zeros(nEx, dtype=int) + zEy = np.zeros(nEy, dtype=int) + + Ex = np.c_[mkvc(iEx), zEx+1, zEx-1, zEx+0, pnEx] + Ey = np.c_[mkvc(iEy), zEy+1, zEy-1, zEy+1, pnEy] + + # Pointers to the edges for the faces + vFz = np.c_[mkvc(iEx[:,:-1]), mkvc(iEx[:,1:]), mkvc(iEy[:-1,:]), mkvc(iEy[1:,:])] + + iC = np.arange(nC, dtype=int) + + zC = np.zeros(nC, dtype=int) + + C = np.c_[iC, zC+1, zC-1, zC+2, vFz] self._nodes = N self._edges = np.r_[Ex, Ey] self._faces = C - self.isNumbered = False + + def _init3D(self): + XYZ = ndgrid(*[np.r_[0, h.cumsum()] for h in self.h]) + + nCx, nCy, nCz = [len(h) for h in self.h] + + vnC = [nCx , nCy , nCz ] + vnN = [nCx+1, nCy+1, nCz+1] + + vnEx = [nCx , nCy+1, nCz+1] + vnEy = [nCx+1, nCy , nCz+1] + vnEz = [nCx+1, nCy+1, nCz ] + + vnFx = [nCx+1, nCy , nCz ] + vnFy = [nCx , nCy+1, nCz ] + vnFz = [nCx , nCy , nCz+1] + + nC = np.prod(vnC) + nN = np.prod(vnN) + nFx = np.prod(vnFx) + nFy = np.prod(vnFy) + nFz = np.prod(vnFz) + nF = nFx + nFy + nFz + nEx = np.prod(vnEx) + nEy = np.prod(vnEy) + nEz = np.prod(vnEz) + nE = nEx + nEy + nEz + + N = np.c_[np.arange(XYZ.shape[0]), np.ones(XYZ.shape[0]), XYZ] + + iN = np.arange(nN, dtype=int).reshape(vnN, order='F') + + # Pointers to the nodes for the edges + pnEx = np.c_[mkvc(iN[:-1,:,:]), mkvc(iN[1:,:,:])] + pnEy = np.c_[mkvc(iN[:,:-1,:]), mkvc(iN[:,1:,:])] + pnEz = np.c_[mkvc(iN[:,:,:-1]), mkvc(iN[:,:,1:])] + + iEx = np.arange(nEx, dtype=int).reshape(*vnEx, order='F') + iEy = np.arange(nEy, dtype=int).reshape(*vnEy, order='F') + nEx + iEz = np.arange(nEz, dtype=int).reshape(*vnEz, order='F') + nEx + nEy + + zEx = np.zeros(nEx, dtype=int) + zEy = np.zeros(nEy, dtype=int) + zEz = np.zeros(nEz, dtype=int) + + Ex = np.c_[mkvc(iEx), zEx+1, zEx-1, zEx+0, pnEx] + Ey = np.c_[mkvc(iEy), zEy+1, zEy-1, zEy+1, pnEy] + Ez = np.c_[mkvc(iEz), zEz+1, zEz-1, zEz+2, pnEz] + + # Pointers to the edges for the faces + peFx = np.c_[ mkvc(iEy[:,:,:-1]), mkvc(iEy[:,:,1:]), mkvc(iEz[:,:-1,:]), mkvc(iEz[:,1:,:])] + peFy = np.c_[mkvc(iEx[:,:,:-1]), mkvc(iEx[:,:,1:]), mkvc(iEz[:-1,:,:]), mkvc(iEz[1:,:,:])] + peFz = np.c_[mkvc(iEx[:,:-1,:]), mkvc(iEx[:,1:,:]), mkvc(iEy[:-1,:,:]), mkvc(iEy[1:,:,:]) ] + + iFx = np.arange(nFx, dtype=int).reshape(*vnFx, order='F') + iFy = np.arange(nFy, dtype=int).reshape(*vnFy, order='F') + nFx + iFz = np.arange(nFz, dtype=int).reshape(*vnFz, order='F') + nFx + nFy + + zFx = np.zeros(nFx, dtype=int) + zFy = np.zeros(nFy, dtype=int) + zFz = np.zeros(nFz, dtype=int) + + Fx = np.c_[mkvc(iFx), zFx+1, zFx-1, zFx+0, peFx] + Fy = np.c_[mkvc(iFy), zFy+1, zFy-1, zFy+1, peFy] + Fz = np.c_[mkvc(iFz), zFz+1, zFz-1, zFz+2, peFz] + + # Pointers to the faces for the cells + pfCx = np.c_[mkvc(iFx[:-1,:,:]), mkvc(iFx[1:,:,:])] + pfCy = np.c_[mkvc(iFy[:,:-1,:]), mkvc(iFy[:,1:,:])] + pfCz = np.c_[mkvc(iFz[:,:,:-1]), mkvc(iFz[:,:,1:])] + + iC = np.arange(nC, dtype=int) + + zC = np.zeros(nC, dtype=int) + + C = np.c_[iC, zC+1, zC-1, pfCx, pfCy, pfCz] + + self._nodes = N + self._edges = np.r_[Ex, Ey, Ez] + self._faces = np.r_[Fx, Fy, Fz] + self._cells = C @property def isNumbered(self): @@ -67,109 +198,6 @@ class TreeMesh(object): if hasattr(self, '_'+name): delattr(self, '_'+name) - @property - def dim(self): - return 2 - - def _push(self, attr, rows): - self.isNumbered = False - rows = np.atleast_2d(rows) - X = getattr(self, attr) - offset = X.shape[0] - rowNumer = np.arange(rows.shape[0], dtype=int) + offset - rows[:,0] = rowNumer*0-1 - setattr(self, attr, np.vstack((X, rows)).astype(X.dtype)) - if rows.shape[0] == 1: - return offset, rows.flatten() - return rowNumer, rows - - def addNode(self, between): - """Add a node between the node in list between""" - between = np.array(between).flatten() - nodes = self._nodes[between.astype(int), :] - newNode = np.mean(nodes, axis=0) - newNode[ACTIVE] = 1 - return self._push('_nodes', newNode) - - def refineEdge(self, index): - e = self._edges[index,:] - if e[ACTIVE] == 0: - # search for the children up to one level deep - subInds = np.argwhere(self._edges[:,PARENT] == index).flatten() - return subInds, self._edges[subInds,:] - - self._edges[index, ACTIVE] = 0 - - newNode, node = self.addNode(e[[ENODE0, ENODE1]]) - - Es = np.zeros((2, 6)) - Es[:, ACTIVE] = 1 - Es[:, PARENT] = index - Es[:, EDIR] = e[EDIR] - Es[0, ENODE0] = e[ENODE0] - Es[0, ENODE1] = newNode - Es[1, ENODE0] = newNode - Es[1, ENODE1] = e[ENODE1] - return self._push('_edges', Es) - - def refineFace(self, index): - f = self._faces[index,:] - if f[ACTIVE] == 0: - # search for the children up to one level deep - subInds = np.argwhere(self._faces[:,PARENT] == index).flatten() - return subInds, self._faces[subInds,:] - - self._faces[index, ACTIVE] = 0 - - # new faces and edges - # 2_______________3 _______________ - # | e1--> | | | | - # ^ | | ^ | 2 3 3 | y z z - # | | | | | | | ^ ^ ^ - # | | x | | ---> |---0---+---1---| | | | - # e2 | | e3 | | | | | | - # | | | 0 2 1 | z-----> x y-----> x x-----> y - # |_______________| |_______|_______| - # 0 e0--> 1 - - # Refine the outer edges - E0i, E0 = self.refineEdge(f[FEDGE0]) - E1i, E1 = self.refineEdge(f[FEDGE1]) - E2i, E2 = self.refineEdge(f[FEDGE2]) - E3i, E3 = self.refineEdge(f[FEDGE3]) - - nodeNums = self._edges[f[[FEDGE0, FEDGE1]],:][:,[ENODE0, ENODE1]] - newNode, node = self.addNode(nodeNums) - - # Refine the inner edges - nE = np.zeros((4,6)) - nE[:, ACTIVE] = 1 - nE[:, PARENT] = -1 - nE[:, EDIR] = [0,0,1,1] if f[FDIR] == 2 else [0,0,2,2] if f[FDIR] == 1 else [1,1,2,2] - nE[0, ENODE0] = E2[0, ENODE1] - nE[0, ENODE1] = newNode - nE[1, ENODE0] = newNode - nE[1, ENODE1] = E3[0, ENODE1] - nE[2, ENODE0] = E0[0, ENODE1] - nE[2, ENODE1] = newNode - nE[3, ENODE0] = newNode - nE[3, ENODE1] = E1[0, ENODE1] - nEi, nE = self._push('_edges', nE) - - # Add four new faces - Fs = np.zeros((4,8)) - Fs[:, ACTIVE] = 1 - Fs[:, PARENT] = index - Fs[:, FDIR] = f[FDIR] - - fInds = [FEDGE0,FEDGE1,FEDGE2,FEDGE3] - Fs[0, fInds] = [E0i[0], nEi[0], E2i[0], nEi[2]] - Fs[1, fInds] = [E0i[1], nEi[1], nEi[2], E3i[0]] - Fs[2, fInds] = [nEi[0], E1i[0], E2i[1], nEi[3]] - Fs[3, fInds] = [nEi[1], E1i[1], nEi[3], E3i[1]] - - return self._push('_faces', Fs) - @property def nC(self): if self.dim == 2: @@ -178,17 +206,19 @@ class TreeMesh(object): @property def nN(self): - return np.sum(self._cells[:,ACTIVE] == 1) + return np.sum(self._nodes[:,ACTIVE] == 1) @property def nE(self): - return np.sum(self._edges[:,ACTIVE] == 1) + if self.dim == 2: + return self.nEx + self.nEy + return self.nEx + self.nEy + self.nEz @property def nF(self): if self.dim == 2: return self.nFx + self.nFy - return np.sum(self._faces[:,ACTIVE] == 1) + return self.nFx + self.nFy + self.nFz @property def nEx(self): @@ -220,7 +250,7 @@ class TreeMesh(object): def nFz(self): if self.dim == 2: return None - return np.sum((self._faces[:,ACTIVE] == 1) & (self._faces[:,FDIR] == 1)) + return np.sum((self._faces[:,ACTIVE] == 1) & (self._faces[:,FDIR] == 2)) @property def edge(self): @@ -365,6 +395,105 @@ class TreeMesh(object): if self.dim == 2: return self.gridEx + def _push(self, attr, rows): + self.isNumbered = False + rows = np.atleast_2d(rows) + X = getattr(self, attr) + offset = X.shape[0] + rowNumer = np.arange(rows.shape[0], dtype=int) + offset + rows[:,0] = rowNumer*0-1 + setattr(self, attr, np.vstack((X, rows)).astype(X.dtype)) + if rows.shape[0] == 1: + return offset, rows.flatten() + return rowNumer, rows + + def addNode(self, between): + """Add a node between the node in list between""" + between = np.array(between).flatten() + nodes = self._nodes[between.astype(int), :] + newNode = np.mean(nodes, axis=0) + newNode[ACTIVE] = 1 + return self._push('_nodes', newNode) + + def refineEdge(self, index): + e = self._edges[index,:] + if e[ACTIVE] == 0: + # search for the children up to one level deep + subInds = np.argwhere(self._edges[:,PARENT] == index).flatten() + return subInds, self._edges[subInds,:] + + self._edges[index, ACTIVE] = 0 + + newNode, node = self.addNode(e[[ENODE0, ENODE1]]) + + Es = np.zeros((2, 6)) + Es[:, ACTIVE] = 1 + Es[:, PARENT] = index + Es[:, EDIR] = e[EDIR] + Es[0, ENODE0] = e[ENODE0] + Es[0, ENODE1] = newNode + Es[1, ENODE0] = newNode + Es[1, ENODE1] = e[ENODE1] + return self._push('_edges', Es) + + def refineFace(self, index): + f = self._faces[index,:] + if f[ACTIVE] == 0: + # search for the children up to one level deep + subInds = np.argwhere(self._faces[:,PARENT] == index).flatten() + return subInds, self._faces[subInds,:] + + self._faces[index, ACTIVE] = 0 + + # new faces and edges + # 2_______________3 _______________ + # | e1--> | | | | + # ^ | | ^ | 2 3 3 | y z z + # | | | | | | | ^ ^ ^ + # | | x | | ---> |---0---+---1---| | | | + # e2 | | e3 | | | | | | + # | | | 0 2 1 | z-----> x y-----> x x-----> y + # |_______________| |_______|_______| + # 0 e0--> 1 + + # Refine the outer edges + E0i, E0 = self.refineEdge(f[FEDGE0]) + E1i, E1 = self.refineEdge(f[FEDGE1]) + E2i, E2 = self.refineEdge(f[FEDGE2]) + E3i, E3 = self.refineEdge(f[FEDGE3]) + + nodeNums = self._edges[f[[FEDGE0, FEDGE1]],:][:,[ENODE0, ENODE1]] + newNode, node = self.addNode(nodeNums) + + # Refine the inner edges + nE = np.zeros((4,6)) + nE[:, ACTIVE] = 1 + nE[:, PARENT] = -1 + nE[:, EDIR] = [0,0,1,1] if f[FDIR] == 2 else [0,0,2,2] if f[FDIR] == 1 else [1,1,2,2] + nE[0, ENODE0] = E2[0, ENODE1] + nE[0, ENODE1] = newNode + nE[1, ENODE0] = newNode + nE[1, ENODE1] = E3[0, ENODE1] + nE[2, ENODE0] = E0[0, ENODE1] + nE[2, ENODE1] = newNode + nE[3, ENODE0] = newNode + nE[3, ENODE1] = E1[0, ENODE1] + nEi, nE = self._push('_edges', nE) + + # Add four new faces + Fs = np.zeros((4,8)) + Fs[:, ACTIVE] = 1 + Fs[:, PARENT] = index + Fs[:, FDIR] = f[FDIR] + + fInds = [FEDGE0,FEDGE1,FEDGE2,FEDGE3] + Fs[0, fInds] = [E0i[0], nEi[0], E2i[0], nEi[2]] + Fs[1, fInds] = [E0i[1], nEi[1], nEi[2], E3i[0]] + Fs[2, fInds] = [nEi[0], E1i[0], E2i[1], nEi[3]] + Fs[3, fInds] = [nEi[1], E1i[1], nEi[3], E3i[1]] + + return self._push('_faces', Fs) + def _index(self, attr, index): index = [index] if np.isscalar(index) else list(index) C = getattr(self, attr) @@ -409,11 +538,16 @@ class TreeMesh(object): self._nodes[:,NUM] = -1 self._edges[:,NUM] = -1 self._faces[:,NUM] = -1 - # self._cells[:,NUM] = -1 self.gridCC self.gridN self.gridEx self.gridEy + if self.dim > 2: + self._cells[:,NUM] = -1 + self.gridEz + self.gridFx + self.gridFy + self.gridFz def plotGrid(self, ax=None, text=True, showIt=False): import matplotlib.pyplot as plt From 72c8dfb3efdfde949037a368ba555834c4b550f5 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Tue, 10 Feb 2015 12:39:41 -0800 Subject: [PATCH 10/83] generalize sorting alg --- SimPEG/Mesh/NewTreeMesh.py | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/SimPEG/Mesh/NewTreeMesh.py b/SimPEG/Mesh/NewTreeMesh.py index 233630db..681ff3b9 100644 --- a/SimPEG/Mesh/NewTreeMesh.py +++ b/SimPEG/Mesh/NewTreeMesh.py @@ -8,15 +8,6 @@ NUM, ACTIVE, PARENT, EDIR, ENODE0, ENODE1 = range(6) NUM, ACTIVE, PARENT, FDIR, FEDGE0, FEDGE1, FEDGE2, FEDGE3 = range(8) NUM, ACTIVE, PARENT, CFACE0, CFACE1, CFACE2, CFACE3, CFACE4, CFACE5 = range(9) -def SortByX0(grid): - dtype=[('x',float),('y',float)] - grid2 = np.zeros(grid.shape[0], dtype=dtype) - grid2['x'][:] = grid[:,0] - grid2['y'][:] = grid[:,1] - P = np.argsort(grid2, order=['y','x']) - return P - - class TreeMesh(BaseMesh): def __init__(self, h_in, x0=None): @@ -40,7 +31,6 @@ class TreeMesh(BaseMesh): x0 = np.array(x0, dtype=float) assert len(x0) == self.dim, 'x0 must have the same dimensions as the mesh' - # TODO: this has a lot of stuff which doesn't work for this style of mesh... BaseMesh.__init__(self, np.array([x.size for x in h]), x0) if self.dim == 2: self._init2D() @@ -591,6 +581,30 @@ class TreeMesh(BaseMesh): if showIt: plt.show() + +def _SortByX0_2D(grid): + dtype=[('x',float),('y',float)] + grid2 = np.zeros(grid.shape[0], dtype=dtype) + grid2['x'][:] = grid[:,0] + grid2['y'][:] = grid[:,1] + return np.argsort(grid2, order=['y','x']) + +def _SortByX0_3D(grid): + dtype=[('x',float),('y',float),('z',float)] + grid2 = np.zeros(grid.shape[0], dtype=dtype) + grid2['x'][:] = grid[:,0] + grid2['y'][:] = grid[:,1] + grid2['z'][:] = grid[:,2] + return np.argsort(grid2, order=['z','y','x']) + +def SortByX0(grid): + if grid.shape[1] == 2: + return _SortByX0_2D(grid) + elif grid.shape[1] == 3: + return _SortByX0_3D(grid) + + + if __name__ == '__main__': from SimPEG import Mesh, Utils import matplotlib.pyplot as plt From 5c85f13cb6073f72bfea0eaac75f05041efce52c Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Tue, 10 Feb 2015 12:42:35 -0800 Subject: [PATCH 11/83] test counting, put dummies in for grid3D calcs --- SimPEG/Mesh/NewTreeMesh.py | 8 +++++++ SimPEG/Tests/test_NewTreeMesh.py | 38 ++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/SimPEG/Mesh/NewTreeMesh.py b/SimPEG/Mesh/NewTreeMesh.py index 681ff3b9..7c484683 100644 --- a/SimPEG/Mesh/NewTreeMesh.py +++ b/SimPEG/Mesh/NewTreeMesh.py @@ -375,6 +375,10 @@ class TreeMesh(BaseMesh): return np.c_[Ex, Ey][P, :] + @property + def gridEz(self): + pass + @property def gridFx(self): if self.dim == 2: @@ -385,6 +389,10 @@ class TreeMesh(BaseMesh): if self.dim == 2: return self.gridEx + @property + def gridFz(self): + pass + def _push(self, attr, rows): self.isNumbered = False rows = np.atleast_2d(rows) diff --git a/SimPEG/Tests/test_NewTreeMesh.py b/SimPEG/Tests/test_NewTreeMesh.py index 3d9807e5..a2a8235f 100644 --- a/SimPEG/Tests/test_NewTreeMesh.py +++ b/SimPEG/Tests/test_NewTreeMesh.py @@ -102,6 +102,44 @@ class SimpleOctreeOperatorTests(unittest.TestCase): +class TestOcTreeObjects(unittest.TestCase): + + def setUp(self): + self.M = TreeMesh([2,1,1]) + self.M.number() + + # self.Mr = TreeMesh([2,1,1]) + # self.Mr.children[0,0,0].refine() + # self.Mr.number() + + def test_counts(self): + self.assertTrue(self.M.nC == 2) + self.assertTrue(self.M.nFx == 3) + self.assertTrue(self.M.nFy == 4) + self.assertTrue(self.M.nFz == 4) + self.assertTrue(self.M.nF == 11) + self.assertTrue(self.M.nEx == 8) + self.assertTrue(self.M.nEy == 6) + self.assertTrue(self.M.nEz == 6) + self.assertTrue(self.M.nE == 20) + self.assertTrue(self.M.nN == 12) + + # self.assertTrue(self.Mr.nC == 9) + # self.assertTrue(self.Mr.nFx == 13) + # self.assertTrue(self.Mr.nFy == 14) + # self.assertTrue(self.Mr.nFz == 14) + # self.assertTrue(self.Mr.nF == 41) + + + # for cell in self.Mr.sortedCells: + # for e in cell.edgeDict: + # self.assertTrue(cell.edgeDict[e].edgeType==e[1].lower()) + + # self.assertTrue(self.Mr.nN == 31) + # self.assertTrue(self.Mr.nEx == 22) + # self.assertTrue(self.Mr.nEy == 20) + # self.assertTrue(self.Mr.nEz == 20) + if __name__ == '__main__': unittest.main() From a4f3db398f47ffcab97e995b91946f6a25aebe6d Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Wed, 11 Feb 2015 12:53:15 -0800 Subject: [PATCH 12/83] fancy indexing classes --- SimPEG/Mesh/NewTreeMesh.py | 427 +++++++++++++++++++++++-------------- 1 file changed, 262 insertions(+), 165 deletions(-) diff --git a/SimPEG/Mesh/NewTreeMesh.py b/SimPEG/Mesh/NewTreeMesh.py index 7c484683..826750b4 100644 --- a/SimPEG/Mesh/NewTreeMesh.py +++ b/SimPEG/Mesh/NewTreeMesh.py @@ -3,11 +3,157 @@ from SimPEG.Utils import ndgrid, mkvc, sdiag from BaseMesh import BaseMesh -NUM, ACTIVE, NX, NY, NZ = range(5) +NUM, ACTIVE, NX, NY, NZ = range(5) # Do not put anything after NZ NUM, ACTIVE, PARENT, EDIR, ENODE0, ENODE1 = range(6) NUM, ACTIVE, PARENT, FDIR, FEDGE0, FEDGE1, FEDGE2, FEDGE3 = range(8) NUM, ACTIVE, PARENT, CFACE0, CFACE1, CFACE2, CFACE3, CFACE4, CFACE5 = range(9) +# The following classes are wrappers to make indexing easier + +class TreeIndexer(object): + def __init__(self, treeMesh, index=slice(None)): + self.M = treeMesh + if index == 'active': + array = getattr(self.M, self._pointer) + index = array[:,ACTIVE] == 1 + self.index = index + + @property + def C(self): return getattr(self.M, '_cells', None) + @property + def F(self): return getattr(self.M, '_faces', None) + @property + def E(self): return getattr(self.M, '_edges', None) + @property + def N(self): return getattr(self.M, '_nodes', None) + + def sort(self, vec): + self.M.number() + P = np.argsort(self.num) + if len(vec.shape) == 1: + return vec[P] + return vec[P,:] + + def _ind(self, column): + array = getattr(self.M, self._pointer) + ind = np.atleast_2d(array[self.index,:])[:,column] + return self._SubTree(self.M, ind) + + def at(self, index=slice(None)): + self.index = index + return self + +class TreeNode(TreeIndexer): + _SubTree = None + _pointer = '_nodes' + @property + def num(self): return self.N[self.index, NUM] + @property + def vec(self): return self.N[self.index,:][:,NX:] + @property + def x(self): return self.N[self.index,:][:,NX] + @property + def y(self): return self.N[self.index,:][:,NY] + @property + def z(self): return self.N[self.index,:][:,NZ] + +class TreeEdge(TreeIndexer): + _SubTree = TreeNode + _pointer = '_edges' + + @property + def num(self):return self.E[self.index, NUM] + @property + def dir(self):return self.E[self.index, EDIR] + @property + def n0(self): return self._ind(ENODE0) + @property + def n1(self): return self._ind(ENODE1) + @property + def nodes(self): + return [self.n0, self.n1] + @property + def length(self): + return np.sum((self.n1.vec - self.n0.vec)**2,axis=1)**0.5 + @property + def center(self): + return (self.n0.vec + self.n1.vec)/2.0 + +class TreeFace(TreeIndexer): + _SubTree = TreeEdge + _pointer = '_faces' + + @property + def num(self):return self.F[self.index, NUM] + @property + def dir(self):return self.F[self.index, FDIR] + @property + def e0(self): return self._ind(FEDGE0) + @property + def e1(self): return self._ind(FEDGE1) + @property + def e2(self): return self._ind(FEDGE2) + @property + def e3(self): return self._ind(FEDGE3) + @property + def n0(self): return self.e0.n0 + @property + def n1(self): return self.e0.n1 + @property + def n2(self): return self.e1.n0 + @property + def n3(self): return self.e1.n1 + @property + def nodes(self): + return [self.n0, self.n1, self.n2, self.n3] + @property + def center(self): + return (self.n0.vec + self.n1.vec + self.n2.vec + self.n3.vec)/4.0 + @property + def area(self): + + n0 = self.n0.vec # 2------3 3------2 + n1 = self.n1.vec # | | ---> | | + n2 = self.n3.vec # | | | | + n3 = self.n2.vec # 0------1 0------1 + + a = np.sum((n1 - n0)**2,axis=1)**0.5 + b = np.sum((n2 - n1)**2,axis=1)**0.5 + c = np.sum((n3 - n2)**2,axis=1)**0.5 + d = np.sum((n0 - n3)**2,axis=1)**0.5 + p = np.sum((n2 - n0)**2,axis=1)**0.5 + q = np.sum((n3 - n1)**2,axis=1)**0.5 + + # Area of an arbitrary quadrilateral (in a plane) + V = 0.25 * (4.0*(p**2)*(q**2) - (a**2 + c**2 - b**2 - d**2)**2)**0.5 + return V + +class TreeCell(TreeIndexer): + _SubTree = TreeFace + _pointer = '_cells' + + @property + def num(self):return self.C[self.index, NUM] + + @property + def fXm(self): return self._ind(CFACE0) + @property + def fXp(self): return self._ind(CFACE1) + @property + def fYm(self): return self._ind(CFACE2) + @property + def fYp(self): return self._ind(CFACE3) + @property + def fZm(self): return self._ind(CFACE4) + @property + def fZp(self): return self._ind(CFACE5) + + @property + def eX0(self): return self.fZm.e0 + + @property + def n0(self): return self.eX0.n0 + class TreeMesh(BaseMesh): def __init__(self, h_in, x0=None): @@ -176,18 +322,60 @@ class TreeMesh(BaseMesh): @property def isNumbered(self): - return self._numberedCC and self._numberedN and self._numberedEx and self._numberedEy + return self._numbered @isNumbered.setter def isNumbered(self, value): assert value is False, 'Can only set to False.' - self._numberedCC = False - self._numberedN = False - self._numberedEx = False - self._numberedEy = False + self._numbered = False for name in ['vol', 'area', 'edge', 'gridCC', 'gridN', 'gridEx', 'gridEy', 'gridEz', 'gridFx', 'gridFy', 'gridFz']: if hasattr(self, '_'+name): delattr(self, '_'+name) + def number(self): + if self._numbered: + return + + dtypeN = [('x',float),('y',float)] + if self.dim == 3: + dtypeN += [('z',float)] + dtypeV = [('v', int)] + + N = TreeNode(self, 'active') + E = TreeEdge(self, 'active') + F = TreeFace(self, 'active') + self._nodes[:,NUM] = -1 + self._edges[:,NUM] = -1 + self._faces[:,NUM] = -1 + if self.dim == 3: + C = TreeCell(self, 'active') + self._cells[:,NUM] = -1 + + + def doNumbering(indexer, nodes, dtype): + grid = np.zeros(np.sum(indexer.index), dtype=dtype) + grid['x'][:] = nodes.x + grid['y'][:] = nodes.y + if self.dim == 3: + grid['z'][:] = nodes.z + if 'v' in [d[0] for d in dtype]: + grid['v'][:] = indexer.dir + P = np.argsort(grid, order=[d[0] for d in reversed(dtype)]) + cnt = np.zeros(P.size, dtype=int) + cnt[P] = np.arange(P.size) + return cnt + + self._nodes[N.index, NUM] = doNumbering(N, N, dtypeN) + + self._edges[E.index, NUM] = doNumbering(E, E.n0, dtypeN + dtypeV) + + dtype = dtypeN if self.dim == 2 else (dtypeN + dtypeV) + self._faces[F.index, NUM] = doNumbering(F, F.n0, dtype) + + if self.dim == 3: + self._cells[C.index, NUM] = doNumbering(C, C.n0, dtypeN) + + self._numbered = True + @property def nC(self): if self.dim == 2: @@ -245,153 +433,71 @@ class TreeMesh(BaseMesh): @property def edge(self): if getattr(self, '_edge', None) is None: - self.number() - - N = self._nodes - E = self._edges - activeEdges = E[:,ACTIVE] == 1 - e0xy = N[E[activeEdges,ENODE0],:][:,[NX,NY]] - e1xy = N[E[activeEdges,ENODE1],:][:,[NX,NY]] - - A = np.sum((e1xy - e0xy)**2,axis=1)**0.5 - - P = np.argsort(E[activeEdges,NUM]) - self._edge = A[P] - + E = TreeEdge(self, 'active') + self._edge = E.sort(E.length) return self._edge @property def area(self): if getattr(self, '_area', None) is None: - self.number() if self.dim == 2: self._area = np.r_[self.edge[self.nEx:], self.edge[:self.nEx]] - return self._area - @property def vol(self): if getattr(self, '_vol', None) is None: - self.number() - - N = self._nodes - E = self._edges - C = self._faces - activeCells = C[:,ACTIVE] == 1 - nInds1 = E[C[activeCells,FEDGE0],:][:,[ENODE0,ENODE1]] - nInds2 = E[C[activeCells,FEDGE1],:][:,[ENODE0,ENODE1]] - n0 = N[nInds1[:,0],:][:,[NX,NY]] # 2------3 3------2 - n1 = N[nInds1[:,1],:][:,[NX,NY]] # | | --> | | - n3 = N[nInds2[:,0],:][:,[NX,NY]] # | | | | - n2 = N[nInds2[:,1],:][:,[NX,NY]] # 0------1 0------1 - - a = np.sum((n1 - n0)**2,axis=1)**0.5 - b = np.sum((n2 - n1)**2,axis=1)**0.5 - c = np.sum((n3 - n2)**2,axis=1)**0.5 - d = np.sum((n0 - n3)**2,axis=1)**0.5 - p = np.sum((n2 - n0)**2,axis=1)**0.5 - q = np.sum((n3 - n1)**2,axis=1)**0.5 - - # Area of an arbitrary quadrilateral (in a plane) - V = 0.25 * (4.0*(p**2)*(q**2) - (a**2 + c**2 - b**2 - d**2)**2)**0.5 - P = np.argsort(C[activeCells,NUM]) - self._vol = V[P] - + F = TreeFace(self, 'active') + self._vol = F.sort(F.area) return self._vol @property def gridN(self): - N = self._nodes - activeNodes = N[:,ACTIVE] == 1 - Nx = N[activeNodes,NX] - Ny = N[activeNodes,NY] - - P = SortByX0(np.c_[Nx, Ny]) - if not self._numberedN: - cnt = np.zeros(P.size, dtype=int) - cnt[P] = np.arange(P.size) - self._nodes[activeNodes, NUM] = cnt - self._numberedN = True - - return np.c_[Nx, Ny][P, :] + N = TreeNode(self, 'active') + return N.sort(N.vec) @property def gridCC(self): - N = self._nodes - E = self._edges - C = self._faces - activeCells = C[:,ACTIVE] == 1 - nInds1 = E[C[activeCells,FEDGE0],:][:,[ENODE0,ENODE1]] - nInds2 = E[C[activeCells,FEDGE1],:][:,[ENODE0,ENODE1]] - Cx = (N[nInds1[:,0],NX] + N[nInds1[:,1],NX] + N[nInds2[:,0],NX] + N[nInds2[:,1],NX])/4.0 - Cy = (N[nInds1[:,0],NY] + N[nInds1[:,1],NY] + N[nInds2[:,0],NY] + N[nInds2[:,1],NY])/4.0 - - P = SortByX0(np.c_[N[nInds1[:,0],NX], N[nInds1[:,0],NY]]) - if not self._numberedCC: - cnt = np.zeros(P.size, dtype=int) - cnt[P] = np.arange(P.size) - self._faces[activeCells, NUM] = cnt - self._numberedCC = True - - return np.c_[Cx, Cy][P, :] + F = TreeFace(self, 'active') + return F.sort(F.center) @property def gridEx(self): - N = self._nodes - E = self._edges - C = self._faces - activeEdges = (E[:,ACTIVE] == 1) & (E[:,EDIR] == 0) - nInds = E[activeEdges,:][:,[ENODE0,ENODE1]] - Ex = (N[nInds[:,0],NX] + N[nInds[:,1],NX])/2.0 - Ey = (N[nInds[:,0],NY] + N[nInds[:,1],NY])/2.0 - - P = SortByX0(np.c_[N[nInds[:,0],NX], N[nInds[:,0],NY]]) - if not self._numberedEx: - cnt = np.zeros(P.size, dtype=int) - cnt[P] = np.arange(P.size) - self._edges[activeEdges, NUM] = cnt - self._numberedEx = True - - return np.c_[Ex, Ey][P, :] + E = TreeEdge(self, (self._edges[:,ACTIVE] == 1) & (self._edges[:,EDIR] == 0)) + return E.sort(E.center) @property def gridEy(self): - N = self._nodes - E = self._edges - C = self._faces - activeEdges = (E[:,ACTIVE] == 1) & (E[:,EDIR] == 1) - nInds = E[activeEdges,:][:,[ENODE0,ENODE1]] - Ex = (N[nInds[:,0],NX] + N[nInds[:,1],NX])/2.0 - Ey = (N[nInds[:,0],NY] + N[nInds[:,1],NY])/2.0 - - P = SortByX0(np.c_[N[nInds[:,0],NX], N[nInds[:,0],NY]]) - if not self._numberedEy: - cnt = np.zeros(P.size, dtype=int) - cnt[P] = np.arange(P.size) - self._edges[activeEdges, NUM] = cnt + self.nEx - self._numberedEy = True - - return np.c_[Ex, Ey][P, :] - + E = TreeEdge(self, (self._edges[:,ACTIVE] == 1) & (self._edges[:,EDIR] == 1)) + return E.sort(E.center) @property def gridEz(self): - pass + if self.dim == 2: return None + E = TreeEdge(self, (self._edges[:,ACTIVE] == 1) & (self._edges[:,EDIR] == 2)) + return E.sort(E.center) @property def gridFx(self): if self.dim == 2: return self.gridEy + else: + F = TreeFace(self, (self._faces[:,ACTIVE] == 1) & (self._faces[:,FDIR] == 0)) + return F.sort(F.center) @property def gridFy(self): if self.dim == 2: return self.gridEx + else: + F = TreeFace(self, (self._faces[:,ACTIVE] == 1) & (self._faces[:,FDIR] == 1)) + return F.sort(F.center) @property def gridFz(self): - pass + if self.dim == 2: return None + F = TreeFace(self, (self._faces[:,ACTIVE] == 1) & (self._faces[:,FDIR] == 2)) + return F.sort(F.center) def _push(self, attr, rows): self.isNumbered = False @@ -443,17 +549,6 @@ class TreeMesh(BaseMesh): self._faces[index, ACTIVE] = 0 - # new faces and edges - # 2_______________3 _______________ - # | e1--> | | | | - # ^ | | ^ | 2 3 3 | y z z - # | | | | | | | ^ ^ ^ - # | | x | | ---> |---0---+---1---| | | | - # e2 | | e3 | | | | | | - # | | | 0 2 1 | z-----> x y-----> x x-----> y - # |_______________| |_______|_______| - # 0 e0--> 1 - # Refine the outer edges E0i, E0 = self.refineEdge(f[FEDGE0]) E1i, E1 = self.refineEdge(f[FEDGE1]) @@ -464,6 +559,17 @@ class TreeMesh(BaseMesh): newNode, node = self.addNode(nodeNums) # Refine the inner edges + # new faces and edges + # 2_______________3 _______________ + # | e1--> | | | | + # ^ | | ^ | 2 3 3 | y z z + # | | | | | | | ^ ^ ^ + # | | + | | ---> |---0---+---1---| | | | + # e2 | | e3 | | | | | | + # | | | 0 2 1 | z-----> x y-----> x x-----> y + # |_______________| |_______|_______| + # 0 e0--> 1 + nE = np.zeros((4,6)) nE[:, ACTIVE] = 1 nE[:, PARENT] = -1 @@ -492,6 +598,28 @@ class TreeMesh(BaseMesh): return self._push('_faces', Fs) + + def refineCell(self, index): + c = self._cells[index,:] + if f[ACTIVE] == 0: + # search for the children up to one level deep + subInds = np.argwhere(self._cells[:,PARENT] == index).flatten() + return subInds, self._cells[subInds,:] + + self._cells[index, ACTIVE] = 0 + + # Refine the outer faces + F0i, F0 = self.refineFace(c[CFACE0]) + F1i, F1 = self.refineFace(c[CFACE1]) + F2i, F2 = self.refineFace(c[CFACE2]) + F3i, F3 = self.refineFace(c[CFACE3]) + F4i, F4 = self.refineFace(c[CFACE4]) + F5i, F5 = self.refineFace(c[CFACE5]) + + nodeNums = self._edges[f[[FEDGE0, FEDGE1]],:][:,[ENODE0, ENODE1]] + newNode, node = self.addNode(nodeNums) + + def _index(self, attr, index): index = [index] if np.isscalar(index) else list(index) C = getattr(self, attr) @@ -530,23 +658,6 @@ class TreeMesh(BaseMesh): self._faceDiv = sdiag(1/VOL)*D*sdiag(S) return self._faceDiv - def number(self): - if self.isNumbered: - return - self._nodes[:,NUM] = -1 - self._edges[:,NUM] = -1 - self._faces[:,NUM] = -1 - self.gridCC - self.gridN - self.gridEx - self.gridEy - if self.dim > 2: - self._cells[:,NUM] = -1 - self.gridEz - self.gridFx - self.gridFy - self.gridFz - def plotGrid(self, ax=None, text=True, showIt=False): import matplotlib.pyplot as plt @@ -590,27 +701,6 @@ class TreeMesh(BaseMesh): plt.show() -def _SortByX0_2D(grid): - dtype=[('x',float),('y',float)] - grid2 = np.zeros(grid.shape[0], dtype=dtype) - grid2['x'][:] = grid[:,0] - grid2['y'][:] = grid[:,1] - return np.argsort(grid2, order=['y','x']) - -def _SortByX0_3D(grid): - dtype=[('x',float),('y',float),('z',float)] - grid2 = np.zeros(grid.shape[0], dtype=dtype) - grid2['x'][:] = grid[:,0] - grid2['y'][:] = grid[:,1] - grid2['z'][:] = grid[:,2] - return np.argsort(grid2, order=['z','y','x']) - -def SortByX0(grid): - if grid.shape[1] == 2: - return _SortByX0_2D(grid) - elif grid.shape[1] == 3: - return _SortByX0_3D(grid) - if __name__ == '__main__': @@ -624,9 +714,19 @@ if __name__ == '__main__': tM.refineFace(3) tM.refineFace(9) + print tM._nodes[:,NUM] + tM.number() + print tM._nodes[:,NUM] + print tM._edges[:,NUM] + + print TreeFace(tM,[0]).e2.n0.x + + + + # print tM._faces # print tM._edges[0,:] - # print tM.area + # print tM.vol # tM.number() @@ -642,6 +742,3 @@ if __name__ == '__main__': # plt.figure(2) # plt.plot(SortByX0(tM.gridCC),'b.') plt.show() - - - From d65a3540a4cccbb71f25abbd7cc9b99faa6b915d Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Wed, 11 Feb 2015 13:38:08 -0800 Subject: [PATCH 13/83] cell indexing --- SimPEG/Mesh/NewTreeMesh.py | 97 +++++++++++++++++++++++++++++++++----- 1 file changed, 86 insertions(+), 11 deletions(-) diff --git a/SimPEG/Mesh/NewTreeMesh.py b/SimPEG/Mesh/NewTreeMesh.py index 826750b4..96e525c0 100644 --- a/SimPEG/Mesh/NewTreeMesh.py +++ b/SimPEG/Mesh/NewTreeMesh.py @@ -87,6 +87,16 @@ class TreeFace(TreeIndexer): def num(self):return self.F[self.index, NUM] @property def dir(self):return self.F[self.index, FDIR] + + # fX fY fZ + # n2___________n3 n2___________n3 n2___________n3 + # | e1 | | e1 | | e1 | + # | | | | | | + # e2 | x | e3 z e2 | x | e3 z e2 | x | e3 y + # | | ^ | | ^ | | ^ + # |___________| |___> y |___________| |___> x |___________| |___> x + # n0 e0 n1 n0 e0 n1 n0 e0 n1 + @property def e0(self): return self._ind(FEDGE0) @property @@ -148,11 +158,80 @@ class TreeCell(TreeIndexer): @property def fZp(self): return self._ind(CFACE5) - @property - def eX0(self): return self.fZm.e0 + # fZp + # | + # 6 ------eX3------ 7 + # /| | / | + # /eZ2 . / eZ3 + # eY2 | fYp eY3 | + # / | / fXp| + # 4 ------eX2----- 5 | + # |fXm 2 -----eX1--|---- 3 z + # eZ0 / | eY1 ^ y + # | eY0 . fYm eZ1 / | / + # | / | | / | / + # 0 ------eX0------1 o----> x + # | + # fZm + # + # + # fX fY fZ + # 2___________3 2___________3 2___________3 + # | e1 | | e1 | | e1 | + # | | | | | | + # e2 | x | e3 z e2 | x | e3 z e2 | x | e3 y + # | | ^ | | ^ | | ^ + # |___________| |___> y |___________| |___> x |___________| |___> x + # 0 e0 1 0 e0 1 0 e0 1 + # + # Mapping Nodes: numOnFace > numOnCell + # + # fXm 0>0, 1>2, 2>4, 3>6 fYm 0>0, 1>1, 2>4, 3>5 fZm 0>0, 1>1, 2>2, 3>3 + # fXp 0>1, 1>3, 2>5, 3>7 fYp 0>2, 1>3, 2>6, 3>7 fZp 0>4, 1>5, 2>6, 3>7 @property - def n0(self): return self.eX0.n0 + def eX0(self): return self.fZm.e0 + @property + def eX1(self): return self.fZm.e1 + @property + def eX2(self): return self.fZp.e0 + @property + def eX3(self): return self.fZp.e1 + + @property + def eY0(self): return self.fZm.e2 + @property + def eY1(self): return self.fZm.e3 + @property + def eY2(self): return self.fZp.e2 + @property + def eY3(self): return self.fZp.e3 + + @property + def eZ0(self): return self.fXm.e2 + @property + def eZ1(self): return self.fXp.e2 + @property + def eZ2(self): return self.fXm.e3 + @property + def eZ3(self): return self.fXp.e3 + + @property + def n0(self): return self.fZm.n0 + @property + def n1(self): return self.fZm.n1 + @property + def n2(self): return self.fZm.n2 + @property + def n3(self): return self.fZm.n3 + @property + def n4(self): return self.fZp.n0 + @property + def n5(self): return self.fZp.n1 + @property + def n6(self): return self.fZp.n2 + @property + def n7(self): return self.fZp.n3 class TreeMesh(BaseMesh): @@ -408,26 +487,22 @@ class TreeMesh(BaseMesh): @property def nEz(self): - if self.dim == 2: - return None + if self.dim == 2: return None return np.sum((self._edges[:,ACTIVE] == 1) & (self._edges[:,EDIR] == 2)) @property def nFx(self): - if self.dim == 2: - return self.nEy + if self.dim == 2: return self.nEy return np.sum((self._faces[:,ACTIVE] == 1) & (self._faces[:,FDIR] == 0)) @property def nFy(self): - if self.dim == 2: - return self.nEx + if self.dim == 2: return self.nEx return np.sum((self._faces[:,ACTIVE] == 1) & (self._faces[:,FDIR] == 1)) @property def nFz(self): - if self.dim == 2: - return None + if self.dim == 2: return None return np.sum((self._faces[:,ACTIVE] == 1) & (self._faces[:,FDIR] == 2)) @property From 5afea4e2b60119bf59ad6a5c49afe00baa39e626 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Wed, 11 Feb 2015 16:36:57 -0800 Subject: [PATCH 14/83] update grids. Think refining is working properly --- SimPEG/Mesh/NewTreeMesh.py | 155 ++++++++++++++++++++++++++----- SimPEG/Tests/test_NewTreeMesh.py | 114 ++++++++++++++++++++--- 2 files changed, 229 insertions(+), 40 deletions(-) diff --git a/SimPEG/Mesh/NewTreeMesh.py b/SimPEG/Mesh/NewTreeMesh.py index 96e525c0..462f0c74 100644 --- a/SimPEG/Mesh/NewTreeMesh.py +++ b/SimPEG/Mesh/NewTreeMesh.py @@ -232,6 +232,10 @@ class TreeCell(TreeIndexer): def n6(self): return self.fZp.n2 @property def n7(self): return self.fZp.n3 + @property + def center(self): + return (self.n0.vec + self.n1.vec + self.n2.vec + self.n3.vec + + self.n4.vec + self.n5.vec + self.n6.vec + self.n7.vec)/8.0 class TreeMesh(BaseMesh): @@ -533,8 +537,11 @@ class TreeMesh(BaseMesh): @property def gridCC(self): - F = TreeFace(self, 'active') - return F.sort(F.center) + if self.dim == 2: + F = TreeFace(self, 'active') + return F.sort(F.center) + C = TreeCell(self, 'active') + return C.sort(C.center) @property def gridEx(self): @@ -660,23 +667,23 @@ class TreeMesh(BaseMesh): nEi, nE = self._push('_edges', nE) # Add four new faces - Fs = np.zeros((4,8)) - Fs[:, ACTIVE] = 1 - Fs[:, PARENT] = index - Fs[:, FDIR] = f[FDIR] + nF = np.zeros((4,8)) + nF[:, ACTIVE] = 1 + nF[:, PARENT] = index + nF[:, FDIR] = f[FDIR] - fInds = [FEDGE0,FEDGE1,FEDGE2,FEDGE3] - Fs[0, fInds] = [E0i[0], nEi[0], E2i[0], nEi[2]] - Fs[1, fInds] = [E0i[1], nEi[1], nEi[2], E3i[0]] - Fs[2, fInds] = [nEi[0], E1i[0], E2i[1], nEi[3]] - Fs[3, fInds] = [nEi[1], E1i[1], nEi[3], E3i[1]] + feInds = [FEDGE0,FEDGE1,FEDGE2,FEDGE3] + nF[0, feInds] = [E0i[0], nEi[0], E2i[0], nEi[2]] + nF[1, feInds] = [E0i[1], nEi[1], nEi[2], E3i[0]] + nF[2, feInds] = [nEi[0], E1i[0], E2i[1], nEi[3]] + nF[3, feInds] = [nEi[1], E1i[1], nEi[3], E3i[1]] - return self._push('_faces', Fs) + return self._push('_faces', nF) def refineCell(self, index): c = self._cells[index,:] - if f[ACTIVE] == 0: + if c[ACTIVE] == 0: # search for the children up to one level deep subInds = np.argwhere(self._cells[:,PARENT] == index).flatten() return subInds, self._cells[subInds,:] @@ -684,16 +691,114 @@ class TreeMesh(BaseMesh): self._cells[index, ACTIVE] = 0 # Refine the outer faces - F0i, F0 = self.refineFace(c[CFACE0]) - F1i, F1 = self.refineFace(c[CFACE1]) - F2i, F2 = self.refineFace(c[CFACE2]) - F3i, F3 = self.refineFace(c[CFACE3]) - F4i, F4 = self.refineFace(c[CFACE4]) - F5i, F5 = self.refineFace(c[CFACE5]) + fXm, rfXm = self.refineFace(c[CFACE0]) + fXp, rfXp = self.refineFace(c[CFACE1]) + fYm, rfYm = self.refineFace(c[CFACE2]) + fYp, rfYp = self.refineFace(c[CFACE3]) + fZm, rfZm = self.refineFace(c[CFACE4]) + fZp, rfZp = self.refineFace(c[CFACE5]) - nodeNums = self._edges[f[[FEDGE0, FEDGE1]],:][:,[ENODE0, ENODE1]] + nodes = TreeCell(self, index).fXm.nodes + TreeCell(self, index).fXp.nodes + nodeNums = [n.index for n in nodes] newNode, node = self.addNode(nodeNums) + nE = np.zeros((6,6)) + nE[:, ACTIVE] = 1 + nE[:, PARENT] = -1 + nE[:, EDIR] = [0, 0, 1, 1, 2, 2] + + nE[0, ENODE0] = TreeFace(self, fXm[0]).n3.index + nE[0, ENODE1] = newNode + nE[1, ENODE0] = newNode + nE[1, ENODE1] = TreeFace(self, fXp[0]).n3.index + + nE[2, ENODE0] = TreeFace(self, fYm[0]).n3.index + nE[2, ENODE1] = newNode + nE[3, ENODE0] = newNode + nE[3, ENODE1] = TreeFace(self, fYp[0]).n3.index + + nE[4, ENODE0] = TreeFace(self, fZm[0]).n3.index + nE[4, ENODE1] = newNode + nE[5, ENODE0] = newNode + nE[5, ENODE1] = TreeFace(self, fZp[0]).n3.index + + nEi, nE = self._push('_edges', nE) + + nF = np.zeros((12,8)) + nF[:, ACTIVE] = 1 + nF[:, PARENT] = -1 + nF[:, FDIR] = [0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2] + + feInds = [FEDGE0,FEDGE1,FEDGE2,FEDGE3] + nF[0, feInds] = [rfZm[0, FEDGE3], nEi[2], rfYm[0, FEDGE3], nEi[4]] + nF[1, feInds] = [rfZm[2, FEDGE3], nEi[3], nEi[4], rfYp[0, FEDGE3]] + nF[2, feInds] = [nEi[2], rfZp[0, FEDGE3], rfYm[2, FEDGE3], nEi[5]] + nF[3, feInds] = [nEi[3], rfZp[2, FEDGE3], nEi[5], rfYp[2, FEDGE3]] + + nF[4, feInds] = [rfZm[0, FEDGE1], nEi[0], rfXm[0, FEDGE3], nEi[4]] + nF[5, feInds] = [rfZm[1, FEDGE1], nEi[1], nEi[4], rfXp[0, FEDGE3]] + nF[6, feInds] = [nEi[0], rfZp[0, FEDGE1], rfXm[2, FEDGE3], nEi[5]] + nF[7, feInds] = [nEi[1], rfZp[1, FEDGE1], nEi[5], rfXp[2, FEDGE3]] + + nF[8, feInds] = [rfYm[0, FEDGE1], nEi[0], rfXm[0, FEDGE1], nEi[2]] + nF[9, feInds] = [rfYm[1, FEDGE1], nEi[1], nEi[2], rfXp[0, FEDGE1]] + nF[10,feInds] = [nEi[0], rfYp[0, FEDGE1], rfXm[2, FEDGE1], nEi[3]] + nF[11,feInds] = [nEi[1], rfYp[1, FEDGE1], nEi[3], rfXp[2, FEDGE1]] + + nFi, nF = self._push('_faces', nF) + + nC = np.zeros((8,9)) + nC[:, ACTIVE] = 1 + nC[:, PARENT] = index + + # .----------------.----------------. + # /| /| /| + # / | / | / | + # / | 6 / | 7 / | + # / | / | / | + # .----------------.----+-----------. | + # /| . ---------/|----.----------/|----. + # fZp / | /| / | /| / | /| + # | / | / | 4 / | / | 5 / | / | + # 6 ------eX3------ 7 / | / | / | / | / | / | + # /| | / | . -------------- .----------------. |/ | + # /eZ2 . / eZ3 | . ---+------|----.----+------|----. | + # eY2 | fYp eY3 | | /| .______|___/|____.______|___/|____. + # / | / fXp| | / | / 2 | / | / 3 | / | / + # 4 ------eX2----- 5 | | / | / | / | / | / | / + # |fXm 2 -----eX1--|---- 3 z . ---+---------- . ---+---------- . | / + # eZ0 / | eY1 ^ y | |/ | |/ | |/ + # | eY0 . fYm eZ1 / | / | . ----------|----.-----------|----. + # | / | | / | / | / 0 | / 1 | / + # 0 ------eX0------1 o----> x | / | / | / + # | | / | / | / + # fZm . -------------- . -------------- . + # + # + # fX fY fZ + # 2___________3 2___________3 2___________3 + # | e1 | | e1 | | e1 | + # | | | | | | + # e2 | x | e3 z e2 | x | e3 z e2 | x | e3 y + # | | ^ | | ^ | | ^ + # |___________| |___> y |___________| |___> x |___________| |___> x + # 0 e0 1 0 e0 1 0 e0 1 + + + cfInds = [CFACE0,CFACE1,CFACE2,CFACE3,CFACE4,CFACE5] + nC[0, cfInds] = [fXm[0], nFi[0], fYm[0], nFi[4], fZm[0], nFi[ 8]] + nC[1, cfInds] = [nFi[0], fXp[0], fYm[1], nFi[5], fZm[1], nFi[ 9]] + nC[2, cfInds] = [fXm[1], nFi[1], nFi[4], fYp[0], fZm[2], nFi[10]] + nC[3, cfInds] = [nFi[1], fXp[1], nFi[5], fYp[1], fZm[3], nFi[11]] + nC[4, cfInds] = [fXm[2], nFi[2], fYm[2], nFi[6], nFi[ 8], fZp[0]] + nC[5, cfInds] = [nFi[2], fXp[2], fYm[3], nFi[7], nFi[ 9], fZp[1]] + nC[6, cfInds] = [fXm[3], nFi[3], nFi[6], fYp[2], nFi[10], fZp[2]] + nC[7, cfInds] = [nFi[3], fXp[3], nFi[7], fYp[3], nFi[11], fZp[3]] + + return self._push('_cells', nC) + + + def _index(self, attr, index): index = [index] if np.isscalar(index) else list(index) @@ -794,7 +899,7 @@ if __name__ == '__main__': print tM._nodes[:,NUM] print tM._edges[:,NUM] - print TreeFace(tM,[0]).e2.n0.x + print TreeFace(tM,0).e3.n1.index @@ -810,10 +915,10 @@ if __name__ == '__main__': # print tM._edges[:,[0,1,3, 4,5 ]] - plt.subplot(211) - plt.spy(tM.faceDiv) - tM.plotGrid(ax=plt.subplot(212)) + # plt.subplot(211) + # plt.spy(tM.faceDiv) + # tM.plotGrid(ax=plt.subplot(212)) # plt.figure(2) # plt.plot(SortByX0(tM.gridCC),'b.') - plt.show() + # plt.show() diff --git a/SimPEG/Tests/test_NewTreeMesh.py b/SimPEG/Tests/test_NewTreeMesh.py index a2a8235f..03cdaba6 100644 --- a/SimPEG/Tests/test_NewTreeMesh.py +++ b/SimPEG/Tests/test_NewTreeMesh.py @@ -108,9 +108,9 @@ class TestOcTreeObjects(unittest.TestCase): self.M = TreeMesh([2,1,1]) self.M.number() - # self.Mr = TreeMesh([2,1,1]) - # self.Mr.children[0,0,0].refine() - # self.Mr.number() + self.Mr = TreeMesh([2,1,1]) + self.Mr.refineCell(0) + self.Mr.number() def test_counts(self): self.assertTrue(self.M.nC == 2) @@ -124,22 +124,106 @@ class TestOcTreeObjects(unittest.TestCase): self.assertTrue(self.M.nE == 20) self.assertTrue(self.M.nN == 12) - # self.assertTrue(self.Mr.nC == 9) - # self.assertTrue(self.Mr.nFx == 13) - # self.assertTrue(self.Mr.nFy == 14) - # self.assertTrue(self.Mr.nFz == 14) - # self.assertTrue(self.Mr.nF == 41) + self.assertTrue(self.Mr.nC == 9) + self.assertTrue(self.Mr.nFx == 13) + self.assertTrue(self.Mr.nFy == 14) + self.assertTrue(self.Mr.nFz == 14) + self.assertTrue(self.Mr.nF == 41) + + self.assertTrue(self.Mr.nN == 31) + self.assertTrue(self.Mr.nEx == 22) + self.assertTrue(self.Mr.nEy == 20) + self.assertTrue(self.Mr.nEz == 20) - # for cell in self.Mr.sortedCells: - # for e in cell.edgeDict: - # self.assertTrue(cell.edgeDict[e].edgeType==e[1].lower()) + def test_gridCC(self): + x = np.r_[0.25,0.75] + y = np.r_[0.5,0.5] + z = np.r_[0.5,0.5] + self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.M.gridCC).flatten()) == 0) - # self.assertTrue(self.Mr.nN == 31) - # self.assertTrue(self.Mr.nEx == 22) - # self.assertTrue(self.Mr.nEy == 20) - # self.assertTrue(self.Mr.nEz == 20) + x = np.r_[0.125,0.375,0.75,0.125,0.375,0.125,0.375,0.125,0.375] + y = np.r_[0.25,0.25,0.5,0.75,0.75,0.25,0.25,0.75,0.75] + z = np.r_[0.25,0.25,0.5,0.25,0.25,0.75,0.75,0.75,0.75] + self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.Mr.gridCC).flatten()) == 0) + def test_gridN(self): + x = np.r_[0,0.5,1,0,0.5,1,0,0.5,1,0,0.5,1] + y = np.r_[0,0,0,1,1,1,0,0,0,1,1,1.] + z = np.r_[0,0,0,0,0,0,1,1,1,1,1,1.] + self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.M.gridN).flatten()) == 0) + + x = np.r_[0,0.25,0.5,1,0,0.25,0.5,0,0.25,0.5,1,0,0.25,0.5,0,0.25,0.5,0,0.25,0.5,0,0.25,0.5,1,0,0.25,0.5,0,0.25,0.5,1] + y = np.r_[0,0,0,0,0.5,0.5,0.5,1,1,1,1,0,0,0,0.5,0.5,0.5,1,1,1,0,0,0,0,0.5,0.5,0.5,1,1,1,1] + z = np.r_[0,0,0,0,0,0,0,0,0,0,0,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,1,1,1,1,1,1,1,1,1,1,1] + self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.Mr.gridN).flatten()) == 0) + + def test_gridFx(self): + x = np.r_[0.0,0.5,1.0] + y = np.r_[0.5,0.5,0.5] + z = np.r_[0.5,0.5,0.5] + self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.M.gridFx).flatten()) == 0) + + x = np.r_[0.0,0.25,0.5,1.0,0.0,0.25,0.5,0.0,0.25,0.5,0.0,0.25,0.5] + y = np.r_[0.25,0.25,0.25,0.5,0.75,0.75,0.75,0.25,0.25,0.25,0.75,0.75,0.75] + z = np.r_[0.25,0.25,0.25,0.5,0.25,0.25,0.25,0.75,0.75,0.75,0.75,0.75,0.75] + self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.Mr.gridFx).flatten()) == 0) + + def test_gridFy(self): + x = np.r_[0.25,0.75,0.25,0.75] + y = np.r_[0,0,1.,1.] + z = np.r_[0.5,0.5,0.5,0.5] + self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.M.gridFy).flatten()) == 0) + + x = np.r_[0.125,0.375,0.75,0.125,0.375,0.125,0.375,0.75,0.125,0.375,0.125,0.375,0.125,0.375] + y = np.r_[0,0,0,0.5,0.5,1,1,1,0,0,0.5,0.5,1,1] + z = np.r_[0.25,0.25,0.5,0.25,0.25,0.25,0.25,0.5,0.75,0.75,0.75,0.75,0.75,0.75] + self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.Mr.gridFy).flatten()) == 0) + + def test_gridFz(self): + x = np.r_[0.25,0.75,0.25,0.75] + y = np.r_[0.5,0.5,0.5,0.5] + z = np.r_[0,0,1.,1.] + self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.M.gridFz).flatten()) == 0) + + x = np.r_[0.125,0.375,0.75,0.125,0.375,0.125,0.375,0.125,0.375,0.125,0.375,0.75,0.125,0.375] + y = np.r_[0.25,0.25,0.5,0.75,0.75,0.25,0.25,0.75,0.75,0.25,0.25,0.5,0.75,0.75] + z = np.r_[0,0,0,0,0,0.5,0.5,0.5,0.5,1,1,1,1,1] + self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.Mr.gridFz).flatten()) == 0) + + + def test_gridEx(self): + x = np.r_[0.25,0.75,0.25,0.75,0.25,0.75,0.25,0.75] + y = np.r_[0,0,1.,1.,0,0,1.,1.] + z = np.r_[0,0,0,0,1.,1.,1.,1.] + self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.M.gridEx).flatten()) == 0) + + x = np.r_[0.125,0.375,0.75,0.125,0.375,0.125,0.375,0.75,0.125,0.375,0.125,0.375,0.125,0.375,0.125,0.375,0.75,0.125,0.375,0.125,0.375,0.75] + y = np.r_[0,0,0,0.5,0.5,1,1,1,0,0,0.5,0.5,1,1,0,0,0,0.5,0.5,1,1,1] + z = np.r_[0,0,0,0,0,0,0,0,0.5,0.5,0.5,0.5,0.5,0.5,1,1,1,1,1,1,1,1] + self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.Mr.gridEx).flatten()) == 0) + + def test_gridEy(self): + x = np.r_[0,0.5,1,0,0.5,1] + y = np.r_[0.5,0.5,0.5,0.5,0.5,0.5] + z = np.r_[0,0,0,1.,1.,1.] + self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.M.gridEy).flatten()) == 0) + + x = np.r_[0,0.25,0.5,1,0,0.25,0.5,0,0.25,0.5,0,0.25,0.5,0,0.25,0.5,1,0,0.25,0.5] + y = np.r_[0.25,0.25,0.25,0.5,0.75,0.75,0.75,0.25,0.25,0.25,0.75,0.75,0.75,0.25,0.25,0.25,0.5,0.75,0.75,0.75] + z = np.r_[0,0,0,0,0,0,0,0.5,0.5,0.5,0.5,0.5,0.5,1,1,1,1,1,1,1] + self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.Mr.gridEy).flatten()) == 0) + + def test_gridEz(self): + x = np.r_[0,0.5,1,0,0.5,1] + y = np.r_[0,0,0,1.,1.,1.] + z = np.r_[0.5,0.5,0.5,0.5,0.5,0.5] + self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.M.gridEz).flatten()) == 0) + + x = np.r_[0,0.25,0.5,1,0 ,0.25,0.5,0,0.25,0.5,1,0,0.25,0.5,0 ,0.25,0.5,0 ,0.25,0.5] + y = np.r_[0,0 ,0 ,0,0.5,0.5 ,0.5,1,1 ,1 ,1,0,0 ,0 ,0.5,0.5 ,0.5,1 ,1 ,1 ] + z = np.r_[0.25,0.25,0.25,0.5,0.25,0.25,0.25,0.25,0.25,0.25,0.5,0.75,0.75,0.75,0.75,0.75,0.75,0.75,0.75,0.75] + self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.Mr.gridEz).flatten()) == 0) if __name__ == '__main__': unittest.main() From 99ada822e8c293526d96c81127f9aad68981d3fa Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Wed, 11 Feb 2015 17:16:29 -0800 Subject: [PATCH 15/83] faceDiv in 3D --- SimPEG/Mesh/NewTreeMesh.py | 169 ++++++++++++++++++++----------- SimPEG/Tests/test_NewTreeMesh.py | 6 +- 2 files changed, 114 insertions(+), 61 deletions(-) diff --git a/SimPEG/Mesh/NewTreeMesh.py b/SimPEG/Mesh/NewTreeMesh.py index 462f0c74..19951b9f 100644 --- a/SimPEG/Mesh/NewTreeMesh.py +++ b/SimPEG/Mesh/NewTreeMesh.py @@ -1,5 +1,5 @@ import numpy as np, scipy.sparse as sp -from SimPEG.Utils import ndgrid, mkvc, sdiag +from SimPEG.Utils import ndgrid, mkvc, sdiag, volTetra from BaseMesh import BaseMesh @@ -237,6 +237,42 @@ class TreeCell(TreeIndexer): return (self.n0.vec + self.n1.vec + self.n2.vec + self.n3.vec + self.n4.vec + self.n5.vec + self.n6.vec + self.n7.vec)/8.0 + @property + def vol(self): + # + # 6 --------------- 7 + # /| / | + # / | / | + # / | / | + # / | / | + # 4 -------------- 5 | + # | 2 ----------|---- 3 z + # | / | / ^ y + # | / | / | / + # | / | / | / + # 0 ---------------1 o----> x + + + # __ Look at the 4 (I mixed up the Z axis, sorry) + # / + n0, n1, n2, n3, n4, n5, n6, n7 = (self.n4.index, self.n5.index, self.n6.index, self.n7.index, + self.n0.index, self.n1.index, self.n2.index, self.n3.index) + + vol1 = (volTetra(self.M._nodes[:,NX:], n4, n5, n0, n6) + # cut edge top + volTetra(self.M._nodes[:,NX:], n5, n6, n7, n3) + # cut edge top + volTetra(self.M._nodes[:,NX:], n5, n0, n6, n3) + # middle + volTetra(self.M._nodes[:,NX:], n5, n1, n0, n3) + # cut edge bottom + volTetra(self.M._nodes[:,NX:], n0, n6, n3, n2)) # cut edge bottom + + vol2 = (volTetra(self.M._nodes[:,NX:], n4, n7, n5, n1) + # cut edge top + volTetra(self.M._nodes[:,NX:], n4, n6, n7, n2) + # cut edge top + volTetra(self.M._nodes[:,NX:], n4, n2, n7, n1) + # middle + volTetra(self.M._nodes[:,NX:], n1, n2, n0, n4) + # cut edge bottom + volTetra(self.M._nodes[:,NX:], n1, n3, n2, n7)) # cut edge bottom + + return (vol1 + vol2)/2.0 + + class TreeMesh(BaseMesh): def __init__(self, h_in, x0=None): @@ -521,13 +557,20 @@ class TreeMesh(BaseMesh): if getattr(self, '_area', None) is None: if self.dim == 2: self._area = np.r_[self.edge[self.nEx:], self.edge[:self.nEx]] + elif self.dim == 3: + F = TreeFace(self, 'active') + self._area = F.sort(F.area) return self._area @property def vol(self): if getattr(self, '_vol', None) is None: - F = TreeFace(self, 'active') - self._vol = F.sort(F.area) + if self.dim == 2: + F = TreeFace(self, 'active') + self._vol = F.sort(F.area) + elif self.dim == 3: + C = TreeCell(self, 'active') + self._vol = C.sort(C.vol) return self._vol @property @@ -702,6 +745,39 @@ class TreeMesh(BaseMesh): nodeNums = [n.index for n in nodes] newNode, node = self.addNode(nodeNums) + # .----------------.----------------. + # /| /| /| + # / | / | / | + # / | 6 / | 7 / | + # / | / | / | + # .----------------.----+-----------. | + # /| . ---------/|----.----------/|----. + # fZp / | /| / | /| / | /| + # | / | / | 4 / | / | 5 / | / | + # 6 ------eX3------ 7 / | / | / | / | / | / | + # /| | / | . -------------- .----------------. |/ | + # /eZ2 . / eZ3 | . ---+------|----.----+------|----. | + # eY2 | fYp eY3 | | /| .______|___/|____.______|___/|____. + # / | / fXp| | / | / 2 | / | / 3 | / | / + # 4 ------eX2----- 5 | | / | / | / | / | / | / + # |fXm 2 -----eX1--|---- 3 z . ---+---------- . ---+---------- . | / + # eZ0 / | eY1 ^ y | |/ | |/ | |/ + # | eY0 . fYm eZ1 / | / | . ----------|----.-----------|----. + # | / | | / | / | / 0 | / 1 | / + # 0 ------eX0------1 o----> x | / | / | / + # | | / | / | / + # fZm . -------------- . -------------- . + # + # + # fX fY fZ + # 2___________3 2___________3 2___________3 + # | e1 | | e1 | | e1 | + # | | | | | | + # e2 | x | e3 z e2 | x | e3 z e2 | x | e3 y + # | | ^ | | ^ | | ^ + # |___________| |___> y |___________| |___> x |___________| |___> x + # 0 e0 1 0 e0 1 0 e0 1 + nE = np.zeros((6,6)) nE[:, ACTIVE] = 1 nE[:, PARENT] = -1 @@ -751,55 +827,18 @@ class TreeMesh(BaseMesh): nC[:, ACTIVE] = 1 nC[:, PARENT] = index - # .----------------.----------------. - # /| /| /| - # / | / | / | - # / | 6 / | 7 / | - # / | / | / | - # .----------------.----+-----------. | - # /| . ---------/|----.----------/|----. - # fZp / | /| / | /| / | /| - # | / | / | 4 / | / | 5 / | / | - # 6 ------eX3------ 7 / | / | / | / | / | / | - # /| | / | . -------------- .----------------. |/ | - # /eZ2 . / eZ3 | . ---+------|----.----+------|----. | - # eY2 | fYp eY3 | | /| .______|___/|____.______|___/|____. - # / | / fXp| | / | / 2 | / | / 3 | / | / - # 4 ------eX2----- 5 | | / | / | / | / | / | / - # |fXm 2 -----eX1--|---- 3 z . ---+---------- . ---+---------- . | / - # eZ0 / | eY1 ^ y | |/ | |/ | |/ - # | eY0 . fYm eZ1 / | / | . ----------|----.-----------|----. - # | / | | / | / | / 0 | / 1 | / - # 0 ------eX0------1 o----> x | / | / | / - # | | / | / | / - # fZm . -------------- . -------------- . - # - # - # fX fY fZ - # 2___________3 2___________3 2___________3 - # | e1 | | e1 | | e1 | - # | | | | | | - # e2 | x | e3 z e2 | x | e3 z e2 | x | e3 y - # | | ^ | | ^ | | ^ - # |___________| |___> y |___________| |___> x |___________| |___> x - # 0 e0 1 0 e0 1 0 e0 1 - - cfInds = [CFACE0,CFACE1,CFACE2,CFACE3,CFACE4,CFACE5] - nC[0, cfInds] = [fXm[0], nFi[0], fYm[0], nFi[4], fZm[0], nFi[ 8]] - nC[1, cfInds] = [nFi[0], fXp[0], fYm[1], nFi[5], fZm[1], nFi[ 9]] - nC[2, cfInds] = [fXm[1], nFi[1], nFi[4], fYp[0], fZm[2], nFi[10]] - nC[3, cfInds] = [nFi[1], fXp[1], nFi[5], fYp[1], fZm[3], nFi[11]] - nC[4, cfInds] = [fXm[2], nFi[2], fYm[2], nFi[6], nFi[ 8], fZp[0]] - nC[5, cfInds] = [nFi[2], fXp[2], fYm[3], nFi[7], nFi[ 9], fZp[1]] - nC[6, cfInds] = [fXm[3], nFi[3], nFi[6], fYp[2], nFi[10], fZp[2]] - nC[7, cfInds] = [nFi[3], fXp[3], nFi[7], fYp[3], nFi[11], fZp[3]] + nC[0, cfInds] = [fXm[0], nFi[0], fYm[0], nFi[4], fZm[ 0], nFi[ 8]] + nC[1, cfInds] = [nFi[0], fXp[0], fYm[1], nFi[5], fZm[ 1], nFi[ 9]] + nC[2, cfInds] = [fXm[1], nFi[1], nFi[4], fYp[0], fZm[ 2], nFi[10]] + nC[3, cfInds] = [nFi[1], fXp[1], nFi[5], fYp[1], fZm[ 3], nFi[11]] + nC[4, cfInds] = [fXm[2], nFi[2], fYm[2], nFi[6], nFi[ 8], fZp[ 0]] + nC[5, cfInds] = [nFi[2], fXp[2], fYm[3], nFi[7], nFi[ 9], fZp[ 1]] + nC[6, cfInds] = [fXm[3], nFi[3], nFi[6], fYp[2], nFi[10], fZp[ 2]] + nC[7, cfInds] = [nFi[3], fXp[3], nFi[7], fYp[3], nFi[11], fZp[ 3]] return self._push('_cells', nC) - - - def _index(self, attr, index): index = [index] if np.isscalar(index) else list(index) C = getattr(self, attr) @@ -820,17 +859,28 @@ class TreeMesh(BaseMesh): def faceDiv(self): if getattr(self, '_faceDiv', None) is None: self.number() + + if self.dim == 2: + offset = np.r_[self.nFx, -self.nEx] # this switches from edge to face numbering + C = self._faces + sign_face = zip([-1,1,-1,1],[FEDGE0, FEDGE1, FEDGE2, FEDGE3]) + faceStr = '_edges' + elif self.dim == 3: + C = self._cells + sign_face = zip([-1,1,-1,1,-1,1],[CFACE0, CFACE1, CFACE2, CFACE3, CFACE4, CFACE5]) + faceStr = '_faces' + # TODO: Preallocate! I, J, V = [], [], [] - - offset = np.r_[self.nFx, -self.nEx] # this switches from edge to face numbering - C = self._faces activeCells = C[:,ACTIVE] == 1 for cell in C[activeCells]: - for sign, face in zip([-1,1,-1,1],[FEDGE0, FEDGE1, FEDGE2, FEDGE3]): - ij, jrow = self._index('_edges', cell[face]) + for sign, face in sign_face: + ij, jrow = self._index(faceStr, cell[face]) I += [cell[NUM]]*len(ij) - J += list(jrow[:,0] + offset[jrow[:,EDIR]]) + if self.dim == 2: + J += list(jrow[:,0] + offset[jrow[:,EDIR]]) + elif self.dim == 3: + J += list(jrow[:,0]) V += [sign]*len(ij) VOL = self.vol D = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.nF)) @@ -894,14 +944,17 @@ if __name__ == '__main__': tM.refineFace(3) tM.refineFace(9) - print tM._nodes[:,NUM] + # print tM._nodes[:,NUM] tM.number() - print tM._nodes[:,NUM] - print tM._edges[:,NUM] + # print tM._nodes[:,NUM] + # print tM._edges[:,NUM] - print TreeFace(tM,0).e3.n1.index + print TreeFace(tM,'active').e3.n1.index + Mr = TreeMesh([2,1,1]) + Mr.refineCell(0) + print Mr.vol # print tM._faces diff --git a/SimPEG/Tests/test_NewTreeMesh.py b/SimPEG/Tests/test_NewTreeMesh.py index 03cdaba6..36d9021b 100644 --- a/SimPEG/Tests/test_NewTreeMesh.py +++ b/SimPEG/Tests/test_NewTreeMesh.py @@ -76,14 +76,14 @@ class SimpleOctreeOperatorTests(unittest.TestCase): h1 = np.random.rand(5) h2 = np.random.rand(7) h3 = np.random.rand(3) - # self.tM = TensorMesh([h1,h2,h3]) - # self.oM = TreeMesh([h1,h2,h3]) + self.tM = TensorMesh([h1,h2,h3]) + self.oM = TreeMesh([h1,h2,h3]) self.tM2 = TensorMesh([h1,h2]) self.oM2 = TreeMesh([h1,h2]) # self.oM2.plotGrid(showIt=True) def test_faceDiv(self): - # self.assertAlmostEqual((self.tM.faceDiv - self.oM.faceDiv).toarray().sum(), 0) + self.assertAlmostEqual((self.tM.faceDiv - self.oM.faceDiv).toarray().sum(), 0) self.assertAlmostEqual((self.tM2.faceDiv - self.oM2.faceDiv).toarray().sum(), 0) # def test_nodalGrad(self): From 3369096126ec15466d51d0c7486f0deaa02e4629 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Wed, 11 Feb 2015 17:30:41 -0800 Subject: [PATCH 16/83] updates to edge Curlssssszzzz --- SimPEG/Mesh/NewTreeMesh.py | 28 ++++++++++++++++++++++++++++ SimPEG/Tests/test_NewTreeMesh.py | 6 +++--- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/SimPEG/Mesh/NewTreeMesh.py b/SimPEG/Mesh/NewTreeMesh.py index 19951b9f..64bac93f 100644 --- a/SimPEG/Mesh/NewTreeMesh.py +++ b/SimPEG/Mesh/NewTreeMesh.py @@ -888,6 +888,30 @@ class TreeMesh(BaseMesh): self._faceDiv = sdiag(1/VOL)*D*sdiag(S) return self._faceDiv + @property + def edgeCurl(self): + """Construct the 3D curl operator.""" + assert self.dim > 2, "Edge Curl only programed for 3D." + + if getattr(self, '_edgeCurl', None) is None: + self.number() + # TODO: Preallocate! + I, J, V = [], [], [] + F = self._faces + sign_edge = zip([-1,1,-1,1],[FEDGE0, FEDGE1, FEDGE2, FEDGE3]) + activeFaces = F[:,ACTIVE] == 1 + for face in F[activeFaces]: + for sign, edge in sign_edge: + ij, jrow = self._index('_edges', face[edge]) + I += [face[NUM]]*len(ij) + J += list(jrow[:,0]) + V += [sign]*len(ij) + C = sp.csr_matrix((V,(I,J)), shape=(self.nF, self.nE)) + S = self.area + L = self.edge + self._edgeCurl = sdiag(1/S)*C*sdiag(L) + return self._edgeCurl + def plotGrid(self, ax=None, text=True, showIt=False): import matplotlib.pyplot as plt @@ -957,6 +981,10 @@ if __name__ == '__main__': print Mr.vol + tM = TreeMesh([100,100,100]) + # print tM.vol + + # print tM._faces # print tM._edges[0,:] # print tM.vol diff --git a/SimPEG/Tests/test_NewTreeMesh.py b/SimPEG/Tests/test_NewTreeMesh.py index 36d9021b..78100df5 100644 --- a/SimPEG/Tests/test_NewTreeMesh.py +++ b/SimPEG/Tests/test_NewTreeMesh.py @@ -90,9 +90,9 @@ class SimpleOctreeOperatorTests(unittest.TestCase): # self.assertAlmostEqual((self.tM.nodalGrad - self.oM.nodalGrad).toarray().sum(), 0) # self.assertAlmostEqual((self.tM2.nodalGrad - self.oM2.nodalGrad).toarray().sum(), 0) - # def test_edgeCurl(self): - # self.assertAlmostEqual((self.tM.edgeCurl - self.oM.edgeCurl).toarray().sum(), 0) - # # self.assertAlmostEqual((self.tM2.edgeCurl - self.oM2.edgeCurl).toarray().sum(), 0) + def test_edgeCurl(self): + self.assertAlmostEqual((self.tM.edgeCurl - self.oM.edgeCurl).toarray().sum(), 0) + # self.assertAlmostEqual((self.tM2.edgeCurl - self.oM2.edgeCurl).toarray().sum(), 0) # def test_InnerProducts(self): # self.assertAlmostEqual((self.tM.getFaceInnerProduct() - self.oM.getFaceInnerProduct()).toarray().sum(), 0) From 5cdab15aa1ffb04ef2ca7c841523f48667c63a7f Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Wed, 11 Feb 2015 21:57:05 -0800 Subject: [PATCH 17/83] nodal gradient --- SimPEG/Mesh/NewTreeMesh.py | 20 +++++++++++++++++++- SimPEG/Tests/test_NewTreeMesh.py | 6 +++--- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/SimPEG/Mesh/NewTreeMesh.py b/SimPEG/Mesh/NewTreeMesh.py index 64bac93f..ca793065 100644 --- a/SimPEG/Mesh/NewTreeMesh.py +++ b/SimPEG/Mesh/NewTreeMesh.py @@ -909,9 +909,27 @@ class TreeMesh(BaseMesh): C = sp.csr_matrix((V,(I,J)), shape=(self.nF, self.nE)) S = self.area L = self.edge - self._edgeCurl = sdiag(1/S)*C*sdiag(L) + self._edgeCurl = sdiag(1.0/S)*C*sdiag(L) return self._edgeCurl + @property + def nodalGrad(self): + if getattr(self, '_nodalGrad', None) is None: + self.number() + # TODO: Preallocate! + I, J, V = [], [], [] + E = self._edges + N = self._nodes + activeEdges = E[:,ACTIVE] == 1 + for edge in E[activeEdges]: + I += [edge[NUM], edge[NUM]] + J += [N[edge[ENODE0], NUM], N[edge[ENODE1], NUM]] + V += [-1, 1] + G = sp.csr_matrix((V,(I,J)), shape=(self.nE, self.nN)) + L = self.edge + self._nodalGrad = sdiag(1.0/L)*G + return self._nodalGrad + def plotGrid(self, ax=None, text=True, showIt=False): import matplotlib.pyplot as plt diff --git a/SimPEG/Tests/test_NewTreeMesh.py b/SimPEG/Tests/test_NewTreeMesh.py index 78100df5..ed1d2864 100644 --- a/SimPEG/Tests/test_NewTreeMesh.py +++ b/SimPEG/Tests/test_NewTreeMesh.py @@ -86,9 +86,9 @@ class SimpleOctreeOperatorTests(unittest.TestCase): self.assertAlmostEqual((self.tM.faceDiv - self.oM.faceDiv).toarray().sum(), 0) self.assertAlmostEqual((self.tM2.faceDiv - self.oM2.faceDiv).toarray().sum(), 0) - # def test_nodalGrad(self): - # self.assertAlmostEqual((self.tM.nodalGrad - self.oM.nodalGrad).toarray().sum(), 0) - # self.assertAlmostEqual((self.tM2.nodalGrad - self.oM2.nodalGrad).toarray().sum(), 0) + def test_nodalGrad(self): + self.assertAlmostEqual((self.tM.nodalGrad - self.oM.nodalGrad).toarray().sum(), 0) + self.assertAlmostEqual((self.tM2.nodalGrad - self.oM2.nodalGrad).toarray().sum(), 0) def test_edgeCurl(self): self.assertAlmostEqual((self.tM.edgeCurl - self.oM.edgeCurl).toarray().sum(), 0) From 0220ee57f2fb79071aaec0995b7308ca55bb16e4 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Wed, 11 Feb 2015 23:08:22 -0800 Subject: [PATCH 18/83] start of inner products --- SimPEG/Mesh/NewTreeMesh.py | 126 ++++++++++++++++++++++++++++++- SimPEG/Tests/test_NewTreeMesh.py | 13 +++- 2 files changed, 133 insertions(+), 6 deletions(-) diff --git a/SimPEG/Mesh/NewTreeMesh.py b/SimPEG/Mesh/NewTreeMesh.py index ca793065..aaae4ff0 100644 --- a/SimPEG/Mesh/NewTreeMesh.py +++ b/SimPEG/Mesh/NewTreeMesh.py @@ -1,7 +1,7 @@ import numpy as np, scipy.sparse as sp from SimPEG.Utils import ndgrid, mkvc, sdiag, volTetra from BaseMesh import BaseMesh - +from InnerProducts import InnerProducts NUM, ACTIVE, NX, NY, NZ = range(5) # Do not put anything after NZ NUM, ACTIVE, PARENT, EDIR, ENODE0, ENODE1 = range(6) @@ -65,6 +65,9 @@ class TreeEdge(TreeIndexer): def num(self):return self.E[self.index, NUM] @property def dir(self):return self.E[self.index, EDIR] + @property + def isleaf(self):return self.E[self.index, ACTIVE] == 1 + @property def n0(self): return self._ind(ENODE0) @property @@ -87,6 +90,8 @@ class TreeFace(TreeIndexer): def num(self):return self.F[self.index, NUM] @property def dir(self):return self.F[self.index, FDIR] + @property + def isleaf(self):return self.F[self.index, ACTIVE] == 1 # fX fY fZ # n2___________n3 n2___________n3 n2___________n3 @@ -144,6 +149,8 @@ class TreeCell(TreeIndexer): @property def num(self):return self.C[self.index, NUM] + @property + def isleaf(self):return self.C[self.index, ACTIVE] == 1 @property def fXm(self): return self._ind(CFACE0) @@ -273,7 +280,7 @@ class TreeCell(TreeIndexer): return (vol1 + vol2)/2.0 -class TreeMesh(BaseMesh): +class TreeMesh(InnerProducts, BaseMesh): def __init__(self, h_in, x0=None): assert type(h_in) in [list, tuple], 'h_in must be a list' @@ -930,6 +937,112 @@ class TreeMesh(BaseMesh): self._nodalGrad = sdiag(1.0/L)*G return self._nodalGrad + + def _getFaceP(self, face0, face1, face2): + if self.dim == 2: + raise NotImplementedError() + + I, J, V = [], [], [] + + Cs = self._cells + activeCells = Cs[:,ACTIVE] == 1 + for cellInd in np.argwhere(activeCells): + + C = TreeCell(self, cellInd) + + face = getattr(C, face0) + if face.isleaf: + j = [int(face.num)] + elif self.dim == 2: + raise NotImplementedError() + j = face.children[0 if 'm' in face1 else 1].index + elif self.dim == 3: + raise NotImplementedError() + j = face.children[0 if 'm' in face1 else 1, + 0 if 'm' in face2 else 1].index + lenj = len(j) + I += [int(C.num)]*lenj + J += j + V += [1./lenj]*lenj + return sp.csr_matrix((V,(I,J)), shape=(self.nC, self.nF)) + + def _getEdgeP(self, edge0, edge1, edge2): + + if self.dim == 2: + raise NotImplementedError() + + I, J, V = [], [], [] + + + Cs = self._cells + activeCells = Cs[:,ACTIVE] == 1 + for cellInd in np.argwhere(activeCells): + + C = TreeCell(self, cellInd) + + if self.dim == 2: + raise NotImplementedError() + e2f = lambda e: ('f' + {'X':'Y','Y':'X'}[e[1]] + + {'0':'m','1':'p'}[e[2]]) + face = cell.faceDict[e2f(edge0)] + if face.isleaf: + j = face.index + else: + j = face.children[0 if 'm' in e2f(edge1) else 1].index + # Need to flip the numbering for edges + if 'X' in edge0: + j = [jj - self.nFx for jj in j] + elif 'Y' in edge0: + j = [jj + self.nFy for jj in j] + elif self.dim == 3: + edge = getattr(C, edge0) + if edge.isleaf: + j = [int(edge.num)] + else: + raise NotImplementedError() + mSide = lambda e: {'0':True,'1':True,'2':False,'3':False}[e[2]] + j = edge.children[0 if mSide(edge1) else 1, + 0 if mSide(edge2) else 1].index + lenj = len(j) + I += [int(C.num)]*lenj + J += j + V += [1./lenj]*lenj + return sp.csr_matrix((V,(I,J)), shape=(self.nC, self.nE)) + + def _getFacePxx(self): + def Pxx(xFace, yFace): + self.number() + xP = self._getFaceP(xFace, yFace, None) + yP = self._getFaceP(yFace, xFace, None) + return sp.vstack((xP, yP)) + return Pxx + + def _getEdgePxx(self): + def Pxx(xEdge, yEdge): + self.number() + xP = self._getEdgeP(xEdge, yEdge, None) + yP = self._getEdgeP(yEdge, xEdge, None) + return sp.vstack((xP, yP)) + return Pxx + + def _getFacePxxx(self): + def Pxxx(xFace, yFace, zFace): + self.number() + xP = self._getFaceP(xFace, yFace, zFace) + yP = self._getFaceP(yFace, xFace, zFace) + zP = self._getFaceP(zFace, xFace, yFace) + return sp.vstack((xP, yP, zP)) + return Pxxx + + def _getEdgePxxx(self): + def Pxxx(xEdge, yEdge, zEdge): + self.number() + xP = self._getEdgeP(xEdge, yEdge, zEdge) + yP = self._getEdgeP(yEdge, xEdge, zEdge) + zP = self._getEdgeP(zEdge, xEdge, yEdge) + return sp.vstack((xP, yP, zP)) + return Pxxx + def plotGrid(self, ax=None, text=True, showIt=False): import matplotlib.pyplot as plt @@ -998,8 +1111,15 @@ if __name__ == '__main__': print Mr.vol + M = TreeMesh([2,2,2]) + M.number() + M.refineCell(0) + M.refineCell(3) + assert M.isNumbered is False + C = TreeCell(M, 'active') + M.getEdgeInnerProduct() - tM = TreeMesh([100,100,100]) + # tM = TreeMesh([100,100,100]) # print tM.vol diff --git a/SimPEG/Tests/test_NewTreeMesh.py b/SimPEG/Tests/test_NewTreeMesh.py index ed1d2864..503834a4 100644 --- a/SimPEG/Tests/test_NewTreeMesh.py +++ b/SimPEG/Tests/test_NewTreeMesh.py @@ -15,6 +15,13 @@ class TestQuadTreeMesh(unittest.TestCase): M.number() # M.plotGrid(showIt=True) + def test_numbering(self): + M = TreeMesh([2,2,2]) + M.number() + M.refineCell(0) + M.refineCell(3) + assert M.isNumbered is False + def test_MeshSizes(self): self.assertTrue(self.M.nC==9) self.assertTrue(self.M.nF==25) @@ -94,11 +101,11 @@ class SimpleOctreeOperatorTests(unittest.TestCase): self.assertAlmostEqual((self.tM.edgeCurl - self.oM.edgeCurl).toarray().sum(), 0) # self.assertAlmostEqual((self.tM2.edgeCurl - self.oM2.edgeCurl).toarray().sum(), 0) - # def test_InnerProducts(self): - # self.assertAlmostEqual((self.tM.getFaceInnerProduct() - self.oM.getFaceInnerProduct()).toarray().sum(), 0) + def test_InnerProducts(self): + self.assertAlmostEqual((self.tM.getFaceInnerProduct() - self.oM.getFaceInnerProduct()).toarray().sum(), 0) + self.assertAlmostEqual((self.tM.getEdgeInnerProduct() - self.oM.getEdgeInnerProduct()).toarray().sum(), 0) # self.assertAlmostEqual((self.tM2.getFaceInnerProduct() - self.oM2.getFaceInnerProduct()).toarray().sum(), 0) # self.assertAlmostEqual((self.tM2.getEdgeInnerProduct() - self.oM2.getEdgeInnerProduct()).toarray().sum(), 0) - # self.assertAlmostEqual((self.tM.getEdgeInnerProduct() - self.oM.getEdgeInnerProduct()).toarray().sum(), 0) From 6ffeb5cc1a27c4f5e52552a98922729d7621a233 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Tue, 3 Mar 2015 10:00:36 -0800 Subject: [PATCH 19/83] minor update to survey, to return dobs from makeSyntheticData --- SimPEG/Survey.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/SimPEG/Survey.py b/SimPEG/Survey.py index e72b7d22..95c79056 100644 --- a/SimPEG/Survey.py +++ b/SimPEG/Survey.py @@ -366,9 +366,10 @@ class BaseSurvey(object): """ if getattr(self, 'dobs', None) is not None and not force: - raise Exception('Survey already has dobs.') + raise Exception('Survey already has dobs. You can use force=True to override this exception.') self.mtrue = m self.dtrue = self.dpred(m, u=u) noise = std*abs(self.dtrue)*np.random.randn(*self.dtrue.shape) self.dobs = self.dtrue+noise self.std = self.dobs*0 + std + return self.dobs From 223380484bfd1ffde39f15f7c53b6bac03756d87 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Sun, 5 Apr 2015 17:07:10 -0700 Subject: [PATCH 20/83] A bug that took six hours to track down. Two characters. --- SimPEG/Mesh/NewTreeMesh.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SimPEG/Mesh/NewTreeMesh.py b/SimPEG/Mesh/NewTreeMesh.py index aaae4ff0..e18464cb 100644 --- a/SimPEG/Mesh/NewTreeMesh.py +++ b/SimPEG/Mesh/NewTreeMesh.py @@ -825,8 +825,8 @@ class TreeMesh(InnerProducts, BaseMesh): nF[8, feInds] = [rfYm[0, FEDGE1], nEi[0], rfXm[0, FEDGE1], nEi[2]] nF[9, feInds] = [rfYm[1, FEDGE1], nEi[1], nEi[2], rfXp[0, FEDGE1]] - nF[10,feInds] = [nEi[0], rfYp[0, FEDGE1], rfXm[2, FEDGE1], nEi[3]] - nF[11,feInds] = [nEi[1], rfYp[1, FEDGE1], nEi[3], rfXp[2, FEDGE1]] + nF[10,feInds] = [nEi[0], rfYp[0, FEDGE1], rfXm[1, FEDGE1], nEi[3]] + nF[11,feInds] = [nEi[1], rfYp[1, FEDGE1], nEi[3], rfXp[1, FEDGE1]] nFi, nF = self._push('_faces', nF) From a9b1f89e7f30de414dc9c85e3b672fbf6fca7364 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Sun, 5 Apr 2015 17:09:03 -0700 Subject: [PATCH 21/83] updates to TreeMesh --- SimPEG/Mesh/NewTreeMesh.py | 161 +++++++++++++++++++++++++++---- SimPEG/Tests/test_NewTreeMesh.py | 93 +++++++++++++++++- 2 files changed, 232 insertions(+), 22 deletions(-) diff --git a/SimPEG/Mesh/NewTreeMesh.py b/SimPEG/Mesh/NewTreeMesh.py index e18464cb..fa1aadd6 100644 --- a/SimPEG/Mesh/NewTreeMesh.py +++ b/SimPEG/Mesh/NewTreeMesh.py @@ -143,6 +143,28 @@ class TreeFace(TreeIndexer): V = 0.25 * (4.0*(p**2)*(q**2) - (a**2 + c**2 - b**2 - d**2)**2)**0.5 return V + @property + def children(self): + if self.isleaf: return None + ind = int(self.index) # can not get children of a fancy slice at the moment. + subInds = np.argwhere(self.F[:,PARENT] == ind).flatten() + return TreeFace(self.M, subInds) + + + def refine(self, function, level): + + int(self.index) # should only be able to refine one at a time. + + toLevel = function(self) + + if toLevel < level+1: + return + + inds, rows = self.M.refineFace(self.index) + for i in inds: + TreeFace(self.M, i).refine(function, level + 1) + + class TreeCell(TreeIndexer): _SubTree = TreeFace _pointer = '_cells' @@ -240,6 +262,9 @@ class TreeCell(TreeIndexer): @property def n7(self): return self.fZp.n3 @property + def nodes(self): + return [self.n0, self.n1, self.n2, self.n3, self.n4, self.n5, self.n6, self.n7] + @property def center(self): return (self.n0.vec + self.n1.vec + self.n2.vec + self.n3.vec + self.n4.vec + self.n5.vec + self.n6.vec + self.n7.vec)/8.0 @@ -279,6 +304,26 @@ class TreeCell(TreeIndexer): return (vol1 + vol2)/2.0 + @property + def children(self): + if self.isleaf: return None + ind = int(self.index) # can not get children of a fancy slice at the moment. + subInds = np.argwhere(self.C[:,PARENT] == ind).flatten() + return TreeCell(self.M, subInds) + + def refine(self, function, level): + + int(self.index) # should only be able to refine one at a time. + + toLevel = function(self) + + if toLevel < level+1: + return + + inds, rows = self.M.refineCell(self.index) + for i in inds: + TreeCell(self.M, i).refine(function, level + 1) + class TreeMesh(InnerProducts, BaseMesh): @@ -687,7 +732,7 @@ class TreeMesh(InnerProducts, BaseMesh): E2i, E2 = self.refineEdge(f[FEDGE2]) E3i, E3 = self.refineEdge(f[FEDGE3]) - nodeNums = self._edges[f[[FEDGE0, FEDGE1]],:][:,[ENODE0, ENODE1]] + nodeNums = [n.index for n in TreeFace(self, index).nodes] newNode, node = self.addNode(nodeNums) # Refine the inner edges @@ -1043,6 +1088,12 @@ class TreeMesh(InnerProducts, BaseMesh): return sp.vstack((xP, yP, zP)) return Pxxx + def refine(self, function): + if self.dim == 3: + TreeCell(self, 0).refine(function, 0) + elif self.dim == 2: + TreeFace(self, 0).refine(function, 0) + def plotGrid(self, ax=None, text=True, showIt=False): import matplotlib.pyplot as plt @@ -1050,22 +1101,63 @@ class TreeMesh(InnerProducts, BaseMesh): axOpts = {'projection':'3d'} if self.dim == 3 else {} if ax is None: ax = plt.subplot(111, **axOpts) + if self.dim == 3: + C = TreeCell(self, 'active') + + + # fZp + # | + # 6 ------eX3------ 7 + # /| | / | + # /eZ2 . / eZ3 + # eY2 | fYp eY3 | + # / | / fXp| + # 4 ------eX2----- 5 | + # |fXm 2 -----eX1--|---- 3 z + # eZ0 / | eY1 ^ y + # | eY0 . fYm eZ1 / | / + # | / | | / | / + # 0 ------eX0------1 o----> x + # | + # fZm + # + + n1, n2, n3, n4, n5 = 0, 1, 3, 2, 0 + eX = np.c_[C.nodes[n1].x, C.nodes[n2].x, C.nodes[n3].x, C.nodes[n4].x, C.nodes[n5].x, [np.nan]*self.nC] + eY = np.c_[C.nodes[n1].y, C.nodes[n2].y, C.nodes[n3].y, C.nodes[n4].y, C.nodes[n5].y, [np.nan]*self.nC] + eZ = np.c_[C.nodes[n1].z, C.nodes[n2].z, C.nodes[n3].z, C.nodes[n4].z, C.nodes[n5].z, [np.nan]*self.nC] + ax.plot(eX.flatten(), eY.flatten(), 'b-', zs=eZ.flatten()) + + n1, n2, n3, n4, n5 = 4, 5, 7, 6, 4 + eX = np.c_[C.nodes[n1].x, C.nodes[n2].x, C.nodes[n3].x, C.nodes[n4].x, C.nodes[n5].x, [np.nan]*self.nC] + eY = np.c_[C.nodes[n1].y, C.nodes[n2].y, C.nodes[n3].y, C.nodes[n4].y, C.nodes[n5].y, [np.nan]*self.nC] + eZ = np.c_[C.nodes[n1].z, C.nodes[n2].z, C.nodes[n3].z, C.nodes[n4].z, C.nodes[n5].z, [np.nan]*self.nC] + ax.plot(eX.flatten(), eY.flatten(), 'r-', zs=eZ.flatten()) + + ax.plot(self.gridN[:,0], self.gridN[:,1], 'bs', zs=self.gridN[:,2]) + + ax.set_xlabel('x') + ax.set_ylabel('y') + ax.set_zlabel('z') + if showIt: plt.show() + return ax + N = self._nodes E = self._edges C = self._faces - plt.plot(N[:,1], N[:,2], 'b.') + ax.plot(N[:,1], N[:,2], 'b.') activeCells = C[:,ACTIVE] == 1 for FEDGE in [FEDGE0, FEDGE1, FEDGE2, FEDGE3]: nInds = E[C[activeCells,FEDGE],:][:,[ENODE0,ENODE1]] eX = np.c_[N[nInds[:,0],NX], N[nInds[:,1],NX], [np.nan]*nInds.shape[0]] eY = np.c_[N[nInds[:,0],NY], N[nInds[:,1],NY], [np.nan]*nInds.shape[0]] - plt.plot(eX.flatten(), eY.flatten(), 'b-') + ax.plot(eX.flatten(), eY.flatten(), 'b-') gridCC = self.gridCC if text: [ax.text(cc[0], cc[1],i) for i, cc in enumerate(gridCC)] - plt.plot(gridCC[:,0], gridCC[:,1], 'r.') + ax.plot(gridCC[:,0], gridCC[:,1], 'r.') gridFx = self.gridFx gridFy = self.gridFy if text: @@ -1092,32 +1184,44 @@ if __name__ == '__main__': from SimPEG import Mesh, Utils import matplotlib.pyplot as plt - tM = TreeMesh([np.ones(3),np.ones(2)]) + # tM = TreeMesh([np.ones(3),np.ones(2)]) + tM = TreeMesh([1,1,1]) - tM.refineFace(0) - tM.refineFace(1) - tM.refineFace(3) - tM.refineFace(9) + tM.refine(lambda c:2) + # tM.refineCell(4) + + M = Mesh.TensorMesh([4,4,4]) + print tM.gridN - M.gridN + tM.plotGrid() + + plt.show() + + + + # tM.refineFace(0) + # tM.refineFace(1) + # tM.refineFace(3) + # tM.refineFace(9) # print tM._nodes[:,NUM] - tM.number() + # tM.number() # print tM._nodes[:,NUM] # print tM._edges[:,NUM] - print TreeFace(tM,'active').e3.n1.index + # print TreeFace(tM,'active').e3.n1.index - Mr = TreeMesh([2,1,1]) - Mr.refineCell(0) + # Mr = TreeMesh([2,1,1]) + # Mr.refineCell(0) - print Mr.vol + # print Mr.vol - M = TreeMesh([2,2,2]) - M.number() - M.refineCell(0) - M.refineCell(3) - assert M.isNumbered is False - C = TreeCell(M, 'active') - M.getEdgeInnerProduct() + # M = TreeMesh([2,2,2]) + # M.number() + # M.refineCell(0) + # M.refineCell(3) + # assert M.isNumbered is False + # C = TreeCell(M, 'active') + # M.getEdgeInnerProduct() # tM = TreeMesh([100,100,100]) # print tM.vol @@ -1141,3 +1245,18 @@ if __name__ == '__main__': # plt.figure(2) # plt.plot(SortByX0(tM.gridCC),'b.') # plt.show() + + + # M = TreeMesh([1,1,1]) + + # def refFunc(cell): + # n = 3 - np.sum((cell.center.flatten() - np.r_[0.5, 0.5, 0.5])**2)**0.5 * 2 + # print n, cell.center + # return n + # return 1 + # M.refine(refFunc) + + # M.plotGrid(text=False) + # plt.show() + + # print M.nC diff --git a/SimPEG/Tests/test_NewTreeMesh.py b/SimPEG/Tests/test_NewTreeMesh.py index 503834a4..f08091a5 100644 --- a/SimPEG/Tests/test_NewTreeMesh.py +++ b/SimPEG/Tests/test_NewTreeMesh.py @@ -1,5 +1,5 @@ from SimPEG.Mesh import TensorMesh -from SimPEG.Mesh.NewTreeMesh import TreeMesh +from SimPEG.Mesh.NewTreeMesh import TreeMesh, TreeCell import numpy as np import unittest import matplotlib.pyplot as plt @@ -75,6 +75,85 @@ class TestQuadTreeMesh(unittest.TestCase): ay = np.r_[0.5,0.5,1,1,0.5,0.5,0.5,0.5,1,1,1,1,1] self.assertTrue(np.linalg.norm((np.r_[ax,ay]-self.M.area)) < TOL) +class TestOcTreeConnectivity(unittest.TestCase): + + def setUp(self): + self.oM = TreeMesh([1,1,1]) + self.oM.refine(lambda c: 1) + + def test_setup(self): + C = TreeCell(self.oM, 0) + children = C.children + assert not C.isleaf + assert len(children.index) == 8 + # assert not TreeCell(self.oM, 0).isleaf + c0, c1, c2, c3, c4, c5, c6, c7 = [TreeCell(self.oM, i) for i in range(1,9)] + + + # .----------------.----------------. + # /| /| /| + # / | / | / | + # / | c6 / | c7 / | + # / | / | / | + # .----------------.----+-----------. | + # /| . ---------/|----.----------/|----. + # fZp / | /| / | /| / | /| + # | / | / | c4 / | / | c5 / | X | + # 6 ------eX3------ 7 / | / | / | / | / | / | + # /| | / | . -------------- .----------------. |/ | + # /eZ2 . / eZ3 | . ---+------|----.----+------|----. | + # eY2 | fYp eY3 | | /| .______|___/|____.______|___/|____. + # / | / fXp| | / | / c2 | / | / c3 | / | / + # 4 ------eX2----- 5 | | / | / | / | / | / | / + # |fXm 2 -----eX1--|---- 3 z . ---+---------- . ---+---------- . | / + # eZ0 / | eY1 ^ y | |/ | |/ | |/ + # | eY0 . fYm eZ1 / | / | . ----------|----.-----------|----. + # | / | | / | / | / c0 | / c1 | / + # 0 ------eX0------1 o----> x | / | / | / + # | | / | / | / + # fZm . -------------- . -------------- . + # + # + # fX fY fZ + # 2___________3 2___________3 2___________3 + # | e1 | | e1 | | e1 | + # | | | | | | + # e2 | x | e3 z e2 | x | e3 z e2 | x | e3 y + # | | ^ | | ^ | | ^ + # |___________| |___> y |___________| |___> x |___________| |___> x + # 0 e0 1 0 e0 1 0 e0 1 + # + + + # there are two faces for each edge + for ii, c in enumerate([c0, c1, c2, c3, c4, c5, c6, c7]): + assert c.fZm.e0.index == c.fYm.e0.index, "Cell %d: fZm.e0 and fYm.e0"%ii + assert c.fZm.e1.index == c.fYp.e0.index, "Cell %d: fZm.e1 and fYp.e0"%ii + assert c.fZp.e0.index == c.fYm.e1.index, "Cell %d: fZp.e0 and fYm.e1"%ii + assert c.fZp.e1.index == c.fYp.e1.index, "Cell %d: fZp.e1 and fYp.e1"%ii + assert c.fZm.e2.index == c.fXm.e0.index, "Cell %d: fZm.e2 and fXm.e0"%ii + assert c.fZm.e3.index == c.fXp.e0.index, "Cell %d: fZm.e3 and fXp.e0"%ii + assert c.fZp.e2.index == c.fXm.e1.index, "Cell %d: fZp.e2 and fXm.e1"%ii + assert c.fZp.e3.index == c.fXp.e1.index, "Cell %d: fZp.e3 and fXp.e1"%ii + assert c.fYm.e2.index == c.fXm.e2.index, "Cell %d: fYm.e2 and fXm.e2"%ii + assert c.fYm.e3.index == c.fXp.e2.index, "Cell %d: fYm.e3 and fXp.e2"%ii + assert c.fYp.e2.index == c.fXm.e3.index, "Cell %d: fYp.e2 and fXm.e3"%ii + assert c.fYp.e3.index == c.fXp.e3.index, "Cell %d: fYp.e3 and fXp.e3"%ii + + assert c0.eZ1.index == c1.eZ0.index + assert c0.eZ3.index == c1.eZ2.index + assert c2.eZ1.index == c3.eZ0.index + assert c2.eZ3.index == c3.eZ2.index + + assert c4.eZ1.index == c5.eZ0.index + assert c4.eZ3.index == c5.eZ2.index + assert c6.eZ1.index == c7.eZ0.index + assert c6.eZ3.index == c7.eZ2.index + + assert c0.n7.index == c7.n0.index + + + class SimpleOctreeOperatorTests(unittest.TestCase): @@ -107,6 +186,18 @@ class SimpleOctreeOperatorTests(unittest.TestCase): # self.assertAlmostEqual((self.tM2.getFaceInnerProduct() - self.oM2.getFaceInnerProduct()).toarray().sum(), 0) # self.assertAlmostEqual((self.tM2.getEdgeInnerProduct() - self.oM2.getEdgeInnerProduct()).toarray().sum(), 0) + def test_grids(self): + tM = TreeMesh([1,1,1]) + tM.refine(lambda c:2) + M = TensorMesh([4,4,4]) + self.assertAlmostEqual((tM.gridN - M.gridN).sum(), 0) + self.assertAlmostEqual((tM.gridCC - M.gridCC).sum(), 0) + self.assertAlmostEqual((tM.gridFx - M.gridFx).sum(), 0) + self.assertAlmostEqual((tM.gridFy - M.gridFy).sum(), 0) + self.assertAlmostEqual((tM.gridFz - M.gridFz).sum(), 0) + self.assertAlmostEqual((tM.gridEx - M.gridEx).sum(), 0) + self.assertAlmostEqual((tM.gridEy - M.gridEy).sum(), 0) + self.assertAlmostEqual((tM.gridEz - M.gridEz).sum(), 0) class TestOcTreeObjects(unittest.TestCase): From e93295e91fc383be317ef58e7806b469aae2d70b Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Mon, 6 Apr 2015 10:19:00 -0700 Subject: [PATCH 22/83] additional unit tests for tree mesh --- SimPEG/Tests/test_NewTreeMesh.py | 62 ++++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 11 deletions(-) diff --git a/SimPEG/Tests/test_NewTreeMesh.py b/SimPEG/Tests/test_NewTreeMesh.py index f08091a5..6dcffb86 100644 --- a/SimPEG/Tests/test_NewTreeMesh.py +++ b/SimPEG/Tests/test_NewTreeMesh.py @@ -186,18 +186,58 @@ class SimpleOctreeOperatorTests(unittest.TestCase): # self.assertAlmostEqual((self.tM2.getFaceInnerProduct() - self.oM2.getFaceInnerProduct()).toarray().sum(), 0) # self.assertAlmostEqual((self.tM2.getEdgeInnerProduct() - self.oM2.getEdgeInnerProduct()).toarray().sum(), 0) + +class SimpleOctreeOperatorTestsRefined(unittest.TestCase): + def setUp(self): + self.tM = TreeMesh([1,1,1]) + self.tM.refine(lambda c:2) + self.M = TensorMesh([4,4,4]) + + self.tM2 = TreeMesh([1,1]) + self.tM2.refine(lambda c:2) + self.M2 = TensorMesh([4,4]) + def test_grids(self): - tM = TreeMesh([1,1,1]) - tM.refine(lambda c:2) - M = TensorMesh([4,4,4]) - self.assertAlmostEqual((tM.gridN - M.gridN).sum(), 0) - self.assertAlmostEqual((tM.gridCC - M.gridCC).sum(), 0) - self.assertAlmostEqual((tM.gridFx - M.gridFx).sum(), 0) - self.assertAlmostEqual((tM.gridFy - M.gridFy).sum(), 0) - self.assertAlmostEqual((tM.gridFz - M.gridFz).sum(), 0) - self.assertAlmostEqual((tM.gridEx - M.gridEx).sum(), 0) - self.assertAlmostEqual((tM.gridEy - M.gridEy).sum(), 0) - self.assertAlmostEqual((tM.gridEz - M.gridEz).sum(), 0) + self.assertAlmostEqual((self.tM2.gridN - self.M2.gridN).sum(), 0) + self.assertAlmostEqual((self.tM2.gridCC - self.M2.gridCC).sum(), 0) + self.assertAlmostEqual((self.tM2.gridFx - self.M2.gridFx).sum(), 0) + self.assertAlmostEqual((self.tM2.gridFy - self.M2.gridFy).sum(), 0) + self.assertAlmostEqual((self.tM2.gridEx - self.M2.gridEx).sum(), 0) + self.assertAlmostEqual((self.tM2.gridEy - self.M2.gridEy).sum(), 0) + + self.assertAlmostEqual((self.tM.gridN - self.M.gridN).sum(), 0) + self.assertAlmostEqual((self.tM.gridCC - self.M.gridCC).sum(), 0) + self.assertAlmostEqual((self.tM.gridFx - self.M.gridFx).sum(), 0) + self.assertAlmostEqual((self.tM.gridFy - self.M.gridFy).sum(), 0) + self.assertAlmostEqual((self.tM.gridFz - self.M.gridFz).sum(), 0) + self.assertAlmostEqual((self.tM.gridEx - self.M.gridEx).sum(), 0) + self.assertAlmostEqual((self.tM.gridEy - self.M.gridEy).sum(), 0) + self.assertAlmostEqual((self.tM.gridEz - self.M.gridEz).sum(), 0) + + def test_InnerProducts(self): + self.assertAlmostEqual((self.tM.getFaceInnerProduct() - self.M.getFaceInnerProduct()).toarray().sum(), 0) + self.assertAlmostEqual((self.tM.getEdgeInnerProduct() - self.M.getEdgeInnerProduct()).toarray().sum(), 0) + + # self.assertAlmostEqual((self.tM2.getFaceInnerProduct() - self.M2.getFaceInnerProduct()).toarray().sum(), 0) + # self.assertAlmostEqual((self.tM2.getEdgeInnerProduct() - self.M2.getEdgeInnerProduct()).toarray().sum(), 0) + + def test_faceDiv(self): + self.assertAlmostEqual((self.tM2.faceDiv - self.M2.faceDiv).toarray().sum(), 0) + self.assertAlmostEqual((self.tM.faceDiv - self.M.faceDiv).toarray().sum(), 0) + + def test_nodalGrad(self): + self.assertAlmostEqual((self.tM2.nodalGrad - self.M2.nodalGrad).toarray().sum(), 0) + self.assertAlmostEqual((self.tM.nodalGrad - self.M.nodalGrad).toarray().sum(), 0) + + def test_edgeCurl(self): + self.assertAlmostEqual((self.tM.edgeCurl - self.M.edgeCurl).toarray().sum(), 0) + # self.assertAlmostEqual((self.tM2.edgeCurl - self.M2.edgeCurl).toarray().sum(), 0) + + def test_InnerProducts(self): + self.assertAlmostEqual((self.tM.getFaceInnerProduct() - self.M.getFaceInnerProduct()).toarray().sum(), 0) + self.assertAlmostEqual((self.tM.getEdgeInnerProduct() - self.M.getEdgeInnerProduct()).toarray().sum(), 0) + # self.assertAlmostEqual((self.tM2.getFaceInnerProduct() - self.M2.getFaceInnerProduct()).toarray().sum(), 0) + # self.assertAlmostEqual((self.tM2.getEdgeInnerProduct() - self.M2.getEdgeInnerProduct()).toarray().sum(), 0) class TestOcTreeObjects(unittest.TestCase): From f86d3d7bdcf4e9da126586be788d9a913bb9d7e4 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Fri, 1 May 2015 11:13:44 -0700 Subject: [PATCH 23/83] updates to plotting --- SimPEG/Mesh/NewTreeMesh.py | 57 +++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 25 deletions(-) diff --git a/SimPEG/Mesh/NewTreeMesh.py b/SimPEG/Mesh/NewTreeMesh.py index fa1aadd6..0069da1f 100644 --- a/SimPEG/Mesh/NewTreeMesh.py +++ b/SimPEG/Mesh/NewTreeMesh.py @@ -1094,14 +1094,15 @@ class TreeMesh(InnerProducts, BaseMesh): elif self.dim == 2: TreeFace(self, 0).refine(function, 0) - def plotGrid(self, ax=None, text=True, showIt=False): + def plotGrid(self, ax=None, text=True, showIt=False, figsize=(10,8)): import matplotlib.pyplot as plt - axOpts = {'projection':'3d'} if self.dim == 3 else {} - if ax is None: ax = plt.subplot(111, **axOpts) + if self.dim == 3: + axOpts = {'projection':'3d'} + if ax is None: ax = plt.subplot(111, **axOpts) C = TreeCell(self, 'active') @@ -1122,19 +1123,24 @@ class TreeMesh(InnerProducts, BaseMesh): # fZm # - n1, n2, n3, n4, n5 = 0, 1, 3, 2, 0 - eX = np.c_[C.nodes[n1].x, C.nodes[n2].x, C.nodes[n3].x, C.nodes[n4].x, C.nodes[n5].x, [np.nan]*self.nC] - eY = np.c_[C.nodes[n1].y, C.nodes[n2].y, C.nodes[n3].y, C.nodes[n4].y, C.nodes[n5].y, [np.nan]*self.nC] - eZ = np.c_[C.nodes[n1].z, C.nodes[n2].z, C.nodes[n3].z, C.nodes[n4].z, C.nodes[n5].z, [np.nan]*self.nC] - ax.plot(eX.flatten(), eY.flatten(), 'b-', zs=eZ.flatten()) - n1, n2, n3, n4, n5 = 4, 5, 7, 6, 4 - eX = np.c_[C.nodes[n1].x, C.nodes[n2].x, C.nodes[n3].x, C.nodes[n4].x, C.nodes[n5].x, [np.nan]*self.nC] - eY = np.c_[C.nodes[n1].y, C.nodes[n2].y, C.nodes[n3].y, C.nodes[n4].y, C.nodes[n5].y, [np.nan]*self.nC] - eZ = np.c_[C.nodes[n1].z, C.nodes[n2].z, C.nodes[n3].z, C.nodes[n4].z, C.nodes[n5].z, [np.nan]*self.nC] - ax.plot(eX.flatten(), eY.flatten(), 'r-', zs=eZ.flatten()) + + Es = TreeEdge(self, 'active') + ax.plot(np.c_[Es.n0.x, Es.n1.x, Es.n1.x+np.nan].flatten(), np.c_[Es.n0.y, Es.n1.y, Es.n1.y+np.nan].flatten(), 'b-', zs=np.c_[Es.n0.z, Es.n1.z, Es.n1.z+np.nan].flatten()) + # n1, n2, n3, n4, n5 = 0, 1, 3, 2, 0 + # eX = np.c_[C.nodes[n1].x, C.nodes[n2].x, C.nodes[n3].x, C.nodes[n4].x, C.nodes[n5].x, [np.nan]*self.nC] + # eY = np.c_[C.nodes[n1].y, C.nodes[n2].y, C.nodes[n3].y, C.nodes[n4].y, C.nodes[n5].y, [np.nan]*self.nC] + # eZ = np.c_[C.nodes[n1].z, C.nodes[n2].z, C.nodes[n3].z, C.nodes[n4].z, C.nodes[n5].z, [np.nan]*self.nC] + # ax.plot(eX.flatten(), eY.flatten(), 'b-', zs=eZ.flatten()) + + # n1, n2, n3, n4, n5 = 4, 5, 7, 6, 4 + # eX = np.c_[C.nodes[n1].x, C.nodes[n2].x, C.nodes[n3].x, C.nodes[n4].x, C.nodes[n5].x, [np.nan]*self.nC] + # eY = np.c_[C.nodes[n1].y, C.nodes[n2].y, C.nodes[n3].y, C.nodes[n4].y, C.nodes[n5].y, [np.nan]*self.nC] + # eZ = np.c_[C.nodes[n1].z, C.nodes[n2].z, C.nodes[n3].z, C.nodes[n4].z, C.nodes[n5].z, [np.nan]*self.nC] + # ax.plot(eX.flatten(), eY.flatten(), 'r-', zs=eZ.flatten()) ax.plot(self.gridN[:,0], self.gridN[:,1], 'bs', zs=self.gridN[:,2]) + ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'ro', zs=self.gridCC[:,2]) ax.set_xlabel('x') ax.set_ylabel('y') @@ -1146,13 +1152,12 @@ class TreeMesh(InnerProducts, BaseMesh): E = self._edges C = self._faces - ax.plot(N[:,1], N[:,2], 'b.') - activeCells = C[:,ACTIVE] == 1 - for FEDGE in [FEDGE0, FEDGE1, FEDGE2, FEDGE3]: - nInds = E[C[activeCells,FEDGE],:][:,[ENODE0,ENODE1]] - eX = np.c_[N[nInds[:,0],NX], N[nInds[:,1],NX], [np.nan]*nInds.shape[0]] - eY = np.c_[N[nInds[:,0],NY], N[nInds[:,1],NY], [np.nan]*nInds.shape[0]] - ax.plot(eX.flatten(), eY.flatten(), 'b-') + if ax is None:f, ax = plt.subplots(1,1,figsize=figsize) + + Es = TreeEdge(self, 'active') + ax.plot(np.c_[Es.n0.x, Es.n1.x, Es.n1.x+np.nan].flatten(), np.c_[Es.n0.y, Es.n1.y, Es.n1.y+np.nan].flatten(), 'b-') + Ns = TreeNode(self, 'active') + ax.plot(Ns.x, Ns.y, 'k.') gridCC = self.gridCC if text: @@ -1185,13 +1190,15 @@ if __name__ == '__main__': import matplotlib.pyplot as plt # tM = TreeMesh([np.ones(3),np.ones(2)]) - tM = TreeMesh([1,1,1]) + tM = TreeMesh([np.ones(2),1,1]) - tM.refine(lambda c:2) - # tM.refineCell(4) + # tM.refine(lambda c:2) + tM.refineCell(0) + tM.refineCell(2) + # tM.refineCell(7) - M = Mesh.TensorMesh([4,4,4]) - print tM.gridN - M.gridN + # M = Mesh.TensorMesh([4,4,4]) + # print tM.gridN - M.gridN tM.plotGrid() plt.show() From b00488a6d07e33e01959e3b39e8a32d9a14f762d Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Fri, 30 Oct 2015 11:56:26 -0700 Subject: [PATCH 24/83] Minor updates to TreeMesh --- SimPEG/Mesh/NewTreeMesh.py | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/SimPEG/Mesh/NewTreeMesh.py b/SimPEG/Mesh/NewTreeMesh.py index 0069da1f..8520f245 100644 --- a/SimPEG/Mesh/NewTreeMesh.py +++ b/SimPEG/Mesh/NewTreeMesh.py @@ -327,15 +327,20 @@ class TreeCell(TreeIndexer): class TreeMesh(InnerProducts, BaseMesh): + _meshType = 'TREEMESH' + _unitDimensions = [1, 1, 1] + def __init__(self, h_in, x0=None): assert type(h_in) in [list, tuple], 'h_in must be a list' assert len(h_in) > 1, "len(h_in) must be greater than 1" h = range(len(h_in)) for i, h_i in enumerate(h_in): - if type(h_i) in [int, long, float]: + if Utils.isScalar(h_i) and type(h_i) is not np.ndarray: # This gives you something over the unit cube. - h_i = np.ones(int(h_i))/int(h_i) + h_i = self._unitDimensions[i] * np.ones(int(h_i))/int(h_i) + elif type(h_i) is list: + h_i = Utils.meshTensor(h_i) assert isinstance(h_i, np.ndarray), ("h[%i] is not a numpy array." % i) assert len(h_i.shape) == 1, ("h[%i] must be a 1D numpy array." % i) h[i] = h_i[:] # make a copy. @@ -1201,7 +1206,7 @@ if __name__ == '__main__': # print tM.gridN - M.gridN tM.plotGrid() - plt.show() + # plt.show() @@ -1254,16 +1259,16 @@ if __name__ == '__main__': # plt.show() - # M = TreeMesh([1,1,1]) + M = TreeMesh([[(1,3)],[(1,3)],[(1,3)]]) - # def refFunc(cell): - # n = 3 - np.sum((cell.center.flatten() - np.r_[0.5, 0.5, 0.5])**2)**0.5 * 2 - # print n, cell.center - # return n - # return 1 - # M.refine(refFunc) + def refFunc(cell): + n = 5 - np.sum((cell.center.flatten() - np.r_[1.5, 1.5, 1.5])**2)**0.5 * 2 + print n, cell.center + return n + return 1 + M.refine(refFunc) + print M.nC - # M.plotGrid(text=False) - # plt.show() + M.plotGrid(text=False) + plt.show() - # print M.nC From 44d11542c7d73d723e5dff5521b2ae5e7bd65ac2 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Wed, 4 Nov 2015 09:08:03 -0800 Subject: [PATCH 25/83] PointerTree, FaceDiv, Visualization --- SimPEG/Mesh/PointerTree.py | 415 +++++++++++++++++++++++++++++++++++++ 1 file changed, 415 insertions(+) create mode 100644 SimPEG/Mesh/PointerTree.py diff --git a/SimPEG/Mesh/PointerTree.py b/SimPEG/Mesh/PointerTree.py new file mode 100644 index 00000000..bdf51a6b --- /dev/null +++ b/SimPEG/Mesh/PointerTree.py @@ -0,0 +1,415 @@ +import scurve +from SimPEG import np, sp, Utils, Solver +import matplotlib.pyplot as plt +import matplotlib + +class Tree(object): + def __init__(self, h_in, levels=3): + assert type(h_in) is list, 'h_in must be a list' + assert len(h_in) > 1, "len(h_in) must be greater than 1" + + h = range(len(h_in)) + for i, h_i in enumerate(h_in): + if type(h_i) in [int, long, float]: + # This gives you something over the unit cube. + h_i = np.ones(int(h_i))/int(h_i) + assert isinstance(h_i, np.ndarray), ("h[%i] is not a numpy array." % i) + assert len(h_i.shape) == 1, ("h[%i] must be a 1D numpy array." % i) + assert len(h_i) == 2**levels, "must make h and levels match" + h[i] = h_i[:] # make a copy. + self.h = h + + + self._levels = levels + self._levelBits = int(np.ceil(np.sqrt(levels)))+1 + + + self._z = scurve.zorder.ZOrder(self.dim,20) + self._treeInds = set() + self._treeInds.add(0) + + @property + def dim(self): return len(self.h) + @property + def levels(self): return self._levels + + @property + def _sortedInds(self): + if getattr(self, '__sortedInds', None) is None: + self.__sortedInds = sorted(self._treeInds) + return self.__sortedInds + + def _structureChange(self): + deleteThese = ['__sortedInds', '_gridCC', '_gridFx'] + for p in deleteThese: + if hasattr(self, p): delattr(self, p) + + def _index(self, pointer): + assert len(pointer) is self.dim+1 + assert pointer[-1] <= self.levels + x = self._z.index([p for p in pointer[:-1]]) # copy + return (x << self._levelBits) + pointer[-1] + + def _pointer(self, index): + assert type(index) in [int, long] + n = index & (2**self._levelBits-1) + p = self._z.point(index >> self._levelBits) + return p + [n] #[p[1],p[0],p[2]] + + def refine(self, function=None, recursive=True, cells=None): + + cells = cells if cells is not None else sorted(self._treeInds) + recurse = [] + for cell in cells: + p = self._pointer(cell) + do = function(self._cellC(cell)) > p[-1] + if do: + recurse += self._refineCell(cell) + + if recursive and len(recurse) > 0: + self.refine(function=function, recursive=True, cells=recurse) + return recurse + + + def _refineCell(self, pointer): + self._structureChange() + pointer = self._asPointer(pointer) + ind = self._asIndex(pointer) + assert ind in self + h = self._levelWidth(pointer[-1])/2 # halfWidth + nL = pointer[-1] + 1 # new level + add = lambda p:p[0]+p[1] + added = [] + def addCell(p): + i = self._index(p+[nL]) + self._treeInds.add(i) + added.append(i) + + addCell(map(add, zip(pointer[:-1], [0,0,0][:self.dim]))) + addCell(map(add, zip(pointer[:-1], [h,0,0][:self.dim]))) + addCell(map(add, zip(pointer[:-1], [0,h,0][:self.dim]))) + addCell(map(add, zip(pointer[:-1], [h,h,0][:self.dim]))) + if self.dim == 3: + addCell(map(add, zip(pointer[:-1], [0,0,h]))) + addCell(map(add, zip(pointer[:-1], [h,0,h]))) + addCell(map(add, zip(pointer[:-1], [0,h,h]))) + addCell(map(add, zip(pointer[:-1], [h,h,h]))) + self._treeInds.remove(ind) + return added + + def _corsenCell(self, pointer): + self._structureChange() + raise Exception('Not yet implemented') + + def _asPointer(self, ind): + if type(ind) in [int, long]: + return self._pointer(ind) + if type(ind) is list: + return ind + if isinstance(ind, np.ndarray): + return ind.tolist() + raise Exception + + def _asIndex(self, pointer): + if type(pointer) in [int, long]: + return pointer + if type(pointer) is list: + return self._index(pointer) + raise Exception + + def _parentPointer(self, pointer): + mod = self._levelWidth(pointer[-1]-1) + return [p - (p % mod) for p in pointer[:-1]] + [pointer[-1]-1] + + def _levelWidth(self, level): + return 2**(self.levels - level) + + def _isInsideMesh(self, pointer): + inside = True + for p in pointer[:-1]: + inside = inside and p >= 0 and p < 2**self.levels + return inside + + def _getNextCell(self, ind, direction=0, positive=True): + """ + Returns a None, int, list, or nested list + The int is the cell number. + + """ + pointer = self._asPointer(ind) + + step = (1 if positive else -1) * self._levelWidth(pointer[-1]) + nextCell = [p if ii is not direction else p + step for ii, p in enumerate(pointer)] + if not self._isInsideMesh(nextCell): return None + + # it might be the same size as me? + if nextCell in self: return self._index(nextCell) + # it might be smaller than me? + if nextCell[-1] + 1 <= self.levels: # if I am not the smallest. + nextCell[-1] += 1 + if not positive: + nextCell[direction] -= step/2 # Get the closer one + if nextCell in self: # there is at least one + + hw = self._levelWidth(pointer[-1]) / 2 + nextCell = np.array([p if ii is not direction else p + (step/2 if positive else 0) for ii, p in enumerate(pointer)]) + + if self.dim == 3: raise Exception + if direction == 0: children = [0,0,1], [0,hw,1] + if direction == 1: children = [0,0,1], [hw,0,1] + nextCells = [] + for child in children: + nextCells.append(self._getNextCell(nextCell + child, direction=direction,positive=positive)) + return nextCells + + # it might be bigger than me? + return self._getNextCell(self._parentPointer(pointer), + direction=direction, positive=positive) + + def __contains__(self, v): + if type(v) in [int, long]: + return v in self._treeInds + return self._index(v) in self._treeInds + + def plotGrid(self, ax=None, showIt=False): + + if ax is None: + fig = plt.figure() + ax = plt.subplot(111) + else: + assert isinstance(ax,matplotlib.axes.Axes), "ax must be an Axes!" + fig = ax.figure + + for ind in self._sortedInds: + p = self._asPointer(ind) + n = self._cellN(p) + h = self._cellH(p) + x = [n[0] , n[0] + h[0], n[0] + h[0], n[0] , n[0]] + y = [n[1] , n[1] , n[1] + h[1], n[1] + h[1], n[1]] + ax.plot(x,y, 'b-') + + ax.plot(self.gridCC[[0,-1],0], self.gridCC[[0,-1],1], 'ro') + ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'r.') + ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'r:') + + ax.plot(self.gridFx[self._hangingFacesX,0], self.gridFx[self._hangingFacesX,1], 'gs', ms=10, mfc='none', mec='green') + ax.plot(self.gridFx[:,0], self.gridFx[:,1], 'g>') + ax.plot(self.gridFy[self._hangingFacesY,0], self.gridFy[self._hangingFacesY,1], 'gs', ms=10, mfc='none', mec='green') + ax.plot(self.gridFy[:,0], self.gridFy[:,1], 'g^') + + if showIt:plt.show() + + def _cellN(self, p): + p = self._asPointer(p) + return [hi[:p[ii]].sum() for ii, hi in enumerate(self.h)] + def _cellH(self, p): + p = self._asPointer(p) + w = self._levelWidth(p[-1]) + return [hi[p[ii]:p[ii]+w].sum() for ii, hi in enumerate(self.h)] + def _cellC(self, p): + return (np.array(self._cellH(p))/2.0 + self._cellN(p)).tolist() + + @property + def gridCC(self): + if getattr(self, '_gridCC', None) is None: + self._gridCC = np.zeros((len(self._treeInds),self.dim)) + for ii, ind in enumerate(self._sortedInds): + p = self._asPointer(ind) + self._gridCC[ii, :] = self._cellC(p) + return self._gridCC + + @property + def gridFx(self): + if getattr(self, '_gridFx', None) is None: + self.number() + return self._gridFx + + @property + def gridFy(self): + if getattr(self, '_gridFy', None) is None: + self.number() + return self._gridFy + + def _onSameLevel(self, i0, i1): + p0 = self._asPointer(i0) + p1 = self._asPointer(i1) + return p0[-1] == p1[-1] + + + def number(self): + + facesX, facesY = [], [] + hangingFacesX, hangingFacesY = [], [] + faceXCount, faceYCount = -1, -1 + fXm,fXp,fYm,fYp,fZm,fZp = range(6) + area, vol = [], [] + + def addXFace(count, p, positive=True): + n = self._cellN(p) + w = self._cellH(p) + area.append(w[1] if self.dim == 2 else w[1]*w[2]) + facesX.append([n[0] + (w[0] if positive else 0), n[1] + w[1]/2.0]) + return count + 1 + def addYFace(count, p, positive=True): + n = self._cellN(p) + w = self._cellH(p) + area.append(w[0] if self.dim == 2 else w[0]*w[2]) + facesY.append([n[0] + w[0]/2.0, n[1] + (w[1] if positive else 0)]) + return count + 1 + + # c2cn = dict() + c2f = dict() + def gc2f(ind): + if ind in c2f: return c2f[ind] + c2f_ind = [list() for _ in xrange(2*self.dim)] + c2f[ind] = c2f_ind + return c2f_ind + + def processCell(ind, faceCount, addFace, hangingFaces, DIR=0): + + fM,fP=(0,1) if DIR == 0 else (2,3) if DIR == 1 else (4,5) + p = self._asPointer(ind) + if self._getNextCell(p, direction=DIR, positive=False) is None: + faceCount = addFace(faceCount, p, positive=False) + gc2f(ind)[fM] += [faceCount] + + nextCell = self._getNextCell(p, direction=DIR) + + # Add the next Xface + if nextCell is None: + # on the boundary + faceCount = addFace(faceCount, p) + gc2f(ind)[fP] += [faceCount] + elif type(nextCell) in [int, long] and self._onSameLevel(p,nextCell): + # same sized cell + faceCount = addFace(faceCount, p) + gc2f(ind)[fP] += [faceCount] + gc2f(nextCell)[fM] += [faceCount] + elif type(nextCell) in [int, long] and not self._onSameLevel(p,nextCell): + # the cell is bigger than me + faceCount = addFace(faceCount, p) + gc2f(ind)[fP] += [faceCount] + gc2f(nextCell)[fM] += [faceCount] + hangingFaces.append(faceCount) + elif type(nextCell) is list: + # the cell is smaller than me + + # TODO: ensure that things are balanced. + p0 = self._pointer(nextCell[0]) + p1 = self._pointer(nextCell[1]) + + faceCount = addFace(faceCount, p0, positive=False) + gc2f(nextCell[0])[fM] += [faceCount] + faceCount = addFace(faceCount, p1, positive=False) + gc2f(nextCell[1])[fM] += [faceCount] + + gc2f(ind)[fP] += [faceCount-1,faceCount] + + hangingFaces += [faceCount-1, faceCount] + + return faceCount + + for ii, ind in enumerate(self._sortedInds): + # c2cn[ind] = ii + vol.append(np.prod(self._cellH(ind))) + faceXCount = processCell(ind, faceXCount, addXFace, hangingFacesX, DIR=0) + faceYCount = processCell(ind, faceYCount, addYFace, hangingFacesY, DIR=1) + + self._c2f = c2f + self.area = np.array(area) + self.vol = np.array(vol) + self._gridFx = np.array(facesX) + self._gridFy = np.array(facesY) + self.nC = len(self._sortedInds) + self.nFx = self._gridFx.shape[0] + self.nFy = self._gridFy.shape[0] + self.nF = self.nFx + self.nFy + self._hangingFacesX = hangingFacesX + self._hangingFacesY = hangingFacesY + + @property + def faceDiv(self): + print self._c2f + if getattr(self, '_faceDiv', None) is None: + self.number() + # TODO: Preallocate! + I, J, V = [], [], [] + PM = [-1,1]*self.dim # plus / minus + offset = [0,0,self.nFx,self.nFx] + + for ii, ind in enumerate(self._sortedInds): + faces = self._c2f[ind] + for off, pm, face in zip(offset,PM,faces): + j = [_ + off for _ in face] + I += [ii]*len(j) + J += j + V += [pm]*len(j) + + VOL = self.vol + D = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.nF)) + S = self.area + self._faceDiv = Utils.sdiag(1.0/VOL)*D*Utils.sdiag(S) + return self._faceDiv + + + +if __name__ == '__main__': + + + def function(xc): + r = xc - np.r_[0.5,0.5] + dist = np.sqrt(r.dot(r)) + # if dist < 0.05: + # return 5 + if dist < 0.1: + return 4 + if dist < 0.3: + return 3 + if dist < 1.0: + return 2 + else: + return 0 + + # T = Tree([16,16],levels=4) + # T.refine(function,recursive=True) + # T.plotGrid(showIt=True) + # BREAK + T = Tree([np.r_[1,2,1,5,2,3,1,1],8]) + T._refineCell([0,0,0]) + T._refineCell([4,4,1]) + T._refineCell([0,0,1]) + T._refineCell([2,2,2]) + T.plotGrid(showIt=True) + + T.number() + print sorted(T._treeInds) == [32, 40, 48, 60, 61, 62, 63, 68, 132, 224, 232, 240, 248] + print len(T._hangingFacesX) == 7 + print T.nFx == 18 + print T.vol == 1.0 + print T.area + + T.faceDiv + + plt.subplot(211) + plt.spy(T.faceDiv) + T.plotGrid(ax=plt.subplot(212), showIt=True) + + print T._getNextCell([4,0,1]) is None + print T._getNextCell([0,4,1]) == [T._index([4,4,2]), T._index([4,6,2])] + print T._getNextCell([0,2,2]) == [T._index([2,2,3]), T._index([2,3,3])] + print T._getNextCell([4,4,2]) == T._index([6,4,2]) + print T._getNextCell([6,4,2]) is None + print T._getNextCell([2,0,2]) == T._index([4,0,1]) + print T._getNextCell([4,0,1], positive=False) == [T._index([2,0,2]), [T._index([3,2,3]), T._index([3,3,3])]] + print T._getNextCell([3,3,3]) == T._index([4,0,1]) + print T._getNextCell([3,2,3]) == T._index([4,0,1]) + print T._getNextCell([2,2,3]) == T._index([3,2,3]) + print T._getNextCell([3,2,3], positive=False) == T._index([2,2,3]) + + + print T._getNextCell([0,0,2], direction=1) == T._index([0,2,2]) + print T._getNextCell([0,2,2], direction=1, positive=False) == T._index([0,0,2]) + print T._getNextCell([0,2,2], direction=1) == T._index([0,4,1]) + print T._getNextCell([0,4,1], direction=1, positive=False) == [T._index([0,2,2]), [T._index([2,3,3]), T._index([3,3,3])]] + + From d2baf15b54ff61d66688ee245e51c3cacb583304 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Wed, 4 Nov 2015 12:13:54 -0800 Subject: [PATCH 26/83] Test pointerTree --- SimPEG/Mesh/PointerTree.py | 87 ++++++++++++++++++---------------- tests/mesh/test_pointerMesh.py | 52 ++++++++++++++++++++ 2 files changed, 98 insertions(+), 41 deletions(-) create mode 100644 tests/mesh/test_pointerMesh.py diff --git a/SimPEG/Mesh/PointerTree.py b/SimPEG/Mesh/PointerTree.py index bdf51a6b..ed4cb305 100644 --- a/SimPEG/Mesh/PointerTree.py +++ b/SimPEG/Mesh/PointerTree.py @@ -1,8 +1,52 @@ -import scurve from SimPEG import np, sp, Utils, Solver import matplotlib.pyplot as plt import matplotlib +class ZCurve(object): + """ + The Z-order curve is generated by interleaving the bits of an offset. + + See: + + https://github.com/cortesi/scurve + Aldo Cortesi + + """ + def __init__(self, dimension, bits): + """ + dimension: Number of dimensions + bits: The number of bits per co-ordinate. Total number of points is + 2**(bits*dimension). + """ + self.dimension, self.bits = dimension, bits + + def bitrange(self, x, width, start, end): + """ + Extract a bit range as an integer. + (start, end) is inclusive lower bound, exclusive upper bound. + """ + return x >> (width-end) & ((2**(end-start))-1) + + def index(self, p): + p.reverse() + idx = 0 + iwidth = self.bits * self.dimension + for i in range(iwidth): + bitoff = self.bits-(i/self.dimension)-1 + poff = self.dimension-(i%self.dimension)-1 + b = self.bitrange(p[poff], self.bits, bitoff, bitoff+1) << i + idx |= b + return idx + + def point(self, idx): + p = [0]*self.dimension + iwidth = self.bits * self.dimension + for i in range(iwidth): + b = self.bitrange(idx, iwidth, i, i+1) << (iwidth-i-1)/self.dimension + p[i%self.dimension] |= b + p.reverse() + return p + class Tree(object): def __init__(self, h_in, levels=3): assert type(h_in) is list, 'h_in must be a list' @@ -24,7 +68,7 @@ class Tree(object): self._levelBits = int(np.ceil(np.sqrt(levels)))+1 - self._z = scurve.zorder.ZOrder(self.dim,20) + self._z = ZCurve(self.dim, 20) self._treeInds = set() self._treeInds.add(0) @@ -374,42 +418,3 @@ if __name__ == '__main__': # T.refine(function,recursive=True) # T.plotGrid(showIt=True) # BREAK - T = Tree([np.r_[1,2,1,5,2,3,1,1],8]) - T._refineCell([0,0,0]) - T._refineCell([4,4,1]) - T._refineCell([0,0,1]) - T._refineCell([2,2,2]) - T.plotGrid(showIt=True) - - T.number() - print sorted(T._treeInds) == [32, 40, 48, 60, 61, 62, 63, 68, 132, 224, 232, 240, 248] - print len(T._hangingFacesX) == 7 - print T.nFx == 18 - print T.vol == 1.0 - print T.area - - T.faceDiv - - plt.subplot(211) - plt.spy(T.faceDiv) - T.plotGrid(ax=plt.subplot(212), showIt=True) - - print T._getNextCell([4,0,1]) is None - print T._getNextCell([0,4,1]) == [T._index([4,4,2]), T._index([4,6,2])] - print T._getNextCell([0,2,2]) == [T._index([2,2,3]), T._index([2,3,3])] - print T._getNextCell([4,4,2]) == T._index([6,4,2]) - print T._getNextCell([6,4,2]) is None - print T._getNextCell([2,0,2]) == T._index([4,0,1]) - print T._getNextCell([4,0,1], positive=False) == [T._index([2,0,2]), [T._index([3,2,3]), T._index([3,3,3])]] - print T._getNextCell([3,3,3]) == T._index([4,0,1]) - print T._getNextCell([3,2,3]) == T._index([4,0,1]) - print T._getNextCell([2,2,3]) == T._index([3,2,3]) - print T._getNextCell([3,2,3], positive=False) == T._index([2,2,3]) - - - print T._getNextCell([0,0,2], direction=1) == T._index([0,2,2]) - print T._getNextCell([0,2,2], direction=1, positive=False) == T._index([0,0,2]) - print T._getNextCell([0,2,2], direction=1) == T._index([0,4,1]) - print T._getNextCell([0,4,1], direction=1, positive=False) == [T._index([0,2,2]), [T._index([2,3,3]), T._index([3,3,3])]] - - diff --git a/tests/mesh/test_pointerMesh.py b/tests/mesh/test_pointerMesh.py new file mode 100644 index 00000000..90f7f476 --- /dev/null +++ b/tests/mesh/test_pointerMesh.py @@ -0,0 +1,52 @@ +from SimPEG.Mesh.PointerTree import Tree +import numpy as np +import unittest + +TOL = 1e-10 + +class TestOcTreeObjects(unittest.TestCase): + + def test_counts(self): + + T = Tree([8,8]) + T._refineCell([0,0,0]) + T._refineCell([4,4,1]) + T._refineCell([0,0,1]) + T._refineCell([2,2,2]) + T.number() + assert sorted(T._treeInds) == [2, 34, 66, 99, 107, 115, 123, 129, 257, 386, 418, 450, 482] + assert len(T._hangingFacesX) == 7 + assert T.nFx == 18 + assert T.vol.sum() == 1.0 + + + def test_connectivity(self): + T = Tree([8,8]) + T._refineCell([0,0,0]) + T._refineCell([4,4,1]) + T._refineCell([0,0,1]) + T._refineCell([2,2,2]) + T.number() + assert T._getNextCell([4,0,1]) is None + assert T._getNextCell([0,4,1]) == [T._index([4,4,2]), T._index([4,6,2])] + assert T._getNextCell([0,2,2]) == [T._index([2,2,3]), T._index([2,3,3])] + assert T._getNextCell([4,4,2]) == T._index([6,4,2]) + assert T._getNextCell([6,4,2]) is None + assert T._getNextCell([2,0,2]) == T._index([4,0,1]) + assert T._getNextCell([4,0,1], positive=False) == [T._index([2,0,2]), [T._index([3,2,3]), T._index([3,3,3])]] + assert T._getNextCell([3,3,3]) == T._index([4,0,1]) + assert T._getNextCell([3,2,3]) == T._index([4,0,1]) + assert T._getNextCell([2,2,3]) == T._index([3,2,3]) + assert T._getNextCell([3,2,3], positive=False) == T._index([2,2,3]) + + + assert T._getNextCell([0,0,2], direction=1) == T._index([0,2,2]) + assert T._getNextCell([0,2,2], direction=1, positive=False) == T._index([0,0,2]) + assert T._getNextCell([0,2,2], direction=1) == T._index([0,4,1]) + assert T._getNextCell([0,4,1], direction=1, positive=False) == [T._index([0,2,2]), [T._index([2,3,3]), T._index([3,3,3])]] + + + + +if __name__ == '__main__': + unittest.main() From 0da5888e37c1a5618aa2cc84726c7343654aad14 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Wed, 4 Nov 2015 13:51:18 -0800 Subject: [PATCH 27/83] permutations --- SimPEG/Mesh/PointerTree.py | 208 ++++++++++++++++++++++++++++----- tests/mesh/test_pointerMesh.py | 34 +++++- 2 files changed, 211 insertions(+), 31 deletions(-) diff --git a/SimPEG/Mesh/PointerTree.py b/SimPEG/Mesh/PointerTree.py index ed4cb305..a9c74029 100644 --- a/SimPEG/Mesh/PointerTree.py +++ b/SimPEG/Mesh/PointerTree.py @@ -47,6 +47,45 @@ class ZCurve(object): p.reverse() return p +def SortGrid(grid, offset=0): + """ + Sorts a grid by the x0 location. + """ + + eps = 1e-7 + def mycmp(c1,c2): + c1 = grid[c1-offset] + c2 = grid[c2-offset] + if c1.size == 2: + if np.abs(c1[1] - c2[1]) < eps: + return c1[0] - c2[0] + return c1[1] - c2[1] + elif c1.size == 3: + if np.abs(c1[2] - c2[2]) < eps: + if np.abs(c1[1] - c2[1]) < eps: + return c1[0] - c2[0] + return c1[1] - c2[1] + return c1[2] - c2[2] + + class K(object): + def __init__(self, obj, *args): + self.obj = obj + def __lt__(self, other): + return mycmp(self.obj, other.obj) < 0 + def __gt__(self, other): + return mycmp(self.obj, other.obj) > 0 + def __eq__(self, other): + return mycmp(self.obj, other.obj) == 0 + def __le__(self, other): + return mycmp(self.obj, other.obj) <= 0 + def __ge__(self, other): + return mycmp(self.obj, other.obj) >= 0 + def __ne__(self, other): + return mycmp(self.obj, other.obj) != 0 + + return sorted(range(offset,grid.shape[0]+offset), key=K) + + class Tree(object): def __init__(self, h_in, levels=3): assert type(h_in) is list, 'h_in must be a list' @@ -63,30 +102,131 @@ class Tree(object): h[i] = h_i[:] # make a copy. self.h = h - self._levels = levels self._levelBits = int(np.ceil(np.sqrt(levels)))+1 - + self.__dirty__ = True #: The numbering is dirty! self._z = ZCurve(self.dim, 20) self._treeInds = set() self._treeInds.add(0) - @property - def dim(self): return len(self.h) @property def levels(self): return self._levels + @property + def dim(self): return len(self.h) + + @property + def nC(self): return len(self._treeInds) + + @property + def nN(self): + self.number() + return self._nN + + @property + def nF(self): + self.number() + return self._nF + + @property + def nFx(self): + self.number() + return self._nFx + + @property + def nFy(self): + self.number() + return self._nFy + + @property + def nFz(self): + self.number() + return None if self.dim < 3 else self._nFz + + @property + def nE(self): + self.number() + if self.dim == 2: + return self.nF + elif self.dim == 3: + return len(self.edges) + + @property + def nEx(self): + self.number() + if self.dim == 2: + return self._nFy + elif self.dim == 3: + return self._nEx + + @property + def nEy(self): + self.number() + if self.dim == 2: + return self._nFx + elif self.dim == 3: + return self._nEy + + @property + def nEz(self): + self.number() + return None if self.dim < 3 else self._nEz + + @property + def vol(self): + self.number() + return self._vol + + @property + def area(self): + self.number() + return self._area + + @property + def edge(self): + self.number() + if self.dim == 2: + return np.r_[self._area[self.nFx:], self._area[:self.nFx]] + @property def _sortedInds(self): if getattr(self, '__sortedInds', None) is None: self.__sortedInds = sorted(self._treeInds) return self.__sortedInds + @property + def permuteCC(self): + #TODO: cache these? + P = SortGrid(self.gridCC) + return sp.identity(self.nC).tocsr()[P,:] + + @property + def permuteF(self): + #TODO: cache these? + P = SortGrid(self.gridFx) + P += SortGrid(self.gridFy, offset=self.nFx) + if self.dim == 3: + P += SortGrid(self.gridFz, offset=self.nFx+self.nFy) + return sp.identity(self.nF).tocsr()[P,:] + + @property + def permuteE(self): + #TODO: cache these? + if self.dim == 2: + P = SortGrid(self.gridFy) + P += SortGrid(self.gridFx, offset=self.nEx) + return sp.identity(self.nE).tocsr()[P,:] + if self.dim == 3: + raise Exception() + def _structureChange(self): + if self.__dirty__: return + deleteThese = ['__sortedInds', '_gridCC', '_gridFx'] for p in deleteThese: if hasattr(self, p): delattr(self, p) + self.__dirty__ = True def _index(self, pointer): assert len(pointer) is self.dim+1 @@ -98,7 +238,12 @@ class Tree(object): assert type(index) in [int, long] n = index & (2**self._levelBits-1) p = self._z.point(index >> self._levelBits) - return p + [n] #[p[1],p[0],p[2]] + return p + [n] + + def __contains__(self, v): + if type(v) in [int, long]: + return v in self._treeInds + return self._index(v) in self._treeInds def refine(self, function=None, recursive=True, cells=None): @@ -165,6 +310,18 @@ class Tree(object): mod = self._levelWidth(pointer[-1]-1) return [p - (p % mod) for p in pointer[:-1]] + [pointer[-1]-1] + def _cellN(self, p): + p = self._asPointer(p) + return [hi[:p[ii]].sum() for ii, hi in enumerate(self.h)] + + def _cellH(self, p): + p = self._asPointer(p) + w = self._levelWidth(p[-1]) + return [hi[p[ii]:p[ii]+w].sum() for ii, hi in enumerate(self.h)] + + def _cellC(self, p): + return (np.array(self._cellH(p))/2.0 + self._cellN(p)).tolist() + def _levelWidth(self, level): return 2**(self.levels - level) @@ -210,10 +367,6 @@ class Tree(object): return self._getNextCell(self._parentPointer(pointer), direction=direction, positive=positive) - def __contains__(self, v): - if type(v) in [int, long]: - return v in self._treeInds - return self._index(v) in self._treeInds def plotGrid(self, ax=None, showIt=False): @@ -243,15 +396,6 @@ class Tree(object): if showIt:plt.show() - def _cellN(self, p): - p = self._asPointer(p) - return [hi[:p[ii]].sum() for ii, hi in enumerate(self.h)] - def _cellH(self, p): - p = self._asPointer(p) - w = self._levelWidth(p[-1]) - return [hi[p[ii]:p[ii]+w].sum() for ii, hi in enumerate(self.h)] - def _cellC(self, p): - return (np.array(self._cellH(p))/2.0 + self._cellN(p)).tolist() @property def gridCC(self): @@ -279,25 +423,26 @@ class Tree(object): p1 = self._asPointer(i1) return p0[-1] == p1[-1] - - def number(self): + def number(self, force=False): + if not self.__dirty__ and not force: return facesX, facesY = [], [] + areaX, areaY = [], [] hangingFacesX, hangingFacesY = [], [] faceXCount, faceYCount = -1, -1 fXm,fXp,fYm,fYp,fZm,fZp = range(6) - area, vol = [], [] + vol = [] def addXFace(count, p, positive=True): n = self._cellN(p) w = self._cellH(p) - area.append(w[1] if self.dim == 2 else w[1]*w[2]) + areaX.append(w[1] if self.dim == 2 else w[1]*w[2]) facesX.append([n[0] + (w[0] if positive else 0), n[1] + w[1]/2.0]) return count + 1 def addYFace(count, p, positive=True): n = self._cellN(p) w = self._cellH(p) - area.append(w[0] if self.dim == 2 else w[0]*w[2]) + areaY.append(w[0] if self.dim == 2 else w[0]*w[2]) facesY.append([n[0] + w[0]/2.0, n[1] + (w[1] if positive else 0)]) return count + 1 @@ -360,20 +505,23 @@ class Tree(object): faceYCount = processCell(ind, faceYCount, addYFace, hangingFacesY, DIR=1) self._c2f = c2f - self.area = np.array(area) - self.vol = np.array(vol) + self._area = np.array(areaX + areaY) + self._vol = np.array(vol) self._gridFx = np.array(facesX) self._gridFy = np.array(facesY) - self.nC = len(self._sortedInds) - self.nFx = self._gridFx.shape[0] - self.nFy = self._gridFy.shape[0] - self.nF = self.nFx + self.nFy + self._nC = len(self._sortedInds) + self._nFx = self._gridFx.shape[0] + self._nFy = self._gridFy.shape[0] + self._nF = self._nFx + self._nFy + self._hangingFacesX = hangingFacesX self._hangingFacesY = hangingFacesY + self.__dirty__ = False + @property def faceDiv(self): - print self._c2f + # print self._c2f if getattr(self, '_faceDiv', None) is None: self.number() # TODO: Preallocate! diff --git a/tests/mesh/test_pointerMesh.py b/tests/mesh/test_pointerMesh.py index 90f7f476..76e1e533 100644 --- a/tests/mesh/test_pointerMesh.py +++ b/tests/mesh/test_pointerMesh.py @@ -1,10 +1,14 @@ +from SimPEG import Mesh from SimPEG.Mesh.PointerTree import Tree import numpy as np +import matplotlib.pyplot as plt import unittest TOL = 1e-10 -class TestOcTreeObjects(unittest.TestCase): + + +class TestSimpleQuadTree(unittest.TestCase): def test_counts(self): @@ -13,7 +17,9 @@ class TestOcTreeObjects(unittest.TestCase): T._refineCell([4,4,1]) T._refineCell([0,0,1]) T._refineCell([2,2,2]) + T.number() + # T.plotGrid(showIt=True) assert sorted(T._treeInds) == [2, 34, 66, 99, 107, 115, 123, 129, 257, 386, 418, 450, 482] assert len(T._hangingFacesX) == 7 assert T.nFx == 18 @@ -46,6 +52,32 @@ class TestOcTreeObjects(unittest.TestCase): assert T._getNextCell([0,4,1], direction=1, positive=False) == [T._index([0,2,2]), [T._index([2,3,3]), T._index([3,3,3])]] +class TestOperatorsQuadTree(unittest.TestCase): + + def test_counts(self): + + hx, hy = np.r_[1.,2,3,4], np.r_[5.,6,7,8] + T = Tree([hx, hy], levels=2) + T.refine(lambda xc:2) + T.plotGrid(showIt=True) + M = Mesh.TensorMesh([hx, hy]) + assert M.nC == T.nC + assert M.nF == T.nF + assert M.nFx == T.nFx + assert M.nFy == T.nFy + assert M.nE == T.nE + assert M.nEx == T.nEx + assert M.nEy == T.nEy + assert np.allclose(M.area, T.permuteF*T.area) + assert np.allclose(M.edge, T.permuteE*T.edge) + assert np.allclose(M.vol, T.permuteCC*T.vol) + + # plt.subplot(211).spy(M.faceDiv) + # plt.subplot(212).spy(T.permuteCC.T*T.faceDiv*T.permuteF) + # plt.show() + + assert (M.faceDiv - T.permuteCC*T.faceDiv*T.permuteF.T).nnz == 0 + if __name__ == '__main__': From c688bfd5ae493adc001bdd3d14cbbeb406e4f13a Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Wed, 4 Nov 2015 14:23:36 -0800 Subject: [PATCH 28/83] Start of 3D PointerTree --- SimPEG/Mesh/PointerTree.py | 101 ++++++++++++++++++++++--------------- 1 file changed, 61 insertions(+), 40 deletions(-) diff --git a/SimPEG/Mesh/PointerTree.py b/SimPEG/Mesh/PointerTree.py index a9c74029..3aceba3c 100644 --- a/SimPEG/Mesh/PointerTree.py +++ b/SimPEG/Mesh/PointerTree.py @@ -259,7 +259,6 @@ class Tree(object): self.refine(function=function, recursive=True, cells=recurse) return recurse - def _refineCell(self, pointer): self._structureChange() pointer = self._asPointer(pointer) @@ -355,9 +354,13 @@ class Tree(object): hw = self._levelWidth(pointer[-1]) / 2 nextCell = np.array([p if ii is not direction else p + (step/2 if positive else 0) for ii, p in enumerate(pointer)]) - if self.dim == 3: raise Exception - if direction == 0: children = [0,0,1], [0,hw,1] - if direction == 1: children = [0,0,1], [hw,0,1] + if self.dim == 2: + if direction == 0: children = [0,0,1], [0,hw,1] + if direction == 1: children = [0,0,1], [hw,0,1] + elif self.dim == 3: + if direction == 0: children = [0,0,0,1], [0,hw,0,1], [0,0,hw,1], [0,hw,hw,1] + if direction == 1: children = [0,0,0,1], [hw,0,0,1], [0,0,hw,1], [hw,0,hw,1] + if direction == 2: children = [0,0,0,1], [hw,0,0,1], [0,hw,0,1], [hw,hw,0,1] nextCells = [] for child in children: nextCells.append(self._getNextCell(nextCell + child, direction=direction,positive=positive)) @@ -367,36 +370,6 @@ class Tree(object): return self._getNextCell(self._parentPointer(pointer), direction=direction, positive=positive) - - def plotGrid(self, ax=None, showIt=False): - - if ax is None: - fig = plt.figure() - ax = plt.subplot(111) - else: - assert isinstance(ax,matplotlib.axes.Axes), "ax must be an Axes!" - fig = ax.figure - - for ind in self._sortedInds: - p = self._asPointer(ind) - n = self._cellN(p) - h = self._cellH(p) - x = [n[0] , n[0] + h[0], n[0] + h[0], n[0] , n[0]] - y = [n[1] , n[1] , n[1] + h[1], n[1] + h[1], n[1]] - ax.plot(x,y, 'b-') - - ax.plot(self.gridCC[[0,-1],0], self.gridCC[[0,-1],1], 'ro') - ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'r.') - ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'r:') - - ax.plot(self.gridFx[self._hangingFacesX,0], self.gridFx[self._hangingFacesX,1], 'gs', ms=10, mfc='none', mec='green') - ax.plot(self.gridFx[:,0], self.gridFx[:,1], 'g>') - ax.plot(self.gridFy[self._hangingFacesY,0], self.gridFy[self._hangingFacesY,1], 'gs', ms=10, mfc='none', mec='green') - ax.plot(self.gridFy[:,0], self.gridFy[:,1], 'g^') - - if showIt:plt.show() - - @property def gridCC(self): if getattr(self, '_gridCC', None) is None: @@ -437,13 +410,19 @@ class Tree(object): n = self._cellN(p) w = self._cellH(p) areaX.append(w[1] if self.dim == 2 else w[1]*w[2]) - facesX.append([n[0] + (w[0] if positive else 0), n[1] + w[1]/2.0]) + if self.dim == 2: + facesX.append([n[0] + (w[0] if positive else 0), n[1] + w[1]/2.0]) + elif self.dim == 3: + facesX.append([n[0] + (w[0] if positive else 0), n[1] + w[1]/2.0, n[2] + w[2]/2.0]) return count + 1 def addYFace(count, p, positive=True): n = self._cellN(p) w = self._cellH(p) areaY.append(w[0] if self.dim == 2 else w[0]*w[2]) - facesY.append([n[0] + w[0]/2.0, n[1] + (w[1] if positive else 0)]) + if self.dim == 2: + facesY.append([n[0] + w[0]/2.0, n[1] + (w[1] if positive else 0)]) + elif self.dim == 3: + facesY.append([n[0] + w[0]/2.0, n[1] + (w[1] if positive else 0), n[2] + w[2]/2.0]) return count + 1 # c2cn = dict() @@ -543,6 +522,47 @@ class Tree(object): self._faceDiv = Utils.sdiag(1.0/VOL)*D*Utils.sdiag(S) return self._faceDiv + def plotGrid(self, ax=None, showIt=False): + + + axOpts = {'projection':'3d'} if self.dim == 3 else {} + if ax is None: + ax = plt.subplot(111, **axOpts) + else: + assert isinstance(ax,matplotlib.axes.Axes), "ax must be an Axes!" + fig = ax.figure + + for ind in self._sortedInds: + p = self._asPointer(ind) + n = self._cellN(p) + h = self._cellH(p) + x = [n[0] , n[0] + h[0], n[0] + h[0], n[0] , n[0]] + y = [n[1] , n[1] , n[1] + h[1], n[1] + h[1], n[1]] + z = [n[2] , n[2] , n[2] , n[2] , n[2]] + ax.plot(x,y, 'b-', zs=None if self.dim == 2 else z) + + if self.dim == 3: + z = [n[2] + h[2], n[2] + h[2], n[2] + h[2], n[2] + h[2], n[2] + h[2]] + ax.plot(x,y, 'b-', zs=z) + sides = [0,0], [h[0],0], [0,h[1]], [h[0],h[1]] + for s in sides: + x = [n[0] + s[0], n[0] + s[0]] + y = [n[1] + s[1], n[1] + s[1]] + z = [n[2] , n[2] + h[2]] + ax.plot(x,y, 'b-', zs=z) + + + ax.plot(self.gridCC[[0,-1],0], self.gridCC[[0,-1],1], 'ro', zs=None if self.dim == 2 else self.gridCC[[0,-1],2]) + ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'r.', zs=None if self.dim == 2 else self.gridCC[:,2]) + ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'r:', zs=None if self.dim == 2 else self.gridCC[:,2]) + + ax.plot(self.gridFx[self._hangingFacesX,0], self.gridFx[self._hangingFacesX,1], 'gs', ms=10, mfc='none', mec='green', zs=None if self.dim == 2 else self.gridFx[self._hangingFacesX,2]) + ax.plot(self.gridFx[:,0], self.gridFx[:,1], 'g>', zs=None if self.dim == 2 else self.gridFx[:,2]) + ax.plot(self.gridFy[self._hangingFacesY,0], self.gridFy[self._hangingFacesY,1], 'gs', ms=10, mfc='none', mec='green', zs=None if self.dim == 2 else self.gridFy[self._hangingFacesY,2]) + ax.plot(self.gridFy[:,0], self.gridFy[:,1], 'g^', zs=None if self.dim == 2 else self.gridFy[:,2]) + + if showIt:plt.show() + if __name__ == '__main__': @@ -562,7 +582,8 @@ if __name__ == '__main__': else: return 0 - # T = Tree([16,16],levels=4) - # T.refine(function,recursive=True) - # T.plotGrid(showIt=True) - # BREAK + T = Tree([4,4,4],levels=2) + T.refine(lambda xc:1) + T._refineCell([0,0,0,1]) + T.plotGrid(showIt=True) + From ff5885cde030b8cb94291ecf41559dd4ca95a6b2 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Wed, 4 Nov 2015 14:55:46 -0800 Subject: [PATCH 29/83] OcTree faceZ --- SimPEG/Mesh/PointerTree.py | 52 ++++++++++++++++++++++++---------- tests/mesh/test_pointerMesh.py | 29 ++++++++++++++++++- 2 files changed, 65 insertions(+), 16 deletions(-) diff --git a/SimPEG/Mesh/PointerTree.py b/SimPEG/Mesh/PointerTree.py index 3aceba3c..ab2c44e6 100644 --- a/SimPEG/Mesh/PointerTree.py +++ b/SimPEG/Mesh/PointerTree.py @@ -391,6 +391,13 @@ class Tree(object): self.number() return self._gridFy + @property + def gridFz(self): + if self.dim < 3: return None + if getattr(self, '_gridFz', None) is None: + self.number() + return self._gridFz + def _onSameLevel(self, i0, i1): p0 = self._asPointer(i0) p1 = self._asPointer(i1) @@ -399,12 +406,12 @@ class Tree(object): def number(self, force=False): if not self.__dirty__ and not force: return - facesX, facesY = [], [] - areaX, areaY = [], [] - hangingFacesX, hangingFacesY = [], [] - faceXCount, faceYCount = -1, -1 + facesX, facesY, facesZ = [], [], [] + areaX, areaY, areaZ = [], [], [] + hangingFacesX, hangingFacesY, hangingFacesZ = [], [], [] + faceXCount, faceYCount, faceZCount = -1, -1, -1 fXm,fXp,fYm,fYp,fZm,fZp = range(6) - vol = [] + vol, nodes = [], [] def addXFace(count, p, positive=True): n = self._cellN(p) @@ -424,6 +431,12 @@ class Tree(object): elif self.dim == 3: facesY.append([n[0] + w[0]/2.0, n[1] + (w[1] if positive else 0), n[2] + w[2]/2.0]) return count + 1 + def addZFace(count, p, positive=True): + n = self._cellN(p) + w = self._cellH(p) + areaZ.append(w[0]*w[1]) + facesZ.append([n[0] + w[0]/2.0, n[1] + w[1]/2.0, n[2] + (w[2] if positive else 0)]) + return count + 1 # c2cn = dict() c2f = dict() @@ -482,19 +495,25 @@ class Tree(object): vol.append(np.prod(self._cellH(ind))) faceXCount = processCell(ind, faceXCount, addXFace, hangingFacesX, DIR=0) faceYCount = processCell(ind, faceYCount, addYFace, hangingFacesY, DIR=1) + if self.dim == 3: + faceZCount = processCell(ind, faceZCount, addZFace, hangingFacesZ, DIR=2) self._c2f = c2f - self._area = np.array(areaX + areaY) + self._area = np.array(areaX + areaY + (areaZ if self.dim == 3 else [])) self._vol = np.array(vol) self._gridFx = np.array(facesX) self._gridFy = np.array(facesY) + self._hangingFacesX = hangingFacesX + self._hangingFacesY = hangingFacesY + if self.dim == 3: + self._gridFz = np.array(facesZ) + self._nFz = self._gridFz.shape[0] + self._hangingFacesZ = hangingFacesZ + self._nC = len(self._sortedInds) self._nFx = self._gridFx.shape[0] self._nFy = self._gridFy.shape[0] - self._nF = self._nFx + self._nFy - - self._hangingFacesX = hangingFacesX - self._hangingFacesY = hangingFacesY + self._nF = self._nFx + self._nFy + (self._nFz if self.dim == 3 else 0) self.__dirty__ = False @@ -506,7 +525,7 @@ class Tree(object): # TODO: Preallocate! I, J, V = [], [], [] PM = [-1,1]*self.dim # plus / minus - offset = [0,0,self.nFx,self.nFx] + offset = [0,0,self.nFx,self.nFx,self.nFx+self.nFy,self.nFx+self.nFy] for ii, ind in enumerate(self._sortedInds): faces = self._c2f[ind] @@ -556,10 +575,13 @@ class Tree(object): ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'r.', zs=None if self.dim == 2 else self.gridCC[:,2]) ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'r:', zs=None if self.dim == 2 else self.gridCC[:,2]) - ax.plot(self.gridFx[self._hangingFacesX,0], self.gridFx[self._hangingFacesX,1], 'gs', ms=10, mfc='none', mec='green', zs=None if self.dim == 2 else self.gridFx[self._hangingFacesX,2]) - ax.plot(self.gridFx[:,0], self.gridFx[:,1], 'g>', zs=None if self.dim == 2 else self.gridFx[:,2]) - ax.plot(self.gridFy[self._hangingFacesY,0], self.gridFy[self._hangingFacesY,1], 'gs', ms=10, mfc='none', mec='green', zs=None if self.dim == 2 else self.gridFy[self._hangingFacesY,2]) - ax.plot(self.gridFy[:,0], self.gridFy[:,1], 'g^', zs=None if self.dim == 2 else self.gridFy[:,2]) + # ax.plot(self.gridFx[self._hangingFacesX,0], self.gridFx[self._hangingFacesX,1], 'gs', ms=10, mfc='none', mec='green', zs=None if self.dim == 2 else self.gridFx[self._hangingFacesX,2]) + # ax.plot(self.gridFx[:,0], self.gridFx[:,1], 'g>', zs=None if self.dim == 2 else self.gridFx[:,2]) + # ax.plot(self.gridFy[self._hangingFacesY,0], self.gridFy[self._hangingFacesY,1], 'gs', ms=10, mfc='none', mec='green', zs=None if self.dim == 2 else self.gridFy[self._hangingFacesY,2]) + # ax.plot(self.gridFy[:,0], self.gridFy[:,1], 'g^', zs=None if self.dim == 2 else self.gridFy[:,2]) + if self.dim == 3: + ax.plot(self.gridFz[self._hangingFacesZ,0], self.gridFz[self._hangingFacesZ,1], 'gs', ms=10, mfc='none', mec='green', zs=self.gridFz[self._hangingFacesZ,2]) + ax.plot(self.gridFz[:,0], self.gridFz[:,1], 'g^', zs=self.gridFz[:,2]) if showIt:plt.show() diff --git a/tests/mesh/test_pointerMesh.py b/tests/mesh/test_pointerMesh.py index 76e1e533..f37a470b 100644 --- a/tests/mesh/test_pointerMesh.py +++ b/tests/mesh/test_pointerMesh.py @@ -59,7 +59,7 @@ class TestOperatorsQuadTree(unittest.TestCase): hx, hy = np.r_[1.,2,3,4], np.r_[5.,6,7,8] T = Tree([hx, hy], levels=2) T.refine(lambda xc:2) - T.plotGrid(showIt=True) + # T.plotGrid(showIt=True) M = Mesh.TensorMesh([hx, hy]) assert M.nC == T.nC assert M.nF == T.nF @@ -79,6 +79,33 @@ class TestOperatorsQuadTree(unittest.TestCase): assert (M.faceDiv - T.permuteCC*T.faceDiv*T.permuteF.T).nnz == 0 +class TestOperatorsOcTree(unittest.TestCase): + + def test_counts(self): + + hx, hy, hz = np.r_[1.,2,3,4], np.r_[5.,6,7,8], np.r_[9.,10,11,12] + T = Tree([hx, hy, hz], levels=2) + T.refine(lambda xc:2) + # T.plotGrid(showIt=True) + M = Mesh.TensorMesh([hx, hy, hz]) + assert M.nC == T.nC + assert M.nF == T.nF + assert M.nFx == T.nFx + assert M.nFy == T.nFy + # assert M.nE == T.nE + # assert M.nEx == T.nEx + # assert M.nEy == T.nEy + assert np.allclose(M.area, T.permuteF*T.area) + # assert np.allclose(M.edge, T.permuteE*T.edge) + assert np.allclose(M.vol, T.permuteCC*T.vol) + + # plt.subplot(211).spy(M.faceDiv) + # plt.subplot(212).spy(T.permuteCC.T*T.faceDiv*T.permuteF) + # plt.show() + + assert (M.faceDiv - T.permuteCC*T.faceDiv*T.permuteF.T).nnz == 0 + + if __name__ == '__main__': unittest.main() From e2e2fcec039d3dc1f350050646c457b0a6988ba1 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Wed, 4 Nov 2015 15:01:22 -0800 Subject: [PATCH 30/83] fix 2d plotting --- SimPEG/Mesh/PointerTree.py | 45 ++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/SimPEG/Mesh/PointerTree.py b/SimPEG/Mesh/PointerTree.py index ab2c44e6..b42adc7a 100644 --- a/SimPEG/Mesh/PointerTree.py +++ b/SimPEG/Mesh/PointerTree.py @@ -446,7 +446,7 @@ class Tree(object): c2f[ind] = c2f_ind return c2f_ind - def processCell(ind, faceCount, addFace, hangingFaces, DIR=0): + def processCellFace(ind, faceCount, addFace, hangingFaces, DIR=0): fM,fP=(0,1) if DIR == 0 else (2,3) if DIR == 1 else (4,5) p = self._asPointer(ind) @@ -493,10 +493,10 @@ class Tree(object): for ii, ind in enumerate(self._sortedInds): # c2cn[ind] = ii vol.append(np.prod(self._cellH(ind))) - faceXCount = processCell(ind, faceXCount, addXFace, hangingFacesX, DIR=0) - faceYCount = processCell(ind, faceYCount, addYFace, hangingFacesY, DIR=1) + faceXCount = processCellFace(ind, faceXCount, addXFace, hangingFacesX, DIR=0) + faceYCount = processCellFace(ind, faceYCount, addYFace, hangingFacesY, DIR=1) if self.dim == 3: - faceZCount = processCell(ind, faceZCount, addZFace, hangingFacesZ, DIR=2) + faceZCount = processCellFace(ind, faceZCount, addZFace, hangingFacesZ, DIR=2) self._c2f = c2f self._area = np.array(areaX + areaY + (areaZ if self.dim == 3 else [])) @@ -557,10 +557,10 @@ class Tree(object): h = self._cellH(p) x = [n[0] , n[0] + h[0], n[0] + h[0], n[0] , n[0]] y = [n[1] , n[1] , n[1] + h[1], n[1] + h[1], n[1]] - z = [n[2] , n[2] , n[2] , n[2] , n[2]] - ax.plot(x,y, 'b-', zs=None if self.dim == 2 else z) - - if self.dim == 3: + if self.dim == 2: + ax.plot(x,y, 'b-') + elif self.dim == 3: + ax.plot(x,y, 'b-', zs=[n[2]]*5) z = [n[2] + h[2], n[2] + h[2], n[2] + h[2], n[2] + h[2], n[2] + h[2]] ax.plot(x,y, 'b-', zs=z) sides = [0,0], [h[0],0], [0,h[1]], [h[0],h[1]] @@ -571,15 +571,22 @@ class Tree(object): ax.plot(x,y, 'b-', zs=z) - ax.plot(self.gridCC[[0,-1],0], self.gridCC[[0,-1],1], 'ro', zs=None if self.dim == 2 else self.gridCC[[0,-1],2]) - ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'r.', zs=None if self.dim == 2 else self.gridCC[:,2]) - ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'r:', zs=None if self.dim == 2 else self.gridCC[:,2]) - - # ax.plot(self.gridFx[self._hangingFacesX,0], self.gridFx[self._hangingFacesX,1], 'gs', ms=10, mfc='none', mec='green', zs=None if self.dim == 2 else self.gridFx[self._hangingFacesX,2]) - # ax.plot(self.gridFx[:,0], self.gridFx[:,1], 'g>', zs=None if self.dim == 2 else self.gridFx[:,2]) - # ax.plot(self.gridFy[self._hangingFacesY,0], self.gridFy[self._hangingFacesY,1], 'gs', ms=10, mfc='none', mec='green', zs=None if self.dim == 2 else self.gridFy[self._hangingFacesY,2]) - # ax.plot(self.gridFy[:,0], self.gridFy[:,1], 'g^', zs=None if self.dim == 2 else self.gridFy[:,2]) - if self.dim == 3: + if self.dim == 2: + ax.plot(self.gridCC[[0,-1],0], self.gridCC[[0,-1],1], 'ro') + ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'r.') + ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'r:') + ax.plot(self.gridFx[self._hangingFacesX,0], self.gridFx[self._hangingFacesX,1], 'gs', ms=10, mfc='none', mec='green') + ax.plot(self.gridFx[:,0], self.gridFx[:,1], 'g>') + ax.plot(self.gridFy[self._hangingFacesY,0], self.gridFy[self._hangingFacesY,1], 'gs', ms=10, mfc='none', mec='green') + ax.plot(self.gridFy[:,0], self.gridFy[:,1], 'g^') + elif self.dim == 3: + ax.plot(self.gridCC[[0,-1],0], self.gridCC[[0,-1],1], 'ro', zs=None if self.dim == 2 else self.gridCC[[0,-1],2]) + ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'r.', zs=None if self.dim == 2 else self.gridCC[:,2]) + ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'r:', zs=None if self.dim == 2 else self.gridCC[:,2]) + ax.plot(self.gridFx[self._hangingFacesX,0], self.gridFx[self._hangingFacesX,1], 'gs', ms=10, mfc='none', mec='green', zs=None if self.dim == 2 else self.gridFx[self._hangingFacesX,2]) + ax.plot(self.gridFx[:,0], self.gridFx[:,1], 'g>', zs=None if self.dim == 2 else self.gridFx[:,2]) + ax.plot(self.gridFy[self._hangingFacesY,0], self.gridFy[self._hangingFacesY,1], 'gs', ms=10, mfc='none', mec='green', zs=None if self.dim == 2 else self.gridFy[self._hangingFacesY,2]) + ax.plot(self.gridFy[:,0], self.gridFy[:,1], 'g^', zs=None if self.dim == 2 else self.gridFy[:,2]) ax.plot(self.gridFz[self._hangingFacesZ,0], self.gridFz[self._hangingFacesZ,1], 'gs', ms=10, mfc='none', mec='green', zs=self.gridFz[self._hangingFacesZ,2]) ax.plot(self.gridFz[:,0], self.gridFz[:,1], 'g^', zs=self.gridFz[:,2]) @@ -604,8 +611,8 @@ if __name__ == '__main__': else: return 0 - T = Tree([4,4,4],levels=2) + T = Tree([4,4],levels=2) T.refine(lambda xc:1) - T._refineCell([0,0,0,1]) + T._refineCell([0,0,1]) T.plotGrid(showIt=True) From 337383f8ab26eec132766b3daed241fdadf6873a Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Fri, 6 Nov 2015 11:22:28 -0800 Subject: [PATCH 31/83] Hanging faces edges and node connectivity --- SimPEG/Mesh/PointerTree.py | 639 +++++++++++++++++++++++++++++---- tests/mesh/test_pointerMesh.py | 2 +- 2 files changed, 574 insertions(+), 67 deletions(-) diff --git a/SimPEG/Mesh/PointerTree.py b/SimPEG/Mesh/PointerTree.py index b42adc7a..fd77fe21 100644 --- a/SimPEG/Mesh/PointerTree.py +++ b/SimPEG/Mesh/PointerTree.py @@ -86,6 +86,9 @@ def SortGrid(grid, offset=0): return sorted(range(offset,grid.shape[0]+offset), key=K) +class NotBalancedException(Exception): + pass + class Tree(object): def __init__(self, h_in, levels=3): assert type(h_in) is list, 'h_in must be a list' @@ -96,6 +99,8 @@ class Tree(object): if type(h_i) in [int, long, float]: # This gives you something over the unit cube. h_i = np.ones(int(h_i))/int(h_i) + elif type(h_i) is list: + h_i = Utils.meshTensor(h_i) assert isinstance(h_i, np.ndarray), ("h[%i] is not a numpy array." % i) assert len(h_i.shape) == 1, ("h[%i] must be a 1D numpy array." % i) assert len(h_i) == 2**levels, "must make h and levels match" @@ -106,10 +111,23 @@ class Tree(object): self._levelBits = int(np.ceil(np.sqrt(levels)))+1 self.__dirty__ = True #: The numbering is dirty! + self._z = ZCurve(self.dim, 20) self._treeInds = set() self._treeInds.add(0) + @property + def __dirty__(self): + return self.__dirtyFaces__ or self.__dirtyEdges__ or self.__dirtyNodes__ or self.__dirtyHanging__ + + @__dirty__.setter + def __dirty__(self, val): + assert val is True + self.__dirtyFaces__ = True + self.__dirtyEdges__ = True + self.__dirtyNodes__ = True + self.__dirtyHanging__ = True + @property def levels(self): return self._levels @@ -121,57 +139,50 @@ class Tree(object): @property def nN(self): - self.number() - return self._nN + self._numberNodes() + return len(self._nodes) @property def nF(self): - self.number() - return self._nF + return self.nFx + self.nFy + (0 if self.dim == 2 else self.nFz) @property def nFx(self): - self.number() - return self._nFx + self._numberFaces() + return len(self._facesX) @property def nFy(self): - self.number() - return self._nFy + self._numberFaces() + return len(self._facesY) @property def nFz(self): - self.number() - return None if self.dim < 3 else self._nFz + if self.dim == 2: return None + self._numberFaces() + return len(self._facesZ) @property def nE(self): - self.number() - if self.dim == 2: - return self.nF - elif self.dim == 3: - return len(self.edges) + return self.nEx + self.nEy + (0 if self.dim == 2 else self.nEz) @property def nEx(self): - self.number() - if self.dim == 2: - return self._nFy - elif self.dim == 3: - return self._nEx + if self.dim == 2:return self.nFy + self._numberEdges() + return len(self._edgesX) @property def nEy(self): - self.number() - if self.dim == 2: - return self._nFx - elif self.dim == 3: - return self._nEy + if self.dim == 2:return self.nFx + self._numberEdges() + return len(self._edgesY) @property def nEz(self): - self.number() - return None if self.dim < 3 else self._nEz + if self.dim == 2: return None + self._numberEdges() + return len(self._edgesZ) @property def vol(self): @@ -379,37 +390,407 @@ class Tree(object): self._gridCC[ii, :] = self._cellC(p) return self._gridCC + @property + def gridN(self): + self._numberNodes() + return self._gridN + @property def gridFx(self): - if getattr(self, '_gridFx', None) is None: - self.number() + self._numberFaces() return self._gridFx @property def gridFy(self): - if getattr(self, '_gridFy', None) is None: - self.number() + self._numberFaces() return self._gridFy @property def gridFz(self): if self.dim < 3: return None - if getattr(self, '_gridFz', None) is None: - self.number() + self._numberFaces() return self._gridFz + @property + def gridEx(self): + if self.dim == 2: return self.gridFy + self._numberEdges() + return self._gridEx + + @property + def gridEy(self): + if self.dim == 2: return self.gridFx + self._numberEdges() + return self._gridEy + + @property + def gridEz(self): + if self.dim < 3: return None + self._numberEdges() + return self._gridEz + def _onSameLevel(self, i0, i1): p0 = self._asPointer(i0) p1 = self._asPointer(i1) return p0[-1] == p1[-1] + def _numberNodes(self, force=False): + if not self.__dirtyNodes__ and not force: return + + self._nodes = set() + + for ind in self._treeInds: + p = self._asPointer(ind) + w = self._levelWidth(p[-1]) + if self.dim == 2: + self._nodes.add(self._index([p[0] , p[1] , p[2]])) + self._nodes.add(self._index([p[0] + w, p[1] , p[2]])) + self._nodes.add(self._index([p[0] , p[1] + w, p[2]])) + self._nodes.add(self._index([p[0] + w, p[1] + w, p[2]])) + elif self.dim == 3: + self._nodes.add(self._index([p[0] , p[1] , p[2] , p[3]])) + self._nodes.add(self._index([p[0] + w, p[1] , p[2] , p[3]])) + self._nodes.add(self._index([p[0] , p[1] + w, p[2] , p[3]])) + self._nodes.add(self._index([p[0] + w, p[1] + w, p[2] , p[3]])) + self._nodes.add(self._index([p[0] , p[1] , p[2] + w, p[3]])) + self._nodes.add(self._index([p[0] + w, p[1] , p[2] + w, p[3]])) + self._nodes.add(self._index([p[0] , p[1] + w, p[2] + w, p[3]])) + self._nodes.add(self._index([p[0] + w, p[1] + w, p[2] + w, p[3]])) + gridN = [] + self._n2i = dict() + for ii, n in enumerate(sorted(self._nodes)): + self._n2i[n] = ii + gridN.append( self._cellN( self._pointer(n)[:-1] ) ) + self._gridN = np.array(gridN) + + self.__dirtyNodes__ = False + + def _numberFaces(self, force=False): + if not self.__dirtyFaces__ and not force: return + + self._facesX = set() + self._facesY = set() + if self.dim == 3: + self._facesZ = set() + + for ind in self._treeInds: + p = self._asPointer(ind) + w = self._levelWidth(p[-1]) + + if self.dim == 2: + self._facesX.add(self._index([p[0] , p[1] , p[2]])) + self._facesX.add(self._index([p[0] + w, p[1] , p[2]])) + self._facesY.add(self._index([p[0] , p[1] , p[2]])) + self._facesY.add(self._index([p[0] , p[1] + w, p[2]])) + elif self.dim == 3: + self._facesX.add(self._index([p[0] , p[1] , p[2] , p[3]])) + self._facesX.add(self._index([p[0] + w, p[1] , p[2] , p[3]])) + self._facesY.add(self._index([p[0] , p[1] , p[2] , p[3]])) + self._facesY.add(self._index([p[0] , p[1] + w, p[2] , p[3]])) + self._facesZ.add(self._index([p[0] , p[1] , p[2] , p[3]])) + self._facesZ.add(self._index([p[0] , p[1] , p[2] + w, p[3]])) + + gridFx = [] + self._fx2i = dict() + for ii, fx in enumerate(sorted(self._facesX)): + self._fx2i[fx] = ii + p = self._pointer(fx) + n, h = self._cellN(p), self._cellH(p) + if self.dim == 2: + gridFx.append( [n[0], n[1] + h[1]/2.0] ) + elif self.dim == 3: + gridFx.append( [n[0], n[1] + h[1]/2.0, n[2] + h[2]/2.0] ) + self._gridFx = np.array(gridFx) + + gridFy = [] + self._fy2i = dict() + for ii, fy in enumerate(sorted(self._facesY)): + self._fy2i[fy] = ii + p = self._pointer(fy) + n, h = self._cellN(p), self._cellH(p) + if self.dim == 2: + gridFy.append( [n[0] + h[0]/2.0, n[1]] ) + elif self.dim == 3: + gridFy.append( [n[0] + h[0]/2.0, n[1], n[2] + h[2]/2.0] ) + self._gridFy = np.array(gridFy) + + if self.dim == 2: + self.__dirtyFaces__ = False + return + + gridFz = [] + self._fz2i = dict() + for ii, fz in enumerate(sorted(self._facesZ)): + self._fz2i[fz] = ii + p = self._pointer(fz) + n, h = self._cellN(p), self._cellH(p) + gridFz.append( [n[0] + h[0]/2.0, n[1] + h[1]/2.0, n[2]] ) + self._gridFz = np.array(gridFz) + + self.__dirtyFaces__ = False + + + def _hanging(self, force=False): + if not self.__dirtyHanging__ and not force: return + + self._numberNodes() + self._numberFaces() + self._numberEdges() + + self._hangingNodes = dict() + self._hangingFacesX = dict() + self._hangingFacesY = dict() + if self.dim == 3: + self._hangingFacesZ = dict() + self._hangingEdgesX = dict() + self._hangingEdgesY = dict() + self._hangingEdgesZ = dict() + + # Compute from x faces + for fx in self._facesX: + p = self._pointer(fx) + if p[-1] + 1 > self.levels: continue + sl = p[-1] + 1 #: small level + test = self._index(p[:-1] + [sl]) + if test not in self._facesX: + # Return early without checking the other faces + continue + w = self._levelWidth(sl) + + if self.dim == 2: + self._hangingFacesX[self._fx2i[test ]] = ([self._fx2i[fx], 0.5], ) + self._hangingFacesX[self._fx2i[self._index([p[0] , p[1] + w, sl])]] = ([self._fx2i[fx], 0.5], ) + + n0, n1 = fx, self._index([p[0], p[1] + 2*w, p[-1]]) + self._hangingNodes[self._n2i[test ]] = ([self._n2i[n0], 1.0], ) + self._hangingNodes[self._n2i[self._index([p[0] , p[1] + w, sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n1], 0.5]) + self._hangingNodes[self._n2i[self._index([p[0] , p[1] + 2*w, sl])]] = ([self._n2i[n1], 1.0], ) + + elif self.dim == 3: + ey0 = fx + ey1 = self._index([p[0], p[1] , p[2] + 2*w, p[-1]]) + ez0 = fx + ez1 = self._index([p[0], p[1] + 2*w, p[2] , p[-1]]) + + n0 = fx + n1 = self._index([p[0], p[1] + 2*w, p[2] , p[-1]]) + n2 = self._index([p[0], p[1] , p[2] + 2*w, p[-1]]) + n3 = self._index([p[0], p[1] + 2*w, p[2] + 2*w, p[-1]]) + + self._hangingFacesX[self._fx2i[test ]] = ([self._fx2i[fx], 0.25], ) + self._hangingFacesX[self._fx2i[self._index([p[0], p[1] + w, p[2] , sl])]] = ([self._fx2i[fx], 0.25], ) + self._hangingFacesX[self._fx2i[self._index([p[0], p[1] , p[2] + w, sl])]] = ([self._fx2i[fx], 0.25], ) + self._hangingFacesX[self._fx2i[self._index([p[0], p[1] + w, p[2] + w, sl])]] = ([self._fx2i[fx], 0.25], ) + + self._hangingEdgesY[self._ey2i[test ]] = ([self._ey2i[ey0], 0.5], ) + self._hangingEdgesY[self._ey2i[self._index([p[0], p[1] + w, p[2] , sl])]] = ([self._ey2i[ey0], 0.5], ) + self._hangingEdgesY[self._ey2i[self._index([p[0], p[1] , p[2] + w, sl])]] = ([self._ey2i[ey0], 0.25], [self._ey2i[ey1], 0.25]) + self._hangingEdgesY[self._ey2i[self._index([p[0], p[1] + w, p[2] + w, sl])]] = ([self._ey2i[ey0], 0.25], [self._ey2i[ey1], 0.25]) + self._hangingEdgesY[self._ey2i[self._index([p[0], p[1] , p[2] + 2*w, sl])]] = ([self._ey2i[ey1], 0.5], ) + self._hangingEdgesY[self._ey2i[self._index([p[0], p[1] + w, p[2] + 2*w, sl])]] = ([self._ey2i[ey1], 0.5], ) + + self._hangingEdgesZ[self._ez2i[test ]] = ([self._ez2i[ez0], 0.5], ) + self._hangingEdgesZ[self._ez2i[self._index([p[0], p[1] , p[2] + w, sl])]] = ([self._ez2i[ez0], 0.5], ) + self._hangingEdgesZ[self._ez2i[self._index([p[0], p[1] + w, p[2] , sl])]] = ([self._ez2i[ez0], 0.25], [self._ez2i[ez1], 0.25]) + self._hangingEdgesZ[self._ez2i[self._index([p[0], p[1] + w, p[2] + w, sl])]] = ([self._ez2i[ez0], 0.25], [self._ez2i[ez1], 0.25]) + self._hangingEdgesZ[self._ez2i[self._index([p[0], p[1] + 2*w, p[2] , sl])]] = ([self._ez2i[ez1], 0.5], ) + self._hangingEdgesZ[self._ez2i[self._index([p[0], p[1] + 2*w, p[2] + w, sl])]] = ([self._ez2i[ez1], 0.5], ) + + self._hangingNodes[ self._n2i[ test ]] = ([self._n2i[n0], 1.0], ) + self._hangingNodes[ self._n2i[ self._index([p[0], p[1] + w, p[2] , sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n1], 0.5]) + self._hangingNodes[ self._n2i[ self._index([p[0], p[1] + 2*w, p[2] , sl])]] = ([self._n2i[n1], 1.0], ) + self._hangingNodes[ self._n2i[ self._index([p[0], p[1] , p[2] + w, sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n2], 0.5]) + self._hangingNodes[ self._n2i[ self._index([p[0], p[1] + w, p[2] + w, sl])]] = ([self._n2i[n0], 0.25], [self._n2i[n1], 0.25], [self._n2i[n2], 0.25], [self._n2i[n3], 0.25]) + self._hangingNodes[ self._n2i[ self._index([p[0], p[1] + 2*w, p[2] + w, sl])]] = ([self._n2i[n1], 0.5], [self._n2i[n3], 0.5]) + self._hangingNodes[ self._n2i[ self._index([p[0], p[1] , p[2] + 2*w, sl])]] = ([self._n2i[n2], 1.0], ) + self._hangingNodes[ self._n2i[ self._index([p[0], p[1] + w, p[2] + 2*w, sl])]] = ([self._n2i[n2], 0.5], [self._n2i[n3], 0.5]) + self._hangingNodes[ self._n2i[ self._index([p[0], p[1] + 2*w, p[2] + 2*w, sl])]] = ([self._n2i[n3], 1.0], ) + + # Compute from y faces + for fy in self._facesY: + p = self._pointer(fy) + if p[-1] + 1 > self.levels: continue + sl = p[-1] + 1 #: small level + test = self._index(p[:-1] + [sl]) + if test not in self._facesY: + # Return early without checking the other faces + continue + w = self._levelWidth(sl) + + if self.dim == 2: + self._hangingFacesY[self._fy2i[test ]] = ([self._fy2i[fy], 0.5], ) + self._hangingFacesY[self._fy2i[self._index([p[0] + w, p[1] , sl])]] = ([self._fy2i[fy], 0.5], ) + + n0, n1 = fy, self._index([p[0] + 2*w, p[1], p[-1]]) + self._hangingNodes[self._n2i[test ]] = ([self._n2i[n0], 1.0], ) + self._hangingNodes[self._n2i[self._index([p[0] + w, p[1] , sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n1], 0.5]) + self._hangingNodes[self._n2i[self._index([p[0] + 2*w, p[1] , sl])]] = ([self._n2i[n1], 1.0], ) + + elif self.dim == 3: + ex0 = fy + ex1 = self._index([p[0] , p[1], p[2] + 2*w, p[-1]]) + ez0 = fy + ez1 = self._index([p[0] + 2*w, p[1], p[2] , p[-1]]) + + n0 = fy + n1 = self._index([p[0] + 2*w, p[1], p[2] , p[-1]]) + n2 = self._index([p[0] , p[1], p[2] + 2*w, p[-1]]) + n3 = self._index([p[0] + 2*w, p[1], p[2] + 2*w, p[-1]]) + + self._hangingFacesY[self._fy2i[test ]] = ([self._fy2i[fy], 0.25], ) + self._hangingFacesY[self._fy2i[self._index([p[0] + w, p[1], p[2] , sl])]] = ([self._fy2i[fy], 0.25], ) + self._hangingFacesY[self._fy2i[self._index([p[0] , p[1], p[2] + w, sl])]] = ([self._fy2i[fy], 0.25], ) + self._hangingFacesY[self._fy2i[self._index([p[0] + w, p[1], p[2] + w, sl])]] = ([self._fy2i[fy], 0.25], ) + + self._hangingEdgesX[self._ex2i[test ]] = ([self._ex2i[ex0], 0.5], ) + self._hangingEdgesX[self._ex2i[self._index([p[0] + w, p[1], p[2] , sl])]] = ([self._ex2i[ex0], 0.5], ) + self._hangingEdgesX[self._ex2i[self._index([p[0] , p[1], p[2] + w, sl])]] = ([self._ex2i[ex0], 0.25], [self._ex2i[ex1], 0.25]) + self._hangingEdgesX[self._ex2i[self._index([p[0] + w, p[1], p[2] + w, sl])]] = ([self._ex2i[ex0], 0.25], [self._ex2i[ex1], 0.25]) + self._hangingEdgesX[self._ex2i[self._index([p[0] , p[1], p[2] + 2*w, sl])]] = ([self._ex2i[ex1], 0.5], ) + self._hangingEdgesX[self._ex2i[self._index([p[0] + w, p[1], p[2] + 2*w, sl])]] = ([self._ex2i[ex1], 0.5], ) + + self._hangingEdgesZ[self._ez2i[test ]] = ([self._ez2i[ez0], 0.5], ) + self._hangingEdgesZ[self._ez2i[self._index([p[0] , p[1], p[2] + w, sl])]] = ([self._ez2i[ez0], 0.5], ) + self._hangingEdgesZ[self._ez2i[self._index([p[0] + w, p[1], p[2] , sl])]] = ([self._ez2i[ez0], 0.25], [self._ez2i[ez1], 0.25]) + self._hangingEdgesZ[self._ez2i[self._index([p[0] + w, p[1], p[2] + w, sl])]] = ([self._ez2i[ez0], 0.25], [self._ez2i[ez1], 0.25]) + self._hangingEdgesZ[self._ez2i[self._index([p[0] + 2*w, p[1], p[2] , sl])]] = ([self._ez2i[ez1], 0.5], ) + self._hangingEdgesZ[self._ez2i[self._index([p[0] + 2*w, p[1], p[2] + w, sl])]] = ([self._ez2i[ez1], 0.5], ) + + self._hangingNodes[ self._n2i[ test ]] = ([self._n2i[n0], 1.0], ) + self._hangingNodes[ self._n2i[ self._index([p[0] + w, p[1], p[2] , sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n1], 0.5]) + self._hangingNodes[ self._n2i[ self._index([p[0] + 2*w, p[1], p[2] , sl])]] = ([self._n2i[n1], 1.0], ) + self._hangingNodes[ self._n2i[ self._index([p[0] , p[1], p[2] + w, sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n2], 0.5]) + self._hangingNodes[ self._n2i[ self._index([p[0] + w, p[1], p[2] + w, sl])]] = ([self._n2i[n0], 0.25], [self._n2i[n1], 0.25], [self._n2i[n2], 0.25], [self._n2i[n3], 0.25]) + self._hangingNodes[ self._n2i[ self._index([p[0] + 2*w, p[1], p[2] + w, sl])]] = ([self._n2i[n1], 0.5], [self._n2i[n3], 0.5]) + self._hangingNodes[ self._n2i[ self._index([p[0] , p[1], p[2] + 2*w, sl])]] = ([self._n2i[n2], 1.0], ) + self._hangingNodes[ self._n2i[ self._index([p[0] + w, p[1], p[2] + 2*w, sl])]] = ([self._n2i[n2], 0.5], [self._n2i[n3], 0.5]) + self._hangingNodes[ self._n2i[ self._index([p[0] + 2*w, p[1], p[2] + 2*w, sl])]] = ([self._n2i[n3], 1.0], ) + + if self.dim == 2: + self.__dirtyHanging__ = False + return + + # Compute from z faces + for fz in self._facesZ: + p = self._pointer(fz) + if p[-1] + 1 > self.levels: continue + sl = p[-1] + 1 #: small level + test = self._index(p[:-1] + [sl]) + if test not in self._facesZ: + # Return early without checking the other faces + continue + w = self._levelWidth(sl) + + ex0 = fz + ex1 = self._index([p[0] , p[1] + 2*w, p[2], p[-1]]) + ey0 = fz + ey1 = self._index([p[0] + 2*w, p[1] , p[2], p[-1]]) + + n0 = fz + n1 = self._index([p[0] + 2*w, p[1] , p[2], p[-1]]) + n2 = self._index([p[0] , p[1] + 2*w, p[2], p[-1]]) + n3 = self._index([p[0] + 2*w, p[1] + 2*w, p[2], p[-1]]) + + self._hangingFacesY[self._fz2i[test ]] = ([self._fz2i[fz], 0.25], ) + self._hangingFacesY[self._fz2i[self._index([p[0] + w, p[1] , p[2], sl])]] = ([self._fz2i[fz], 0.25], ) + self._hangingFacesY[self._fz2i[self._index([p[0] , p[1] + w, p[2], sl])]] = ([self._fz2i[fz], 0.25], ) + self._hangingFacesY[self._fz2i[self._index([p[0] + w, p[1] + w, p[2], sl])]] = ([self._fz2i[fz], 0.25], ) + + self._hangingEdgesX[self._ex2i[test ]] = ([self._ex2i[ex0], 0.5], ) + self._hangingEdgesX[self._ex2i[self._index([p[0] + w, p[1] , p[2], sl])]] = ([self._ex2i[ex0], 0.5], ) + self._hangingEdgesX[self._ex2i[self._index([p[0] , p[1] + w, p[2], sl])]] = ([self._ex2i[ex0], 0.25], [self._ex2i[ex1], 0.25]) + self._hangingEdgesX[self._ex2i[self._index([p[0] + w, p[1] + w, p[2], sl])]] = ([self._ex2i[ex0], 0.25], [self._ex2i[ex1], 0.25]) + self._hangingEdgesX[self._ex2i[self._index([p[0] , p[1] + 2*w, p[2], sl])]] = ([self._ex2i[ex1], 0.5], ) + self._hangingEdgesX[self._ex2i[self._index([p[0] + w, p[1] + 2*w, p[2], sl])]] = ([self._ex2i[ex1], 0.5], ) + + self._hangingEdgesY[self._ey2i[test ]] = ([self._ey2i[ey0], 0.5], ) + self._hangingEdgesY[self._ey2i[self._index([p[0] , p[1] + w, p[2], sl])]] = ([self._ey2i[ey0], 0.5], ) + self._hangingEdgesY[self._ey2i[self._index([p[0] + w, p[1] , p[2], sl])]] = ([self._ey2i[ey0], 0.25], [self._ey2i[ey1], 0.25]) + self._hangingEdgesY[self._ey2i[self._index([p[0] + w, p[1] + w, p[2], sl])]] = ([self._ey2i[ey0], 0.25], [self._ey2i[ey1], 0.25]) + self._hangingEdgesY[self._ey2i[self._index([p[0] + 2*w, p[1] , p[2], sl])]] = ([self._ey2i[ey1], 0.5], ) + self._hangingEdgesY[self._ey2i[self._index([p[0] + 2*w, p[1] + w, p[2], sl])]] = ([self._ey2i[ey1], 0.5], ) + + self._hangingNodes[ self._n2i[ test ]] = ([self._n2i[n0], 1.0], ) + self._hangingNodes[ self._n2i[ self._index([p[0] + w, p[1] , p[2], sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n1], 0.5]) + self._hangingNodes[ self._n2i[ self._index([p[0] + 2*w, p[1] , p[2], sl])]] = ([self._n2i[n1], 1.0], ) + self._hangingNodes[ self._n2i[ self._index([p[0] , p[1] + w, p[2], sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n2], 0.5]) + self._hangingNodes[ self._n2i[ self._index([p[0] + w, p[1] + w, p[2], sl])]] = ([self._n2i[n0], 0.25], [self._n2i[n1], 0.25], [self._n2i[n2], 0.25], [self._n2i[n3], 0.25]) + self._hangingNodes[ self._n2i[ self._index([p[0] + 2*w, p[1] + w, p[2], sl])]] = ([self._n2i[n1], 0.5], [self._n2i[n3], 0.5]) + self._hangingNodes[ self._n2i[ self._index([p[0] , p[1] + 2*w, p[2], sl])]] = ([self._n2i[n2], 1.0], ) + self._hangingNodes[ self._n2i[ self._index([p[0] + w, p[1] + 2*w, p[2], sl])]] = ([self._n2i[n2], 0.5], [self._n2i[n3], 0.5]) + self._hangingNodes[ self._n2i[ self._index([p[0] + 2*w, p[1] + 2*w, p[2], sl])]] = ([self._n2i[n3], 1.0], ) + + + self.__dirtyHanging__ = False + + + def _numberEdges(self, force=False): + if self.dim == 2: return + if not self.__dirtyEdges__ and not force: return + + self._edgesX = set() + self._edgesY = set() + self._edgesZ = set() + + for ind in self._treeInds: + p = self._asPointer(ind) + w = self._levelWidth(p[-1]) + self._edgesX.add(self._index([p[0] , p[1] , p[2] , p[3]])) + self._edgesX.add(self._index([p[0] , p[1] + w, p[2] , p[3]])) + self._edgesX.add(self._index([p[0] , p[1] , p[2] + w, p[3]])) + self._edgesX.add(self._index([p[0] , p[1] + w, p[2] + w, p[3]])) + + self._edgesY.add(self._index([p[0] , p[1] , p[2] , p[3]])) + self._edgesY.add(self._index([p[0] + w, p[1] , p[2] , p[3]])) + self._edgesY.add(self._index([p[0] , p[1] , p[2] + w, p[3]])) + self._edgesY.add(self._index([p[0] + w, p[1] , p[2] + w, p[3]])) + + self._edgesZ.add(self._index([p[0] , p[1] , p[2] , p[3]])) + self._edgesZ.add(self._index([p[0] + w, p[1] , p[2] , p[3]])) + self._edgesZ.add(self._index([p[0] , p[1] + w, p[2] , p[3]])) + self._edgesZ.add(self._index([p[0] + w, p[1] + w, p[2] , p[3]])) + + gridEx = [] + self._ex2i = dict() + for ii, ex in enumerate(sorted(self._edgesX)): + self._ex2i[ex] = ii + p = self._pointer(ex) + n, h = self._cellN(p), self._cellH(p) + gridEx.append( [n[0] + h[0]/2.0, n[1], n[2]] ) + self._gridEx = np.array(gridEx) + + gridEy = [] + self._ey2i = dict() + for ii, ey in enumerate(sorted(self._edgesY)): + self._ey2i[ey] = ii + p = self._pointer(ey) + n, h = self._cellN(p), self._cellH(p) + gridEy.append( [n[0], n[1] + h[1]/2.0, n[2]] ) + self._gridEy = np.array(gridEy) + + gridEz = [] + self._ez2i = dict() + for ii, ez in enumerate(sorted(self._edgesZ)): + self._ez2i[ez] = ii + p = self._pointer(ez) + n, h = self._cellN(p), self._cellH(p) + gridEz.append( [n[0], n[1], n[2] + h[2]/2.0] ) + self._gridEz = np.array(gridEz) + + self.__dirtyEdges__ = False + + def number(self, force=False): if not self.__dirty__ and not force: return + self._hanging() + return facesX, facesY, facesZ = [], [], [] areaX, areaY, areaZ = [], [], [] hangingFacesX, hangingFacesY, hangingFacesZ = [], [], [] + hangingNodes = [] faceXCount, faceYCount, faceZCount = -1, -1, -1 + nodeCount = -1 fXm,fXp,fYm,fYp,fZm,fZp = range(6) vol, nodes = [], [] @@ -438,6 +819,15 @@ class Tree(object): facesZ.append([n[0] + w[0]/2.0, n[1] + w[1]/2.0, n[2] + (w[2] if positive else 0)]) return count + 1 + def addNode(count, p, loc=[0,0,0]): + """loc=[0,0]""" + n = self._cellN(p) + w = self._cellH(p) + if self.dim == 2: + nodes.append([n[0] + w[0]*loc[0], n[1] + w[1]*loc[1]]) + elif self.dim == 3: + nodes.append([n[0] + w[0]*loc[0], n[1] + w[1]*loc[1], n[2] + w[2]*loc[2]]) + return count + 1 # c2cn = dict() c2f = dict() def gc2f(ind): @@ -445,6 +835,12 @@ class Tree(object): c2f_ind = [list() for _ in xrange(2*self.dim)] c2f[ind] = c2f_ind return c2f_ind + c2n = dict() + def gc2n(ind): + if ind in c2n: return c2n[ind] + c2n_ind = [list() for _ in xrange(2**self.dim)] + c2n[ind] = c2n_ind + return c2n_ind def processCellFace(ind, faceCount, addFace, hangingFaces, DIR=0): @@ -490,9 +886,73 @@ class Tree(object): return faceCount + + def processCellNode(ind, nodeCount): + + MMM, PMM, MPM, PPM, MMP, PMP, MPP, PPP = range(8) + p = self._asPointer(ind) + + xM = self._getNextCell(p, direction=0, positive=False) + yM = self._getNextCell(p, direction=1, positive=False) + zM = None if self.dim == 2 else self._getNextCell(p, direction=2, positive=False) + + xP = self._getNextCell(p, direction=0, positive=True) + yP = self._getNextCell(p, direction=1, positive=True) + zP = None if self.dim == 2 else self._getNextCell(p, direction=2, positive=True) + + if xM is None and yM is None and zM is None: + nodeCount = addNode(nodeCount, p, loc=[0,0,0]) + gc2n(ind)[MMM] += [nodeCount] + if yM is None: + nodeCount = addNode(nodeCount, p, loc=[1,0,0]) + gc2n(ind)[PMM] += [nodeCount] + if xM is None: + nodeCount = addNode(nodeCount, p, loc=[0,1,0]) + gc2n(ind)[MPM] += [nodeCount] + + # Add the next Xface + if nextCell is None: + # on the boundary + pass + # nodeCount = addFace(nodeCount, p) + # gc2f(ind)[fP] += [nodeCount] + elif type(nextCell) in [int, long] and self._onSameLevel(p,nextCell): + # same sized cell + pass + # nodeCount = addFace(nodeCount, p) + # gc2f(ind)[fP] += [nodeCount] + # gc2f(nextCell)[fM] += [nodeCount] + elif type(nextCell) in [int, long] and not self._onSameLevel(p,nextCell): + # the cell is bigger than me + pass + # nodeCount = addFace(nodeCount, p) + # gc2f(ind)[fP] += [nodeCount] + # gc2f(nextCell)[fM] += [nodeCount] + # hangingFaces.append(nodeCount) + elif type(nextCell) is list: + # the cell is smaller than me + pass + # TODO: ensure that things are balanced. + # p0 = self._pointer(nextCell[0]) + # p1 = self._pointer(nextCell[1]) + + # nodeCount = addFace(nodeCount, p0, positive=False) + # gc2f(nextCell[0])[fM] += [nodeCount] + # nodeCount = addFace(nodeCount, p1, positive=False) + # gc2f(nextCell[1])[fM] += [nodeCount] + + # gc2f(ind)[fP] += [nodeCount-1,nodeCount] + + # hangingFaces += [nodeCount-1, nodeCount] + + return nodeCount + for ii, ind in enumerate(self._sortedInds): # c2cn[ind] = ii vol.append(np.prod(self._cellH(ind))) + + # nodeCount = processCellNode(ind, nodeCount) + faceXCount = processCellFace(ind, faceXCount, addXFace, hangingFacesX, DIR=0) faceYCount = processCellFace(ind, faceYCount, addYFace, hangingFacesY, DIR=1) if self.dim == 3: @@ -503,6 +963,7 @@ class Tree(object): self._vol = np.array(vol) self._gridFx = np.array(facesX) self._gridFy = np.array(facesY) + self._gridN = np.array(nodes) self._hangingFacesX = hangingFacesX self._hangingFacesY = hangingFacesY if self.dim == 3: @@ -511,11 +972,12 @@ class Tree(object): self._hangingFacesZ = hangingFacesZ self._nC = len(self._sortedInds) + self._nN = self._gridN.shape[0] self._nFx = self._gridFx.shape[0] self._nFy = self._gridFy.shape[0] self._nF = self._nFx + self._nFy + (self._nFz if self.dim == 3 else 0) - self.__dirty__ = False + # self.__dirty__ = False @property def faceDiv(self): @@ -541,8 +1003,9 @@ class Tree(object): self._faceDiv = Utils.sdiag(1.0/VOL)*D*Utils.sdiag(S) return self._faceDiv - def plotGrid(self, ax=None, showIt=False): + def plotGrid(self, ax=None, showIt=False, grid=True): + self.number() axOpts = {'projection':'3d'} if self.dim == 3 else {} if ax is None: @@ -551,45 +1014,77 @@ class Tree(object): assert isinstance(ax,matplotlib.axes.Axes), "ax must be an Axes!" fig = ax.figure - for ind in self._sortedInds: - p = self._asPointer(ind) - n = self._cellN(p) - h = self._cellH(p) - x = [n[0] , n[0] + h[0], n[0] + h[0], n[0] , n[0]] - y = [n[1] , n[1] , n[1] + h[1], n[1] + h[1], n[1]] - if self.dim == 2: - ax.plot(x,y, 'b-') - elif self.dim == 3: - ax.plot(x,y, 'b-', zs=[n[2]]*5) - z = [n[2] + h[2], n[2] + h[2], n[2] + h[2], n[2] + h[2], n[2] + h[2]] - ax.plot(x,y, 'b-', zs=z) - sides = [0,0], [h[0],0], [0,h[1]], [h[0],h[1]] - for s in sides: - x = [n[0] + s[0], n[0] + s[0]] - y = [n[1] + s[1], n[1] + s[1]] - z = [n[2] , n[2] + h[2]] + if grid: + for ind in self._sortedInds: + p = self._asPointer(ind) + n = self._cellN(p) + h = self._cellH(p) + x = [n[0] , n[0] + h[0], n[0] + h[0], n[0] , n[0]] + y = [n[1] , n[1] , n[1] + h[1], n[1] + h[1], n[1]] + if self.dim == 2: + ax.plot(x,y, 'b-') + elif self.dim == 3: + ax.plot(x,y, 'b-', zs=[n[2]]*5) + z = [n[2] + h[2], n[2] + h[2], n[2] + h[2], n[2] + h[2], n[2] + h[2]] ax.plot(x,y, 'b-', zs=z) - + sides = [0,0], [h[0],0], [0,h[1]], [h[0],h[1]] + for s in sides: + x = [n[0] + s[0], n[0] + s[0]] + y = [n[1] + s[1], n[1] + s[1]] + z = [n[2] , n[2] + h[2]] + ax.plot(x,y, 'b-', zs=z) if self.dim == 2: ax.plot(self.gridCC[[0,-1],0], self.gridCC[[0,-1],1], 'ro') ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'r.') ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'r:') - ax.plot(self.gridFx[self._hangingFacesX,0], self.gridFx[self._hangingFacesX,1], 'gs', ms=10, mfc='none', mec='green') + ax.plot(self.gridN[:,0], self.gridN[:,1], 'ms') + ax.plot(self.gridN[self._hangingNodes.keys(),0], self.gridN[self._hangingNodes.keys(),1], 'ms', ms=10, mfc='none', mec='m') + ax.plot(self.gridFx[self._hangingFacesX.keys(),0], self.gridFx[self._hangingFacesX.keys(),1], 'gs', ms=10, mfc='none', mec='g') ax.plot(self.gridFx[:,0], self.gridFx[:,1], 'g>') - ax.plot(self.gridFy[self._hangingFacesY,0], self.gridFy[self._hangingFacesY,1], 'gs', ms=10, mfc='none', mec='green') + ax.plot(self.gridFy[self._hangingFacesY.keys(),0], self.gridFy[self._hangingFacesY.keys(),1], 'gs', ms=10, mfc='none', mec='g') ax.plot(self.gridFy[:,0], self.gridFy[:,1], 'g^') elif self.dim == 3: - ax.plot(self.gridCC[[0,-1],0], self.gridCC[[0,-1],1], 'ro', zs=None if self.dim == 2 else self.gridCC[[0,-1],2]) - ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'r.', zs=None if self.dim == 2 else self.gridCC[:,2]) - ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'r:', zs=None if self.dim == 2 else self.gridCC[:,2]) - ax.plot(self.gridFx[self._hangingFacesX,0], self.gridFx[self._hangingFacesX,1], 'gs', ms=10, mfc='none', mec='green', zs=None if self.dim == 2 else self.gridFx[self._hangingFacesX,2]) - ax.plot(self.gridFx[:,0], self.gridFx[:,1], 'g>', zs=None if self.dim == 2 else self.gridFx[:,2]) - ax.plot(self.gridFy[self._hangingFacesY,0], self.gridFy[self._hangingFacesY,1], 'gs', ms=10, mfc='none', mec='green', zs=None if self.dim == 2 else self.gridFy[self._hangingFacesY,2]) - ax.plot(self.gridFy[:,0], self.gridFy[:,1], 'g^', zs=None if self.dim == 2 else self.gridFy[:,2]) - ax.plot(self.gridFz[self._hangingFacesZ,0], self.gridFz[self._hangingFacesZ,1], 'gs', ms=10, mfc='none', mec='green', zs=self.gridFz[self._hangingFacesZ,2]) + ax.plot(self.gridCC[[0,-1],0], self.gridCC[[0,-1],1], 'ro', zs=self.gridCC[[0,-1],2]) + ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'r.', zs=self.gridCC[:,2]) + ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'r:', zs=self.gridCC[:,2]) + + ax.plot(self.gridN[:,0], self.gridN[:,1], 'ms', zs=self.gridN[:,2]) + ax.plot(self.gridN[self._hangingNodes.keys(),0], self.gridN[self._hangingNodes.keys(),1], 'ms', ms=10, mfc='none', mec='m', zs=self.gridN[self._hangingNodes.keys(),2]) + + ax.plot(self.gridFx[self._hangingFacesX.keys(),0], self.gridFx[self._hangingFacesX.keys(),1], 'gs', ms=10, mfc='none', mec='g', zs=self.gridFx[self._hangingFacesX.keys(),2]) + ax.plot(self.gridFx[:,0], self.gridFx[:,1], 'g>', zs=self.gridFx[:,2]) + + ax.plot(self.gridFy[self._hangingFacesY.keys(),0], self.gridFy[self._hangingFacesY.keys(),1], 'gs', ms=10, mfc='none', mec='g', zs=self.gridFy[self._hangingFacesY.keys(),2]) + ax.plot(self.gridFy[:,0], self.gridFy[:,1], 'g^', zs=self.gridFy[:,2]) + + ax.plot(self.gridFz[self._hangingFacesZ.keys(),0], self.gridFz[self._hangingFacesZ.keys(),1], 'gs', ms=10, mfc='none', mec='g', zs=self.gridFz[self._hangingFacesZ.keys(),2]) ax.plot(self.gridFz[:,0], self.gridFz[:,1], 'g^', zs=self.gridFz[:,2]) + ax.plot(self.gridEx[:,0], self.gridEx[:,1], 'k>', zs=self.gridEx[:,2]) + ax.plot(self.gridEx[self._hangingEdgesX.keys(),0], self.gridEx[self._hangingEdgesX.keys(),1], 'ks', ms=10, mfc='none', mec='k', zs=self.gridEx[self._hangingEdgesX.keys(),2]) + for key in self._hangingEdgesX.keys(): + for hf in self._hangingEdgesX[key]: + ind = [key, hf[0]] + ax.plot(self.gridEx[ind,0], self.gridEx[ind,1], 'k:', zs=self.gridEx[ind,2]) + + + ax.plot(self.gridEy[:,0], self.gridEy[:,1], 'k<', zs=self.gridEy[:,2]) + ax.plot(self.gridEy[self._hangingEdgesY.keys(),0], self.gridEy[self._hangingEdgesY.keys(),1], 'ks', ms=10, mfc='none', mec='k', zs=self.gridEy[self._hangingEdgesY.keys(),2]) + for key in self._hangingEdgesY.keys(): + for hf in self._hangingEdgesY[key]: + ind = [key, hf[0]] + ax.plot(self.gridEy[ind,0], self.gridEy[ind,1], 'k:', zs=self.gridEy[ind,2]) + + ax.plot(self.gridEz[:,0], self.gridEz[:,1], 'k^', zs=self.gridEz[:,2]) + ax.plot(self.gridEz[self._hangingEdgesZ.keys(),0], self.gridEz[self._hangingEdgesZ.keys(),1], 'ks', ms=10, mfc='none', mec='k', zs=self.gridEz[self._hangingEdgesZ.keys(),2]) + for key in self._hangingEdgesZ.keys(): + for hf in self._hangingEdgesZ[key]: + ind = [key, hf[0]] + ax.plot(self.gridEz[ind,0], self.gridEz[ind,1], 'k:', zs=self.gridEz[ind,2]) + + + ax.axis('equal') if showIt:plt.show() @@ -611,8 +1106,20 @@ if __name__ == '__main__': else: return 0 - T = Tree([4,4],levels=2) + T = Tree([[(1,8)],[(1,8)],[(1,8)]],levels=3) + # T = Tree([[(1,16)],[(1,16)]],levels=4) T.refine(lambda xc:1) - T._refineCell([0,0,1]) - T.plotGrid(showIt=True) + # T._refineCell([4,4,2]) + T._refineCell([0,0,0,1]) + + + T.plotGrid(grid=False) + + + + + + # print T.nN + + plt.show() diff --git a/tests/mesh/test_pointerMesh.py b/tests/mesh/test_pointerMesh.py index f37a470b..dff3e8de 100644 --- a/tests/mesh/test_pointerMesh.py +++ b/tests/mesh/test_pointerMesh.py @@ -19,7 +19,7 @@ class TestSimpleQuadTree(unittest.TestCase): T._refineCell([2,2,2]) T.number() - # T.plotGrid(showIt=True) + T.plotGrid(showIt=True) assert sorted(T._treeInds) == [2, 34, 66, 99, 107, 115, 123, 129, 257, 386, 418, 450, 482] assert len(T._hangingFacesX) == 7 assert T.nFx == 18 From e55dc2e78d06af47cfbaaf68a286f214aa923e24 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Fri, 6 Nov 2015 11:53:46 -0800 Subject: [PATCH 32/83] rename hangingNodes --> hangingN etc. --- SimPEG/Mesh/PointerTree.py | 242 ++++++++++++++++++++----------------- 1 file changed, 129 insertions(+), 113 deletions(-) diff --git a/SimPEG/Mesh/PointerTree.py b/SimPEG/Mesh/PointerTree.py index fd77fe21..2876ce5f 100644 --- a/SimPEG/Mesh/PointerTree.py +++ b/SimPEG/Mesh/PointerTree.py @@ -537,14 +537,14 @@ class Tree(object): self._numberFaces() self._numberEdges() - self._hangingNodes = dict() - self._hangingFacesX = dict() - self._hangingFacesY = dict() + self._hangingN = dict() + self._hangingFx = dict() + self._hangingFy = dict() if self.dim == 3: - self._hangingFacesZ = dict() - self._hangingEdgesX = dict() - self._hangingEdgesY = dict() - self._hangingEdgesZ = dict() + self._hangingFz = dict() + self._hangingEx = dict() + self._hangingEy = dict() + self._hangingEz = dict() # Compute from x faces for fx in self._facesX: @@ -558,13 +558,13 @@ class Tree(object): w = self._levelWidth(sl) if self.dim == 2: - self._hangingFacesX[self._fx2i[test ]] = ([self._fx2i[fx], 0.5], ) - self._hangingFacesX[self._fx2i[self._index([p[0] , p[1] + w, sl])]] = ([self._fx2i[fx], 0.5], ) + self._hangingFx[self._fx2i[test ]] = ([self._fx2i[fx], 0.5], ) + self._hangingFx[self._fx2i[self._index([p[0] , p[1] + w, sl])]] = ([self._fx2i[fx], 0.5], ) n0, n1 = fx, self._index([p[0], p[1] + 2*w, p[-1]]) - self._hangingNodes[self._n2i[test ]] = ([self._n2i[n0], 1.0], ) - self._hangingNodes[self._n2i[self._index([p[0] , p[1] + w, sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n1], 0.5]) - self._hangingNodes[self._n2i[self._index([p[0] , p[1] + 2*w, sl])]] = ([self._n2i[n1], 1.0], ) + self._hangingN[self._n2i[test ]] = ([self._n2i[n0], 1.0], ) + self._hangingN[self._n2i[self._index([p[0] , p[1] + w, sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n1], 0.5]) + self._hangingN[self._n2i[self._index([p[0] , p[1] + 2*w, sl])]] = ([self._n2i[n1], 1.0], ) elif self.dim == 3: ey0 = fx @@ -577,34 +577,34 @@ class Tree(object): n2 = self._index([p[0], p[1] , p[2] + 2*w, p[-1]]) n3 = self._index([p[0], p[1] + 2*w, p[2] + 2*w, p[-1]]) - self._hangingFacesX[self._fx2i[test ]] = ([self._fx2i[fx], 0.25], ) - self._hangingFacesX[self._fx2i[self._index([p[0], p[1] + w, p[2] , sl])]] = ([self._fx2i[fx], 0.25], ) - self._hangingFacesX[self._fx2i[self._index([p[0], p[1] , p[2] + w, sl])]] = ([self._fx2i[fx], 0.25], ) - self._hangingFacesX[self._fx2i[self._index([p[0], p[1] + w, p[2] + w, sl])]] = ([self._fx2i[fx], 0.25], ) + self._hangingFx[self._fx2i[test ]] = ([self._fx2i[fx], 0.25], ) + self._hangingFx[self._fx2i[self._index([p[0], p[1] + w, p[2] , sl])]] = ([self._fx2i[fx], 0.25], ) + self._hangingFx[self._fx2i[self._index([p[0], p[1] , p[2] + w, sl])]] = ([self._fx2i[fx], 0.25], ) + self._hangingFx[self._fx2i[self._index([p[0], p[1] + w, p[2] + w, sl])]] = ([self._fx2i[fx], 0.25], ) - self._hangingEdgesY[self._ey2i[test ]] = ([self._ey2i[ey0], 0.5], ) - self._hangingEdgesY[self._ey2i[self._index([p[0], p[1] + w, p[2] , sl])]] = ([self._ey2i[ey0], 0.5], ) - self._hangingEdgesY[self._ey2i[self._index([p[0], p[1] , p[2] + w, sl])]] = ([self._ey2i[ey0], 0.25], [self._ey2i[ey1], 0.25]) - self._hangingEdgesY[self._ey2i[self._index([p[0], p[1] + w, p[2] + w, sl])]] = ([self._ey2i[ey0], 0.25], [self._ey2i[ey1], 0.25]) - self._hangingEdgesY[self._ey2i[self._index([p[0], p[1] , p[2] + 2*w, sl])]] = ([self._ey2i[ey1], 0.5], ) - self._hangingEdgesY[self._ey2i[self._index([p[0], p[1] + w, p[2] + 2*w, sl])]] = ([self._ey2i[ey1], 0.5], ) + self._hangingEy[self._ey2i[test ]] = ([self._ey2i[ey0], 0.5], ) + self._hangingEy[self._ey2i[self._index([p[0], p[1] + w, p[2] , sl])]] = ([self._ey2i[ey0], 0.5], ) + self._hangingEy[self._ey2i[self._index([p[0], p[1] , p[2] + w, sl])]] = ([self._ey2i[ey0], 0.25], [self._ey2i[ey1], 0.25]) + self._hangingEy[self._ey2i[self._index([p[0], p[1] + w, p[2] + w, sl])]] = ([self._ey2i[ey0], 0.25], [self._ey2i[ey1], 0.25]) + self._hangingEy[self._ey2i[self._index([p[0], p[1] , p[2] + 2*w, sl])]] = ([self._ey2i[ey1], 0.5], ) + self._hangingEy[self._ey2i[self._index([p[0], p[1] + w, p[2] + 2*w, sl])]] = ([self._ey2i[ey1], 0.5], ) - self._hangingEdgesZ[self._ez2i[test ]] = ([self._ez2i[ez0], 0.5], ) - self._hangingEdgesZ[self._ez2i[self._index([p[0], p[1] , p[2] + w, sl])]] = ([self._ez2i[ez0], 0.5], ) - self._hangingEdgesZ[self._ez2i[self._index([p[0], p[1] + w, p[2] , sl])]] = ([self._ez2i[ez0], 0.25], [self._ez2i[ez1], 0.25]) - self._hangingEdgesZ[self._ez2i[self._index([p[0], p[1] + w, p[2] + w, sl])]] = ([self._ez2i[ez0], 0.25], [self._ez2i[ez1], 0.25]) - self._hangingEdgesZ[self._ez2i[self._index([p[0], p[1] + 2*w, p[2] , sl])]] = ([self._ez2i[ez1], 0.5], ) - self._hangingEdgesZ[self._ez2i[self._index([p[0], p[1] + 2*w, p[2] + w, sl])]] = ([self._ez2i[ez1], 0.5], ) + self._hangingEz[self._ez2i[test ]] = ([self._ez2i[ez0], 0.5], ) + self._hangingEz[self._ez2i[self._index([p[0], p[1] , p[2] + w, sl])]] = ([self._ez2i[ez0], 0.5], ) + self._hangingEz[self._ez2i[self._index([p[0], p[1] + w, p[2] , sl])]] = ([self._ez2i[ez0], 0.25], [self._ez2i[ez1], 0.25]) + self._hangingEz[self._ez2i[self._index([p[0], p[1] + w, p[2] + w, sl])]] = ([self._ez2i[ez0], 0.25], [self._ez2i[ez1], 0.25]) + self._hangingEz[self._ez2i[self._index([p[0], p[1] + 2*w, p[2] , sl])]] = ([self._ez2i[ez1], 0.5], ) + self._hangingEz[self._ez2i[self._index([p[0], p[1] + 2*w, p[2] + w, sl])]] = ([self._ez2i[ez1], 0.5], ) - self._hangingNodes[ self._n2i[ test ]] = ([self._n2i[n0], 1.0], ) - self._hangingNodes[ self._n2i[ self._index([p[0], p[1] + w, p[2] , sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n1], 0.5]) - self._hangingNodes[ self._n2i[ self._index([p[0], p[1] + 2*w, p[2] , sl])]] = ([self._n2i[n1], 1.0], ) - self._hangingNodes[ self._n2i[ self._index([p[0], p[1] , p[2] + w, sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n2], 0.5]) - self._hangingNodes[ self._n2i[ self._index([p[0], p[1] + w, p[2] + w, sl])]] = ([self._n2i[n0], 0.25], [self._n2i[n1], 0.25], [self._n2i[n2], 0.25], [self._n2i[n3], 0.25]) - self._hangingNodes[ self._n2i[ self._index([p[0], p[1] + 2*w, p[2] + w, sl])]] = ([self._n2i[n1], 0.5], [self._n2i[n3], 0.5]) - self._hangingNodes[ self._n2i[ self._index([p[0], p[1] , p[2] + 2*w, sl])]] = ([self._n2i[n2], 1.0], ) - self._hangingNodes[ self._n2i[ self._index([p[0], p[1] + w, p[2] + 2*w, sl])]] = ([self._n2i[n2], 0.5], [self._n2i[n3], 0.5]) - self._hangingNodes[ self._n2i[ self._index([p[0], p[1] + 2*w, p[2] + 2*w, sl])]] = ([self._n2i[n3], 1.0], ) + self._hangingN[ self._n2i[ test ]] = ([self._n2i[n0], 1.0], ) + self._hangingN[ self._n2i[ self._index([p[0], p[1] + w, p[2] , sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n1], 0.5]) + self._hangingN[ self._n2i[ self._index([p[0], p[1] + 2*w, p[2] , sl])]] = ([self._n2i[n1], 1.0], ) + self._hangingN[ self._n2i[ self._index([p[0], p[1] , p[2] + w, sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n2], 0.5]) + self._hangingN[ self._n2i[ self._index([p[0], p[1] + w, p[2] + w, sl])]] = ([self._n2i[n0], 0.25], [self._n2i[n1], 0.25], [self._n2i[n2], 0.25], [self._n2i[n3], 0.25]) + self._hangingN[ self._n2i[ self._index([p[0], p[1] + 2*w, p[2] + w, sl])]] = ([self._n2i[n1], 0.5], [self._n2i[n3], 0.5]) + self._hangingN[ self._n2i[ self._index([p[0], p[1] , p[2] + 2*w, sl])]] = ([self._n2i[n2], 1.0], ) + self._hangingN[ self._n2i[ self._index([p[0], p[1] + w, p[2] + 2*w, sl])]] = ([self._n2i[n2], 0.5], [self._n2i[n3], 0.5]) + self._hangingN[ self._n2i[ self._index([p[0], p[1] + 2*w, p[2] + 2*w, sl])]] = ([self._n2i[n3], 1.0], ) # Compute from y faces for fy in self._facesY: @@ -618,13 +618,13 @@ class Tree(object): w = self._levelWidth(sl) if self.dim == 2: - self._hangingFacesY[self._fy2i[test ]] = ([self._fy2i[fy], 0.5], ) - self._hangingFacesY[self._fy2i[self._index([p[0] + w, p[1] , sl])]] = ([self._fy2i[fy], 0.5], ) + self._hangingFy[self._fy2i[test ]] = ([self._fy2i[fy], 0.5], ) + self._hangingFy[self._fy2i[self._index([p[0] + w, p[1] , sl])]] = ([self._fy2i[fy], 0.5], ) n0, n1 = fy, self._index([p[0] + 2*w, p[1], p[-1]]) - self._hangingNodes[self._n2i[test ]] = ([self._n2i[n0], 1.0], ) - self._hangingNodes[self._n2i[self._index([p[0] + w, p[1] , sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n1], 0.5]) - self._hangingNodes[self._n2i[self._index([p[0] + 2*w, p[1] , sl])]] = ([self._n2i[n1], 1.0], ) + self._hangingN[self._n2i[test ]] = ([self._n2i[n0], 1.0], ) + self._hangingN[self._n2i[self._index([p[0] + w, p[1] , sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n1], 0.5]) + self._hangingN[self._n2i[self._index([p[0] + 2*w, p[1] , sl])]] = ([self._n2i[n1], 1.0], ) elif self.dim == 3: ex0 = fy @@ -637,34 +637,34 @@ class Tree(object): n2 = self._index([p[0] , p[1], p[2] + 2*w, p[-1]]) n3 = self._index([p[0] + 2*w, p[1], p[2] + 2*w, p[-1]]) - self._hangingFacesY[self._fy2i[test ]] = ([self._fy2i[fy], 0.25], ) - self._hangingFacesY[self._fy2i[self._index([p[0] + w, p[1], p[2] , sl])]] = ([self._fy2i[fy], 0.25], ) - self._hangingFacesY[self._fy2i[self._index([p[0] , p[1], p[2] + w, sl])]] = ([self._fy2i[fy], 0.25], ) - self._hangingFacesY[self._fy2i[self._index([p[0] + w, p[1], p[2] + w, sl])]] = ([self._fy2i[fy], 0.25], ) + self._hangingFy[self._fy2i[test ]] = ([self._fy2i[fy], 0.25], ) + self._hangingFy[self._fy2i[self._index([p[0] + w, p[1], p[2] , sl])]] = ([self._fy2i[fy], 0.25], ) + self._hangingFy[self._fy2i[self._index([p[0] , p[1], p[2] + w, sl])]] = ([self._fy2i[fy], 0.25], ) + self._hangingFy[self._fy2i[self._index([p[0] + w, p[1], p[2] + w, sl])]] = ([self._fy2i[fy], 0.25], ) - self._hangingEdgesX[self._ex2i[test ]] = ([self._ex2i[ex0], 0.5], ) - self._hangingEdgesX[self._ex2i[self._index([p[0] + w, p[1], p[2] , sl])]] = ([self._ex2i[ex0], 0.5], ) - self._hangingEdgesX[self._ex2i[self._index([p[0] , p[1], p[2] + w, sl])]] = ([self._ex2i[ex0], 0.25], [self._ex2i[ex1], 0.25]) - self._hangingEdgesX[self._ex2i[self._index([p[0] + w, p[1], p[2] + w, sl])]] = ([self._ex2i[ex0], 0.25], [self._ex2i[ex1], 0.25]) - self._hangingEdgesX[self._ex2i[self._index([p[0] , p[1], p[2] + 2*w, sl])]] = ([self._ex2i[ex1], 0.5], ) - self._hangingEdgesX[self._ex2i[self._index([p[0] + w, p[1], p[2] + 2*w, sl])]] = ([self._ex2i[ex1], 0.5], ) + self._hangingEx[self._ex2i[test ]] = ([self._ex2i[ex0], 0.5], ) + self._hangingEx[self._ex2i[self._index([p[0] + w, p[1], p[2] , sl])]] = ([self._ex2i[ex0], 0.5], ) + self._hangingEx[self._ex2i[self._index([p[0] , p[1], p[2] + w, sl])]] = ([self._ex2i[ex0], 0.25], [self._ex2i[ex1], 0.25]) + self._hangingEx[self._ex2i[self._index([p[0] + w, p[1], p[2] + w, sl])]] = ([self._ex2i[ex0], 0.25], [self._ex2i[ex1], 0.25]) + self._hangingEx[self._ex2i[self._index([p[0] , p[1], p[2] + 2*w, sl])]] = ([self._ex2i[ex1], 0.5], ) + self._hangingEx[self._ex2i[self._index([p[0] + w, p[1], p[2] + 2*w, sl])]] = ([self._ex2i[ex1], 0.5], ) - self._hangingEdgesZ[self._ez2i[test ]] = ([self._ez2i[ez0], 0.5], ) - self._hangingEdgesZ[self._ez2i[self._index([p[0] , p[1], p[2] + w, sl])]] = ([self._ez2i[ez0], 0.5], ) - self._hangingEdgesZ[self._ez2i[self._index([p[0] + w, p[1], p[2] , sl])]] = ([self._ez2i[ez0], 0.25], [self._ez2i[ez1], 0.25]) - self._hangingEdgesZ[self._ez2i[self._index([p[0] + w, p[1], p[2] + w, sl])]] = ([self._ez2i[ez0], 0.25], [self._ez2i[ez1], 0.25]) - self._hangingEdgesZ[self._ez2i[self._index([p[0] + 2*w, p[1], p[2] , sl])]] = ([self._ez2i[ez1], 0.5], ) - self._hangingEdgesZ[self._ez2i[self._index([p[0] + 2*w, p[1], p[2] + w, sl])]] = ([self._ez2i[ez1], 0.5], ) + self._hangingEz[self._ez2i[test ]] = ([self._ez2i[ez0], 0.5], ) + self._hangingEz[self._ez2i[self._index([p[0] , p[1], p[2] + w, sl])]] = ([self._ez2i[ez0], 0.5], ) + self._hangingEz[self._ez2i[self._index([p[0] + w, p[1], p[2] , sl])]] = ([self._ez2i[ez0], 0.25], [self._ez2i[ez1], 0.25]) + self._hangingEz[self._ez2i[self._index([p[0] + w, p[1], p[2] + w, sl])]] = ([self._ez2i[ez0], 0.25], [self._ez2i[ez1], 0.25]) + self._hangingEz[self._ez2i[self._index([p[0] + 2*w, p[1], p[2] , sl])]] = ([self._ez2i[ez1], 0.5], ) + self._hangingEz[self._ez2i[self._index([p[0] + 2*w, p[1], p[2] + w, sl])]] = ([self._ez2i[ez1], 0.5], ) - self._hangingNodes[ self._n2i[ test ]] = ([self._n2i[n0], 1.0], ) - self._hangingNodes[ self._n2i[ self._index([p[0] + w, p[1], p[2] , sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n1], 0.5]) - self._hangingNodes[ self._n2i[ self._index([p[0] + 2*w, p[1], p[2] , sl])]] = ([self._n2i[n1], 1.0], ) - self._hangingNodes[ self._n2i[ self._index([p[0] , p[1], p[2] + w, sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n2], 0.5]) - self._hangingNodes[ self._n2i[ self._index([p[0] + w, p[1], p[2] + w, sl])]] = ([self._n2i[n0], 0.25], [self._n2i[n1], 0.25], [self._n2i[n2], 0.25], [self._n2i[n3], 0.25]) - self._hangingNodes[ self._n2i[ self._index([p[0] + 2*w, p[1], p[2] + w, sl])]] = ([self._n2i[n1], 0.5], [self._n2i[n3], 0.5]) - self._hangingNodes[ self._n2i[ self._index([p[0] , p[1], p[2] + 2*w, sl])]] = ([self._n2i[n2], 1.0], ) - self._hangingNodes[ self._n2i[ self._index([p[0] + w, p[1], p[2] + 2*w, sl])]] = ([self._n2i[n2], 0.5], [self._n2i[n3], 0.5]) - self._hangingNodes[ self._n2i[ self._index([p[0] + 2*w, p[1], p[2] + 2*w, sl])]] = ([self._n2i[n3], 1.0], ) + self._hangingN[ self._n2i[ test ]] = ([self._n2i[n0], 1.0], ) + self._hangingN[ self._n2i[ self._index([p[0] + w, p[1], p[2] , sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n1], 0.5]) + self._hangingN[ self._n2i[ self._index([p[0] + 2*w, p[1], p[2] , sl])]] = ([self._n2i[n1], 1.0], ) + self._hangingN[ self._n2i[ self._index([p[0] , p[1], p[2] + w, sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n2], 0.5]) + self._hangingN[ self._n2i[ self._index([p[0] + w, p[1], p[2] + w, sl])]] = ([self._n2i[n0], 0.25], [self._n2i[n1], 0.25], [self._n2i[n2], 0.25], [self._n2i[n3], 0.25]) + self._hangingN[ self._n2i[ self._index([p[0] + 2*w, p[1], p[2] + w, sl])]] = ([self._n2i[n1], 0.5], [self._n2i[n3], 0.5]) + self._hangingN[ self._n2i[ self._index([p[0] , p[1], p[2] + 2*w, sl])]] = ([self._n2i[n2], 1.0], ) + self._hangingN[ self._n2i[ self._index([p[0] + w, p[1], p[2] + 2*w, sl])]] = ([self._n2i[n2], 0.5], [self._n2i[n3], 0.5]) + self._hangingN[ self._n2i[ self._index([p[0] + 2*w, p[1], p[2] + 2*w, sl])]] = ([self._n2i[n3], 1.0], ) if self.dim == 2: self.__dirtyHanging__ = False @@ -691,35 +691,34 @@ class Tree(object): n2 = self._index([p[0] , p[1] + 2*w, p[2], p[-1]]) n3 = self._index([p[0] + 2*w, p[1] + 2*w, p[2], p[-1]]) - self._hangingFacesY[self._fz2i[test ]] = ([self._fz2i[fz], 0.25], ) - self._hangingFacesY[self._fz2i[self._index([p[0] + w, p[1] , p[2], sl])]] = ([self._fz2i[fz], 0.25], ) - self._hangingFacesY[self._fz2i[self._index([p[0] , p[1] + w, p[2], sl])]] = ([self._fz2i[fz], 0.25], ) - self._hangingFacesY[self._fz2i[self._index([p[0] + w, p[1] + w, p[2], sl])]] = ([self._fz2i[fz], 0.25], ) + self._hangingFz[self._fz2i[test ]] = ([self._fz2i[fz], 0.25], ) + self._hangingFz[self._fz2i[self._index([p[0] + w, p[1] , p[2], sl])]] = ([self._fz2i[fz], 0.25], ) + self._hangingFz[self._fz2i[self._index([p[0] , p[1] + w, p[2], sl])]] = ([self._fz2i[fz], 0.25], ) + self._hangingFz[self._fz2i[self._index([p[0] + w, p[1] + w, p[2], sl])]] = ([self._fz2i[fz], 0.25], ) - self._hangingEdgesX[self._ex2i[test ]] = ([self._ex2i[ex0], 0.5], ) - self._hangingEdgesX[self._ex2i[self._index([p[0] + w, p[1] , p[2], sl])]] = ([self._ex2i[ex0], 0.5], ) - self._hangingEdgesX[self._ex2i[self._index([p[0] , p[1] + w, p[2], sl])]] = ([self._ex2i[ex0], 0.25], [self._ex2i[ex1], 0.25]) - self._hangingEdgesX[self._ex2i[self._index([p[0] + w, p[1] + w, p[2], sl])]] = ([self._ex2i[ex0], 0.25], [self._ex2i[ex1], 0.25]) - self._hangingEdgesX[self._ex2i[self._index([p[0] , p[1] + 2*w, p[2], sl])]] = ([self._ex2i[ex1], 0.5], ) - self._hangingEdgesX[self._ex2i[self._index([p[0] + w, p[1] + 2*w, p[2], sl])]] = ([self._ex2i[ex1], 0.5], ) + self._hangingEx[self._ex2i[test ]] = ([self._ex2i[ex0], 0.5], ) + self._hangingEx[self._ex2i[self._index([p[0] + w, p[1] , p[2], sl])]] = ([self._ex2i[ex0], 0.5], ) + self._hangingEx[self._ex2i[self._index([p[0] , p[1] + w, p[2], sl])]] = ([self._ex2i[ex0], 0.25], [self._ex2i[ex1], 0.25]) + self._hangingEx[self._ex2i[self._index([p[0] + w, p[1] + w, p[2], sl])]] = ([self._ex2i[ex0], 0.25], [self._ex2i[ex1], 0.25]) + self._hangingEx[self._ex2i[self._index([p[0] , p[1] + 2*w, p[2], sl])]] = ([self._ex2i[ex1], 0.5], ) + self._hangingEx[self._ex2i[self._index([p[0] + w, p[1] + 2*w, p[2], sl])]] = ([self._ex2i[ex1], 0.5], ) - self._hangingEdgesY[self._ey2i[test ]] = ([self._ey2i[ey0], 0.5], ) - self._hangingEdgesY[self._ey2i[self._index([p[0] , p[1] + w, p[2], sl])]] = ([self._ey2i[ey0], 0.5], ) - self._hangingEdgesY[self._ey2i[self._index([p[0] + w, p[1] , p[2], sl])]] = ([self._ey2i[ey0], 0.25], [self._ey2i[ey1], 0.25]) - self._hangingEdgesY[self._ey2i[self._index([p[0] + w, p[1] + w, p[2], sl])]] = ([self._ey2i[ey0], 0.25], [self._ey2i[ey1], 0.25]) - self._hangingEdgesY[self._ey2i[self._index([p[0] + 2*w, p[1] , p[2], sl])]] = ([self._ey2i[ey1], 0.5], ) - self._hangingEdgesY[self._ey2i[self._index([p[0] + 2*w, p[1] + w, p[2], sl])]] = ([self._ey2i[ey1], 0.5], ) - - self._hangingNodes[ self._n2i[ test ]] = ([self._n2i[n0], 1.0], ) - self._hangingNodes[ self._n2i[ self._index([p[0] + w, p[1] , p[2], sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n1], 0.5]) - self._hangingNodes[ self._n2i[ self._index([p[0] + 2*w, p[1] , p[2], sl])]] = ([self._n2i[n1], 1.0], ) - self._hangingNodes[ self._n2i[ self._index([p[0] , p[1] + w, p[2], sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n2], 0.5]) - self._hangingNodes[ self._n2i[ self._index([p[0] + w, p[1] + w, p[2], sl])]] = ([self._n2i[n0], 0.25], [self._n2i[n1], 0.25], [self._n2i[n2], 0.25], [self._n2i[n3], 0.25]) - self._hangingNodes[ self._n2i[ self._index([p[0] + 2*w, p[1] + w, p[2], sl])]] = ([self._n2i[n1], 0.5], [self._n2i[n3], 0.5]) - self._hangingNodes[ self._n2i[ self._index([p[0] , p[1] + 2*w, p[2], sl])]] = ([self._n2i[n2], 1.0], ) - self._hangingNodes[ self._n2i[ self._index([p[0] + w, p[1] + 2*w, p[2], sl])]] = ([self._n2i[n2], 0.5], [self._n2i[n3], 0.5]) - self._hangingNodes[ self._n2i[ self._index([p[0] + 2*w, p[1] + 2*w, p[2], sl])]] = ([self._n2i[n3], 1.0], ) + self._hangingEy[self._ey2i[test ]] = ([self._ey2i[ey0], 0.5], ) + self._hangingEy[self._ey2i[self._index([p[0] , p[1] + w, p[2], sl])]] = ([self._ey2i[ey0], 0.5], ) + self._hangingEy[self._ey2i[self._index([p[0] + w, p[1] , p[2], sl])]] = ([self._ey2i[ey0], 0.25], [self._ey2i[ey1], 0.25]) + self._hangingEy[self._ey2i[self._index([p[0] + w, p[1] + w, p[2], sl])]] = ([self._ey2i[ey0], 0.25], [self._ey2i[ey1], 0.25]) + self._hangingEy[self._ey2i[self._index([p[0] + 2*w, p[1] , p[2], sl])]] = ([self._ey2i[ey1], 0.5], ) + self._hangingEy[self._ey2i[self._index([p[0] + 2*w, p[1] + w, p[2], sl])]] = ([self._ey2i[ey1], 0.5], ) + self._hangingN[ self._n2i[ test ]] = ([self._n2i[n0], 1.0], ) + self._hangingN[ self._n2i[ self._index([p[0] + w, p[1] , p[2], sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n1], 0.5]) + self._hangingN[ self._n2i[ self._index([p[0] + 2*w, p[1] , p[2], sl])]] = ([self._n2i[n1], 1.0], ) + self._hangingN[ self._n2i[ self._index([p[0] , p[1] + w, p[2], sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n2], 0.5]) + self._hangingN[ self._n2i[ self._index([p[0] + w, p[1] + w, p[2], sl])]] = ([self._n2i[n0], 0.25], [self._n2i[n1], 0.25], [self._n2i[n2], 0.25], [self._n2i[n3], 0.25]) + self._hangingN[ self._n2i[ self._index([p[0] + 2*w, p[1] + w, p[2], sl])]] = ([self._n2i[n1], 0.5], [self._n2i[n3], 0.5]) + self._hangingN[ self._n2i[ self._index([p[0] , p[1] + 2*w, p[2], sl])]] = ([self._n2i[n2], 1.0], ) + self._hangingN[ self._n2i[ self._index([p[0] + w, p[1] + 2*w, p[2], sl])]] = ([self._n2i[n2], 0.5], [self._n2i[n3], 0.5]) + self._hangingN[ self._n2i[ self._index([p[0] + 2*w, p[1] + 2*w, p[2], sl])]] = ([self._n2i[n3], 1.0], ) self.__dirtyHanging__ = False @@ -964,12 +963,12 @@ class Tree(object): self._gridFx = np.array(facesX) self._gridFy = np.array(facesY) self._gridN = np.array(nodes) - self._hangingFacesX = hangingFacesX - self._hangingFacesY = hangingFacesY + self._hangingFx = hangingFacesX + self._hangingFy = hangingFacesY if self.dim == 3: self._gridFz = np.array(facesZ) self._nFz = self._gridFz.shape[0] - self._hangingFacesZ = hangingFacesZ + self._hangingFz = hangingFacesZ self._nC = len(self._sortedInds) self._nN = self._gridN.shape[0] @@ -1039,10 +1038,10 @@ class Tree(object): ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'r.') ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'r:') ax.plot(self.gridN[:,0], self.gridN[:,1], 'ms') - ax.plot(self.gridN[self._hangingNodes.keys(),0], self.gridN[self._hangingNodes.keys(),1], 'ms', ms=10, mfc='none', mec='m') - ax.plot(self.gridFx[self._hangingFacesX.keys(),0], self.gridFx[self._hangingFacesX.keys(),1], 'gs', ms=10, mfc='none', mec='g') + ax.plot(self.gridN[self._hangingN.keys(),0], self.gridN[self._hangingN.keys(),1], 'ms', ms=10, mfc='none', mec='m') + ax.plot(self.gridFx[self._hangingFx.keys(),0], self.gridFx[self._hangingFx.keys(),1], 'gs', ms=10, mfc='none', mec='g') ax.plot(self.gridFx[:,0], self.gridFx[:,1], 'g>') - ax.plot(self.gridFy[self._hangingFacesY.keys(),0], self.gridFy[self._hangingFacesY.keys(),1], 'gs', ms=10, mfc='none', mec='g') + ax.plot(self.gridFy[self._hangingFy.keys(),0], self.gridFy[self._hangingFy.keys(),1], 'gs', ms=10, mfc='none', mec='g') ax.plot(self.gridFy[:,0], self.gridFy[:,1], 'g^') elif self.dim == 3: ax.plot(self.gridCC[[0,-1],0], self.gridCC[[0,-1],1], 'ro', zs=self.gridCC[[0,-1],2]) @@ -1050,36 +1049,53 @@ class Tree(object): ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'r:', zs=self.gridCC[:,2]) ax.plot(self.gridN[:,0], self.gridN[:,1], 'ms', zs=self.gridN[:,2]) - ax.plot(self.gridN[self._hangingNodes.keys(),0], self.gridN[self._hangingNodes.keys(),1], 'ms', ms=10, mfc='none', mec='m', zs=self.gridN[self._hangingNodes.keys(),2]) + ax.plot(self.gridN[self._hangingN.keys(),0], self.gridN[self._hangingN.keys(),1], 'ms', ms=10, mfc='none', mec='m', zs=self.gridN[self._hangingN.keys(),2]) + for key in self._hangingN.keys(): + for hf in self._hangingN[key]: + ind = [key, hf[0]] + ax.plot(self.gridN[ind,0], self.gridN[ind,1], 'm:', zs=self.gridN[ind,2]) - ax.plot(self.gridFx[self._hangingFacesX.keys(),0], self.gridFx[self._hangingFacesX.keys(),1], 'gs', ms=10, mfc='none', mec='g', zs=self.gridFx[self._hangingFacesX.keys(),2]) ax.plot(self.gridFx[:,0], self.gridFx[:,1], 'g>', zs=self.gridFx[:,2]) + ax.plot(self.gridFx[self._hangingFx.keys(),0], self.gridFx[self._hangingFx.keys(),1], 'gs', ms=10, mfc='none', mec='g', zs=self.gridFx[self._hangingFx.keys(),2]) + for key in self._hangingFx.keys(): + for hf in self._hangingFx[key]: + ind = [key, hf[0]] + ax.plot(self.gridFx[ind,0], self.gridFx[ind,1], 'g:', zs=self.gridFx[ind,2]) - ax.plot(self.gridFy[self._hangingFacesY.keys(),0], self.gridFy[self._hangingFacesY.keys(),1], 'gs', ms=10, mfc='none', mec='g', zs=self.gridFy[self._hangingFacesY.keys(),2]) ax.plot(self.gridFy[:,0], self.gridFy[:,1], 'g^', zs=self.gridFy[:,2]) + ax.plot(self.gridFy[self._hangingFy.keys(),0], self.gridFy[self._hangingFy.keys(),1], 'gs', ms=10, mfc='none', mec='g', zs=self.gridFy[self._hangingFy.keys(),2]) + for key in self._hangingFy.keys(): + for hf in self._hangingFy[key]: + ind = [key, hf[0]] + ax.plot(self.gridFy[ind,0], self.gridFy[ind,1], 'g:', zs=self.gridFy[ind,2]) - ax.plot(self.gridFz[self._hangingFacesZ.keys(),0], self.gridFz[self._hangingFacesZ.keys(),1], 'gs', ms=10, mfc='none', mec='g', zs=self.gridFz[self._hangingFacesZ.keys(),2]) ax.plot(self.gridFz[:,0], self.gridFz[:,1], 'g^', zs=self.gridFz[:,2]) + ax.plot(self.gridFz[self._hangingFz.keys(),0], self.gridFz[self._hangingFz.keys(),1], 'gs', ms=10, mfc='none', mec='g', zs=self.gridFz[self._hangingFz.keys(),2]) + for key in self._hangingFz.keys(): + for hf in self._hangingFz[key]: + ind = [key, hf[0]] + ax.plot(self.gridFz[ind,0], self.gridFz[ind,1], 'g:', zs=self.gridFz[ind,2]) + ax.plot(self.gridEx[:,0], self.gridEx[:,1], 'k>', zs=self.gridEx[:,2]) - ax.plot(self.gridEx[self._hangingEdgesX.keys(),0], self.gridEx[self._hangingEdgesX.keys(),1], 'ks', ms=10, mfc='none', mec='k', zs=self.gridEx[self._hangingEdgesX.keys(),2]) - for key in self._hangingEdgesX.keys(): - for hf in self._hangingEdgesX[key]: + ax.plot(self.gridEx[self._hangingEx.keys(),0], self.gridEx[self._hangingEx.keys(),1], 'ks', ms=10, mfc='none', mec='k', zs=self.gridEx[self._hangingEx.keys(),2]) + for key in self._hangingEx.keys(): + for hf in self._hangingEx[key]: ind = [key, hf[0]] ax.plot(self.gridEx[ind,0], self.gridEx[ind,1], 'k:', zs=self.gridEx[ind,2]) ax.plot(self.gridEy[:,0], self.gridEy[:,1], 'k<', zs=self.gridEy[:,2]) - ax.plot(self.gridEy[self._hangingEdgesY.keys(),0], self.gridEy[self._hangingEdgesY.keys(),1], 'ks', ms=10, mfc='none', mec='k', zs=self.gridEy[self._hangingEdgesY.keys(),2]) - for key in self._hangingEdgesY.keys(): - for hf in self._hangingEdgesY[key]: + ax.plot(self.gridEy[self._hangingEy.keys(),0], self.gridEy[self._hangingEy.keys(),1], 'ks', ms=10, mfc='none', mec='k', zs=self.gridEy[self._hangingEy.keys(),2]) + for key in self._hangingEy.keys(): + for hf in self._hangingEy[key]: ind = [key, hf[0]] ax.plot(self.gridEy[ind,0], self.gridEy[ind,1], 'k:', zs=self.gridEy[ind,2]) ax.plot(self.gridEz[:,0], self.gridEz[:,1], 'k^', zs=self.gridEz[:,2]) - ax.plot(self.gridEz[self._hangingEdgesZ.keys(),0], self.gridEz[self._hangingEdgesZ.keys(),1], 'ks', ms=10, mfc='none', mec='k', zs=self.gridEz[self._hangingEdgesZ.keys(),2]) - for key in self._hangingEdgesZ.keys(): - for hf in self._hangingEdgesZ[key]: + ax.plot(self.gridEz[self._hangingEz.keys(),0], self.gridEz[self._hangingEz.keys(),1], 'ks', ms=10, mfc='none', mec='k', zs=self.gridEz[self._hangingEz.keys(),2]) + for key in self._hangingEz.keys(): + for hf in self._hangingEz[key]: ind = [key, hf[0]] ax.plot(self.gridEz[ind,0], self.gridEz[ind,1], 'k:', zs=self.gridEz[ind,2]) @@ -1110,7 +1126,7 @@ if __name__ == '__main__': # T = Tree([[(1,16)],[(1,16)]],levels=4) T.refine(lambda xc:1) # T._refineCell([4,4,2]) - T._refineCell([0,0,0,1]) + T._refineCell([4,4,4,1]) T.plotGrid(grid=False) From ac688254aca308630d7bd7d6c91ca4d3c2efb277 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Fri, 6 Nov 2015 13:37:13 -0800 Subject: [PATCH 33/83] Deflation matrix and faceDiv start --- SimPEG/Mesh/PointerTree.py | 95 ++++++++++++++++++++++++++++++++------ 1 file changed, 80 insertions(+), 15 deletions(-) diff --git a/SimPEG/Mesh/PointerTree.py b/SimPEG/Mesh/PointerTree.py index 2876ce5f..cf4f31e8 100644 --- a/SimPEG/Mesh/PointerTree.py +++ b/SimPEG/Mesh/PointerTree.py @@ -978,6 +978,25 @@ class Tree(object): # self.__dirty__ = False + + def _deflationMatrix(self, theSet, theHang, theIndex): + reducedInd = dict() # final reduced index + ii = 0 + I,J,V = [],[],[] + for fx in sorted(theSet): + if theIndex[fx] not in theHang: + reducedInd[theIndex[fx]] = ii + I += [theIndex[fx]] + J += [ii] + V += [1.0] + ii += 1 + for hfkey in theHang.keys(): + hf = theHang[hfkey] + I += [hfkey]*len(hf) + J += [_[0] for _ in hf] + V += [_[1] for _ in hf] + return sp.csr_matrix((V,(I,J)), shape=(len(theSet), len(reducedInd))) + @property def faceDiv(self): # print self._c2f @@ -989,17 +1008,46 @@ class Tree(object): offset = [0,0,self.nFx,self.nFx,self.nFx+self.nFy,self.nFx+self.nFy] for ii, ind in enumerate(self._sortedInds): - faces = self._c2f[ind] - for off, pm, face in zip(offset,PM,faces): - j = [_ + off for _ in face] - I += [ii]*len(j) - J += j - V += [pm]*len(j) - VOL = self.vol - D = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.nF)) - S = self.area - self._faceDiv = Utils.sdiag(1.0/VOL)*D*Utils.sdiag(S) + p = self._pointer(ind) + w = self._levelWidth(p[-1]) + + if self.dim == 2: + faces = [ + self._fx2i[self._index([ p[0] , p[1] , p[2]])], + self._fx2i[self._index([ p[0] + w, p[1] , p[2]])], + self._fy2i[self._index([ p[0] , p[1] , p[2]])], + self._fy2i[self._index([ p[0] , p[1] + w, p[2]])] + ] + elif self.dim == 3: + faces = [ + self._fx2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._fx2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], + self._fy2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._fy2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], + self._fz2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._fz2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])] + ] + + for off, pm, face in zip(offset,PM,faces): + I += [ii] + J += [face + off] + V += [pm] + + # total number of faces + tnF = len(self._facesX) + len(self._facesY) + (0 if self.dim == 2 else len(self._facesZ)) + + D = sp.csr_matrix((V,(I,J)), shape=(self.nC, tnF)) + Rlist = [0]*self.dim + Rlist[0] = self._deflationMatrix(self._facesX, self._hangingFx, self._fx2i) + Rlist[1] = self._deflationMatrix(self._facesY, self._hangingFy, self._fy2i) + if self.dim == 3: + Rlist[2] = self._deflationMatrix(self._facesZ, self._hangingFz, self._fz2i) + R = sp.block_diag(Rlist) + # VOL = self.vol + # S = self.area + self._faceDiv = D * R + # self._faceDiv = Utils.sdiag(1.0/VOL)*D*Utils.sdiag(S) return self._faceDiv def plotGrid(self, ax=None, showIt=False, grid=True): @@ -1122,14 +1170,31 @@ if __name__ == '__main__': else: return 0 - T = Tree([[(1,8)],[(1,8)],[(1,8)]],levels=3) - # T = Tree([[(1,16)],[(1,16)]],levels=4) + # T = Tree([[(1,8)],[(1,8)],[(1,8)]],levels=3) + T = Tree([[(1,16)],[(1,16)]],levels=4) T.refine(lambda xc:1) - # T._refineCell([4,4,2]) - T._refineCell([4,4,4,1]) + T._refineCell([0,0,1]) + T._refineCell([8,8,1]) + # T._refineCell([4,4,4,1]) + + ax = plt.subplot(211) + ax.spy(T.faceDiv) - T.plotGrid(grid=False) + + # R = deflationMatrix(T._facesX, T._hangingFx, T._fx2i) + # print R + + ax = plt.subplot(212) + # ax.spy(R) + + # ax = plt.subplot(313) + # ax.spy(T.faceDiv[:,:T.nFx] * R) + + + + T.plotGrid(ax=ax) + From 109a5f0f864fd26cefe7da14a709c19f035f3f25 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Fri, 6 Nov 2015 19:43:21 -0800 Subject: [PATCH 34/83] Simple Balancing --- SimPEG/Mesh/PointerTree.py | 704 +++++++++++++++++-------------------- 1 file changed, 325 insertions(+), 379 deletions(-) diff --git a/SimPEG/Mesh/PointerTree.py b/SimPEG/Mesh/PointerTree.py index cf4f31e8..339e3008 100644 --- a/SimPEG/Mesh/PointerTree.py +++ b/SimPEG/Mesh/PointerTree.py @@ -184,22 +184,6 @@ class Tree(object): self._numberEdges() return len(self._edgesZ) - @property - def vol(self): - self.number() - return self._vol - - @property - def area(self): - self.number() - return self._area - - @property - def edge(self): - self.number() - if self.dim == 2: - return np.r_[self._area[self.nFx:], self._area[:self.nFx]] - @property def _sortedInds(self): if getattr(self, '__sortedInds', None) is None: @@ -234,7 +218,7 @@ class Tree(object): def _structureChange(self): if self.__dirty__: return - deleteThese = ['__sortedInds', '_gridCC', '_gridFx'] + deleteThese = ['__sortedInds', '_gridCC', '_gridN', '_gridFx', '_gridFy', '_gridFz', '_gridEx', '_gridEy', '_gridEz', '_area', '_edge', '_vol'] for p in deleteThese: if hasattr(self, p): delattr(self, p) self.__dirty__ = True @@ -256,7 +240,7 @@ class Tree(object): return v in self._treeInds return self._index(v) in self._treeInds - def refine(self, function=None, recursive=True, cells=None): + def refine(self, function=None, recursive=True, cells=None, balance=True): cells = cells if cells is not None else sorted(self._treeInds) recurse = [] @@ -267,7 +251,10 @@ class Tree(object): recurse += self._refineCell(cell) if recursive and len(recurse) > 0: - self.refine(function=function, recursive=True, cells=recurse) + recurse += self.refine(function=function, recursive=True, cells=recurse, balance=balance) + + if balance: + recurse += self.balance(recursive=True) return recurse def _refineCell(self, pointer): @@ -304,6 +291,8 @@ class Tree(object): if type(ind) in [int, long]: return self._pointer(ind) if type(ind) is list: + assert len(ind) == (self.dim + 1), str(ind) +' is not valid pointer' + assert ind[-1] <= self.levels, str(ind) +' is not valid pointer' return ind if isinstance(ind, np.ndarray): return ind.tolist() @@ -316,8 +305,41 @@ class Tree(object): return self._index(pointer) raise Exception + + def _childPointers(self, pointer, direction=0, positive=True): + l = self._levelWidth(pointer[-1] + 1) + + if self.dim == 2: + + children = [ + [pointer[0] , pointer[1] , pointer[-1] + 1], + [pointer[0] + l, pointer[1] , pointer[-1] + 1], + [pointer[0] , pointer[1] + l, pointer[-1] + 1], + [pointer[0] + l, pointer[1] + l, pointer[-1] + 1] + ] + + elif self.dim == 3: + + children = [ + [pointer[0] , pointer[1] , pointer[2] , pointer[-1] + 1], + [pointer[0] + l, pointer[1] , pointer[2] , pointer[-1] + 1], + [pointer[0] , pointer[1] + l, pointer[2] , pointer[-1] + 1], + [pointer[0] + l, pointer[1] + l, pointer[2] , pointer[-1] + 1], + [pointer[0] , pointer[1] , pointer[2] + l, pointer[-1] + 1], + [pointer[0] + l, pointer[1] , pointer[2] + l, pointer[-1] + 1], + [pointer[0] , pointer[1] + l, pointer[2] + l, pointer[-1] + 1], + [pointer[0] + l, pointer[1] + l, pointer[2] + l, pointer[-1] + 1] + ] + + if direction == 0: ind = [0,2,4,6] if not positive else [1,3,5,7] + if direction == 1: ind = [0,1,4,5] if not positive else [2,3,6,7] + if direction == 2: ind = [0,1,2,3] if not positive else [4,5,6,7] + + return [children[_] for _ in ind[:(self.dim-1)*2]] + + def _parentPointer(self, pointer): - mod = self._levelWidth(pointer[-1]-1) + mod = self._levelWidth(pointer[-1] - 1) return [p - (p % mod) for p in pointer[:-1]] + [pointer[-1]-1] def _cellN(self, p): @@ -341,46 +363,62 @@ class Tree(object): inside = inside and p >= 0 and p < 2**self.levels return inside - def _getNextCell(self, ind, direction=0, positive=True): + def _getNextCell(self, ind, direction=0, positive=True, _lookUp=True): """ Returns a None, int, list, or nested list The int is the cell number. """ + if direction >= self.dim: return None pointer = self._asPointer(ind) + if pointer[-1] > self.levels: return None step = (1 if positive else -1) * self._levelWidth(pointer[-1]) nextCell = [p if ii is not direction else p + step for ii, p in enumerate(pointer)] + # raise Exception(pointer, nextCell) if not self._isInsideMesh(nextCell): return None # it might be the same size as me? if nextCell in self: return self._index(nextCell) - # it might be smaller than me? + if nextCell[-1] + 1 <= self.levels: # if I am not the smallest. - nextCell[-1] += 1 - if not positive: - nextCell[direction] -= step/2 # Get the closer one - if nextCell in self: # there is at least one - - hw = self._levelWidth(pointer[-1]) / 2 - nextCell = np.array([p if ii is not direction else p + (step/2 if positive else 0) for ii, p in enumerate(pointer)]) - - if self.dim == 2: - if direction == 0: children = [0,0,1], [0,hw,1] - if direction == 1: children = [0,0,1], [hw,0,1] - elif self.dim == 3: - if direction == 0: children = [0,0,0,1], [0,hw,0,1], [0,0,hw,1], [0,hw,hw,1] - if direction == 1: children = [0,0,0,1], [hw,0,0,1], [0,0,hw,1], [hw,0,hw,1] - if direction == 2: children = [0,0,0,1], [hw,0,0,1], [0,hw,0,1], [hw,hw,0,1] - nextCells = [] - for child in children: - nextCells.append(self._getNextCell(nextCell + child, direction=direction,positive=positive)) + children = self._childPointers(pointer, direction=direction, positive=positive) + nextCells = [self._getNextCell(child, direction=direction, positive=positive, _lookUp=False) for child in children] + if nextCells[0] is not None: return nextCells + if not _lookUp: return None + # it might be bigger than me? return self._getNextCell(self._parentPointer(pointer), direction=direction, positive=positive) + def balance(self, recursive=True): + + recurse = [] + for cell in sorted(self._treeInds): + cs = range(6) + cs[0] = self._getNextCell(cell, direction=0, positive=False) + cs[1] = self._getNextCell(cell, direction=0, positive=True) + cs[2] = self._getNextCell(cell, direction=1, positive=False) + cs[3] = self._getNextCell(cell, direction=1, positive=True) + cs[4] = self._getNextCell(cell, direction=2, positive=False) # this will be None if in 2D + cs[5] = self._getNextCell(cell, direction=2, positive=True) # this will be None if in 2D + + do = np.any([ + type(c) is list and np.any([type(_) is list for _ in c]) + for c in cs + if c is not None + ]) + # print cs, do + if do: + recurse += self._refineCell(cell) + + if recursive and len(recurse) > 0: + # print 'here' + recurse += self.balance() + return recurse + @property def gridCC(self): if getattr(self, '_gridCC', None) is None: @@ -392,43 +430,74 @@ class Tree(object): @property def gridN(self): - self._numberNodes() + self.number() return self._gridN @property def gridFx(self): - self._numberFaces() + self.number() return self._gridFx @property def gridFy(self): - self._numberFaces() + self.number() return self._gridFy @property def gridFz(self): if self.dim < 3: return None - self._numberFaces() + self.number() return self._gridFz @property def gridEx(self): if self.dim == 2: return self.gridFy - self._numberEdges() + self.number() return self._gridEx @property def gridEy(self): if self.dim == 2: return self.gridFx - self._numberEdges() + self.number() return self._gridEy @property def gridEz(self): if self.dim < 3: return None - self._numberEdges() + self.number() return self._gridEz + @property + def vol(self): + if getattr(self, '_vol', None) is None: + self._vol = np.zeros(len(self._treeInds)) + for ii, ind in enumerate(self._sortedInds): + p = self._asPointer(ind) + self._vol[ii] = np.prod(self._cellH(p)) + return self._vol + + @property + def area(self): + self.number() + if getattr(self, '_area', None) is None: + Rlist = [0]*self.dim + Rlist[0] = self._deflationMatrix(self._facesX, self._hangingFx, self._fx2i, withHanging=False) + Rlist[1] = self._deflationMatrix(self._facesY, self._hangingFy, self._fy2i, withHanging=False) + if self.dim == 3: + Rlist[2] = self._deflationMatrix(self._facesZ, self._hangingFz, self._fz2i, withHanging=False) + R = sp.block_diag(Rlist) + self._area = R.T * ( + np.r_[self._areaFxFull, self._areaFyFull] if self.dim == 2 else + np.r_[self._areaFxFull, self._areaFyFull, self._areaFzFull] + ) + return self._area + + @property + def edge(self): + self.number() + if self.dim == 2: + return np.r_[self._area[self.nFx:], self._area[:self.nFx]] + def _onSameLevel(self, i0, i1): p0 = self._asPointer(i0) p1 = self._asPointer(i1) @@ -460,7 +529,7 @@ class Tree(object): self._n2i = dict() for ii, n in enumerate(sorted(self._nodes)): self._n2i[n] = ii - gridN.append( self._cellN( self._pointer(n)[:-1] ) ) + gridN.append( self._cellN( self._pointer(n) ) ) self._gridN = np.array(gridN) self.__dirtyNodes__ = False @@ -491,6 +560,7 @@ class Tree(object): self._facesZ.add(self._index([p[0] , p[1] , p[2] + w, p[3]])) gridFx = [] + areaFx = [] self._fx2i = dict() for ii, fx in enumerate(sorted(self._facesX)): self._fx2i[fx] = ii @@ -498,11 +568,15 @@ class Tree(object): n, h = self._cellN(p), self._cellH(p) if self.dim == 2: gridFx.append( [n[0], n[1] + h[1]/2.0] ) + areaFx.append( h[1] ) elif self.dim == 3: gridFx.append( [n[0], n[1] + h[1]/2.0, n[2] + h[2]/2.0] ) + areaFx.append( h[1]*h[2] ) self._gridFx = np.array(gridFx) + self._areaFxFull = np.array(areaFx) gridFy = [] + areaFy = [] self._fy2i = dict() for ii, fy in enumerate(sorted(self._facesY)): self._fy2i[fy] = ii @@ -510,25 +584,85 @@ class Tree(object): n, h = self._cellN(p), self._cellH(p) if self.dim == 2: gridFy.append( [n[0] + h[0]/2.0, n[1]] ) + areaFy.append( h[0] ) elif self.dim == 3: gridFy.append( [n[0] + h[0]/2.0, n[1], n[2] + h[2]/2.0] ) + areaFy.append( h[0]*h[2] ) self._gridFy = np.array(gridFy) + self._areaFyFull = np.array(areaFy) if self.dim == 2: self.__dirtyFaces__ = False return gridFz = [] + areaFz = [] self._fz2i = dict() for ii, fz in enumerate(sorted(self._facesZ)): self._fz2i[fz] = ii p = self._pointer(fz) n, h = self._cellN(p), self._cellH(p) gridFz.append( [n[0] + h[0]/2.0, n[1] + h[1]/2.0, n[2]] ) + areaFz.append(h[0]*h[1]) self._gridFz = np.array(gridFz) + self._areaFzFull = np.array(areaFz) self.__dirtyFaces__ = False + def _numberEdges(self, force=False): + if self.dim == 2: return + if not self.__dirtyEdges__ and not force: return + + self._edgesX = set() + self._edgesY = set() + self._edgesZ = set() + + for ind in self._treeInds: + p = self._asPointer(ind) + w = self._levelWidth(p[-1]) + self._edgesX.add(self._index([p[0] , p[1] , p[2] , p[3]])) + self._edgesX.add(self._index([p[0] , p[1] + w, p[2] , p[3]])) + self._edgesX.add(self._index([p[0] , p[1] , p[2] + w, p[3]])) + self._edgesX.add(self._index([p[0] , p[1] + w, p[2] + w, p[3]])) + + self._edgesY.add(self._index([p[0] , p[1] , p[2] , p[3]])) + self._edgesY.add(self._index([p[0] + w, p[1] , p[2] , p[3]])) + self._edgesY.add(self._index([p[0] , p[1] , p[2] + w, p[3]])) + self._edgesY.add(self._index([p[0] + w, p[1] , p[2] + w, p[3]])) + + self._edgesZ.add(self._index([p[0] , p[1] , p[2] , p[3]])) + self._edgesZ.add(self._index([p[0] + w, p[1] , p[2] , p[3]])) + self._edgesZ.add(self._index([p[0] , p[1] + w, p[2] , p[3]])) + self._edgesZ.add(self._index([p[0] + w, p[1] + w, p[2] , p[3]])) + + gridEx = [] + self._ex2i = dict() + for ii, ex in enumerate(sorted(self._edgesX)): + self._ex2i[ex] = ii + p = self._pointer(ex) + n, h = self._cellN(p), self._cellH(p) + gridEx.append( [n[0] + h[0]/2.0, n[1], n[2]] ) + self._gridEx = np.array(gridEx) + + gridEy = [] + self._ey2i = dict() + for ii, ey in enumerate(sorted(self._edgesY)): + self._ey2i[ey] = ii + p = self._pointer(ey) + n, h = self._cellN(p), self._cellH(p) + gridEy.append( [n[0], n[1] + h[1]/2.0, n[2]] ) + self._gridEy = np.array(gridEy) + + gridEz = [] + self._ez2i = dict() + for ii, ez in enumerate(sorted(self._edgesZ)): + self._ez2i[ez] = ii + p = self._pointer(ez) + n, h = self._cellN(p), self._cellH(p) + gridEz.append( [n[0], n[1], n[2] + h[2]/2.0] ) + self._gridEz = np.array(gridEz) + + self.__dirtyEdges__ = False def _hanging(self, force=False): if not self.__dirtyHanging__ and not force: return @@ -722,264 +856,12 @@ class Tree(object): self.__dirtyHanging__ = False - - def _numberEdges(self, force=False): - if self.dim == 2: return - if not self.__dirtyEdges__ and not force: return - - self._edgesX = set() - self._edgesY = set() - self._edgesZ = set() - - for ind in self._treeInds: - p = self._asPointer(ind) - w = self._levelWidth(p[-1]) - self._edgesX.add(self._index([p[0] , p[1] , p[2] , p[3]])) - self._edgesX.add(self._index([p[0] , p[1] + w, p[2] , p[3]])) - self._edgesX.add(self._index([p[0] , p[1] , p[2] + w, p[3]])) - self._edgesX.add(self._index([p[0] , p[1] + w, p[2] + w, p[3]])) - - self._edgesY.add(self._index([p[0] , p[1] , p[2] , p[3]])) - self._edgesY.add(self._index([p[0] + w, p[1] , p[2] , p[3]])) - self._edgesY.add(self._index([p[0] , p[1] , p[2] + w, p[3]])) - self._edgesY.add(self._index([p[0] + w, p[1] , p[2] + w, p[3]])) - - self._edgesZ.add(self._index([p[0] , p[1] , p[2] , p[3]])) - self._edgesZ.add(self._index([p[0] + w, p[1] , p[2] , p[3]])) - self._edgesZ.add(self._index([p[0] , p[1] + w, p[2] , p[3]])) - self._edgesZ.add(self._index([p[0] + w, p[1] + w, p[2] , p[3]])) - - gridEx = [] - self._ex2i = dict() - for ii, ex in enumerate(sorted(self._edgesX)): - self._ex2i[ex] = ii - p = self._pointer(ex) - n, h = self._cellN(p), self._cellH(p) - gridEx.append( [n[0] + h[0]/2.0, n[1], n[2]] ) - self._gridEx = np.array(gridEx) - - gridEy = [] - self._ey2i = dict() - for ii, ey in enumerate(sorted(self._edgesY)): - self._ey2i[ey] = ii - p = self._pointer(ey) - n, h = self._cellN(p), self._cellH(p) - gridEy.append( [n[0], n[1] + h[1]/2.0, n[2]] ) - self._gridEy = np.array(gridEy) - - gridEz = [] - self._ez2i = dict() - for ii, ez in enumerate(sorted(self._edgesZ)): - self._ez2i[ez] = ii - p = self._pointer(ez) - n, h = self._cellN(p), self._cellH(p) - gridEz.append( [n[0], n[1], n[2] + h[2]/2.0] ) - self._gridEz = np.array(gridEz) - - self.__dirtyEdges__ = False - - def number(self, force=False): if not self.__dirty__ and not force: return self._hanging() return - facesX, facesY, facesZ = [], [], [] - areaX, areaY, areaZ = [], [], [] - hangingFacesX, hangingFacesY, hangingFacesZ = [], [], [] - hangingNodes = [] - faceXCount, faceYCount, faceZCount = -1, -1, -1 - nodeCount = -1 - fXm,fXp,fYm,fYp,fZm,fZp = range(6) - vol, nodes = [], [] - - def addXFace(count, p, positive=True): - n = self._cellN(p) - w = self._cellH(p) - areaX.append(w[1] if self.dim == 2 else w[1]*w[2]) - if self.dim == 2: - facesX.append([n[0] + (w[0] if positive else 0), n[1] + w[1]/2.0]) - elif self.dim == 3: - facesX.append([n[0] + (w[0] if positive else 0), n[1] + w[1]/2.0, n[2] + w[2]/2.0]) - return count + 1 - def addYFace(count, p, positive=True): - n = self._cellN(p) - w = self._cellH(p) - areaY.append(w[0] if self.dim == 2 else w[0]*w[2]) - if self.dim == 2: - facesY.append([n[0] + w[0]/2.0, n[1] + (w[1] if positive else 0)]) - elif self.dim == 3: - facesY.append([n[0] + w[0]/2.0, n[1] + (w[1] if positive else 0), n[2] + w[2]/2.0]) - return count + 1 - def addZFace(count, p, positive=True): - n = self._cellN(p) - w = self._cellH(p) - areaZ.append(w[0]*w[1]) - facesZ.append([n[0] + w[0]/2.0, n[1] + w[1]/2.0, n[2] + (w[2] if positive else 0)]) - return count + 1 - - def addNode(count, p, loc=[0,0,0]): - """loc=[0,0]""" - n = self._cellN(p) - w = self._cellH(p) - if self.dim == 2: - nodes.append([n[0] + w[0]*loc[0], n[1] + w[1]*loc[1]]) - elif self.dim == 3: - nodes.append([n[0] + w[0]*loc[0], n[1] + w[1]*loc[1], n[2] + w[2]*loc[2]]) - return count + 1 - # c2cn = dict() - c2f = dict() - def gc2f(ind): - if ind in c2f: return c2f[ind] - c2f_ind = [list() for _ in xrange(2*self.dim)] - c2f[ind] = c2f_ind - return c2f_ind - c2n = dict() - def gc2n(ind): - if ind in c2n: return c2n[ind] - c2n_ind = [list() for _ in xrange(2**self.dim)] - c2n[ind] = c2n_ind - return c2n_ind - - def processCellFace(ind, faceCount, addFace, hangingFaces, DIR=0): - - fM,fP=(0,1) if DIR == 0 else (2,3) if DIR == 1 else (4,5) - p = self._asPointer(ind) - if self._getNextCell(p, direction=DIR, positive=False) is None: - faceCount = addFace(faceCount, p, positive=False) - gc2f(ind)[fM] += [faceCount] - - nextCell = self._getNextCell(p, direction=DIR) - - # Add the next Xface - if nextCell is None: - # on the boundary - faceCount = addFace(faceCount, p) - gc2f(ind)[fP] += [faceCount] - elif type(nextCell) in [int, long] and self._onSameLevel(p,nextCell): - # same sized cell - faceCount = addFace(faceCount, p) - gc2f(ind)[fP] += [faceCount] - gc2f(nextCell)[fM] += [faceCount] - elif type(nextCell) in [int, long] and not self._onSameLevel(p,nextCell): - # the cell is bigger than me - faceCount = addFace(faceCount, p) - gc2f(ind)[fP] += [faceCount] - gc2f(nextCell)[fM] += [faceCount] - hangingFaces.append(faceCount) - elif type(nextCell) is list: - # the cell is smaller than me - - # TODO: ensure that things are balanced. - p0 = self._pointer(nextCell[0]) - p1 = self._pointer(nextCell[1]) - - faceCount = addFace(faceCount, p0, positive=False) - gc2f(nextCell[0])[fM] += [faceCount] - faceCount = addFace(faceCount, p1, positive=False) - gc2f(nextCell[1])[fM] += [faceCount] - - gc2f(ind)[fP] += [faceCount-1,faceCount] - - hangingFaces += [faceCount-1, faceCount] - - return faceCount - - - def processCellNode(ind, nodeCount): - - MMM, PMM, MPM, PPM, MMP, PMP, MPP, PPP = range(8) - p = self._asPointer(ind) - - xM = self._getNextCell(p, direction=0, positive=False) - yM = self._getNextCell(p, direction=1, positive=False) - zM = None if self.dim == 2 else self._getNextCell(p, direction=2, positive=False) - - xP = self._getNextCell(p, direction=0, positive=True) - yP = self._getNextCell(p, direction=1, positive=True) - zP = None if self.dim == 2 else self._getNextCell(p, direction=2, positive=True) - - if xM is None and yM is None and zM is None: - nodeCount = addNode(nodeCount, p, loc=[0,0,0]) - gc2n(ind)[MMM] += [nodeCount] - if yM is None: - nodeCount = addNode(nodeCount, p, loc=[1,0,0]) - gc2n(ind)[PMM] += [nodeCount] - if xM is None: - nodeCount = addNode(nodeCount, p, loc=[0,1,0]) - gc2n(ind)[MPM] += [nodeCount] - - # Add the next Xface - if nextCell is None: - # on the boundary - pass - # nodeCount = addFace(nodeCount, p) - # gc2f(ind)[fP] += [nodeCount] - elif type(nextCell) in [int, long] and self._onSameLevel(p,nextCell): - # same sized cell - pass - # nodeCount = addFace(nodeCount, p) - # gc2f(ind)[fP] += [nodeCount] - # gc2f(nextCell)[fM] += [nodeCount] - elif type(nextCell) in [int, long] and not self._onSameLevel(p,nextCell): - # the cell is bigger than me - pass - # nodeCount = addFace(nodeCount, p) - # gc2f(ind)[fP] += [nodeCount] - # gc2f(nextCell)[fM] += [nodeCount] - # hangingFaces.append(nodeCount) - elif type(nextCell) is list: - # the cell is smaller than me - pass - # TODO: ensure that things are balanced. - # p0 = self._pointer(nextCell[0]) - # p1 = self._pointer(nextCell[1]) - - # nodeCount = addFace(nodeCount, p0, positive=False) - # gc2f(nextCell[0])[fM] += [nodeCount] - # nodeCount = addFace(nodeCount, p1, positive=False) - # gc2f(nextCell[1])[fM] += [nodeCount] - - # gc2f(ind)[fP] += [nodeCount-1,nodeCount] - - # hangingFaces += [nodeCount-1, nodeCount] - - return nodeCount - - for ii, ind in enumerate(self._sortedInds): - # c2cn[ind] = ii - vol.append(np.prod(self._cellH(ind))) - - # nodeCount = processCellNode(ind, nodeCount) - - faceXCount = processCellFace(ind, faceXCount, addXFace, hangingFacesX, DIR=0) - faceYCount = processCellFace(ind, faceYCount, addYFace, hangingFacesY, DIR=1) - if self.dim == 3: - faceZCount = processCellFace(ind, faceZCount, addZFace, hangingFacesZ, DIR=2) - - self._c2f = c2f - self._area = np.array(areaX + areaY + (areaZ if self.dim == 3 else [])) - self._vol = np.array(vol) - self._gridFx = np.array(facesX) - self._gridFy = np.array(facesY) - self._gridN = np.array(nodes) - self._hangingFx = hangingFacesX - self._hangingFy = hangingFacesY - if self.dim == 3: - self._gridFz = np.array(facesZ) - self._nFz = self._gridFz.shape[0] - self._hangingFz = hangingFacesZ - - self._nC = len(self._sortedInds) - self._nN = self._gridN.shape[0] - self._nFx = self._gridFx.shape[0] - self._nFy = self._gridFy.shape[0] - self._nF = self._nFx + self._nFy + (self._nFz if self.dim == 3 else 0) - - # self.__dirty__ = False - - - def _deflationMatrix(self, theSet, theHang, theIndex): + def _deflationMatrix(self, theSet, theHang, theIndex, withHanging=True): reducedInd = dict() # final reduced index ii = 0 I,J,V = [],[],[] @@ -990,16 +872,16 @@ class Tree(object): J += [ii] V += [1.0] ii += 1 - for hfkey in theHang.keys(): - hf = theHang[hfkey] - I += [hfkey]*len(hf) - J += [_[0] for _ in hf] - V += [_[1] for _ in hf] + if withHanging: + for hfkey in theHang.keys(): + hf = theHang[hfkey] + I += [hfkey]*len(hf) + J += [reducedInd[_[0]] for _ in hf] + V += [_[1] for _ in hf] return sp.csr_matrix((V,(I,J)), shape=(len(theSet), len(reducedInd))) @property def faceDiv(self): - # print self._c2f if getattr(self, '_faceDiv', None) is None: self.number() # TODO: Preallocate! @@ -1044,13 +926,40 @@ class Tree(object): if self.dim == 3: Rlist[2] = self._deflationMatrix(self._facesZ, self._hangingFz, self._fz2i) R = sp.block_diag(Rlist) - # VOL = self.vol - # S = self.area - self._faceDiv = D * R - # self._faceDiv = Utils.sdiag(1.0/VOL)*D*Utils.sdiag(S) + VOL = self.vol + S = self.area + self._faceDiv = Utils.sdiag(1.0/VOL)*D*R*Utils.sdiag(S) return self._faceDiv - def plotGrid(self, ax=None, showIt=False, grid=True): + @property + def edgeCurl(self): + """Construct the 3D curl operator.""" + assert self.dim > 2, "Edge Curl only programed for 3D." + + if getattr(self, '_edgeCurl', None) is None: + self.number() + # TODO: Preallocate! + I, J, V = [], [], [] + for face in self.faces: + for ii, edge in enumerate([face.edge0, face.edge1, face.edge2, face.edge3]): + j = edge.index + I += [face.num]*len(j) + J += j + isNeg = [True, False, True, False] + V += [-1 if isNeg[ii] else 1]*len(j) + C = sp.csr_matrix((V,(I,J)), shape=(self.nF, self.nE)) + S = self.area + L = self.edge + self._edgeCurl = Utils.sdiag(1/S)*C*Utils.sdiag(L) + return self._edgeCurl + + + def plotGrid(self, ax=None, showIt=False, + grid=True, + cells=True, cellLine=False, + nodes=False, + facesX=False, facesY=False, facesZ=False, + edgesX=False, edgesY=False, edgesZ=False): self.number() @@ -1082,70 +991,83 @@ class Tree(object): ax.plot(x,y, 'b-', zs=z) if self.dim == 2: - ax.plot(self.gridCC[[0,-1],0], self.gridCC[[0,-1],1], 'ro') - ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'r.') - ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'r:') - ax.plot(self.gridN[:,0], self.gridN[:,1], 'ms') - ax.plot(self.gridN[self._hangingN.keys(),0], self.gridN[self._hangingN.keys(),1], 'ms', ms=10, mfc='none', mec='m') - ax.plot(self.gridFx[self._hangingFx.keys(),0], self.gridFx[self._hangingFx.keys(),1], 'gs', ms=10, mfc='none', mec='g') - ax.plot(self.gridFx[:,0], self.gridFx[:,1], 'g>') - ax.plot(self.gridFy[self._hangingFy.keys(),0], self.gridFy[self._hangingFy.keys(),1], 'gs', ms=10, mfc='none', mec='g') - ax.plot(self.gridFy[:,0], self.gridFy[:,1], 'g^') + if cells: + ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'r.') + if cellLine: + ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'r:') + ax.plot(self.gridCC[[0,-1],0], self.gridCC[[0,-1],1], 'ro') + if nodes: + ax.plot(self.gridN[:,0], self.gridN[:,1], 'ms') + ax.plot(self.gridN[self._hangingN.keys(),0], self.gridN[self._hangingN.keys(),1], 'ms', ms=10, mfc='none', mec='m') + if facesX: + ax.plot(self.gridFx[self._hangingFx.keys(),0], self.gridFx[self._hangingFx.keys(),1], 'gs', ms=10, mfc='none', mec='g') + ax.plot(self.gridFx[:,0], self.gridFx[:,1], 'g>') + if facesY: + ax.plot(self.gridFy[self._hangingFy.keys(),0], self.gridFy[self._hangingFy.keys(),1], 'gs', ms=10, mfc='none', mec='g') + ax.plot(self.gridFy[:,0], self.gridFy[:,1], 'g^') elif self.dim == 3: - ax.plot(self.gridCC[[0,-1],0], self.gridCC[[0,-1],1], 'ro', zs=self.gridCC[[0,-1],2]) - ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'r.', zs=self.gridCC[:,2]) - ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'r:', zs=self.gridCC[:,2]) + if cells: + ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'r.', zs=self.gridCC[:,2]) + if cellLine: + ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'r:', zs=self.gridCC[:,2]) + ax.plot(self.gridCC[[0,-1],0], self.gridCC[[0,-1],1], 'ro', zs=self.gridCC[[0,-1],2]) - ax.plot(self.gridN[:,0], self.gridN[:,1], 'ms', zs=self.gridN[:,2]) - ax.plot(self.gridN[self._hangingN.keys(),0], self.gridN[self._hangingN.keys(),1], 'ms', ms=10, mfc='none', mec='m', zs=self.gridN[self._hangingN.keys(),2]) - for key in self._hangingN.keys(): - for hf in self._hangingN[key]: - ind = [key, hf[0]] - ax.plot(self.gridN[ind,0], self.gridN[ind,1], 'm:', zs=self.gridN[ind,2]) + if nodes: + ax.plot(self.gridN[:,0], self.gridN[:,1], 'ms', zs=self.gridN[:,2]) + ax.plot(self.gridN[self._hangingN.keys(),0], self.gridN[self._hangingN.keys(),1], 'ms', ms=10, mfc='none', mec='m', zs=self.gridN[self._hangingN.keys(),2]) + for key in self._hangingN.keys(): + for hf in self._hangingN[key]: + ind = [key, hf[0]] + ax.plot(self.gridN[ind,0], self.gridN[ind,1], 'm:', zs=self.gridN[ind,2]) - ax.plot(self.gridFx[:,0], self.gridFx[:,1], 'g>', zs=self.gridFx[:,2]) - ax.plot(self.gridFx[self._hangingFx.keys(),0], self.gridFx[self._hangingFx.keys(),1], 'gs', ms=10, mfc='none', mec='g', zs=self.gridFx[self._hangingFx.keys(),2]) - for key in self._hangingFx.keys(): - for hf in self._hangingFx[key]: - ind = [key, hf[0]] - ax.plot(self.gridFx[ind,0], self.gridFx[ind,1], 'g:', zs=self.gridFx[ind,2]) + if facesX: + ax.plot(self.gridFx[:,0], self.gridFx[:,1], 'g>', zs=self.gridFx[:,2]) + ax.plot(self.gridFx[self._hangingFx.keys(),0], self.gridFx[self._hangingFx.keys(),1], 'gs', ms=10, mfc='none', mec='g', zs=self.gridFx[self._hangingFx.keys(),2]) + for key in self._hangingFx.keys(): + for hf in self._hangingFx[key]: + ind = [key, hf[0]] + ax.plot(self.gridFx[ind,0], self.gridFx[ind,1], 'g:', zs=self.gridFx[ind,2]) - ax.plot(self.gridFy[:,0], self.gridFy[:,1], 'g^', zs=self.gridFy[:,2]) - ax.plot(self.gridFy[self._hangingFy.keys(),0], self.gridFy[self._hangingFy.keys(),1], 'gs', ms=10, mfc='none', mec='g', zs=self.gridFy[self._hangingFy.keys(),2]) - for key in self._hangingFy.keys(): - for hf in self._hangingFy[key]: - ind = [key, hf[0]] - ax.plot(self.gridFy[ind,0], self.gridFy[ind,1], 'g:', zs=self.gridFy[ind,2]) + if facesY: + ax.plot(self.gridFy[:,0], self.gridFy[:,1], 'g^', zs=self.gridFy[:,2]) + ax.plot(self.gridFy[self._hangingFy.keys(),0], self.gridFy[self._hangingFy.keys(),1], 'gs', ms=10, mfc='none', mec='g', zs=self.gridFy[self._hangingFy.keys(),2]) + for key in self._hangingFy.keys(): + for hf in self._hangingFy[key]: + ind = [key, hf[0]] + ax.plot(self.gridFy[ind,0], self.gridFy[ind,1], 'g:', zs=self.gridFy[ind,2]) - ax.plot(self.gridFz[:,0], self.gridFz[:,1], 'g^', zs=self.gridFz[:,2]) - ax.plot(self.gridFz[self._hangingFz.keys(),0], self.gridFz[self._hangingFz.keys(),1], 'gs', ms=10, mfc='none', mec='g', zs=self.gridFz[self._hangingFz.keys(),2]) - for key in self._hangingFz.keys(): - for hf in self._hangingFz[key]: - ind = [key, hf[0]] - ax.plot(self.gridFz[ind,0], self.gridFz[ind,1], 'g:', zs=self.gridFz[ind,2]) + if facesZ: + ax.plot(self.gridFz[:,0], self.gridFz[:,1], 'g^', zs=self.gridFz[:,2]) + ax.plot(self.gridFz[self._hangingFz.keys(),0], self.gridFz[self._hangingFz.keys(),1], 'gs', ms=10, mfc='none', mec='g', zs=self.gridFz[self._hangingFz.keys(),2]) + for key in self._hangingFz.keys(): + for hf in self._hangingFz[key]: + ind = [key, hf[0]] + ax.plot(self.gridFz[ind,0], self.gridFz[ind,1], 'g:', zs=self.gridFz[ind,2]) + + if edgesX: + ax.plot(self.gridEx[:,0], self.gridEx[:,1], 'k>', zs=self.gridEx[:,2]) + ax.plot(self.gridEx[self._hangingEx.keys(),0], self.gridEx[self._hangingEx.keys(),1], 'ks', ms=10, mfc='none', mec='k', zs=self.gridEx[self._hangingEx.keys(),2]) + for key in self._hangingEx.keys(): + for hf in self._hangingEx[key]: + ind = [key, hf[0]] + ax.plot(self.gridEx[ind,0], self.gridEx[ind,1], 'k:', zs=self.gridEx[ind,2]) - ax.plot(self.gridEx[:,0], self.gridEx[:,1], 'k>', zs=self.gridEx[:,2]) - ax.plot(self.gridEx[self._hangingEx.keys(),0], self.gridEx[self._hangingEx.keys(),1], 'ks', ms=10, mfc='none', mec='k', zs=self.gridEx[self._hangingEx.keys(),2]) - for key in self._hangingEx.keys(): - for hf in self._hangingEx[key]: - ind = [key, hf[0]] - ax.plot(self.gridEx[ind,0], self.gridEx[ind,1], 'k:', zs=self.gridEx[ind,2]) + if edgesY: + ax.plot(self.gridEy[:,0], self.gridEy[:,1], 'k<', zs=self.gridEy[:,2]) + ax.plot(self.gridEy[self._hangingEy.keys(),0], self.gridEy[self._hangingEy.keys(),1], 'ks', ms=10, mfc='none', mec='k', zs=self.gridEy[self._hangingEy.keys(),2]) + for key in self._hangingEy.keys(): + for hf in self._hangingEy[key]: + ind = [key, hf[0]] + ax.plot(self.gridEy[ind,0], self.gridEy[ind,1], 'k:', zs=self.gridEy[ind,2]) - - ax.plot(self.gridEy[:,0], self.gridEy[:,1], 'k<', zs=self.gridEy[:,2]) - ax.plot(self.gridEy[self._hangingEy.keys(),0], self.gridEy[self._hangingEy.keys(),1], 'ks', ms=10, mfc='none', mec='k', zs=self.gridEy[self._hangingEy.keys(),2]) - for key in self._hangingEy.keys(): - for hf in self._hangingEy[key]: - ind = [key, hf[0]] - ax.plot(self.gridEy[ind,0], self.gridEy[ind,1], 'k:', zs=self.gridEy[ind,2]) - - ax.plot(self.gridEz[:,0], self.gridEz[:,1], 'k^', zs=self.gridEz[:,2]) - ax.plot(self.gridEz[self._hangingEz.keys(),0], self.gridEz[self._hangingEz.keys(),1], 'ks', ms=10, mfc='none', mec='k', zs=self.gridEz[self._hangingEz.keys(),2]) - for key in self._hangingEz.keys(): - for hf in self._hangingEz[key]: - ind = [key, hf[0]] - ax.plot(self.gridEz[ind,0], self.gridEz[ind,1], 'k:', zs=self.gridEz[ind,2]) + if edgesZ: + ax.plot(self.gridEz[:,0], self.gridEz[:,1], 'k^', zs=self.gridEz[:,2]) + ax.plot(self.gridEz[self._hangingEz.keys(),0], self.gridEz[self._hangingEz.keys(),1], 'ks', ms=10, mfc='none', mec='k', zs=self.gridEz[self._hangingEz.keys(),2]) + for key in self._hangingEz.keys(): + for hf in self._hangingEz[key]: + ind = [key, hf[0]] + ax.plot(self.gridEz[ind,0], self.gridEz[ind,1], 'k:', zs=self.gridEz[ind,2]) ax.axis('equal') @@ -1157,24 +1079,30 @@ if __name__ == '__main__': def function(xc): - r = xc - np.r_[0.5,0.5] + r = xc - np.r_[0.5*128,0.5*128] dist = np.sqrt(r.dot(r)) # if dist < 0.05: # return 5 - if dist < 0.1: - return 4 - if dist < 0.3: + if dist < 0.1*128: + return 5 + if dist < 0.3*128: return 3 - if dist < 1.0: - return 2 + # if dist < 1.0*128: + # return 2 else: return 0 # T = Tree([[(1,8)],[(1,8)],[(1,8)]],levels=3) - T = Tree([[(1,16)],[(1,16)]],levels=4) - T.refine(lambda xc:1) - T._refineCell([0,0,1]) - T._refineCell([8,8,1]) + # T = Tree([[(1,16)],[(1,16)]],levels=4) + T = Tree([[(1,128)],[(1,128)]],levels=7) + T.refine(lambda xc:2, balance=False) + T.refine(function) + # T._refineCell([8,0,1]) + # T._refineCell([8,0,2]) + # T._refineCell([12,0,2]) + # T._refineCell([8,4,2]) + # T._refineCell([6,0,3]) + # T._refineCell([8,8,1]) # T._refineCell([4,4,4,1]) ax = plt.subplot(211) @@ -1185,7 +1113,7 @@ if __name__ == '__main__': # R = deflationMatrix(T._facesX, T._hangingFx, T._fx2i) # print R - ax = plt.subplot(212) + ax = plt.subplot(212)#, projection='3d') # ax.spy(R) # ax = plt.subplot(313) @@ -1195,6 +1123,24 @@ if __name__ == '__main__': T.plotGrid(ax=ax) + # cx = T._getNextCell([0,0,1],direction=0,positive=True) + # print cx + # # print [T._asPointer(_) for _ in cx] + # cx = T._getNextCell([8,0,3],direction=0,positive=False) + # print T._asPointer(cx) + # cx = T._getNextCell([8,8,1],direction=1,positive=False) + # print cx, #[T._asPointer(_) for _ in cx] + # cm = T._getNextCell([64,80,4],direction=0,positive=False) + # cy = T._getNextCell([64,80,4],direction=1,positive=True) + # cp = T._getNextCell([64,80,4],direction=1,positive=False) + + # ax.plot( T._cellN([4,0,1])[0],T._cellN([4,0,1])[1], 'yd') + # ax.plot( T._cellN(cx)[0],T._cellN(cx)[1], 'ys') + # ax.plot( T._cellN(cm)[0],T._cellN(cm)[1], 'ys') + # ax.plot( T._cellN(cy)[0],T._cellN(cy)[1], 'ys') + # ax.plot( T._cellN(cp[0])[0],T._cellN(cp[0])[1], 'ys') + # ax.plot( T._cellN(cp[1])[0],T._cellN(cp[1])[1], 'ys') + From e8ae516030f3db95bbad88e697d271b76bb8e77a Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Sat, 7 Nov 2015 16:47:19 -0800 Subject: [PATCH 35/83] Speed improvements, cython, balancing. --- SimPEG/Mesh/PointerTree.py | 158 ++++++++++++++++++------------------- SimPEG/Mesh/TreeUtils.pyx | 85 ++++++++++++++++++++ 2 files changed, 160 insertions(+), 83 deletions(-) create mode 100644 SimPEG/Mesh/TreeUtils.pyx diff --git a/SimPEG/Mesh/PointerTree.py b/SimPEG/Mesh/PointerTree.py index 339e3008..1db06c1a 100644 --- a/SimPEG/Mesh/PointerTree.py +++ b/SimPEG/Mesh/PointerTree.py @@ -1,51 +1,10 @@ from SimPEG import np, sp, Utils, Solver import matplotlib.pyplot as plt import matplotlib +import TreeUtils +import time -class ZCurve(object): - """ - The Z-order curve is generated by interleaving the bits of an offset. - - See: - - https://github.com/cortesi/scurve - Aldo Cortesi - - """ - def __init__(self, dimension, bits): - """ - dimension: Number of dimensions - bits: The number of bits per co-ordinate. Total number of points is - 2**(bits*dimension). - """ - self.dimension, self.bits = dimension, bits - - def bitrange(self, x, width, start, end): - """ - Extract a bit range as an integer. - (start, end) is inclusive lower bound, exclusive upper bound. - """ - return x >> (width-end) & ((2**(end-start))-1) - - def index(self, p): - p.reverse() - idx = 0 - iwidth = self.bits * self.dimension - for i in range(iwidth): - bitoff = self.bits-(i/self.dimension)-1 - poff = self.dimension-(i%self.dimension)-1 - b = self.bitrange(p[poff], self.bits, bitoff, bitoff+1) << i - idx |= b - return idx - - def point(self, idx): - p = [0]*self.dimension - iwidth = self.bits * self.dimension - for i in range(iwidth): - b = self.bitrange(idx, iwidth, i, i+1) << (iwidth-i-1)/self.dimension - p[i%self.dimension] |= b - p.reverse() - return p +MAX_BITS = 20 def SortGrid(grid, offset=0): """ @@ -112,7 +71,6 @@ class Tree(object): self.__dirty__ = True #: The numbering is dirty! - self._z = ZCurve(self.dim, 20) self._treeInds = set() self._treeInds.add(0) @@ -216,8 +174,6 @@ class Tree(object): raise Exception() def _structureChange(self): - if self.__dirty__: return - deleteThese = ['__sortedInds', '_gridCC', '_gridN', '_gridFx', '_gridFy', '_gridFz', '_gridEx', '_gridEy', '_gridEz', '_area', '_edge', '_vol'] for p in deleteThese: if hasattr(self, p): delattr(self, p) @@ -226,39 +182,42 @@ class Tree(object): def _index(self, pointer): assert len(pointer) is self.dim+1 assert pointer[-1] <= self.levels - x = self._z.index([p for p in pointer[:-1]]) # copy - return (x << self._levelBits) + pointer[-1] + return TreeUtils.index(self.dim, MAX_BITS, self._levelBits, pointer[:-1], pointer[-1]) def _pointer(self, index): assert type(index) in [int, long] - n = index & (2**self._levelBits-1) - p = self._z.point(index >> self._levelBits) - return p + [n] + return TreeUtils.point(self.dim, MAX_BITS, self._levelBits, index) def __contains__(self, v): if type(v) in [int, long]: return v in self._treeInds return self._index(v) in self._treeInds - def refine(self, function=None, recursive=True, cells=None, balance=True): + def refine(self, function=None, recursive=True, cells=None, balance=True, _inRecursion=False): + + if not _inRecursion: + self._structureChange() + print 'Refining Mesh' cells = cells if cells is not None else sorted(self._treeInds) recurse = [] + tic = time.time() for cell in cells: p = self._pointer(cell) do = function(self._cellC(cell)) > p[-1] if do: recurse += self._refineCell(cell) - if recursive and len(recurse) > 0: - recurse += self.refine(function=function, recursive=True, cells=recurse, balance=balance) + print ' ', time.time() - tic - if balance: - recurse += self.balance(recursive=True) + if recursive and len(recurse) > 0: + recurse += self.refine(function=function, recursive=True, cells=recurse, balance=balance, _inRecursion=True) + + if balance and not _inRecursion: + self.balance() return recurse def _refineCell(self, pointer): - self._structureChange() pointer = self._asPointer(pointer) ind = self._asIndex(pointer) assert ind in self @@ -283,10 +242,13 @@ class Tree(object): self._treeInds.remove(ind) return added - def _corsenCell(self, pointer): + def corsen(self, function=None): self._structureChange() raise Exception('Not yet implemented') + def _corsenCell(self, pointer): + raise Exception('Not yet implemented') + def _asPointer(self, ind): if type(ind) in [int, long]: return self._pointer(ind) @@ -393,10 +355,24 @@ class Tree(object): return self._getNextCell(self._parentPointer(pointer), direction=direction, positive=positive) - def balance(self, recursive=True): + def balance(self, recursive=True, cells=None, _inRecursion=False): + + tic = time.time() + if not _inRecursion: + self._structureChange() + print 'Balancing Mesh:' + + cells = cells if cells is not None else sorted(self._treeInds) + + # calcDepth = lambda i: lambda A: i if type(A) is not list else max(map(calcDepth(i+1), A)) + # flatten = lambda A: A if calcDepth(0)(A) == 1 else flatten([_ for __ in A for _ in (__ if type(__) is list else [__])]) + + recurse = set() + + for cell in cells: + p = self._asPointer(cell) + if p[-1] == self.levels: continue - recurse = [] - for cell in sorted(self._treeInds): cs = range(6) cs[0] = self._getNextCell(cell, direction=0, positive=False) cs[1] = self._getNextCell(cell, direction=0, positive=True) @@ -410,14 +386,20 @@ class Tree(object): for c in cs if c is not None ]) - # print cs, do - if do: - recurse += self._refineCell(cell) + # depth = calcDepth(0)(cs) + # print depth, depth > 2, do, [jj for jj in flatten(cs) if jj is not None] + # recurse += [jj for jj in flatten(cs) if jj is not None] + if do and cell in self: + newCells = self._refineCell(cell) + recurse.update([_ for _ in cs if type(_) in [int, long]]) # only add the bigger ones! + recurse.update(newCells) + + print ' ', len(cells), time.time() - tic if recursive and len(recurse) > 0: - # print 'here' - recurse += self.balance() - return recurse + self.balance(cells=sorted(recurse), _inRecursion=True) + + @property def gridCC(self): @@ -961,7 +943,7 @@ class Tree(object): facesX=False, facesY=False, facesZ=False, edgesX=False, edgesY=False, edgesZ=False): - self.number() + # self.number() axOpts = {'projection':'3d'} if self.dim == 3 else {} if ax is None: @@ -1070,7 +1052,7 @@ class Tree(object): ax.plot(self.gridEz[ind,0], self.gridEz[ind,1], 'k:', zs=self.gridEz[ind,2]) - ax.axis('equal') + # ax.axis('equal') if showIt:plt.show() @@ -1079,36 +1061,47 @@ if __name__ == '__main__': def function(xc): - r = xc - np.r_[0.5*128,0.5*128] + r = xc - np.array([0.5*128]*len(xc)) dist = np.sqrt(r.dot(r)) # if dist < 0.05: # return 5 if dist < 0.1*128: - return 5 + return 7 if dist < 0.3*128: - return 3 - # if dist < 1.0*128: - # return 2 + return 5 + if dist < 1.0*128: + return 2 else: return 0 - # T = Tree([[(1,8)],[(1,8)],[(1,8)]],levels=3) + T = Tree([[(1,128)],[(1,128)],[(1,128)]],levels=7) # T = Tree([[(1,16)],[(1,16)]],levels=4) - T = Tree([[(1,128)],[(1,128)]],levels=7) - T.refine(lambda xc:2, balance=False) - T.refine(function) + # T = Tree([[(1,128)],[(1,128)]],levels=7) + # T.refine(lambda xc:6, balance=False) + # T._index([0,0,0]) + # T._pointer(0) + + + tic = time.time() + T.refine(function)#, balance=False) + print time.time() - tic + print T.nC + + asdf # T._refineCell([8,0,1]) # T._refineCell([8,0,2]) # T._refineCell([12,0,2]) # T._refineCell([8,4,2]) # T._refineCell([6,0,3]) # T._refineCell([8,8,1]) - # T._refineCell([4,4,4,1]) + # T._refineCell([0,0,0,1]) + ax = plt.subplot(211) - ax.spy(T.faceDiv) + # ax.spy(T.faceDiv) + T.plotGrid(ax=ax) # R = deflationMatrix(T._facesX, T._hangingFx, T._fx2i) # print R @@ -1120,7 +1113,7 @@ if __name__ == '__main__': # ax.spy(T.faceDiv[:,:T.nFx] * R) - + T.balance() T.plotGrid(ax=ax) # cx = T._getNextCell([0,0,1],direction=0,positive=True) @@ -1145,7 +1138,6 @@ if __name__ == '__main__': - # print T.nN plt.show() diff --git a/SimPEG/Mesh/TreeUtils.pyx b/SimPEG/Mesh/TreeUtils.pyx new file mode 100644 index 00000000..d9bf5238 --- /dev/null +++ b/SimPEG/Mesh/TreeUtils.pyx @@ -0,0 +1,85 @@ +# from __future__ import division +# import numpy as np +# cimport numpy as np +# from libcpp.vector cimport vector + + +""" + The Z-order curve is generated by interleaving the bits of an offset. + + See also: + + https://github.com/cortesi/scurve + Aldo Cortesi + +""" + +def bitrange(long x, int width, int start, int end): + """ + Extract a bit range as an integer. + (start, end) is inclusive lower bound, exclusive upper bound. + """ + return x >> (width-end) & ((2**(end-start))-1) + +def index(int dimension, int bits, int levelBits, list p, int level): + cdef long idx = 0 + cdef int iwidth + cdef int i + cdef long b + cdef int bitoff + + p = [_ for _ in p] + + p.reverse() + iwidth = bits * dimension + for i in range(iwidth): + bitoff = bits-(i/dimension)-1 + poff = dimension-(i%dimension)-1 + b = bitrange(p[poff], bits, bitoff, bitoff+1) << i + idx |= b + + return (idx << levelBits) + level + +def point(int dimension, int bits, int levelBits, long idx): + cdef list p + cdef int iwidth + cdef int i, n + cdef long b + + n = idx & (2**levelBits-1) + idx = idx >> levelBits + + p = [0]*dimension + iwidth = bits * dimension + for i in range(iwidth): + b = bitrange(idx, iwidth, i, i+1) << (iwidth-i-1)/dimension + p[i%dimension] |= b + p.reverse() + return p + [n] + + +# def _refineCell(int dimension, int bits, self, pointer): +# self._structureChange() +# pointer = self._asPointer(pointer) +# ind = self._asIndex(pointer) +# assert ind in self +# h = self._levelWidth(pointer[-1])/2 # halfWidth +# nL = pointer[-1] + 1 # new level +# add = lambda p:p[0]+p[1] +# added = [] +# def addCell(p): +# i = self._index(p+[nL]) +# self._treeInds.add(i) +# added.append(i) + +# addCell(map(add, zip(pointer[:-1], [0,0,0]))) +# addCell(map(add, zip(pointer[:-1], [h,0,0]))) +# addCell(map(add, zip(pointer[:-1], [0,h,0]))) +# addCell(map(add, zip(pointer[:-1], [h,h,0]))) +# if self.dim == 3: +# addCell(map(add, zip(pointer[:-1], [0,0,h]))) +# addCell(map(add, zip(pointer[:-1], [h,0,h]))) +# addCell(map(add, zip(pointer[:-1], [0,h,h]))) +# addCell(map(add, zip(pointer[:-1], [h,h,h]))) +# self._treeInds.remove(ind) +# return added From 0aafb8931b1b1c064cf2b99653f342cfd70b14cd Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Sat, 7 Nov 2015 16:49:01 -0800 Subject: [PATCH 36/83] Rename _treeInds to _cells --- SimPEG/Mesh/PointerTree.py | 46 +++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/SimPEG/Mesh/PointerTree.py b/SimPEG/Mesh/PointerTree.py index 1db06c1a..efed782e 100644 --- a/SimPEG/Mesh/PointerTree.py +++ b/SimPEG/Mesh/PointerTree.py @@ -71,8 +71,8 @@ class Tree(object): self.__dirty__ = True #: The numbering is dirty! - self._treeInds = set() - self._treeInds.add(0) + self._cells = set() + self._cells.add(0) @property def __dirty__(self): @@ -93,7 +93,7 @@ class Tree(object): def dim(self): return len(self.h) @property - def nC(self): return len(self._treeInds) + def nC(self): return len(self._cells) @property def nN(self): @@ -143,10 +143,10 @@ class Tree(object): return len(self._edgesZ) @property - def _sortedInds(self): - if getattr(self, '__sortedInds', None) is None: - self.__sortedInds = sorted(self._treeInds) - return self.__sortedInds + def _sortedCells(self): + if getattr(self, '__sortedCells', None) is None: + self.__sortedCells = sorted(self._cells) + return self.__sortedCells @property def permuteCC(self): @@ -174,7 +174,7 @@ class Tree(object): raise Exception() def _structureChange(self): - deleteThese = ['__sortedInds', '_gridCC', '_gridN', '_gridFx', '_gridFy', '_gridFz', '_gridEx', '_gridEy', '_gridEz', '_area', '_edge', '_vol'] + deleteThese = ['__sortedCells', '_gridCC', '_gridN', '_gridFx', '_gridFy', '_gridFz', '_gridEx', '_gridEy', '_gridEz', '_area', '_edge', '_vol'] for p in deleteThese: if hasattr(self, p): delattr(self, p) self.__dirty__ = True @@ -190,8 +190,8 @@ class Tree(object): def __contains__(self, v): if type(v) in [int, long]: - return v in self._treeInds - return self._index(v) in self._treeInds + return v in self._cells + return self._index(v) in self._cells def refine(self, function=None, recursive=True, cells=None, balance=True, _inRecursion=False): @@ -199,7 +199,7 @@ class Tree(object): self._structureChange() print 'Refining Mesh' - cells = cells if cells is not None else sorted(self._treeInds) + cells = cells if cells is not None else sorted(self._cells) recurse = [] tic = time.time() for cell in cells: @@ -227,7 +227,7 @@ class Tree(object): added = [] def addCell(p): i = self._index(p+[nL]) - self._treeInds.add(i) + self._cells.add(i) added.append(i) addCell(map(add, zip(pointer[:-1], [0,0,0][:self.dim]))) @@ -239,7 +239,7 @@ class Tree(object): addCell(map(add, zip(pointer[:-1], [h,0,h]))) addCell(map(add, zip(pointer[:-1], [0,h,h]))) addCell(map(add, zip(pointer[:-1], [h,h,h]))) - self._treeInds.remove(ind) + self._cells.remove(ind) return added def corsen(self, function=None): @@ -362,7 +362,7 @@ class Tree(object): self._structureChange() print 'Balancing Mesh:' - cells = cells if cells is not None else sorted(self._treeInds) + cells = cells if cells is not None else sorted(self._cells) # calcDepth = lambda i: lambda A: i if type(A) is not list else max(map(calcDepth(i+1), A)) # flatten = lambda A: A if calcDepth(0)(A) == 1 else flatten([_ for __ in A for _ in (__ if type(__) is list else [__])]) @@ -404,8 +404,8 @@ class Tree(object): @property def gridCC(self): if getattr(self, '_gridCC', None) is None: - self._gridCC = np.zeros((len(self._treeInds),self.dim)) - for ii, ind in enumerate(self._sortedInds): + self._gridCC = np.zeros((len(self._cells),self.dim)) + for ii, ind in enumerate(self._sortedCells): p = self._asPointer(ind) self._gridCC[ii, :] = self._cellC(p) return self._gridCC @@ -452,8 +452,8 @@ class Tree(object): @property def vol(self): if getattr(self, '_vol', None) is None: - self._vol = np.zeros(len(self._treeInds)) - for ii, ind in enumerate(self._sortedInds): + self._vol = np.zeros(len(self._cells)) + for ii, ind in enumerate(self._sortedCells): p = self._asPointer(ind) self._vol[ii] = np.prod(self._cellH(p)) return self._vol @@ -490,7 +490,7 @@ class Tree(object): self._nodes = set() - for ind in self._treeInds: + for ind in self._cells: p = self._asPointer(ind) w = self._levelWidth(p[-1]) if self.dim == 2: @@ -524,7 +524,7 @@ class Tree(object): if self.dim == 3: self._facesZ = set() - for ind in self._treeInds: + for ind in self._cells: p = self._asPointer(ind) w = self._levelWidth(p[-1]) @@ -599,7 +599,7 @@ class Tree(object): self._edgesY = set() self._edgesZ = set() - for ind in self._treeInds: + for ind in self._cells: p = self._asPointer(ind) w = self._levelWidth(p[-1]) self._edgesX.add(self._index([p[0] , p[1] , p[2] , p[3]])) @@ -871,7 +871,7 @@ class Tree(object): PM = [-1,1]*self.dim # plus / minus offset = [0,0,self.nFx,self.nFx,self.nFx+self.nFy,self.nFx+self.nFy] - for ii, ind in enumerate(self._sortedInds): + for ii, ind in enumerate(self._sortedCells): p = self._pointer(ind) w = self._levelWidth(p[-1]) @@ -953,7 +953,7 @@ class Tree(object): fig = ax.figure if grid: - for ind in self._sortedInds: + for ind in self._sortedCells: p = self._asPointer(ind) n = self._cellN(p) h = self._cellH(p) From ebb57f62187e7166d404caecba9179a92f7eeb47 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Sat, 7 Nov 2015 17:32:59 -0800 Subject: [PATCH 37/83] edgeCurl --- SimPEG/Mesh/PointerTree.py | 134 ++++++++++++++++++++++++++++++++----- 1 file changed, 116 insertions(+), 18 deletions(-) diff --git a/SimPEG/Mesh/PointerTree.py b/SimPEG/Mesh/PointerTree.py index efed782e..59bfa950 100644 --- a/SimPEG/Mesh/PointerTree.py +++ b/SimPEG/Mesh/PointerTree.py @@ -1,4 +1,4 @@ -from SimPEG import np, sp, Utils, Solver +from SimPEG import np, sp, Utils, Solver, Mesh import matplotlib.pyplot as plt import matplotlib import TreeUtils @@ -174,7 +174,12 @@ class Tree(object): raise Exception() def _structureChange(self): - deleteThese = ['__sortedCells', '_gridCC', '_gridN', '_gridFx', '_gridFy', '_gridFz', '_gridEx', '_gridEy', '_gridEz', '_area', '_edge', '_vol'] + deleteThese = [ + '__sortedCells', + '_gridCC', '_gridN', '_gridFx', '_gridFy', '_gridFz', '_gridEx', '_gridEy', '_gridEz', + '_area', '_edge', '_vol', + '_faceDiv', '_edgeCurl', '_nodalGrad' + ] for p in deleteThese: if hasattr(self, p): delattr(self, p) self.__dirty__ = True @@ -479,6 +484,15 @@ class Tree(object): self.number() if self.dim == 2: return np.r_[self._area[self.nFx:], self._area[:self.nFx]] + if getattr(self, '_edge', None) is None: + R = sp.block_diag([ + self._deflationMatrix(self._edgesX, self._hangingEx, self._ex2i, withHanging=False), + self._deflationMatrix(self._edgesY, self._hangingEy, self._ey2i, withHanging=False), + self._deflationMatrix(self._edgesZ, self._hangingEz, self._ez2i, withHanging=False) + ]) + self._edge = R.T * np.r_[self._edgeExFull, self._edgeEyFull, self._edgeEzFull] + + return self._edge def _onSameLevel(self, i0, i1): p0 = self._asPointer(i0) @@ -618,31 +632,40 @@ class Tree(object): self._edgesZ.add(self._index([p[0] + w, p[1] + w, p[2] , p[3]])) gridEx = [] + edgeEx = [] self._ex2i = dict() for ii, ex in enumerate(sorted(self._edgesX)): self._ex2i[ex] = ii p = self._pointer(ex) n, h = self._cellN(p), self._cellH(p) gridEx.append( [n[0] + h[0]/2.0, n[1], n[2]] ) + edgeEx.append( h[0] ) self._gridEx = np.array(gridEx) + self._edgeExFull = np.array(edgeEx) gridEy = [] + edgeEy = [] self._ey2i = dict() for ii, ey in enumerate(sorted(self._edgesY)): self._ey2i[ey] = ii p = self._pointer(ey) n, h = self._cellN(p), self._cellH(p) gridEy.append( [n[0], n[1] + h[1]/2.0, n[2]] ) + edgeEy.append( h[1] ) self._gridEy = np.array(gridEy) + self._edgeEyFull = np.array(edgeEx) gridEz = [] + edgeEz = [] self._ez2i = dict() for ii, ez in enumerate(sorted(self._edgesZ)): self._ez2i[ez] = ii p = self._pointer(ez) n, h = self._cellN(p), self._cellH(p) gridEz.append( [n[0], n[1], n[2] + h[2]/2.0] ) + edgeEz.append( h[2] ) self._gridEz = np.array(gridEz) + self._edgeEzFull = np.array(edgeEx) self.__dirtyEdges__ = False @@ -866,6 +889,7 @@ class Tree(object): def faceDiv(self): if getattr(self, '_faceDiv', None) is None: self.number() + # TODO: Preallocate! I, J, V = [], [], [] PM = [-1,1]*self.dim # plus / minus @@ -922,17 +946,85 @@ class Tree(object): self.number() # TODO: Preallocate! I, J, V = [], [], [] - for face in self.faces: - for ii, edge in enumerate([face.edge0, face.edge1, face.edge2, face.edge3]): - j = edge.index - I += [face.num]*len(j) - J += j - isNeg = [True, False, True, False] - V += [-1 if isNeg[ii] else 1]*len(j) - C = sp.csr_matrix((V,(I,J)), shape=(self.nF, self.nE)) + faceOffset = 0 + offset = [self.nEx]*2 + [self.nEx+self.nEy]*2 + PM = [1, -1, -1, 1] + for ii, fx in enumerate(sorted(self._facesX)): + + p = self._pointer(fx) + w = self._levelWidth(p[-1]) + + edges = [ + self._ey2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._ey2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])], + self._ez2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._ez2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], + ] + + for off, pm, edge in zip(offset,PM,edges): + I += [ii + faceOffset] + J += [edge + off] + V += [pm] + + faceOffset = self.nFx + offset = [0]*2 + [self.nEx+self.nEy]*2 + PM = [-1, 1, 1, -1] + for ii, fy in enumerate(sorted(self._facesY)): + + p = self._pointer(fy) + w = self._levelWidth(p[-1]) + + edges = [ + self._ex2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._ex2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])], + self._ez2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._ez2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], + ] + + for off, pm, edge in zip(offset,PM,edges): + I += [ii + faceOffset] + J += [edge + off] + V += [pm] + + faceOffset = self.nFx + self.nFy + offset = [0]*2 + [self.nEx]*2 + PM = [1, -1, -1, 1] + for ii, fz in enumerate(sorted(self._facesZ)): + + p = self._pointer(fz) + w = self._levelWidth(p[-1]) + + edges = [ + self._ex2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._ex2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], + self._ey2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._ey2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], + ] + + for off, pm, edge in zip(offset,PM,edges): + I += [ii + faceOffset] + J += [edge + off] + V += [pm] + + tnF = len(self._facesX) + len(self._facesY) + len(self._facesZ) + tnE = len(self._edgesX) + len(self._edgesY) + len(self._edgesZ) + + Rf = sp.block_diag([ + self._deflationMatrix(self._facesX, self._hangingFx, self._fx2i), + self._deflationMatrix(self._facesY, self._hangingFy, self._fy2i), + self._deflationMatrix(self._facesZ, self._hangingFz, self._fz2i) + ]) + + Re = sp.block_diag([ + self._deflationMatrix(self._edgesX, self._hangingEx, self._ex2i), + self._deflationMatrix(self._edgesY, self._hangingEy, self._ey2i), + self._deflationMatrix(self._edgesZ, self._hangingEz, self._ez2i) + ]) + + C = sp.csr_matrix((V,(I,J)), shape=(tnF, tnE)) S = self.area L = self.edge - self._edgeCurl = Utils.sdiag(1/S)*C*Utils.sdiag(L) + self._edgeCurl = Utils.sdiag(1/S)*Rf.T*C*Re*Utils.sdiag(L) return self._edgeCurl @@ -1075,6 +1167,7 @@ if __name__ == '__main__': return 0 T = Tree([[(1,128)],[(1,128)],[(1,128)]],levels=7) + T = Tree([128,128,128],levels=7) # T = Tree([[(1,16)],[(1,16)]],levels=4) # T = Tree([[(1,128)],[(1,128)]],levels=7) # T.refine(lambda xc:6, balance=False) @@ -1083,11 +1176,11 @@ if __name__ == '__main__': tic = time.time() - T.refine(function)#, balance=False) + # T.refine(function)#, balance=False) print time.time() - tic print T.nC - asdf + # T._refineCell([8,0,1]) # T._refineCell([8,0,2]) # T._refineCell([12,0,2]) @@ -1098,23 +1191,28 @@ if __name__ == '__main__': ax = plt.subplot(211) - # ax.spy(T.faceDiv) + ax.spy(T.edgeCurl) + print Mesh.TensorMesh([1,1,1]).edgeCurl.todense() + print T.edgeCurl.todense() + print Mesh.TensorMesh([1,1,1]).edgeCurl.todense() - T.edgeCurl.todense() + print T.gridEy - Mesh.TensorMesh([1,1,1]).gridEy - T.plotGrid(ax=ax) + print T.edge + # T.plotGrid(ax=ax) # R = deflationMatrix(T._facesX, T._hangingFx, T._fx2i) # print R ax = plt.subplot(212)#, projection='3d') - # ax.spy(R) + ax.spy(Mesh.TensorMesh([1,1,1]).edgeCurl) # ax = plt.subplot(313) # ax.spy(T.faceDiv[:,:T.nFx] * R) - T.balance() - T.plotGrid(ax=ax) + # T.balance() + # T.plotGrid(ax=ax) # cx = T._getNextCell([0,0,1],direction=0,positive=True) # print cx From b2381796f779014df2b63010577f822b25f93751 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Sat, 7 Nov 2015 17:51:02 -0800 Subject: [PATCH 38/83] Fix numbering --- SimPEG/Mesh/PointerTree.py | 73 ++++++++++++++++++++++---------------- SimPEG/Utils/meshutils.py | 50 +++++++++++++------------- 2 files changed, 67 insertions(+), 56 deletions(-) diff --git a/SimPEG/Mesh/PointerTree.py b/SimPEG/Mesh/PointerTree.py index 59bfa950..f96abe20 100644 --- a/SimPEG/Mesh/PointerTree.py +++ b/SimPEG/Mesh/PointerTree.py @@ -97,8 +97,8 @@ class Tree(object): @property def nN(self): - self._numberNodes() - return len(self._nodes) + self.number() + return len(self._nodes) - len(self._hangingN) @property def nF(self): @@ -106,19 +106,19 @@ class Tree(object): @property def nFx(self): - self._numberFaces() - return len(self._facesX) + self.number() + return len(self._facesX) - len(self._hangingFx) @property def nFy(self): - self._numberFaces() - return len(self._facesY) + self.number() + return len(self._facesY) - len(self._hangingFy) @property def nFz(self): if self.dim == 2: return None - self._numberFaces() - return len(self._facesZ) + self.number() + return len(self._facesZ) - len(self._hangingFz) @property def nE(self): @@ -127,20 +127,20 @@ class Tree(object): @property def nEx(self): if self.dim == 2:return self.nFy - self._numberEdges() - return len(self._edgesX) + self.number() + return len(self._edgesX) - len(self._hangingEx) @property def nEy(self): if self.dim == 2:return self.nFx - self._numberEdges() - return len(self._edgesY) + self.number() + return len(self._edgesY) - len(self._hangingEy) @property def nEz(self): if self.dim == 2: return None - self._numberEdges() - return len(self._edgesZ) + self.number() + return len(self._edgesZ) - len(self._hangingEz) @property def _sortedCells(self): @@ -404,8 +404,6 @@ class Tree(object): if recursive and len(recurse) > 0: self.balance(cells=sorted(recurse), _inRecursion=True) - - @property def gridCC(self): if getattr(self, '_gridCC', None) is None: @@ -418,41 +416,48 @@ class Tree(object): @property def gridN(self): self.number() - return self._gridN + R = self._deflationMatrix(self._nodes, self._hangingN, self._n2i, withHanging=False) + return R.T * self._gridN @property def gridFx(self): self.number() - return self._gridFx + R = self._deflationMatrix(self._facesX, self._hangingFx, self._fx2i, withHanging=False) + return R.T * self._gridFx @property def gridFy(self): self.number() - return self._gridFy + R = self._deflationMatrix(self._facesY, self._hangingFy, self._fy2i, withHanging=False) + return R.T * self._gridFy @property def gridFz(self): if self.dim < 3: return None self.number() - return self._gridFz + R = self._deflationMatrix(self._facesZ, self._hangingFz, self._fz2i, withHanging=False) + return R.T * self._gridFz @property def gridEx(self): if self.dim == 2: return self.gridFy self.number() - return self._gridEx + R = self._deflationMatrix(self._edgesX, self._hangingEx, self._ex2i, withHanging=False) + return R.T * self._gridEx @property def gridEy(self): if self.dim == 2: return self.gridFx self.number() - return self._gridEy + R = self._deflationMatrix(self._edgesY, self._hangingEy, self._ey2i, withHanging=False) + return R.T * self._gridEy @property def gridEz(self): if self.dim < 3: return None self.number() - return self._gridEz + R = self._deflationMatrix(self._edgesZ, self._hangingEz, self._ez2i, withHanging=False) + return R.T * self._gridEz @property def vol(self): @@ -1170,7 +1175,7 @@ if __name__ == '__main__': T = Tree([128,128,128],levels=7) # T = Tree([[(1,16)],[(1,16)]],levels=4) # T = Tree([[(1,128)],[(1,128)]],levels=7) - # T.refine(lambda xc:6, balance=False) + T.refine(lambda xc:1, balance=False) # T._index([0,0,0]) # T._pointer(0) @@ -1180,6 +1185,8 @@ if __name__ == '__main__': print time.time() - tic print T.nC + print T.gridFz + # T._refineCell([8,0,1]) # T._refineCell([8,0,2]) @@ -1187,25 +1194,29 @@ if __name__ == '__main__': # T._refineCell([8,4,2]) # T._refineCell([6,0,3]) # T._refineCell([8,8,1]) - # T._refineCell([0,0,0,1]) + T._refineCell([0,0,0,1]) + T.__dirty__ = True + + + print T.gridFx.shape[0], T.nFx ax = plt.subplot(211) ax.spy(T.edgeCurl) - print Mesh.TensorMesh([1,1,1]).edgeCurl.todense() - print T.edgeCurl.todense() - print Mesh.TensorMesh([1,1,1]).edgeCurl.todense() - T.edgeCurl.todense() - print T.gridEy - Mesh.TensorMesh([1,1,1]).gridEy + # print Mesh.TensorMesh([2,2,2]).edgeCurl.todense() + # print T.edgeCurl.todense() + # print Mesh.TensorMesh([2,2,2]).edgeCurl.todense() - T.edgeCurl.todense() + # print T.gridEy - Mesh.TensorMesh([2,2,2]).gridEy - print T.edge + # print T.edge # T.plotGrid(ax=ax) # R = deflationMatrix(T._facesX, T._hangingFx, T._fx2i) # print R ax = plt.subplot(212)#, projection='3d') - ax.spy(Mesh.TensorMesh([1,1,1]).edgeCurl) + ax.spy(Mesh.TensorMesh([2,2,2]).edgeCurl) # ax = plt.subplot(313) # ax.spy(T.faceDiv[:,:T.nFx] * R) diff --git a/SimPEG/Utils/meshutils.py b/SimPEG/Utils/meshutils.py index 85ad8f21..585fcc9a 100644 --- a/SimPEG/Utils/meshutils.py +++ b/SimPEG/Utils/meshutils.py @@ -149,7 +149,7 @@ def readUBCTensorModel(fileName, mesh): Input: :param fileName, path to the UBC GIF mesh file to read - :param mesh, TensorMesh object, mesh that coresponds to the model + :param mesh, TensorMesh object, mesh that coresponds to the model Output: :return numpy array, model with TensorMesh ordered @@ -170,7 +170,7 @@ def writeUBCTensorMesh(fileName, mesh): :param str fileName: File to write to :param simpeg.Mesh.TensorMesh mesh: The mesh - + """ assert mesh.dim == 3 s = '' @@ -216,7 +216,7 @@ def readVTRFile(fileName): Output: :return SimPEG TensorMesh object :return SimPEG model dictionary - + """ # Import from vtk import vtkXMLRectilinearGridReader as vtrFileReader @@ -324,56 +324,56 @@ def ExtractCoreMesh(xyzlim, mesh, meshType='tensor'): Extracts Core Mesh from Global mesh xyzlim: 2D array [ndim x 2] mesh: SimPEG mesh - This function ouputs: + This function ouputs: - actind: corresponding boolean index from global to core - - meshcore: core SimPEG mesh + - meshcore: core SimPEG mesh Warning: 1D and 2D has not been tested """ from SimPEG import Mesh if mesh.dim ==1: xyzlim = xyzlim.flatten() xmin, xmax = xyzlim[0], xyzlim[1] - - xind = np.logical_and(mesh.vectorCCx>xmin, mesh.vectorCCxxmin, mesh.vectorCCxxmin) & (mesh.gridCC[:,0]ymin, mesh.vectorCCyzmin, mesh.vectorCCzzmin, mesh.vectorCCzxmin) & (mesh.gridCC[:,0]ymin) & (mesh.gridCC[:,1]xmin, mesh.vectorCCxymin, mesh.vectorCCyzmin, mesh.vectorCCzzmin, mesh.vectorCCzxmin) & (mesh.gridCC[:,0]ymin) & (mesh.gridCC[:,1]zmin) & (mesh.gridCC[:,2] Date: Sat, 7 Nov 2015 17:55:45 -0800 Subject: [PATCH 39/83] Remove structure change, replace with __dirty__ --- SimPEG/Mesh/PointerTree.py | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/SimPEG/Mesh/PointerTree.py b/SimPEG/Mesh/PointerTree.py index f96abe20..135e0aad 100644 --- a/SimPEG/Mesh/PointerTree.py +++ b/SimPEG/Mesh/PointerTree.py @@ -86,6 +86,15 @@ class Tree(object): self.__dirtyNodes__ = True self.__dirtyHanging__ = True + deleteThese = [ + '__sortedCells', + '_gridCC', '_gridN', '_gridFx', '_gridFy', '_gridFz', '_gridEx', '_gridEy', '_gridEz', + '_area', '_edge', '_vol', + '_faceDiv', '_edgeCurl', '_nodalGrad' + ] + for p in deleteThese: + if hasattr(self, p): delattr(self, p) + @property def levels(self): return self._levels @@ -173,17 +182,6 @@ class Tree(object): if self.dim == 3: raise Exception() - def _structureChange(self): - deleteThese = [ - '__sortedCells', - '_gridCC', '_gridN', '_gridFx', '_gridFy', '_gridFz', '_gridEx', '_gridEy', '_gridEz', - '_area', '_edge', '_vol', - '_faceDiv', '_edgeCurl', '_nodalGrad' - ] - for p in deleteThese: - if hasattr(self, p): delattr(self, p) - self.__dirty__ = True - def _index(self, pointer): assert len(pointer) is self.dim+1 assert pointer[-1] <= self.levels @@ -201,7 +199,7 @@ class Tree(object): def refine(self, function=None, recursive=True, cells=None, balance=True, _inRecursion=False): if not _inRecursion: - self._structureChange() + self.__dirty__ = True print 'Refining Mesh' cells = cells if cells is not None else sorted(self._cells) @@ -248,7 +246,7 @@ class Tree(object): return added def corsen(self, function=None): - self._structureChange() + self.__dirty__ = True raise Exception('Not yet implemented') def _corsenCell(self, pointer): @@ -364,7 +362,7 @@ class Tree(object): tic = time.time() if not _inRecursion: - self._structureChange() + self.__dirty__ = True print 'Balancing Mesh:' cells = cells if cells is not None else sorted(self._cells) @@ -488,7 +486,7 @@ class Tree(object): def edge(self): self.number() if self.dim == 2: - return np.r_[self._area[self.nFx:], self._area[:self.nFx]] + return np.r_[self.area[self.nFx:], self.area[:self.nFx]] if getattr(self, '_edge', None) is None: R = sp.block_diag([ self._deflationMatrix(self._edgesX, self._hangingEx, self._ex2i, withHanging=False), From 406addd3320e575bb0714038338e3ca105141e62 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Sat, 7 Nov 2015 17:58:11 -0800 Subject: [PATCH 40/83] Recursive force --- SimPEG/Mesh/PointerTree.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/SimPEG/Mesh/PointerTree.py b/SimPEG/Mesh/PointerTree.py index 135e0aad..f49047ed 100644 --- a/SimPEG/Mesh/PointerTree.py +++ b/SimPEG/Mesh/PointerTree.py @@ -675,9 +675,9 @@ class Tree(object): def _hanging(self, force=False): if not self.__dirtyHanging__ and not force: return - self._numberNodes() - self._numberFaces() - self._numberEdges() + self._numberNodes(force=force) + self._numberFaces(force=force) + self._numberEdges(force=force) self._hangingN = dict() self._hangingFx = dict() @@ -866,7 +866,7 @@ class Tree(object): def number(self, force=False): if not self.__dirty__ and not force: return - self._hanging() + self._hanging(force=force) return def _deflationMatrix(self, theSet, theHang, theIndex, withHanging=True): From 855c92dc77f27ecba1dc2b0448e215923e01524e Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Sat, 7 Nov 2015 18:04:06 -0800 Subject: [PATCH 41/83] Number of hanging things. --- SimPEG/Mesh/PointerTree.py | 47 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/SimPEG/Mesh/PointerTree.py b/SimPEG/Mesh/PointerTree.py index f49047ed..73855e27 100644 --- a/SimPEG/Mesh/PointerTree.py +++ b/SimPEG/Mesh/PointerTree.py @@ -151,6 +151,53 @@ class Tree(object): self.number() return len(self._edgesZ) - len(self._hangingEz) + @property + def nhN(self): + self.number() + return len(self._hangingN) + + @property + def nhF(self): + return self.nhFx + self.nhFy + (0 if self.dim == 2 else self.nhFz) + + @property + def nhFx(self): + self.number() + return len(self._hangingFx) + + @property + def nhFy(self): + self.number() + return len(self._hangingFy) + + @property + def nhFz(self): + if self.dim == 2: return None + self.number() + return len(self._hangingFz) + + @property + def nhE(self): + return self.nhEx + self.nhEy + (0 if self.dim == 2 else self.nhEz) + + @property + def nhEx(self): + if self.dim == 2:return self.nhFy + self.number() + return len(self._hangingEx) + + @property + def nhEy(self): + if self.dim == 2:return self.nhFx + self.number() + return len(self._hangingEy) + + @property + def nhEz(self): + if self.dim == 2: return None + self.number() + return len(self._hangingEz) + @property def _sortedCells(self): if getattr(self, '__sortedCells', None) is None: From fb18d8a5d8b3dc466ec68f29a49fda8c4a03db8e Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Sat, 7 Nov 2015 18:19:40 -0800 Subject: [PATCH 42/83] Dirty edges --- SimPEG/Mesh/PointerTree.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/SimPEG/Mesh/PointerTree.py b/SimPEG/Mesh/PointerTree.py index 73855e27..d7cc1706 100644 --- a/SimPEG/Mesh/PointerTree.py +++ b/SimPEG/Mesh/PointerTree.py @@ -656,7 +656,9 @@ class Tree(object): self.__dirtyFaces__ = False def _numberEdges(self, force=False): - if self.dim == 2: return + if self.dim == 2: + self.__dirtyEdges__ = False + return if not self.__dirtyEdges__ and not force: return self._edgesX = set() @@ -913,8 +915,8 @@ class Tree(object): def number(self, force=False): if not self.__dirty__ and not force: return + self.balance() self._hanging(force=force) - return def _deflationMatrix(self, theSet, theHang, theIndex, withHanging=True): reducedInd = dict() # final reduced index From 91284e22860b7ee7acf7f96ad6fc77bbd0300ad6 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Sat, 7 Nov 2015 18:34:50 -0800 Subject: [PATCH 43/83] Edge Bug --- SimPEG/Mesh/PointerTree.py | 63 +- SimPEG/Mesh/TreeUtils.c | 2843 ++++++++++++++++++++++++++++++++ setup.py | 2 +- tests/mesh/test_pointerMesh.py | 101 +- 4 files changed, 2926 insertions(+), 83 deletions(-) create mode 100644 SimPEG/Mesh/TreeUtils.c diff --git a/SimPEG/Mesh/PointerTree.py b/SimPEG/Mesh/PointerTree.py index d7cc1706..8e98a6fe 100644 --- a/SimPEG/Mesh/PointerTree.py +++ b/SimPEG/Mesh/PointerTree.py @@ -227,7 +227,10 @@ class Tree(object): P += SortGrid(self.gridFx, offset=self.nEx) return sp.identity(self.nE).tocsr()[P,:] if self.dim == 3: - raise Exception() + P = SortGrid(self.gridEx) + P += SortGrid(self.gridEy, offset=self.nEx) + P += SortGrid(self.gridEz, offset=self.nEx+self.nEy) + return sp.identity(self.nE).tocsr()[P,:] def _index(self, pointer): assert len(pointer) is self.dim+1 @@ -705,7 +708,7 @@ class Tree(object): gridEy.append( [n[0], n[1] + h[1]/2.0, n[2]] ) edgeEy.append( h[1] ) self._gridEy = np.array(gridEy) - self._edgeEyFull = np.array(edgeEx) + self._edgeEyFull = np.array(edgeEy) gridEz = [] edgeEz = [] @@ -717,7 +720,7 @@ class Tree(object): gridEz.append( [n[0], n[1], n[2] + h[2]/2.0] ) edgeEz.append( h[2] ) self._gridEz = np.array(gridEz) - self._edgeEzFull = np.array(edgeEx) + self._edgeEzFull = np.array(edgeEz) self.__dirtyEdges__ = False @@ -1123,14 +1126,14 @@ class Tree(object): ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'r:') ax.plot(self.gridCC[[0,-1],0], self.gridCC[[0,-1],1], 'ro') if nodes: - ax.plot(self.gridN[:,0], self.gridN[:,1], 'ms') - ax.plot(self.gridN[self._hangingN.keys(),0], self.gridN[self._hangingN.keys(),1], 'ms', ms=10, mfc='none', mec='m') + ax.plot(self._gridN[:,0], self._gridN[:,1], 'ms') + ax.plot(self._gridN[self._hangingN.keys(),0], self._gridN[self._hangingN.keys(),1], 'ms', ms=10, mfc='none', mec='m') if facesX: - ax.plot(self.gridFx[self._hangingFx.keys(),0], self.gridFx[self._hangingFx.keys(),1], 'gs', ms=10, mfc='none', mec='g') - ax.plot(self.gridFx[:,0], self.gridFx[:,1], 'g>') + ax.plot(self._gridFx[self._hangingFx.keys(),0], self._gridFx[self._hangingFx.keys(),1], 'gs', ms=10, mfc='none', mec='g') + ax.plot(self._gridFx[:,0], self._gridFx[:,1], 'g>') if facesY: - ax.plot(self.gridFy[self._hangingFy.keys(),0], self.gridFy[self._hangingFy.keys(),1], 'gs', ms=10, mfc='none', mec='g') - ax.plot(self.gridFy[:,0], self.gridFy[:,1], 'g^') + ax.plot(self._gridFy[self._hangingFy.keys(),0], self._gridFy[self._hangingFy.keys(),1], 'gs', ms=10, mfc='none', mec='g') + ax.plot(self._gridFy[:,0], self._gridFy[:,1], 'g^') elif self.dim == 3: if cells: ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'r.', zs=self.gridCC[:,2]) @@ -1139,61 +1142,61 @@ class Tree(object): ax.plot(self.gridCC[[0,-1],0], self.gridCC[[0,-1],1], 'ro', zs=self.gridCC[[0,-1],2]) if nodes: - ax.plot(self.gridN[:,0], self.gridN[:,1], 'ms', zs=self.gridN[:,2]) - ax.plot(self.gridN[self._hangingN.keys(),0], self.gridN[self._hangingN.keys(),1], 'ms', ms=10, mfc='none', mec='m', zs=self.gridN[self._hangingN.keys(),2]) + ax.plot(self._gridN[:,0], self._gridN[:,1], 'ms', zs=self._gridN[:,2]) + ax.plot(self._gridN[self._hangingN.keys(),0], self._gridN[self._hangingN.keys(),1], 'ms', ms=10, mfc='none', mec='m', zs=self._gridN[self._hangingN.keys(),2]) for key in self._hangingN.keys(): for hf in self._hangingN[key]: ind = [key, hf[0]] - ax.plot(self.gridN[ind,0], self.gridN[ind,1], 'm:', zs=self.gridN[ind,2]) + ax.plot(self._gridN[ind,0], self._gridN[ind,1], 'm:', zs=self._gridN[ind,2]) if facesX: - ax.plot(self.gridFx[:,0], self.gridFx[:,1], 'g>', zs=self.gridFx[:,2]) - ax.plot(self.gridFx[self._hangingFx.keys(),0], self.gridFx[self._hangingFx.keys(),1], 'gs', ms=10, mfc='none', mec='g', zs=self.gridFx[self._hangingFx.keys(),2]) + ax.plot(self._gridFx[:,0], self._gridFx[:,1], 'g>', zs=self._gridFx[:,2]) + ax.plot(self._gridFx[self._hangingFx.keys(),0], self._gridFx[self._hangingFx.keys(),1], 'gs', ms=10, mfc='none', mec='g', zs=self._gridFx[self._hangingFx.keys(),2]) for key in self._hangingFx.keys(): for hf in self._hangingFx[key]: ind = [key, hf[0]] - ax.plot(self.gridFx[ind,0], self.gridFx[ind,1], 'g:', zs=self.gridFx[ind,2]) + ax.plot(self._gridFx[ind,0], self._gridFx[ind,1], 'g:', zs=self._gridFx[ind,2]) if facesY: - ax.plot(self.gridFy[:,0], self.gridFy[:,1], 'g^', zs=self.gridFy[:,2]) - ax.plot(self.gridFy[self._hangingFy.keys(),0], self.gridFy[self._hangingFy.keys(),1], 'gs', ms=10, mfc='none', mec='g', zs=self.gridFy[self._hangingFy.keys(),2]) + ax.plot(self._gridFy[:,0], self._gridFy[:,1], 'g^', zs=self._gridFy[:,2]) + ax.plot(self._gridFy[self._hangingFy.keys(),0], self._gridFy[self._hangingFy.keys(),1], 'gs', ms=10, mfc='none', mec='g', zs=self._gridFy[self._hangingFy.keys(),2]) for key in self._hangingFy.keys(): for hf in self._hangingFy[key]: ind = [key, hf[0]] - ax.plot(self.gridFy[ind,0], self.gridFy[ind,1], 'g:', zs=self.gridFy[ind,2]) + ax.plot(self._gridFy[ind,0], self._gridFy[ind,1], 'g:', zs=self._gridFy[ind,2]) if facesZ: - ax.plot(self.gridFz[:,0], self.gridFz[:,1], 'g^', zs=self.gridFz[:,2]) - ax.plot(self.gridFz[self._hangingFz.keys(),0], self.gridFz[self._hangingFz.keys(),1], 'gs', ms=10, mfc='none', mec='g', zs=self.gridFz[self._hangingFz.keys(),2]) + ax.plot(self._gridFz[:,0], self._gridFz[:,1], 'g^', zs=self._gridFz[:,2]) + ax.plot(self._gridFz[self._hangingFz.keys(),0], self._gridFz[self._hangingFz.keys(),1], 'gs', ms=10, mfc='none', mec='g', zs=self._gridFz[self._hangingFz.keys(),2]) for key in self._hangingFz.keys(): for hf in self._hangingFz[key]: ind = [key, hf[0]] - ax.plot(self.gridFz[ind,0], self.gridFz[ind,1], 'g:', zs=self.gridFz[ind,2]) + ax.plot(self._gridFz[ind,0], self._gridFz[ind,1], 'g:', zs=self._gridFz[ind,2]) if edgesX: - ax.plot(self.gridEx[:,0], self.gridEx[:,1], 'k>', zs=self.gridEx[:,2]) - ax.plot(self.gridEx[self._hangingEx.keys(),0], self.gridEx[self._hangingEx.keys(),1], 'ks', ms=10, mfc='none', mec='k', zs=self.gridEx[self._hangingEx.keys(),2]) + ax.plot(self._gridEx[:,0], self._gridEx[:,1], 'k>', zs=self._gridEx[:,2]) + ax.plot(self._gridEx[self._hangingEx.keys(),0], self._gridEx[self._hangingEx.keys(),1], 'ks', ms=10, mfc='none', mec='k', zs=self._gridEx[self._hangingEx.keys(),2]) for key in self._hangingEx.keys(): for hf in self._hangingEx[key]: ind = [key, hf[0]] - ax.plot(self.gridEx[ind,0], self.gridEx[ind,1], 'k:', zs=self.gridEx[ind,2]) + ax.plot(self._gridEx[ind,0], self._gridEx[ind,1], 'k:', zs=self._gridEx[ind,2]) if edgesY: - ax.plot(self.gridEy[:,0], self.gridEy[:,1], 'k<', zs=self.gridEy[:,2]) - ax.plot(self.gridEy[self._hangingEy.keys(),0], self.gridEy[self._hangingEy.keys(),1], 'ks', ms=10, mfc='none', mec='k', zs=self.gridEy[self._hangingEy.keys(),2]) + ax.plot(self._gridEy[:,0], self._gridEy[:,1], 'k<', zs=self._gridEy[:,2]) + ax.plot(self._gridEy[self._hangingEy.keys(),0], self._gridEy[self._hangingEy.keys(),1], 'ks', ms=10, mfc='none', mec='k', zs=self._gridEy[self._hangingEy.keys(),2]) for key in self._hangingEy.keys(): for hf in self._hangingEy[key]: ind = [key, hf[0]] - ax.plot(self.gridEy[ind,0], self.gridEy[ind,1], 'k:', zs=self.gridEy[ind,2]) + ax.plot(self._gridEy[ind,0], self._gridEy[ind,1], 'k:', zs=self._gridEy[ind,2]) if edgesZ: - ax.plot(self.gridEz[:,0], self.gridEz[:,1], 'k^', zs=self.gridEz[:,2]) - ax.plot(self.gridEz[self._hangingEz.keys(),0], self.gridEz[self._hangingEz.keys(),1], 'ks', ms=10, mfc='none', mec='k', zs=self.gridEz[self._hangingEz.keys(),2]) + ax.plot(self._gridEz[:,0], self._gridEz[:,1], 'k^', zs=self._gridEz[:,2]) + ax.plot(self._gridEz[self._hangingEz.keys(),0], self._gridEz[self._hangingEz.keys(),1], 'ks', ms=10, mfc='none', mec='k', zs=self._gridEz[self._hangingEz.keys(),2]) for key in self._hangingEz.keys(): for hf in self._hangingEz[key]: ind = [key, hf[0]] - ax.plot(self.gridEz[ind,0], self.gridEz[ind,1], 'k:', zs=self.gridEz[ind,2]) + ax.plot(self._gridEz[ind,0], self._gridEz[ind,1], 'k:', zs=self._gridEz[ind,2]) # ax.axis('equal') diff --git a/SimPEG/Mesh/TreeUtils.c b/SimPEG/Mesh/TreeUtils.c new file mode 100644 index 00000000..26fbafec --- /dev/null +++ b/SimPEG/Mesh/TreeUtils.c @@ -0,0 +1,2843 @@ +/* Generated by Cython 0.22.1 */ + +/* BEGIN: Cython Metadata +{ + "distutils": {} +} +END: Cython Metadata */ + +#define PY_SSIZE_T_CLEAN +#ifndef CYTHON_USE_PYLONG_INTERNALS +#ifdef PYLONG_BITS_IN_DIGIT +#define CYTHON_USE_PYLONG_INTERNALS 0 +#else +#include "pyconfig.h" +#ifdef PYLONG_BITS_IN_DIGIT +#define CYTHON_USE_PYLONG_INTERNALS 1 +#else +#define CYTHON_USE_PYLONG_INTERNALS 0 +#endif +#endif +#endif +#include "Python.h" +#ifndef Py_PYTHON_H + #error Python headers needed to compile C extensions, please install development version of Python. +#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03020000) + #error Cython requires Python 2.6+ or Python 3.2+. +#else +#define CYTHON_ABI "0_22_1" +#include +#ifndef offsetof +#define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) +#endif +#if !defined(WIN32) && !defined(MS_WINDOWS) + #ifndef __stdcall + #define __stdcall + #endif + #ifndef __cdecl + #define __cdecl + #endif + #ifndef __fastcall + #define __fastcall + #endif +#endif +#ifndef DL_IMPORT + #define DL_IMPORT(t) t +#endif +#ifndef DL_EXPORT + #define DL_EXPORT(t) t +#endif +#ifndef PY_LONG_LONG + #define PY_LONG_LONG LONG_LONG +#endif +#ifndef Py_HUGE_VAL + #define Py_HUGE_VAL HUGE_VAL +#endif +#ifdef PYPY_VERSION +#define CYTHON_COMPILING_IN_PYPY 1 +#define CYTHON_COMPILING_IN_CPYTHON 0 +#else +#define CYTHON_COMPILING_IN_PYPY 0 +#define CYTHON_COMPILING_IN_CPYTHON 1 +#endif +#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600 && !defined(Py_OptimizeFlag) +#define Py_OptimizeFlag 0 +#endif +#define __PYX_BUILD_PY_SSIZE_T "n" +#define CYTHON_FORMAT_SSIZE_T "z" +#if PY_MAJOR_VERSION < 3 + #define __Pyx_BUILTIN_MODULE_NAME "__builtin__" + #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \ + PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) + #define __Pyx_DefaultClassType PyClass_Type +#else + #define __Pyx_BUILTIN_MODULE_NAME "builtins" + #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \ + PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) + #define __Pyx_DefaultClassType PyType_Type +#endif +#ifndef Py_TPFLAGS_CHECKTYPES + #define Py_TPFLAGS_CHECKTYPES 0 +#endif +#ifndef Py_TPFLAGS_HAVE_INDEX + #define Py_TPFLAGS_HAVE_INDEX 0 +#endif +#ifndef Py_TPFLAGS_HAVE_NEWBUFFER + #define Py_TPFLAGS_HAVE_NEWBUFFER 0 +#endif +#ifndef Py_TPFLAGS_HAVE_FINALIZE + #define Py_TPFLAGS_HAVE_FINALIZE 0 +#endif +#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND) + #define CYTHON_PEP393_ENABLED 1 + #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ? \ + 0 : _PyUnicode_Ready((PyObject *)(op))) + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) + #define __Pyx_PyUnicode_KIND(u) PyUnicode_KIND(u) + #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u) + #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) +#else + #define CYTHON_PEP393_ENABLED 0 + #define __Pyx_PyUnicode_READY(op) (0) + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i])) + #define __Pyx_PyUnicode_KIND(u) (sizeof(Py_UNICODE)) + #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u)) + #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i])) +#endif +#if CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b) + #define __Pyx_PyFrozenSet_Size(s) PyObject_Size(s) +#else + #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ? \ + PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b)) + #define __Pyx_PyFrozenSet_Size(s) PySet_Size(s) +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyUnicode_Contains) + #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) +#endif +#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) +#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b) +#else + #define __Pyx_PyString_Format(a, b) PyString_Format(a, b) +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyBaseString_Type PyUnicode_Type + #define PyStringObject PyUnicodeObject + #define PyString_Type PyUnicode_Type + #define PyString_Check PyUnicode_Check + #define PyString_CheckExact PyUnicode_CheckExact +#endif +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj) + #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj) +#else + #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj)) + #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj)) +#endif +#ifndef PySet_CheckExact + #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type) +#endif +#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) +#if PY_MAJOR_VERSION >= 3 + #define PyIntObject PyLongObject + #define PyInt_Type PyLong_Type + #define PyInt_Check(op) PyLong_Check(op) + #define PyInt_CheckExact(op) PyLong_CheckExact(op) + #define PyInt_FromString PyLong_FromString + #define PyInt_FromUnicode PyLong_FromUnicode + #define PyInt_FromLong PyLong_FromLong + #define PyInt_FromSize_t PyLong_FromSize_t + #define PyInt_FromSsize_t PyLong_FromSsize_t + #define PyInt_AsLong PyLong_AsLong + #define PyInt_AS_LONG PyLong_AS_LONG + #define PyInt_AsSsize_t PyLong_AsSsize_t + #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask + #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask + #define PyNumber_Int PyNumber_Long +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyBoolObject PyLongObject +#endif +#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY + #ifndef PyUnicode_InternFromString + #define PyUnicode_InternFromString(s) PyUnicode_FromString(s) + #endif +#endif +#if PY_VERSION_HEX < 0x030200A4 + typedef long Py_hash_t; + #define __Pyx_PyInt_FromHash_t PyInt_FromLong + #define __Pyx_PyInt_AsHash_t PyInt_AsLong +#else + #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t + #define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t +#endif +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func)) +#else + #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass) +#endif +#ifndef CYTHON_INLINE + #if defined(__GNUC__) + #define CYTHON_INLINE __inline__ + #elif defined(_MSC_VER) + #define CYTHON_INLINE __inline + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_INLINE inline + #else + #define CYTHON_INLINE + #endif +#endif +#ifndef CYTHON_RESTRICT + #if defined(__GNUC__) + #define CYTHON_RESTRICT __restrict__ + #elif defined(_MSC_VER) && _MSC_VER >= 1400 + #define CYTHON_RESTRICT __restrict + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_RESTRICT restrict + #else + #define CYTHON_RESTRICT + #endif +#endif +#ifdef NAN +#define __PYX_NAN() ((float) NAN) +#else +static CYTHON_INLINE float __PYX_NAN() { + /* Initialize NaN. The sign is irrelevant, an exponent with all bits 1 and + a nonzero mantissa means NaN. If the first bit in the mantissa is 1, it is + a quiet NaN. */ + float value; + memset(&value, 0xFF, sizeof(value)); + return value; +} +#endif +#define __Pyx_void_to_None(void_result) (void_result, Py_INCREF(Py_None), Py_None) +#ifdef __cplusplus +template +void __Pyx_call_destructor(T* x) { + x->~T(); +} +template +class __Pyx_FakeReference { + public: + __Pyx_FakeReference() : ptr(NULL) { } + __Pyx_FakeReference(T& ref) : ptr(&ref) { } + T *operator->() { return ptr; } + operator T&() { return *ptr; } + private: + T *ptr; +}; +#endif + + +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) + #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) +#else + #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y) + #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y) +#endif + +#ifndef __PYX_EXTERN_C + #ifdef __cplusplus + #define __PYX_EXTERN_C extern "C" + #else + #define __PYX_EXTERN_C extern + #endif +#endif + +#if defined(WIN32) || defined(MS_WINDOWS) +#define _USE_MATH_DEFINES +#endif +#include +#define __PYX_HAVE__SimPEG__Mesh__TreeUtils +#define __PYX_HAVE_API__SimPEG__Mesh__TreeUtils +#ifdef _OPENMP +#include +#endif /* _OPENMP */ + +#ifdef PYREX_WITHOUT_ASSERTIONS +#define CYTHON_WITHOUT_ASSERTIONS +#endif + +#ifndef CYTHON_UNUSED +# if defined(__GNUC__) +# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +#endif +#ifndef CYTHON_NCP_UNUSED +# if CYTHON_COMPILING_IN_CPYTHON +# define CYTHON_NCP_UNUSED +# else +# define CYTHON_NCP_UNUSED CYTHON_UNUSED +# endif +#endif +typedef struct {PyObject **p; char *s; const Py_ssize_t n; const char* encoding; + const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; + +#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0 +#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 0 +#define __PYX_DEFAULT_STRING_ENCODING "" +#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString +#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize +#define __Pyx_fits_Py_ssize_t(v, type, is_signed) ( \ + (sizeof(type) < sizeof(Py_ssize_t)) || \ + (sizeof(type) > sizeof(Py_ssize_t) && \ + likely(v < (type)PY_SSIZE_T_MAX || \ + v == (type)PY_SSIZE_T_MAX) && \ + (!is_signed || likely(v > (type)PY_SSIZE_T_MIN || \ + v == (type)PY_SSIZE_T_MIN))) || \ + (sizeof(type) == sizeof(Py_ssize_t) && \ + (is_signed || likely(v < (type)PY_SSIZE_T_MAX || \ + v == (type)PY_SSIZE_T_MAX))) ) +static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject*); +static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); +#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s)) +#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l) +#define __Pyx_PyBytes_FromString PyBytes_FromString +#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); +#if PY_MAJOR_VERSION < 3 + #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString + #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize +#else + #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString + #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize +#endif +#define __Pyx_PyObject_AsSString(s) ((signed char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_FromCString(s) __Pyx_PyObject_FromString((const char*)s) +#define __Pyx_PyBytes_FromCString(s) __Pyx_PyBytes_FromString((const char*)s) +#define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) +#define __Pyx_PyStr_FromCString(s) __Pyx_PyStr_FromString((const char*)s) +#define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s) +#if PY_MAJOR_VERSION < 3 +static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u) +{ + const Py_UNICODE *u_end = u; + while (*u_end++) ; + return (size_t)(u_end - u - 1); +} +#else +#define __Pyx_Py_UNICODE_strlen Py_UNICODE_strlen +#endif +#define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u)) +#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode +#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode +#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None) +#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False)) +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); +static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x); +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); +static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); +#if CYTHON_COMPILING_IN_CPYTHON +#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) +#else +#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x) +#endif +#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x)) +#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII +static int __Pyx_sys_getdefaultencoding_not_ascii; +static int __Pyx_init_sys_getdefaultencoding_params(void) { + PyObject* sys; + PyObject* default_encoding = NULL; + PyObject* ascii_chars_u = NULL; + PyObject* ascii_chars_b = NULL; + const char* default_encoding_c; + sys = PyImport_ImportModule("sys"); + if (!sys) goto bad; + default_encoding = PyObject_CallMethod(sys, (char*) "getdefaultencoding", NULL); + Py_DECREF(sys); + if (!default_encoding) goto bad; + default_encoding_c = PyBytes_AsString(default_encoding); + if (!default_encoding_c) goto bad; + if (strcmp(default_encoding_c, "ascii") == 0) { + __Pyx_sys_getdefaultencoding_not_ascii = 0; + } else { + char ascii_chars[128]; + int c; + for (c = 0; c < 128; c++) { + ascii_chars[c] = c; + } + __Pyx_sys_getdefaultencoding_not_ascii = 1; + ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL); + if (!ascii_chars_u) goto bad; + ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL); + if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) { + PyErr_Format( + PyExc_ValueError, + "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.", + default_encoding_c); + goto bad; + } + Py_DECREF(ascii_chars_u); + Py_DECREF(ascii_chars_b); + } + Py_DECREF(default_encoding); + return 0; +bad: + Py_XDECREF(default_encoding); + Py_XDECREF(ascii_chars_u); + Py_XDECREF(ascii_chars_b); + return -1; +} +#endif +#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3 +#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL) +#else +#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL) +#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT +static char* __PYX_DEFAULT_STRING_ENCODING; +static int __Pyx_init_sys_getdefaultencoding_params(void) { + PyObject* sys; + PyObject* default_encoding = NULL; + char* default_encoding_c; + sys = PyImport_ImportModule("sys"); + if (!sys) goto bad; + default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL); + Py_DECREF(sys); + if (!default_encoding) goto bad; + default_encoding_c = PyBytes_AsString(default_encoding); + if (!default_encoding_c) goto bad; + __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c)); + if (!__PYX_DEFAULT_STRING_ENCODING) goto bad; + strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c); + Py_DECREF(default_encoding); + return 0; +bad: + Py_XDECREF(default_encoding); + return -1; +} +#endif +#endif + + +/* Test for GCC > 2.95 */ +#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))) + #define likely(x) __builtin_expect(!!(x), 1) + #define unlikely(x) __builtin_expect(!!(x), 0) +#else /* !__GNUC__ or GCC < 2.95 */ + #define likely(x) (x) + #define unlikely(x) (x) +#endif /* __GNUC__ */ + +static PyObject *__pyx_m; +static PyObject *__pyx_d; +static PyObject *__pyx_b; +static PyObject *__pyx_empty_tuple; +static PyObject *__pyx_empty_bytes; +static int __pyx_lineno; +static int __pyx_clineno = 0; +static const char * __pyx_cfilenm= __FILE__; +static const char *__pyx_filename; + + +static const char *__pyx_f[] = { + "SimPEG/Mesh/TreeUtils.pyx", +}; + +/*--- Type declarations ---*/ + +/* --- Runtime support code (head) --- */ +#ifndef CYTHON_REFNANNY + #define CYTHON_REFNANNY 0 +#endif +#if CYTHON_REFNANNY + typedef struct { + void (*INCREF)(void*, PyObject*, int); + void (*DECREF)(void*, PyObject*, int); + void (*GOTREF)(void*, PyObject*, int); + void (*GIVEREF)(void*, PyObject*, int); + void* (*SetupContext)(const char*, int, const char*); + void (*FinishContext)(void**); + } __Pyx_RefNannyAPIStruct; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); + #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL; +#ifdef WITH_THREAD + #define __Pyx_RefNannySetupContext(name, acquire_gil) \ + if (acquire_gil) { \ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \ + PyGILState_Release(__pyx_gilstate_save); \ + } else { \ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \ + } +#else + #define __Pyx_RefNannySetupContext(name, acquire_gil) \ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__) +#endif + #define __Pyx_RefNannyFinishContext() \ + __Pyx_RefNanny->FinishContext(&__pyx_refnanny) + #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0) + #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0) + #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0) + #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0) +#else + #define __Pyx_RefNannyDeclarations + #define __Pyx_RefNannySetupContext(name, acquire_gil) + #define __Pyx_RefNannyFinishContext() + #define __Pyx_INCREF(r) Py_INCREF(r) + #define __Pyx_DECREF(r) Py_DECREF(r) + #define __Pyx_GOTREF(r) + #define __Pyx_GIVEREF(r) + #define __Pyx_XINCREF(r) Py_XINCREF(r) + #define __Pyx_XDECREF(r) Py_XDECREF(r) + #define __Pyx_XGOTREF(r) + #define __Pyx_XGIVEREF(r) +#endif +#define __Pyx_XDECREF_SET(r, v) do { \ + PyObject *tmp = (PyObject *) r; \ + r = v; __Pyx_XDECREF(tmp); \ + } while (0) +#define __Pyx_DECREF_SET(r, v) do { \ + PyObject *tmp = (PyObject *) r; \ + r = v; __Pyx_DECREF(tmp); \ + } while (0) +#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0) +#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0) + +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) { + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_getattro)) + return tp->tp_getattro(obj, attr_name); +#if PY_MAJOR_VERSION < 3 + if (likely(tp->tp_getattr)) + return tp->tp_getattr(obj, PyString_AS_STRING(attr_name)); +#endif + return PyObject_GetAttr(obj, attr_name); +} +#else +#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n) +#endif + +static PyObject *__Pyx_GetBuiltinName(PyObject *name); + +static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, + Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); + +static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); + +static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \ + PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \ + const char* function_name); + +static CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed, + const char *name, int exact); + +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE int __Pyx_ListComp_Append(PyObject* list, PyObject* x) { + PyListObject* L = (PyListObject*) list; + Py_ssize_t len = Py_SIZE(list); + if (likely(L->allocated > len)) { + Py_INCREF(x); + PyList_SET_ITEM(list, len, x); + Py_SIZE(list) = len+1; + return 0; + } + return PyList_Append(list, x); +} +#else +#define __Pyx_ListComp_Append(L,x) PyList_Append(L,x) +#endif + +static CYTHON_INLINE int __Pyx_div_int(int, int); /* proto */ + +#ifndef __PYX_FORCE_INIT_THREADS + #define __PYX_FORCE_INIT_THREADS 0 +#endif + +#define UNARY_NEG_WOULD_OVERFLOW(x) (((x) < 0) & ((unsigned long)(x) == 0-(unsigned long)(x))) + +static CYTHON_INLINE int __Pyx_mod_int(int, int); /* proto */ + +static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name); + +#define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \ + __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) : \ + (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) : \ + __Pyx_GetItemInt_Generic(o, to_py_func(i)))) +#define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \ + __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \ + (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL)) +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, + int wraparound, int boundscheck); +#define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \ + __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \ + (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL)) +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, + int wraparound, int boundscheck); +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j); +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, + int is_list, int wraparound, int boundscheck); + +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw); +#else +#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw) +#endif + +static CYTHON_INLINE long __Pyx_div_long(long, long); /* proto */ + +#define __Pyx_SetItemInt(o, i, v, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \ + __Pyx_SetItemInt_Fast(o, (Py_ssize_t)i, v, is_list, wraparound, boundscheck) : \ + (is_list ? (PyErr_SetString(PyExc_IndexError, "list assignment index out of range"), -1) : \ + __Pyx_SetItemInt_Generic(o, to_py_func(i), v))) +static CYTHON_INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v); +static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v, + int is_list, int wraparound, int boundscheck); + +typedef struct { + int code_line; + PyCodeObject* code_object; +} __Pyx_CodeObjectCacheEntry; +struct __Pyx_CodeObjectCache { + int count; + int max_count; + __Pyx_CodeObjectCacheEntry* entries; +}; +static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL}; +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line); +static PyCodeObject *__pyx_find_code_object(int code_line); +static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object); + +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename); + +static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *); + +static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *); + +static CYTHON_INLINE long __Pyx_pow_long(long, long); /* proto */ + +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value); + +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value); + +static int __Pyx_check_binary_version(void); + +static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); + + +/* Module declarations from 'SimPEG.Mesh.TreeUtils' */ +#define __Pyx_MODULE_NAME "SimPEG.Mesh.TreeUtils" +int __pyx_module_is_main_SimPEG__Mesh__TreeUtils = 0; + +/* Implementation of 'SimPEG.Mesh.TreeUtils' */ +static PyObject *__pyx_builtin_range; +static PyObject *__pyx_pf_6SimPEG_4Mesh_9TreeUtils_bitrange(CYTHON_UNUSED PyObject *__pyx_self, long __pyx_v_x, int __pyx_v_width, int __pyx_v_start, int __pyx_v_end); /* proto */ +static PyObject *__pyx_pf_6SimPEG_4Mesh_9TreeUtils_2index(CYTHON_UNUSED PyObject *__pyx_self, int __pyx_v_dimension, int __pyx_v_bits, int __pyx_v_levelBits, PyObject *__pyx_v_p, int __pyx_v_level); /* proto */ +static PyObject *__pyx_pf_6SimPEG_4Mesh_9TreeUtils_4point(CYTHON_UNUSED PyObject *__pyx_self, int __pyx_v_dimension, int __pyx_v_bits, int __pyx_v_levelBits, long __pyx_v_idx); /* proto */ +static char __pyx_k_b[] = "b"; +static char __pyx_k_i[] = "i"; +static char __pyx_k_n[] = "n"; +static char __pyx_k_p[] = "p"; +static char __pyx_k_x[] = "x"; +static char __pyx_k__3[] = "_"; +static char __pyx_k_end[] = "end"; +static char __pyx_k_idx[] = "idx"; +static char __pyx_k_bits[] = "bits"; +static char __pyx_k_main[] = "__main__"; +static char __pyx_k_poff[] = "poff"; +static char __pyx_k_test[] = "__test__"; +static char __pyx_k_index[] = "index"; +static char __pyx_k_level[] = "level"; +static char __pyx_k_point[] = "point"; +static char __pyx_k_range[] = "range"; +static char __pyx_k_start[] = "start"; +static char __pyx_k_width[] = "width"; +static char __pyx_k_bitoff[] = "bitoff"; +static char __pyx_k_iwidth[] = "iwidth"; +static char __pyx_k_bitrange[] = "bitrange"; +static char __pyx_k_dimension[] = "dimension"; +static char __pyx_k_levelBits[] = "levelBits"; +static char __pyx_k_SimPEG_Mesh_TreeUtils[] = "SimPEG.Mesh.TreeUtils"; +static char __pyx_k_The_Z_order_curve_is_generated[] = "\n The Z-order curve is generated by interleaving the bits of an offset.\n\n See also:\n\n https://github.com/cortesi/scurve\n Aldo Cortesi \n\n"; +static char __pyx_k_Users_rowan_git_simpeg_simpeg_S[] = "/Users/rowan/git/simpeg/simpeg/SimPEG/Mesh/TreeUtils.pyx"; +static PyObject *__pyx_n_s_SimPEG_Mesh_TreeUtils; +static PyObject *__pyx_kp_s_Users_rowan_git_simpeg_simpeg_S; +static PyObject *__pyx_n_s__3; +static PyObject *__pyx_n_s_b; +static PyObject *__pyx_n_s_bitoff; +static PyObject *__pyx_n_s_bitrange; +static PyObject *__pyx_n_s_bits; +static PyObject *__pyx_n_s_dimension; +static PyObject *__pyx_n_s_end; +static PyObject *__pyx_n_s_i; +static PyObject *__pyx_n_s_idx; +static PyObject *__pyx_n_s_index; +static PyObject *__pyx_n_s_iwidth; +static PyObject *__pyx_n_s_level; +static PyObject *__pyx_n_s_levelBits; +static PyObject *__pyx_n_s_main; +static PyObject *__pyx_n_s_n; +static PyObject *__pyx_n_s_p; +static PyObject *__pyx_n_s_poff; +static PyObject *__pyx_n_s_point; +static PyObject *__pyx_n_s_range; +static PyObject *__pyx_n_s_start; +static PyObject *__pyx_n_s_test; +static PyObject *__pyx_n_s_width; +static PyObject *__pyx_n_s_x; +static PyObject *__pyx_int_0; +static PyObject *__pyx_tuple_; +static PyObject *__pyx_tuple__4; +static PyObject *__pyx_tuple__6; +static PyObject *__pyx_codeobj__2; +static PyObject *__pyx_codeobj__5; +static PyObject *__pyx_codeobj__7; + +/* "SimPEG/Mesh/TreeUtils.pyx":17 + * """ + * + * def bitrange(long x, int width, int start, int end): # <<<<<<<<<<<<<< + * """ + * Extract a bit range as an integer. + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_6SimPEG_4Mesh_9TreeUtils_1bitrange(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static char __pyx_doc_6SimPEG_4Mesh_9TreeUtils_bitrange[] = "\n Extract a bit range as an integer.\n (start, end) is inclusive lower bound, exclusive upper bound.\n "; +static PyMethodDef __pyx_mdef_6SimPEG_4Mesh_9TreeUtils_1bitrange = {"bitrange", (PyCFunction)__pyx_pw_6SimPEG_4Mesh_9TreeUtils_1bitrange, METH_VARARGS|METH_KEYWORDS, __pyx_doc_6SimPEG_4Mesh_9TreeUtils_bitrange}; +static PyObject *__pyx_pw_6SimPEG_4Mesh_9TreeUtils_1bitrange(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + long __pyx_v_x; + int __pyx_v_width; + int __pyx_v_start; + int __pyx_v_end; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("bitrange (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_x,&__pyx_n_s_width,&__pyx_n_s_start,&__pyx_n_s_end,0}; + PyObject* values[4] = {0,0,0,0}; + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); + case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_x)) != 0)) kw_args--; + else goto __pyx_L5_argtuple_error; + case 1: + if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_width)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("bitrange", 1, 4, 4, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + case 2: + if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_start)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("bitrange", 1, 4, 4, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + case 3: + if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_end)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("bitrange", 1, 4, 4, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "bitrange") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + } else if (PyTuple_GET_SIZE(__pyx_args) != 4) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + values[3] = PyTuple_GET_ITEM(__pyx_args, 3); + } + __pyx_v_x = __Pyx_PyInt_As_long(values[0]); if (unlikely((__pyx_v_x == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_v_width = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_width == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_v_start = __Pyx_PyInt_As_int(values[2]); if (unlikely((__pyx_v_start == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_v_end = __Pyx_PyInt_As_int(values[3]); if (unlikely((__pyx_v_end == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("bitrange", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_L3_error:; + __Pyx_AddTraceback("SimPEG.Mesh.TreeUtils.bitrange", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_6SimPEG_4Mesh_9TreeUtils_bitrange(__pyx_self, __pyx_v_x, __pyx_v_width, __pyx_v_start, __pyx_v_end); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_6SimPEG_4Mesh_9TreeUtils_bitrange(CYTHON_UNUSED PyObject *__pyx_self, long __pyx_v_x, int __pyx_v_width, int __pyx_v_start, int __pyx_v_end) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("bitrange", 0); + + /* "SimPEG/Mesh/TreeUtils.pyx":22 + * (start, end) is inclusive lower bound, exclusive upper bound. + * """ + * return x >> (width-end) & ((2**(end-start))-1) # <<<<<<<<<<<<<< + * + * def index(int dimension, int bits, int levelBits, list p, int level): + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __Pyx_PyInt_From_long(((__pyx_v_x >> (__pyx_v_width - __pyx_v_end)) & (__Pyx_pow_long(2, ((long)(__pyx_v_end - __pyx_v_start))) - 1))); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "SimPEG/Mesh/TreeUtils.pyx":17 + * """ + * + * def bitrange(long x, int width, int start, int end): # <<<<<<<<<<<<<< + * """ + * Extract a bit range as an integer. + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("SimPEG.Mesh.TreeUtils.bitrange", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "SimPEG/Mesh/TreeUtils.pyx":24 + * return x >> (width-end) & ((2**(end-start))-1) + * + * def index(int dimension, int bits, int levelBits, list p, int level): # <<<<<<<<<<<<<< + * cdef long idx = 0 + * cdef int iwidth + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_6SimPEG_4Mesh_9TreeUtils_3index(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static PyMethodDef __pyx_mdef_6SimPEG_4Mesh_9TreeUtils_3index = {"index", (PyCFunction)__pyx_pw_6SimPEG_4Mesh_9TreeUtils_3index, METH_VARARGS|METH_KEYWORDS, 0}; +static PyObject *__pyx_pw_6SimPEG_4Mesh_9TreeUtils_3index(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + int __pyx_v_dimension; + int __pyx_v_bits; + int __pyx_v_levelBits; + PyObject *__pyx_v_p = 0; + int __pyx_v_level; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("index (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_dimension,&__pyx_n_s_bits,&__pyx_n_s_levelBits,&__pyx_n_s_p,&__pyx_n_s_level,0}; + PyObject* values[5] = {0,0,0,0,0}; + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4); + case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); + case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_dimension)) != 0)) kw_args--; + else goto __pyx_L5_argtuple_error; + case 1: + if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_bits)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("index", 1, 5, 5, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + case 2: + if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_levelBits)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("index", 1, 5, 5, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + case 3: + if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_p)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("index", 1, 5, 5, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + case 4: + if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_level)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("index", 1, 5, 5, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "index") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + } else if (PyTuple_GET_SIZE(__pyx_args) != 5) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + values[3] = PyTuple_GET_ITEM(__pyx_args, 3); + values[4] = PyTuple_GET_ITEM(__pyx_args, 4); + } + __pyx_v_dimension = __Pyx_PyInt_As_int(values[0]); if (unlikely((__pyx_v_dimension == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_v_bits = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_bits == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_v_levelBits = __Pyx_PyInt_As_int(values[2]); if (unlikely((__pyx_v_levelBits == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_v_p = ((PyObject*)values[3]); + __pyx_v_level = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_level == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("index", 1, 5, 5, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_L3_error:; + __Pyx_AddTraceback("SimPEG.Mesh.TreeUtils.index", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_p), (&PyList_Type), 1, "p", 1))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_r = __pyx_pf_6SimPEG_4Mesh_9TreeUtils_2index(__pyx_self, __pyx_v_dimension, __pyx_v_bits, __pyx_v_levelBits, __pyx_v_p, __pyx_v_level); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __pyx_r = NULL; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_6SimPEG_4Mesh_9TreeUtils_2index(CYTHON_UNUSED PyObject *__pyx_self, int __pyx_v_dimension, int __pyx_v_bits, int __pyx_v_levelBits, PyObject *__pyx_v_p, int __pyx_v_level) { + long __pyx_v_idx; + int __pyx_v_iwidth; + int __pyx_v_i; + long __pyx_v_b; + int __pyx_v_bitoff; + long __pyx_v_poff; + PyObject *__pyx_v__ = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + Py_ssize_t __pyx_t_3; + PyObject *__pyx_t_4 = NULL; + int __pyx_t_5; + int __pyx_t_6; + int __pyx_t_7; + PyObject *__pyx_t_8 = NULL; + PyObject *__pyx_t_9 = NULL; + PyObject *__pyx_t_10 = NULL; + PyObject *__pyx_t_11 = NULL; + PyObject *__pyx_t_12 = NULL; + long __pyx_t_13; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("index", 0); + __Pyx_INCREF(__pyx_v_p); + + /* "SimPEG/Mesh/TreeUtils.pyx":25 + * + * def index(int dimension, int bits, int levelBits, list p, int level): + * cdef long idx = 0 # <<<<<<<<<<<<<< + * cdef int iwidth + * cdef int i + */ + __pyx_v_idx = 0; + + /* "SimPEG/Mesh/TreeUtils.pyx":31 + * cdef int bitoff + * + * p = [_ for _ in p] # <<<<<<<<<<<<<< + * + * p.reverse() + */ + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + if (unlikely(__pyx_v_p == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_t_2 = __pyx_v_p; __Pyx_INCREF(__pyx_t_2); __pyx_t_3 = 0; + for (;;) { + if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_2)) break; + #if CYTHON_COMPILING_IN_CPYTHON + __pyx_t_4 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_4); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + #else + __pyx_t_4 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_4); + #endif + __Pyx_XDECREF_SET(__pyx_v__, __pyx_t_4); + __pyx_t_4 = 0; + if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_v__))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF_SET(__pyx_v_p, ((PyObject*)__pyx_t_1)); + __pyx_t_1 = 0; + + /* "SimPEG/Mesh/TreeUtils.pyx":33 + * p = [_ for _ in p] + * + * p.reverse() # <<<<<<<<<<<<<< + * iwidth = bits * dimension + * for i in range(iwidth): + */ + __pyx_t_5 = PyList_Reverse(__pyx_v_p); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 33; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + + /* "SimPEG/Mesh/TreeUtils.pyx":34 + * + * p.reverse() + * iwidth = bits * dimension # <<<<<<<<<<<<<< + * for i in range(iwidth): + * bitoff = bits-(i/dimension)-1 + */ + __pyx_v_iwidth = (__pyx_v_bits * __pyx_v_dimension); + + /* "SimPEG/Mesh/TreeUtils.pyx":35 + * p.reverse() + * iwidth = bits * dimension + * for i in range(iwidth): # <<<<<<<<<<<<<< + * bitoff = bits-(i/dimension)-1 + * poff = dimension-(i%dimension)-1 + */ + __pyx_t_6 = __pyx_v_iwidth; + for (__pyx_t_7 = 0; __pyx_t_7 < __pyx_t_6; __pyx_t_7+=1) { + __pyx_v_i = __pyx_t_7; + + /* "SimPEG/Mesh/TreeUtils.pyx":36 + * iwidth = bits * dimension + * for i in range(iwidth): + * bitoff = bits-(i/dimension)-1 # <<<<<<<<<<<<<< + * poff = dimension-(i%dimension)-1 + * b = bitrange(p[poff], bits, bitoff, bitoff+1) << i + */ + if (unlikely(__pyx_v_dimension == 0)) { + #ifdef WITH_THREAD + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); + #endif + PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero"); + #ifdef WITH_THREAD + PyGILState_Release(__pyx_gilstate_save); + #endif + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + else if (sizeof(int) == sizeof(long) && (!(((int)-1) > 0)) && unlikely(__pyx_v_dimension == (int)-1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(__pyx_v_i))) { + #ifdef WITH_THREAD + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); + #endif + PyErr_SetString(PyExc_OverflowError, "value too large to perform division"); + #ifdef WITH_THREAD + PyGILState_Release(__pyx_gilstate_save); + #endif + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_v_bitoff = ((__pyx_v_bits - __Pyx_div_int(__pyx_v_i, __pyx_v_dimension)) - 1); + + /* "SimPEG/Mesh/TreeUtils.pyx":37 + * for i in range(iwidth): + * bitoff = bits-(i/dimension)-1 + * poff = dimension-(i%dimension)-1 # <<<<<<<<<<<<<< + * b = bitrange(p[poff], bits, bitoff, bitoff+1) << i + * idx |= b + */ + if (unlikely(__pyx_v_dimension == 0)) { + #ifdef WITH_THREAD + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); + #endif + PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero"); + #ifdef WITH_THREAD + PyGILState_Release(__pyx_gilstate_save); + #endif + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_v_poff = ((__pyx_v_dimension - __Pyx_mod_int(__pyx_v_i, __pyx_v_dimension)) - 1); + + /* "SimPEG/Mesh/TreeUtils.pyx":38 + * bitoff = bits-(i/dimension)-1 + * poff = dimension-(i%dimension)-1 + * b = bitrange(p[poff], bits, bitoff, bitoff+1) << i # <<<<<<<<<<<<<< + * idx |= b + * + */ + __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_bitrange); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = __Pyx_GetItemInt_List(__pyx_v_p, __pyx_v_poff, long, 1, __Pyx_PyInt_From_long, 1, 1, 1); if (unlikely(__pyx_t_4 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_8 = __Pyx_PyInt_From_int(__pyx_v_bits); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_9 = __Pyx_PyInt_From_int(__pyx_v_bitoff); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_10 = __Pyx_PyInt_From_long((__pyx_v_bitoff + 1)); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_11 = NULL; + __pyx_t_3 = 0; + if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_11 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_11)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_11); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_3 = 1; + } + } + __pyx_t_12 = PyTuple_New(4+__pyx_t_3); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_12); + if (__pyx_t_11) { + __Pyx_GIVEREF(__pyx_t_11); PyTuple_SET_ITEM(__pyx_t_12, 0, __pyx_t_11); __pyx_t_11 = NULL; + } + __Pyx_GIVEREF(__pyx_t_4); + PyTuple_SET_ITEM(__pyx_t_12, 0+__pyx_t_3, __pyx_t_4); + __Pyx_GIVEREF(__pyx_t_8); + PyTuple_SET_ITEM(__pyx_t_12, 1+__pyx_t_3, __pyx_t_8); + __Pyx_GIVEREF(__pyx_t_9); + PyTuple_SET_ITEM(__pyx_t_12, 2+__pyx_t_3, __pyx_t_9); + __Pyx_GIVEREF(__pyx_t_10); + PyTuple_SET_ITEM(__pyx_t_12, 3+__pyx_t_3, __pyx_t_10); + __pyx_t_4 = 0; + __pyx_t_8 = 0; + __pyx_t_9 = 0; + __pyx_t_10 = 0; + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_12, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_i); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_12 = PyNumber_Lshift(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_12); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_13 = __Pyx_PyInt_As_long(__pyx_t_12); if (unlikely((__pyx_t_13 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + __pyx_v_b = __pyx_t_13; + + /* "SimPEG/Mesh/TreeUtils.pyx":39 + * poff = dimension-(i%dimension)-1 + * b = bitrange(p[poff], bits, bitoff, bitoff+1) << i + * idx |= b # <<<<<<<<<<<<<< + * + * return (idx << levelBits) + level + */ + __pyx_v_idx = (__pyx_v_idx | __pyx_v_b); + } + + /* "SimPEG/Mesh/TreeUtils.pyx":41 + * idx |= b + * + * return (idx << levelBits) + level # <<<<<<<<<<<<<< + * + * def point(int dimension, int bits, int levelBits, long idx): + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_12 = __Pyx_PyInt_From_long(((__pyx_v_idx << __pyx_v_levelBits) + __pyx_v_level)); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_12); + __pyx_r = __pyx_t_12; + __pyx_t_12 = 0; + goto __pyx_L0; + + /* "SimPEG/Mesh/TreeUtils.pyx":24 + * return x >> (width-end) & ((2**(end-start))-1) + * + * def index(int dimension, int bits, int levelBits, list p, int level): # <<<<<<<<<<<<<< + * cdef long idx = 0 + * cdef int iwidth + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_XDECREF(__pyx_t_10); + __Pyx_XDECREF(__pyx_t_11); + __Pyx_XDECREF(__pyx_t_12); + __Pyx_AddTraceback("SimPEG.Mesh.TreeUtils.index", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v__); + __Pyx_XDECREF(__pyx_v_p); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "SimPEG/Mesh/TreeUtils.pyx":43 + * return (idx << levelBits) + level + * + * def point(int dimension, int bits, int levelBits, long idx): # <<<<<<<<<<<<<< + * cdef list p + * cdef int iwidth + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_6SimPEG_4Mesh_9TreeUtils_5point(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static PyMethodDef __pyx_mdef_6SimPEG_4Mesh_9TreeUtils_5point = {"point", (PyCFunction)__pyx_pw_6SimPEG_4Mesh_9TreeUtils_5point, METH_VARARGS|METH_KEYWORDS, 0}; +static PyObject *__pyx_pw_6SimPEG_4Mesh_9TreeUtils_5point(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + int __pyx_v_dimension; + int __pyx_v_bits; + int __pyx_v_levelBits; + long __pyx_v_idx; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("point (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_dimension,&__pyx_n_s_bits,&__pyx_n_s_levelBits,&__pyx_n_s_idx,0}; + PyObject* values[4] = {0,0,0,0}; + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); + case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_dimension)) != 0)) kw_args--; + else goto __pyx_L5_argtuple_error; + case 1: + if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_bits)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("point", 1, 4, 4, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 43; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + case 2: + if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_levelBits)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("point", 1, 4, 4, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 43; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + case 3: + if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_idx)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("point", 1, 4, 4, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 43; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "point") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 43; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + } else if (PyTuple_GET_SIZE(__pyx_args) != 4) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + values[3] = PyTuple_GET_ITEM(__pyx_args, 3); + } + __pyx_v_dimension = __Pyx_PyInt_As_int(values[0]); if (unlikely((__pyx_v_dimension == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 43; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_v_bits = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_bits == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 43; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_v_levelBits = __Pyx_PyInt_As_int(values[2]); if (unlikely((__pyx_v_levelBits == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 43; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_v_idx = __Pyx_PyInt_As_long(values[3]); if (unlikely((__pyx_v_idx == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 43; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("point", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 43; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_L3_error:; + __Pyx_AddTraceback("SimPEG.Mesh.TreeUtils.point", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_6SimPEG_4Mesh_9TreeUtils_4point(__pyx_self, __pyx_v_dimension, __pyx_v_bits, __pyx_v_levelBits, __pyx_v_idx); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_6SimPEG_4Mesh_9TreeUtils_4point(CYTHON_UNUSED PyObject *__pyx_self, int __pyx_v_dimension, int __pyx_v_bits, int __pyx_v_levelBits, long __pyx_v_idx) { + PyObject *__pyx_v_p = 0; + int __pyx_v_iwidth; + int __pyx_v_i; + int __pyx_v_n; + long __pyx_v_b; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_t_2; + int __pyx_t_3; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + PyObject *__pyx_t_9 = NULL; + Py_ssize_t __pyx_t_10; + PyObject *__pyx_t_11 = NULL; + long __pyx_t_12; + int __pyx_t_13; + int __pyx_t_14; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("point", 0); + + /* "SimPEG/Mesh/TreeUtils.pyx":49 + * cdef long b + * + * n = idx & (2**levelBits-1) # <<<<<<<<<<<<<< + * idx = idx >> levelBits + * + */ + __pyx_v_n = (__pyx_v_idx & (__Pyx_pow_long(2, ((long)__pyx_v_levelBits)) - 1)); + + /* "SimPEG/Mesh/TreeUtils.pyx":50 + * + * n = idx & (2**levelBits-1) + * idx = idx >> levelBits # <<<<<<<<<<<<<< + * + * p = [0]*dimension + */ + __pyx_v_idx = (__pyx_v_idx >> __pyx_v_levelBits); + + /* "SimPEG/Mesh/TreeUtils.pyx":52 + * idx = idx >> levelBits + * + * p = [0]*dimension # <<<<<<<<<<<<<< + * iwidth = bits * dimension + * for i in range(iwidth): + */ + __pyx_t_1 = PyList_New(1 * ((__pyx_v_dimension<0) ? 0:__pyx_v_dimension)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 52; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + { Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < __pyx_v_dimension; __pyx_temp++) { + __Pyx_INCREF(__pyx_int_0); + __Pyx_GIVEREF(__pyx_int_0); + PyList_SET_ITEM(__pyx_t_1, __pyx_temp, __pyx_int_0); + } + } + __pyx_v_p = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + + /* "SimPEG/Mesh/TreeUtils.pyx":53 + * + * p = [0]*dimension + * iwidth = bits * dimension # <<<<<<<<<<<<<< + * for i in range(iwidth): + * b = bitrange(idx, iwidth, i, i+1) << (iwidth-i-1)/dimension + */ + __pyx_v_iwidth = (__pyx_v_bits * __pyx_v_dimension); + + /* "SimPEG/Mesh/TreeUtils.pyx":54 + * p = [0]*dimension + * iwidth = bits * dimension + * for i in range(iwidth): # <<<<<<<<<<<<<< + * b = bitrange(idx, iwidth, i, i+1) << (iwidth-i-1)/dimension + * p[i%dimension] |= b + */ + __pyx_t_2 = __pyx_v_iwidth; + for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) { + __pyx_v_i = __pyx_t_3; + + /* "SimPEG/Mesh/TreeUtils.pyx":55 + * iwidth = bits * dimension + * for i in range(iwidth): + * b = bitrange(idx, iwidth, i, i+1) << (iwidth-i-1)/dimension # <<<<<<<<<<<<<< + * p[i%dimension] |= b + * p.reverse() + */ + __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_bitrange); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = __Pyx_PyInt_From_long(__pyx_v_idx); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_6 = __Pyx_PyInt_From_int(__pyx_v_iwidth); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_7 = __Pyx_PyInt_From_int(__pyx_v_i); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_8 = __Pyx_PyInt_From_long((__pyx_v_i + 1)); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_9 = NULL; + __pyx_t_10 = 0; + if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_4))) { + __pyx_t_9 = PyMethod_GET_SELF(__pyx_t_4); + if (likely(__pyx_t_9)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4); + __Pyx_INCREF(__pyx_t_9); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_4, function); + __pyx_t_10 = 1; + } + } + __pyx_t_11 = PyTuple_New(4+__pyx_t_10); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_11); + if (__pyx_t_9) { + __Pyx_GIVEREF(__pyx_t_9); PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_9); __pyx_t_9 = NULL; + } + __Pyx_GIVEREF(__pyx_t_5); + PyTuple_SET_ITEM(__pyx_t_11, 0+__pyx_t_10, __pyx_t_5); + __Pyx_GIVEREF(__pyx_t_6); + PyTuple_SET_ITEM(__pyx_t_11, 1+__pyx_t_10, __pyx_t_6); + __Pyx_GIVEREF(__pyx_t_7); + PyTuple_SET_ITEM(__pyx_t_11, 2+__pyx_t_10, __pyx_t_7); + __Pyx_GIVEREF(__pyx_t_8); + PyTuple_SET_ITEM(__pyx_t_11, 3+__pyx_t_10, __pyx_t_8); + __pyx_t_5 = 0; + __pyx_t_6 = 0; + __pyx_t_7 = 0; + __pyx_t_8 = 0; + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_11, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_12 = ((__pyx_v_iwidth - __pyx_v_i) - 1); + if (unlikely(__pyx_v_dimension == 0)) { + #ifdef WITH_THREAD + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); + #endif + PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero"); + #ifdef WITH_THREAD + PyGILState_Release(__pyx_gilstate_save); + #endif + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + else if (sizeof(long) == sizeof(long) && (!(((int)-1) > 0)) && unlikely(__pyx_v_dimension == (int)-1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(__pyx_t_12))) { + #ifdef WITH_THREAD + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); + #endif + PyErr_SetString(PyExc_OverflowError, "value too large to perform division"); + #ifdef WITH_THREAD + PyGILState_Release(__pyx_gilstate_save); + #endif + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_t_4 = __Pyx_PyInt_From_long(__Pyx_div_long(__pyx_t_12, __pyx_v_dimension)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_11 = PyNumber_Lshift(__pyx_t_1, __pyx_t_4); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_11); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_12 = __Pyx_PyInt_As_long(__pyx_t_11); if (unlikely((__pyx_t_12 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + __pyx_v_b = __pyx_t_12; + + /* "SimPEG/Mesh/TreeUtils.pyx":56 + * for i in range(iwidth): + * b = bitrange(idx, iwidth, i, i+1) << (iwidth-i-1)/dimension + * p[i%dimension] |= b # <<<<<<<<<<<<<< + * p.reverse() + * return p + [n] + */ + if (unlikely(__pyx_v_dimension == 0)) { + #ifdef WITH_THREAD + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); + #endif + PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero"); + #ifdef WITH_THREAD + PyGILState_Release(__pyx_gilstate_save); + #endif + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_t_13 = __Pyx_mod_int(__pyx_v_i, __pyx_v_dimension); + __pyx_t_11 = __Pyx_GetItemInt_List(__pyx_v_p, __pyx_t_13, int, 1, __Pyx_PyInt_From_int, 1, 1, 1); if (unlikely(__pyx_t_11 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; + __Pyx_GOTREF(__pyx_t_11); + __pyx_t_4 = __Pyx_PyInt_From_long(__pyx_v_b); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_1 = PyNumber_InPlaceOr(__pyx_t_11, __pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(__Pyx_SetItemInt(__pyx_v_p, __pyx_t_13, __pyx_t_1, int, 1, __Pyx_PyInt_From_int, 1, 1, 1) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } + + /* "SimPEG/Mesh/TreeUtils.pyx":57 + * b = bitrange(idx, iwidth, i, i+1) << (iwidth-i-1)/dimension + * p[i%dimension] |= b + * p.reverse() # <<<<<<<<<<<<<< + * return p + [n] + * + */ + __pyx_t_14 = PyList_Reverse(__pyx_v_p); if (unlikely(__pyx_t_14 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 57; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + + /* "SimPEG/Mesh/TreeUtils.pyx":58 + * p[i%dimension] |= b + * p.reverse() + * return p + [n] # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_n); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_4 = PyList_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_4); + __Pyx_GIVEREF(__pyx_t_1); + PyList_SET_ITEM(__pyx_t_4, 0, __pyx_t_1); + __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Add(__pyx_v_p, __pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "SimPEG/Mesh/TreeUtils.pyx":43 + * return (idx << levelBits) + level + * + * def point(int dimension, int bits, int levelBits, long idx): # <<<<<<<<<<<<<< + * cdef list p + * cdef int iwidth + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_XDECREF(__pyx_t_11); + __Pyx_AddTraceback("SimPEG.Mesh.TreeUtils.point", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_p); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyMethodDef __pyx_methods[] = { + {0, 0, 0, 0} +}; + +#if PY_MAJOR_VERSION >= 3 +static struct PyModuleDef __pyx_moduledef = { + #if PY_VERSION_HEX < 0x03020000 + { PyObject_HEAD_INIT(NULL) NULL, 0, NULL }, + #else + PyModuleDef_HEAD_INIT, + #endif + "TreeUtils", + __pyx_k_The_Z_order_curve_is_generated, /* m_doc */ + -1, /* m_size */ + __pyx_methods /* m_methods */, + NULL, /* m_reload */ + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL /* m_free */ +}; +#endif + +static __Pyx_StringTabEntry __pyx_string_tab[] = { + {&__pyx_n_s_SimPEG_Mesh_TreeUtils, __pyx_k_SimPEG_Mesh_TreeUtils, sizeof(__pyx_k_SimPEG_Mesh_TreeUtils), 0, 0, 1, 1}, + {&__pyx_kp_s_Users_rowan_git_simpeg_simpeg_S, __pyx_k_Users_rowan_git_simpeg_simpeg_S, sizeof(__pyx_k_Users_rowan_git_simpeg_simpeg_S), 0, 0, 1, 0}, + {&__pyx_n_s__3, __pyx_k__3, sizeof(__pyx_k__3), 0, 0, 1, 1}, + {&__pyx_n_s_b, __pyx_k_b, sizeof(__pyx_k_b), 0, 0, 1, 1}, + {&__pyx_n_s_bitoff, __pyx_k_bitoff, sizeof(__pyx_k_bitoff), 0, 0, 1, 1}, + {&__pyx_n_s_bitrange, __pyx_k_bitrange, sizeof(__pyx_k_bitrange), 0, 0, 1, 1}, + {&__pyx_n_s_bits, __pyx_k_bits, sizeof(__pyx_k_bits), 0, 0, 1, 1}, + {&__pyx_n_s_dimension, __pyx_k_dimension, sizeof(__pyx_k_dimension), 0, 0, 1, 1}, + {&__pyx_n_s_end, __pyx_k_end, sizeof(__pyx_k_end), 0, 0, 1, 1}, + {&__pyx_n_s_i, __pyx_k_i, sizeof(__pyx_k_i), 0, 0, 1, 1}, + {&__pyx_n_s_idx, __pyx_k_idx, sizeof(__pyx_k_idx), 0, 0, 1, 1}, + {&__pyx_n_s_index, __pyx_k_index, sizeof(__pyx_k_index), 0, 0, 1, 1}, + {&__pyx_n_s_iwidth, __pyx_k_iwidth, sizeof(__pyx_k_iwidth), 0, 0, 1, 1}, + {&__pyx_n_s_level, __pyx_k_level, sizeof(__pyx_k_level), 0, 0, 1, 1}, + {&__pyx_n_s_levelBits, __pyx_k_levelBits, sizeof(__pyx_k_levelBits), 0, 0, 1, 1}, + {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1}, + {&__pyx_n_s_n, __pyx_k_n, sizeof(__pyx_k_n), 0, 0, 1, 1}, + {&__pyx_n_s_p, __pyx_k_p, sizeof(__pyx_k_p), 0, 0, 1, 1}, + {&__pyx_n_s_poff, __pyx_k_poff, sizeof(__pyx_k_poff), 0, 0, 1, 1}, + {&__pyx_n_s_point, __pyx_k_point, sizeof(__pyx_k_point), 0, 0, 1, 1}, + {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1}, + {&__pyx_n_s_start, __pyx_k_start, sizeof(__pyx_k_start), 0, 0, 1, 1}, + {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1}, + {&__pyx_n_s_width, __pyx_k_width, sizeof(__pyx_k_width), 0, 0, 1, 1}, + {&__pyx_n_s_x, __pyx_k_x, sizeof(__pyx_k_x), 0, 0, 1, 1}, + {0, 0, 0, 0, 0, 0, 0} +}; +static int __Pyx_InitCachedBuiltins(void) { + __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + return 0; + __pyx_L1_error:; + return -1; +} + +static int __Pyx_InitCachedConstants(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); + + /* "SimPEG/Mesh/TreeUtils.pyx":17 + * """ + * + * def bitrange(long x, int width, int start, int end): # <<<<<<<<<<<<<< + * """ + * Extract a bit range as an integer. + */ + __pyx_tuple_ = PyTuple_Pack(4, __pyx_n_s_x, __pyx_n_s_width, __pyx_n_s_start, __pyx_n_s_end); if (unlikely(!__pyx_tuple_)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_tuple_); + __Pyx_GIVEREF(__pyx_tuple_); + __pyx_codeobj__2 = (PyObject*)__Pyx_PyCode_New(4, 0, 4, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple_, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_rowan_git_simpeg_simpeg_S, __pyx_n_s_bitrange, 17, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + + /* "SimPEG/Mesh/TreeUtils.pyx":24 + * return x >> (width-end) & ((2**(end-start))-1) + * + * def index(int dimension, int bits, int levelBits, list p, int level): # <<<<<<<<<<<<<< + * cdef long idx = 0 + * cdef int iwidth + */ + __pyx_tuple__4 = PyTuple_Pack(12, __pyx_n_s_dimension, __pyx_n_s_bits, __pyx_n_s_levelBits, __pyx_n_s_p, __pyx_n_s_level, __pyx_n_s_idx, __pyx_n_s_iwidth, __pyx_n_s_i, __pyx_n_s_b, __pyx_n_s_bitoff, __pyx_n_s_poff, __pyx_n_s__3); if (unlikely(!__pyx_tuple__4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_tuple__4); + __Pyx_GIVEREF(__pyx_tuple__4); + __pyx_codeobj__5 = (PyObject*)__Pyx_PyCode_New(5, 0, 12, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__4, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_rowan_git_simpeg_simpeg_S, __pyx_n_s_index, 24, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + + /* "SimPEG/Mesh/TreeUtils.pyx":43 + * return (idx << levelBits) + level + * + * def point(int dimension, int bits, int levelBits, long idx): # <<<<<<<<<<<<<< + * cdef list p + * cdef int iwidth + */ + __pyx_tuple__6 = PyTuple_Pack(9, __pyx_n_s_dimension, __pyx_n_s_bits, __pyx_n_s_levelBits, __pyx_n_s_idx, __pyx_n_s_p, __pyx_n_s_iwidth, __pyx_n_s_i, __pyx_n_s_n, __pyx_n_s_b); if (unlikely(!__pyx_tuple__6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 43; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_tuple__6); + __Pyx_GIVEREF(__pyx_tuple__6); + __pyx_codeobj__7 = (PyObject*)__Pyx_PyCode_New(4, 0, 9, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__6, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_rowan_git_simpeg_simpeg_S, __pyx_n_s_point, 43, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 43; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_RefNannyFinishContext(); + return 0; + __pyx_L1_error:; + __Pyx_RefNannyFinishContext(); + return -1; +} + +static int __Pyx_InitGlobals(void) { + if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; + __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + return 0; + __pyx_L1_error:; + return -1; +} + +#if PY_MAJOR_VERSION < 3 +PyMODINIT_FUNC initTreeUtils(void); /*proto*/ +PyMODINIT_FUNC initTreeUtils(void) +#else +PyMODINIT_FUNC PyInit_TreeUtils(void); /*proto*/ +PyMODINIT_FUNC PyInit_TreeUtils(void) +#endif +{ + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannyDeclarations + #if CYTHON_REFNANNY + __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); + if (!__Pyx_RefNanny) { + PyErr_Clear(); + __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); + if (!__Pyx_RefNanny) + Py_FatalError("failed to import 'refnanny' module"); + } + #endif + __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit_TreeUtils(void)", 0); + if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + #ifdef __Pyx_CyFunction_USED + if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + #endif + #ifdef __Pyx_FusedFunction_USED + if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + #endif + #ifdef __Pyx_Generator_USED + if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + #endif + /*--- Library function declarations ---*/ + /*--- Threads initialization code ---*/ + #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS + #ifdef WITH_THREAD /* Python build with threading support? */ + PyEval_InitThreads(); + #endif + #endif + /*--- Module creation code ---*/ + #if PY_MAJOR_VERSION < 3 + __pyx_m = Py_InitModule4("TreeUtils", __pyx_methods, __pyx_k_The_Z_order_curve_is_generated, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m); + #else + __pyx_m = PyModule_Create(&__pyx_moduledef); + #endif + if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + Py_INCREF(__pyx_d); + __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + #if CYTHON_COMPILING_IN_PYPY + Py_INCREF(__pyx_b); + #endif + if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; + /*--- Initialize various global constants etc. ---*/ + if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) + if (__Pyx_init_sys_getdefaultencoding_params() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + #endif + if (__pyx_module_is_main_SimPEG__Mesh__TreeUtils) { + if (PyObject_SetAttrString(__pyx_m, "__name__", __pyx_n_s_main) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; + } + #if PY_MAJOR_VERSION >= 3 + { + PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + if (!PyDict_GetItemString(modules, "SimPEG.Mesh.TreeUtils")) { + if (unlikely(PyDict_SetItemString(modules, "SimPEG.Mesh.TreeUtils", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + } + #endif + /*--- Builtin init code ---*/ + if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + /*--- Constants init code ---*/ + if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + /*--- Global init code ---*/ + /*--- Variable export code ---*/ + /*--- Function export code ---*/ + /*--- Type init code ---*/ + /*--- Type import code ---*/ + /*--- Variable import code ---*/ + /*--- Function import code ---*/ + /*--- Execution code ---*/ + + /* "SimPEG/Mesh/TreeUtils.pyx":17 + * """ + * + * def bitrange(long x, int width, int start, int end): # <<<<<<<<<<<<<< + * """ + * Extract a bit range as an integer. + */ + __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_6SimPEG_4Mesh_9TreeUtils_1bitrange, NULL, __pyx_n_s_SimPEG_Mesh_TreeUtils); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_bitrange, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "SimPEG/Mesh/TreeUtils.pyx":24 + * return x >> (width-end) & ((2**(end-start))-1) + * + * def index(int dimension, int bits, int levelBits, list p, int level): # <<<<<<<<<<<<<< + * cdef long idx = 0 + * cdef int iwidth + */ + __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_6SimPEG_4Mesh_9TreeUtils_3index, NULL, __pyx_n_s_SimPEG_Mesh_TreeUtils); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_index, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "SimPEG/Mesh/TreeUtils.pyx":43 + * return (idx << levelBits) + level + * + * def point(int dimension, int bits, int levelBits, long idx): # <<<<<<<<<<<<<< + * cdef list p + * cdef int iwidth + */ + __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_6SimPEG_4Mesh_9TreeUtils_5point, NULL, __pyx_n_s_SimPEG_Mesh_TreeUtils); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 43; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_point, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 43; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "SimPEG/Mesh/TreeUtils.pyx":1 + * # from __future__ import division # <<<<<<<<<<<<<< + * # import numpy as np + * # cimport numpy as np + */ + __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /*--- Wrapped vars code ---*/ + + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + if (__pyx_m) { + if (__pyx_d) { + __Pyx_AddTraceback("init SimPEG.Mesh.TreeUtils", __pyx_clineno, __pyx_lineno, __pyx_filename); + } + Py_DECREF(__pyx_m); __pyx_m = 0; + } else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ImportError, "init SimPEG.Mesh.TreeUtils"); + } + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + #if PY_MAJOR_VERSION < 3 + return; + #else + return __pyx_m; + #endif +} + +/* --- Runtime support code --- */ +#if CYTHON_REFNANNY +static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { + PyObject *m = NULL, *p = NULL; + void *r = NULL; + m = PyImport_ImportModule((char *)modname); + if (!m) goto end; + p = PyObject_GetAttrString(m, (char *)"RefNannyAPI"); + if (!p) goto end; + r = PyLong_AsVoidPtr(p); +end: + Py_XDECREF(p); + Py_XDECREF(m); + return (__Pyx_RefNannyAPIStruct *)r; +} +#endif + +static PyObject *__Pyx_GetBuiltinName(PyObject *name) { + PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name); + if (unlikely(!result)) { + PyErr_Format(PyExc_NameError, +#if PY_MAJOR_VERSION >= 3 + "name '%U' is not defined", name); +#else + "name '%.200s' is not defined", PyString_AS_STRING(name)); +#endif + } + return result; +} + +static void __Pyx_RaiseArgtupleInvalid( + const char* func_name, + int exact, + Py_ssize_t num_min, + Py_ssize_t num_max, + Py_ssize_t num_found) +{ + Py_ssize_t num_expected; + const char *more_or_less; + if (num_found < num_min) { + num_expected = num_min; + more_or_less = "at least"; + } else { + num_expected = num_max; + more_or_less = "at most"; + } + if (exact) { + more_or_less = "exactly"; + } + PyErr_Format(PyExc_TypeError, + "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)", + func_name, more_or_less, num_expected, + (num_expected == 1) ? "" : "s", num_found); +} + +static void __Pyx_RaiseDoubleKeywordsError( + const char* func_name, + PyObject* kw_name) +{ + PyErr_Format(PyExc_TypeError, + #if PY_MAJOR_VERSION >= 3 + "%s() got multiple values for keyword argument '%U'", func_name, kw_name); + #else + "%s() got multiple values for keyword argument '%s'", func_name, + PyString_AsString(kw_name)); + #endif +} + +static int __Pyx_ParseOptionalKeywords( + PyObject *kwds, + PyObject **argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + const char* function_name) +{ + PyObject *key = 0, *value = 0; + Py_ssize_t pos = 0; + PyObject*** name; + PyObject*** first_kw_arg = argnames + num_pos_args; + while (PyDict_Next(kwds, &pos, &key, &value)) { + name = first_kw_arg; + while (*name && (**name != key)) name++; + if (*name) { + values[name-argnames] = value; + continue; + } + name = first_kw_arg; + #if PY_MAJOR_VERSION < 3 + if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) { + while (*name) { + if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key)) + && _PyString_Eq(**name, key)) { + values[name-argnames] = value; + break; + } + name++; + } + if (*name) continue; + else { + PyObject*** argname = argnames; + while (argname != first_kw_arg) { + if ((**argname == key) || ( + (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key)) + && _PyString_Eq(**argname, key))) { + goto arg_passed_twice; + } + argname++; + } + } + } else + #endif + if (likely(PyUnicode_Check(key))) { + while (*name) { + int cmp = (**name == key) ? 0 : + #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 + (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 : + #endif + PyUnicode_Compare(**name, key); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) { + values[name-argnames] = value; + break; + } + name++; + } + if (*name) continue; + else { + PyObject*** argname = argnames; + while (argname != first_kw_arg) { + int cmp = (**argname == key) ? 0 : + #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 + (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 : + #endif + PyUnicode_Compare(**argname, key); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) goto arg_passed_twice; + argname++; + } + } + } else + goto invalid_keyword_type; + if (kwds2) { + if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; + } else { + goto invalid_keyword; + } + } + return 0; +arg_passed_twice: + __Pyx_RaiseDoubleKeywordsError(function_name, key); + goto bad; +invalid_keyword_type: + PyErr_Format(PyExc_TypeError, + "%.200s() keywords must be strings", function_name); + goto bad; +invalid_keyword: + PyErr_Format(PyExc_TypeError, + #if PY_MAJOR_VERSION < 3 + "%.200s() got an unexpected keyword argument '%.200s'", + function_name, PyString_AsString(key)); + #else + "%s() got an unexpected keyword argument '%U'", + function_name, key); + #endif +bad: + return -1; +} + +static void __Pyx_RaiseArgumentTypeInvalid(const char* name, PyObject *obj, PyTypeObject *type) { + PyErr_Format(PyExc_TypeError, + "Argument '%.200s' has incorrect type (expected %.200s, got %.200s)", + name, type->tp_name, Py_TYPE(obj)->tp_name); +} +static CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed, + const char *name, int exact) +{ + if (unlikely(!type)) { + PyErr_SetString(PyExc_SystemError, "Missing type object"); + return 0; + } + if (none_allowed && obj == Py_None) return 1; + else if (exact) { + if (likely(Py_TYPE(obj) == type)) return 1; + #if PY_MAJOR_VERSION == 2 + else if ((type == &PyBaseString_Type) && likely(__Pyx_PyBaseString_CheckExact(obj))) return 1; + #endif + } + else { + if (likely(PyObject_TypeCheck(obj, type))) return 1; + } + __Pyx_RaiseArgumentTypeInvalid(name, obj, type); + return 0; +} + +static CYTHON_INLINE int __Pyx_div_int(int a, int b) { + int q = a / b; + int r = a - q*b; + q -= ((r != 0) & ((r ^ b) < 0)); + return q; +} + +static CYTHON_INLINE int __Pyx_mod_int(int a, int b) { + int r = a % b; + r += ((r != 0) & ((r ^ b) < 0)) * b; + return r; +} + +static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name) { + PyObject *result; +#if CYTHON_COMPILING_IN_CPYTHON + result = PyDict_GetItem(__pyx_d, name); + if (likely(result)) { + Py_INCREF(result); + } else { +#else + result = PyObject_GetItem(__pyx_d, name); + if (!result) { + PyErr_Clear(); +#endif + result = __Pyx_GetBuiltinName(name); + } + return result; +} + +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) { + PyObject *r; + if (!j) return NULL; + r = PyObject_GetItem(o, j); + Py_DECREF(j); + return r; +} +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, + CYTHON_NCP_UNUSED int wraparound, + CYTHON_NCP_UNUSED int boundscheck) { +#if CYTHON_COMPILING_IN_CPYTHON + if (wraparound & unlikely(i < 0)) i += PyList_GET_SIZE(o); + if ((!boundscheck) || likely((0 <= i) & (i < PyList_GET_SIZE(o)))) { + PyObject *r = PyList_GET_ITEM(o, i); + Py_INCREF(r); + return r; + } + return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); +#else + return PySequence_GetItem(o, i); +#endif +} +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, + CYTHON_NCP_UNUSED int wraparound, + CYTHON_NCP_UNUSED int boundscheck) { +#if CYTHON_COMPILING_IN_CPYTHON + if (wraparound & unlikely(i < 0)) i += PyTuple_GET_SIZE(o); + if ((!boundscheck) || likely((0 <= i) & (i < PyTuple_GET_SIZE(o)))) { + PyObject *r = PyTuple_GET_ITEM(o, i); + Py_INCREF(r); + return r; + } + return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); +#else + return PySequence_GetItem(o, i); +#endif +} +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, int is_list, + CYTHON_NCP_UNUSED int wraparound, + CYTHON_NCP_UNUSED int boundscheck) { +#if CYTHON_COMPILING_IN_CPYTHON + if (is_list || PyList_CheckExact(o)) { + Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o); + if ((!boundscheck) || (likely((n >= 0) & (n < PyList_GET_SIZE(o))))) { + PyObject *r = PyList_GET_ITEM(o, n); + Py_INCREF(r); + return r; + } + } + else if (PyTuple_CheckExact(o)) { + Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o); + if ((!boundscheck) || likely((n >= 0) & (n < PyTuple_GET_SIZE(o)))) { + PyObject *r = PyTuple_GET_ITEM(o, n); + Py_INCREF(r); + return r; + } + } else { + PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence; + if (likely(m && m->sq_item)) { + if (wraparound && unlikely(i < 0) && likely(m->sq_length)) { + Py_ssize_t l = m->sq_length(o); + if (likely(l >= 0)) { + i += l; + } else { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) + PyErr_Clear(); + else + return NULL; + } + } + return m->sq_item(o, i); + } + } +#else + if (is_list || PySequence_Check(o)) { + return PySequence_GetItem(o, i); + } +#endif + return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); +} + +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) { + PyObject *result; + ternaryfunc call = func->ob_type->tp_call; + if (unlikely(!call)) + return PyObject_Call(func, arg, kw); + if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) + return NULL; + result = (*call)(func, arg, kw); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +static CYTHON_INLINE long __Pyx_div_long(long a, long b) { + long q = a / b; + long r = a - q*b; + q -= ((r != 0) & ((r ^ b) < 0)); + return q; +} + +static CYTHON_INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) { + int r; + if (!j) return -1; + r = PyObject_SetItem(o, j, v); + Py_DECREF(j); + return r; +} +static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v, int is_list, + CYTHON_NCP_UNUSED int wraparound, CYTHON_NCP_UNUSED int boundscheck) { +#if CYTHON_COMPILING_IN_CPYTHON + if (is_list || PyList_CheckExact(o)) { + Py_ssize_t n = (!wraparound) ? i : ((likely(i >= 0)) ? i : i + PyList_GET_SIZE(o)); + if ((!boundscheck) || likely((n >= 0) & (n < PyList_GET_SIZE(o)))) { + PyObject* old = PyList_GET_ITEM(o, n); + Py_INCREF(v); + PyList_SET_ITEM(o, n, v); + Py_DECREF(old); + return 1; + } + } else { + PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence; + if (likely(m && m->sq_ass_item)) { + if (wraparound && unlikely(i < 0) && likely(m->sq_length)) { + Py_ssize_t l = m->sq_length(o); + if (likely(l >= 0)) { + i += l; + } else { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) + PyErr_Clear(); + else + return -1; + } + } + return m->sq_ass_item(o, i, v); + } + } +#else +#if CYTHON_COMPILING_IN_PYPY + if (is_list || (PySequence_Check(o) && !PyDict_Check(o))) { +#else + if (is_list || PySequence_Check(o)) { +#endif + return PySequence_SetItem(o, i, v); + } +#endif + return __Pyx_SetItemInt_Generic(o, PyInt_FromSsize_t(i), v); +} + +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { + int start = 0, mid = 0, end = count - 1; + if (end >= 0 && code_line > entries[end].code_line) { + return count; + } + while (start < end) { + mid = (start + end) / 2; + if (code_line < entries[mid].code_line) { + end = mid; + } else if (code_line > entries[mid].code_line) { + start = mid + 1; + } else { + return mid; + } + } + if (code_line <= entries[mid].code_line) { + return mid; + } else { + return mid + 1; + } +} +static PyCodeObject *__pyx_find_code_object(int code_line) { + PyCodeObject* code_object; + int pos; + if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) { + return NULL; + } + pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); + if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) { + return NULL; + } + code_object = __pyx_code_cache.entries[pos].code_object; + Py_INCREF(code_object); + return code_object; +} +static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) { + int pos, i; + __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries; + if (unlikely(!code_line)) { + return; + } + if (unlikely(!entries)) { + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry)); + if (likely(entries)) { + __pyx_code_cache.entries = entries; + __pyx_code_cache.max_count = 64; + __pyx_code_cache.count = 1; + entries[0].code_line = code_line; + entries[0].code_object = code_object; + Py_INCREF(code_object); + } + return; + } + pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); + if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) { + PyCodeObject* tmp = entries[pos].code_object; + entries[pos].code_object = code_object; + Py_DECREF(tmp); + return; + } + if (__pyx_code_cache.count == __pyx_code_cache.max_count) { + int new_max = __pyx_code_cache.max_count + 64; + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc( + __pyx_code_cache.entries, (size_t)new_max*sizeof(__Pyx_CodeObjectCacheEntry)); + if (unlikely(!entries)) { + return; + } + __pyx_code_cache.entries = entries; + __pyx_code_cache.max_count = new_max; + } + for (i=__pyx_code_cache.count; i>pos; i--) { + entries[i] = entries[i-1]; + } + entries[pos].code_line = code_line; + entries[pos].code_object = code_object; + __pyx_code_cache.count++; + Py_INCREF(code_object); +} + +#include "compile.h" +#include "frameobject.h" +#include "traceback.h" +static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( + const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = 0; + PyObject *py_srcfile = 0; + PyObject *py_funcname = 0; + #if PY_MAJOR_VERSION < 3 + py_srcfile = PyString_FromString(filename); + #else + py_srcfile = PyUnicode_FromString(filename); + #endif + if (!py_srcfile) goto bad; + if (c_line) { + #if PY_MAJOR_VERSION < 3 + py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + #else + py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + #endif + } + else { + #if PY_MAJOR_VERSION < 3 + py_funcname = PyString_FromString(funcname); + #else + py_funcname = PyUnicode_FromString(funcname); + #endif + } + if (!py_funcname) goto bad; + py_code = __Pyx_PyCode_New( + 0, + 0, + 0, + 0, + 0, + __pyx_empty_bytes, /*PyObject *code,*/ + __pyx_empty_tuple, /*PyObject *consts,*/ + __pyx_empty_tuple, /*PyObject *names,*/ + __pyx_empty_tuple, /*PyObject *varnames,*/ + __pyx_empty_tuple, /*PyObject *freevars,*/ + __pyx_empty_tuple, /*PyObject *cellvars,*/ + py_srcfile, /*PyObject *filename,*/ + py_funcname, /*PyObject *name,*/ + py_line, + __pyx_empty_bytes /*PyObject *lnotab*/ + ); + Py_DECREF(py_srcfile); + Py_DECREF(py_funcname); + return py_code; +bad: + Py_XDECREF(py_srcfile); + Py_XDECREF(py_funcname); + return NULL; +} +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = 0; + PyFrameObject *py_frame = 0; + py_code = __pyx_find_code_object(c_line ? c_line : py_line); + if (!py_code) { + py_code = __Pyx_CreateCodeObjectForTraceback( + funcname, c_line, py_line, filename); + if (!py_code) goto bad; + __pyx_insert_code_object(c_line ? c_line : py_line, py_code); + } + py_frame = PyFrame_New( + PyThreadState_GET(), /*PyThreadState *tstate,*/ + py_code, /*PyCodeObject *code,*/ + __pyx_d, /*PyObject *globals,*/ + 0 /*PyObject *locals*/ + ); + if (!py_frame) goto bad; + py_frame->f_lineno = py_line; + PyTraceBack_Here(py_frame); +bad: + Py_XDECREF(py_code); + Py_XDECREF(py_frame); +} + +#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value) \ + { \ + func_type value = func_value; \ + if (sizeof(target_type) < sizeof(func_type)) { \ + if (unlikely(value != (func_type) (target_type) value)) { \ + func_type zero = 0; \ + if (is_unsigned && unlikely(value < zero)) \ + goto raise_neg_overflow; \ + else \ + goto raise_overflow; \ + } \ + } \ + return (target_type) value; \ + } + +#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 + #if CYTHON_USE_PYLONG_INTERNALS + #include "longintrepr.h" + #endif +#endif + +static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { + const long neg_one = (long) -1, const_zero = 0; + const int is_unsigned = neg_one > const_zero; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x))) { + if (sizeof(long) < sizeof(long)) { + __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x)) + } else { + long val = PyInt_AS_LONG(x); + if (is_unsigned && unlikely(val < 0)) { + goto raise_neg_overflow; + } + return (long) val; + } + } else +#endif + if (likely(PyLong_Check(x))) { + if (is_unsigned) { +#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 + #if CYTHON_USE_PYLONG_INTERNALS + switch (Py_SIZE(x)) { + case 0: return 0; + case 1: __PYX_VERIFY_RETURN_INT(long, digit, ((PyLongObject*)x)->ob_digit[0]); + } + #endif +#endif +#if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (long) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if (sizeof(long) <= sizeof(unsigned long)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, PyLong_AsUnsignedLong(x)) + } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) + } + } else { +#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 + #if CYTHON_USE_PYLONG_INTERNALS + switch (Py_SIZE(x)) { + case 0: return 0; + case 1: __PYX_VERIFY_RETURN_INT(long, digit, +(((PyLongObject*)x)->ob_digit[0])); + case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]); + } + #endif +#endif + if (sizeof(long) <= sizeof(long)) { + __PYX_VERIFY_RETURN_INT(long, long, PyLong_AsLong(x)) + } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT(long, PY_LONG_LONG, PyLong_AsLongLong(x)) + } + } + { +#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) + PyErr_SetString(PyExc_RuntimeError, + "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); +#else + long val; + PyObject *v = __Pyx_PyNumber_Int(x); + #if PY_MAJOR_VERSION < 3 + if (likely(v) && !PyLong_Check(v)) { + PyObject *tmp = v; + v = PyNumber_Long(tmp); + Py_DECREF(tmp); + } + #endif + if (likely(v)) { + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + int ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); + Py_DECREF(v); + if (likely(!ret)) + return val; + } +#endif + return (long) -1; + } + } else { + long val; + PyObject *tmp = __Pyx_PyNumber_Int(x); + if (!tmp) return (long) -1; + val = __Pyx_PyInt_As_long(tmp); + Py_DECREF(tmp); + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to long"); + return (long) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to long"); + return (long) -1; +} + +static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { + const int neg_one = (int) -1, const_zero = 0; + const int is_unsigned = neg_one > const_zero; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x))) { + if (sizeof(int) < sizeof(long)) { + __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x)) + } else { + long val = PyInt_AS_LONG(x); + if (is_unsigned && unlikely(val < 0)) { + goto raise_neg_overflow; + } + return (int) val; + } + } else +#endif + if (likely(PyLong_Check(x))) { + if (is_unsigned) { +#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 + #if CYTHON_USE_PYLONG_INTERNALS + switch (Py_SIZE(x)) { + case 0: return 0; + case 1: __PYX_VERIFY_RETURN_INT(int, digit, ((PyLongObject*)x)->ob_digit[0]); + } + #endif +#endif +#if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (int) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if (sizeof(int) <= sizeof(unsigned long)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, PyLong_AsUnsignedLong(x)) + } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) + } + } else { +#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 + #if CYTHON_USE_PYLONG_INTERNALS + switch (Py_SIZE(x)) { + case 0: return 0; + case 1: __PYX_VERIFY_RETURN_INT(int, digit, +(((PyLongObject*)x)->ob_digit[0])); + case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]); + } + #endif +#endif + if (sizeof(int) <= sizeof(long)) { + __PYX_VERIFY_RETURN_INT(int, long, PyLong_AsLong(x)) + } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT(int, PY_LONG_LONG, PyLong_AsLongLong(x)) + } + } + { +#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) + PyErr_SetString(PyExc_RuntimeError, + "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); +#else + int val; + PyObject *v = __Pyx_PyNumber_Int(x); + #if PY_MAJOR_VERSION < 3 + if (likely(v) && !PyLong_Check(v)) { + PyObject *tmp = v; + v = PyNumber_Long(tmp); + Py_DECREF(tmp); + } + #endif + if (likely(v)) { + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + int ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); + Py_DECREF(v); + if (likely(!ret)) + return val; + } +#endif + return (int) -1; + } + } else { + int val; + PyObject *tmp = __Pyx_PyNumber_Int(x); + if (!tmp) return (int) -1; + val = __Pyx_PyInt_As_int(tmp); + Py_DECREF(tmp); + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to int"); + return (int) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to int"); + return (int) -1; +} + +static CYTHON_INLINE long __Pyx_pow_long(long b, long e) { + long t = b; + switch (e) { + case 3: + t *= b; + case 2: + t *= b; + case 1: + return t; + case 0: + return 1; + } + #if 1 + if (unlikely(e<0)) return 0; + #endif + t = 1; + while (likely(e)) { + t *= (b * (e&1)) | ((~e)&1); /* 1 or b */ + b *= b; + e >>= 1; + } + return t; +} + +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { + const long neg_one = (long) -1, const_zero = 0; + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(long) < sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(long) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); + } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); + } + } else { + if (sizeof(long) <= sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); + } + } + { + int one = 1; int little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&value; + return _PyLong_FromByteArray(bytes, sizeof(long), + little, !is_unsigned); + } +} + +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) { + const int neg_one = (int) -1, const_zero = 0; + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(int) < sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(int) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); + } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); + } + } else { + if (sizeof(int) <= sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); + } + } + { + int one = 1; int little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&value; + return _PyLong_FromByteArray(bytes, sizeof(int), + little, !is_unsigned); + } +} + +static int __Pyx_check_binary_version(void) { + char ctversion[4], rtversion[4]; + PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION); + PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion()); + if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) { + char message[200]; + PyOS_snprintf(message, sizeof(message), + "compiletime version %s of module '%.100s' " + "does not match runtime version %s", + ctversion, __Pyx_MODULE_NAME, rtversion); + return PyErr_WarnEx(NULL, message, 1); + } + return 0; +} + +static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { + while (t->p) { + #if PY_MAJOR_VERSION < 3 + if (t->is_unicode) { + *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL); + } else if (t->intern) { + *t->p = PyString_InternFromString(t->s); + } else { + *t->p = PyString_FromStringAndSize(t->s, t->n - 1); + } + #else + if (t->is_unicode | t->is_str) { + if (t->intern) { + *t->p = PyUnicode_InternFromString(t->s); + } else if (t->encoding) { + *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL); + } else { + *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1); + } + } else { + *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1); + } + #endif + if (!*t->p) + return -1; + ++t; + } + return 0; +} + +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { + return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str)); +} +static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject* o) { + Py_ssize_t ignore; + return __Pyx_PyObject_AsStringAndSize(o, &ignore); +} +static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) { +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT + if ( +#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + __Pyx_sys_getdefaultencoding_not_ascii && +#endif + PyUnicode_Check(o)) { +#if PY_VERSION_HEX < 0x03030000 + char* defenc_c; + PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL); + if (!defenc) return NULL; + defenc_c = PyBytes_AS_STRING(defenc); +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + { + char* end = defenc_c + PyBytes_GET_SIZE(defenc); + char* c; + for (c = defenc_c; c < end; c++) { + if ((unsigned char) (*c) >= 128) { + PyUnicode_AsASCIIString(o); + return NULL; + } + } + } +#endif + *length = PyBytes_GET_SIZE(defenc); + return defenc_c; +#else + if (__Pyx_PyUnicode_READY(o) == -1) return NULL; +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + if (PyUnicode_IS_ASCII(o)) { + *length = PyUnicode_GET_LENGTH(o); + return PyUnicode_AsUTF8(o); + } else { + PyUnicode_AsASCIIString(o); + return NULL; + } +#else + return PyUnicode_AsUTF8AndSize(o, length); +#endif +#endif + } else +#endif +#if !CYTHON_COMPILING_IN_PYPY + if (PyByteArray_Check(o)) { + *length = PyByteArray_GET_SIZE(o); + return PyByteArray_AS_STRING(o); + } else +#endif + { + char* result; + int r = PyBytes_AsStringAndSize(o, &result, length); + if (unlikely(r < 0)) { + return NULL; + } else { + return result; + } + } +} +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { + int is_true = x == Py_True; + if (is_true | (x == Py_False) | (x == Py_None)) return is_true; + else return PyObject_IsTrue(x); +} +static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) { + PyNumberMethods *m; + const char *name = NULL; + PyObject *res = NULL; +#if PY_MAJOR_VERSION < 3 + if (PyInt_Check(x) || PyLong_Check(x)) +#else + if (PyLong_Check(x)) +#endif + return Py_INCREF(x), x; + m = Py_TYPE(x)->tp_as_number; +#if PY_MAJOR_VERSION < 3 + if (m && m->nb_int) { + name = "int"; + res = PyNumber_Int(x); + } + else if (m && m->nb_long) { + name = "long"; + res = PyNumber_Long(x); + } +#else + if (m && m->nb_int) { + name = "int"; + res = PyNumber_Long(x); + } +#endif + if (res) { +#if PY_MAJOR_VERSION < 3 + if (!PyInt_Check(res) && !PyLong_Check(res)) { +#else + if (!PyLong_Check(res)) { +#endif + PyErr_Format(PyExc_TypeError, + "__%.4s__ returned non-%.4s (type %.200s)", + name, name, Py_TYPE(res)->tp_name); + Py_DECREF(res); + return NULL; + } + } + else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, + "an integer is required"); + } + return res; +} +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { + Py_ssize_t ival; + PyObject *x; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_CheckExact(b))) + return PyInt_AS_LONG(b); +#endif + if (likely(PyLong_CheckExact(b))) { + #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 + #if CYTHON_USE_PYLONG_INTERNALS + switch (Py_SIZE(b)) { + case -1: return -(sdigit)((PyLongObject*)b)->ob_digit[0]; + case 0: return 0; + case 1: return ((PyLongObject*)b)->ob_digit[0]; + } + #endif + #endif + return PyLong_AsSsize_t(b); + } + x = PyNumber_Index(b); + if (!x) return -1; + ival = PyInt_AsSsize_t(x); + Py_DECREF(x); + return ival; +} +static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) { + return PyInt_FromSize_t(ival); +} + + +#endif /* Py_PYTHON_H */ diff --git a/setup.py b/setup.py index 71c52814..f2af5b53 100644 --- a/setup.py +++ b/setup.py @@ -51,5 +51,5 @@ setup( platforms = ["Windows", "Linux", "Solaris", "Mac OS-X", "Unix"], use_2to3 = False, include_dirs=[np.get_include()], - ext_modules = cythonize('SimPEG/Utils/interputils_cython.pyx') + ext_modules = cythonize(['SimPEG/Utils/interputils_cython.pyx', 'SimPEG/Mesh/TreeUtils.pyx']) ) diff --git a/tests/mesh/test_pointerMesh.py b/tests/mesh/test_pointerMesh.py index dff3e8de..4147a0a9 100644 --- a/tests/mesh/test_pointerMesh.py +++ b/tests/mesh/test_pointerMesh.py @@ -12,44 +12,41 @@ class TestSimpleQuadTree(unittest.TestCase): def test_counts(self): - T = Tree([8,8]) - T._refineCell([0,0,0]) - T._refineCell([4,4,1]) - T._refineCell([0,0,1]) - T._refineCell([2,2,2]) - - T.number() - T.plotGrid(showIt=True) - assert sorted(T._treeInds) == [2, 34, 66, 99, 107, 115, 123, 129, 257, 386, 418, 450, 482] - assert len(T._hangingFacesX) == 7 - assert T.nFx == 18 - assert T.vol.sum() == 1.0 + M = Tree([8,8]) + M._refineCell([0,0,0]) + M._refineCell([0,0,1]) + M.number() + # M.plotGrid(showIt=True) + # assert sorted(M._cells) == [2, 34, 66, 99, 107, 115, 123, 129, 257, 386, 418, 450, 482] + assert M.nhFx == 2 + assert M.nFx == 9 + assert M.vol.sum() == 1.0 - def test_connectivity(self): - T = Tree([8,8]) - T._refineCell([0,0,0]) - T._refineCell([4,4,1]) - T._refineCell([0,0,1]) - T._refineCell([2,2,2]) - T.number() - assert T._getNextCell([4,0,1]) is None - assert T._getNextCell([0,4,1]) == [T._index([4,4,2]), T._index([4,6,2])] - assert T._getNextCell([0,2,2]) == [T._index([2,2,3]), T._index([2,3,3])] - assert T._getNextCell([4,4,2]) == T._index([6,4,2]) - assert T._getNextCell([6,4,2]) is None - assert T._getNextCell([2,0,2]) == T._index([4,0,1]) - assert T._getNextCell([4,0,1], positive=False) == [T._index([2,0,2]), [T._index([3,2,3]), T._index([3,3,3])]] - assert T._getNextCell([3,3,3]) == T._index([4,0,1]) - assert T._getNextCell([3,2,3]) == T._index([4,0,1]) - assert T._getNextCell([2,2,3]) == T._index([3,2,3]) - assert T._getNextCell([3,2,3], positive=False) == T._index([2,2,3]) + # def test_connectivity(self): + # T = Tree([8,8]) + # T._refineCell([0,0,0]) + # T._refineCell([4,4,1]) + # T._refineCell([0,0,1]) + # T._refineCell([2,2,2]) + # T.number() + # assert T._getNextCell([4,0,1]) is None + # assert T._getNextCell([0,4,1]) == [T._index([4,4,2]), T._index([4,6,2])] + # assert T._getNextCell([0,2,2]) == [T._index([2,2,3]), T._index([2,3,3])] + # assert T._getNextCell([4,4,2]) == T._index([6,4,2]) + # assert T._getNextCell([6,4,2]) is None + # assert T._getNextCell([2,0,2]) == T._index([4,0,1]) + # assert T._getNextCell([4,0,1], positive=False) == [T._index([2,0,2]), [T._index([3,2,3]), T._index([3,3,3])]] + # assert T._getNextCell([3,3,3]) == T._index([4,0,1]) + # assert T._getNextCell([3,2,3]) == T._index([4,0,1]) + # assert T._getNextCell([2,2,3]) == T._index([3,2,3]) + # assert T._getNextCell([3,2,3], positive=False) == T._index([2,2,3]) - assert T._getNextCell([0,0,2], direction=1) == T._index([0,2,2]) - assert T._getNextCell([0,2,2], direction=1, positive=False) == T._index([0,0,2]) - assert T._getNextCell([0,2,2], direction=1) == T._index([0,4,1]) - assert T._getNextCell([0,4,1], direction=1, positive=False) == [T._index([0,2,2]), [T._index([2,3,3]), T._index([3,3,3])]] + # assert T._getNextCell([0,0,2], direction=1) == T._index([0,2,2]) + # assert T._getNextCell([0,2,2], direction=1, positive=False) == T._index([0,0,2]) + # assert T._getNextCell([0,2,2], direction=1) == T._index([0,4,1]) + # assert T._getNextCell([0,4,1], direction=1, positive=False) == [T._index([0,2,2]), [T._index([2,3,3]), T._index([3,3,3])]] class TestOperatorsQuadTree(unittest.TestCase): @@ -81,29 +78,29 @@ class TestOperatorsQuadTree(unittest.TestCase): class TestOperatorsOcTree(unittest.TestCase): - def test_counts(self): + def test_faceDiv(self): hx, hy, hz = np.r_[1.,2,3,4], np.r_[5.,6,7,8], np.r_[9.,10,11,12] - T = Tree([hx, hy, hz], levels=2) - T.refine(lambda xc:2) - # T.plotGrid(showIt=True) - M = Mesh.TensorMesh([hx, hy, hz]) - assert M.nC == T.nC - assert M.nF == T.nF - assert M.nFx == T.nFx - assert M.nFy == T.nFy - # assert M.nE == T.nE - # assert M.nEx == T.nEx - # assert M.nEy == T.nEy - assert np.allclose(M.area, T.permuteF*T.area) - # assert np.allclose(M.edge, T.permuteE*T.edge) - assert np.allclose(M.vol, T.permuteCC*T.vol) + M = Tree([hx, hy, hz], levels=2) + M.refine(lambda xc:2) + # M.plotGrid(showIt=True) + Mr = Mesh.TensorMesh([hx, hy, hz]) + assert M.nC == Mr.nC + assert M.nF == Mr.nF + assert M.nFx == Mr.nFx + assert M.nFy == Mr.nFy + assert M.nE == Mr.nE + assert M.nEx == Mr.nEx + assert M.nEy == Mr.nEy + assert np.allclose(Mr.area, M.permuteF*M.area) + assert np.allclose(Mr.edge, M.permuteE*M.edge) + assert np.allclose(Mr.vol, M.permuteCC*M.vol) - # plt.subplot(211).spy(M.faceDiv) - # plt.subplot(212).spy(T.permuteCC.T*T.faceDiv*T.permuteF) + # plt.subplot(211).spy(Mr.faceDiv) + # plt.subplot(212).spy(M.permuteCC.T*M.faceDiv*M.permuteF) # plt.show() - assert (M.faceDiv - T.permuteCC*T.faceDiv*T.permuteF.T).nnz == 0 + assert (Mr.faceDiv - M.permuteCC*M.faceDiv*M.permuteF.T).nnz == 0 From 5b85bcaeaf183ade5f83132b1e080f4753a2281d Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Mon, 9 Nov 2015 10:13:45 -0800 Subject: [PATCH 44/83] ntFx: number of total faces in x direction --- SimPEG/Mesh/PointerTree.py | 74 ++++++++++++++++++++++++++++++-------- 1 file changed, 59 insertions(+), 15 deletions(-) diff --git a/SimPEG/Mesh/PointerTree.py b/SimPEG/Mesh/PointerTree.py index 8e98a6fe..eb792113 100644 --- a/SimPEG/Mesh/PointerTree.py +++ b/SimPEG/Mesh/PointerTree.py @@ -198,6 +198,54 @@ class Tree(object): self.number() return len(self._hangingEz) + + @property + def ntN(self): + self.number() + return len(self._nodes) + + @property + def ntF(self): + return self.ntFx + self.ntFy + (0 if self.dim == 2 else self.ntFz) + + @property + def ntFx(self): + self.number() + return len(self._facesX) + + @property + def ntFy(self): + self.number() + return len(self._facesY) + + @property + def ntFz(self): + if self.dim == 2: return None + self.number() + return len(self._facesZ) + + @property + def ntE(self): + return self.ntEx + self.ntEy + (0 if self.dim == 2 else self.ntEz) + + @property + def ntEx(self): + if self.dim == 2:return self.ntFy + self.number() + return len(self._edgesX) + + @property + def ntEy(self): + if self.dim == 2:return self.ntFx + self.number() + return len(self._edgesY) + + @property + def ntEz(self): + if self.dim == 2: return None + self.number() + return len(self._edgesZ) + @property def _sortedCells(self): if getattr(self, '__sortedCells', None) is None: @@ -948,7 +996,9 @@ class Tree(object): # TODO: Preallocate! I, J, V = [], [], [] PM = [-1,1]*self.dim # plus / minus - offset = [0,0,self.nFx,self.nFx,self.nFx+self.nFy,self.nFx+self.nFy] + + # TODO total number of faces? + offset = [0]*2 + [self.ntFx]*2 + [self.ntFx+self.ntFy]*2 for ii, ind in enumerate(self._sortedCells): @@ -977,10 +1027,7 @@ class Tree(object): J += [face + off] V += [pm] - # total number of faces - tnF = len(self._facesX) + len(self._facesY) + (0 if self.dim == 2 else len(self._facesZ)) - - D = sp.csr_matrix((V,(I,J)), shape=(self.nC, tnF)) + D = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.ntF)) Rlist = [0]*self.dim Rlist[0] = self._deflationMatrix(self._facesX, self._hangingFx, self._fx2i) Rlist[1] = self._deflationMatrix(self._facesY, self._hangingFy, self._fy2i) @@ -1002,7 +1049,7 @@ class Tree(object): # TODO: Preallocate! I, J, V = [], [], [] faceOffset = 0 - offset = [self.nEx]*2 + [self.nEx+self.nEy]*2 + offset = [self.ntEx]*2 + [self.ntEx+self.ntEy]*2 PM = [1, -1, -1, 1] for ii, fx in enumerate(sorted(self._facesX)): @@ -1022,7 +1069,7 @@ class Tree(object): V += [pm] faceOffset = self.nFx - offset = [0]*2 + [self.nEx+self.nEy]*2 + offset = [0]*2 + [self.ntEx+self.ntEy]*2 PM = [-1, 1, 1, -1] for ii, fy in enumerate(sorted(self._facesY)): @@ -1042,7 +1089,7 @@ class Tree(object): V += [pm] faceOffset = self.nFx + self.nFy - offset = [0]*2 + [self.nEx]*2 + offset = [0]*2 + [self.ntEx]*2 PM = [1, -1, -1, 1] for ii, fz in enumerate(sorted(self._facesZ)): @@ -1061,9 +1108,6 @@ class Tree(object): J += [edge + off] V += [pm] - tnF = len(self._facesX) + len(self._facesY) + len(self._facesZ) - tnE = len(self._edgesX) + len(self._edgesY) + len(self._edgesZ) - Rf = sp.block_diag([ self._deflationMatrix(self._facesX, self._hangingFx, self._fx2i), self._deflationMatrix(self._facesY, self._hangingFy, self._fy2i), @@ -1076,7 +1120,7 @@ class Tree(object): self._deflationMatrix(self._edgesZ, self._hangingEz, self._ez2i) ]) - C = sp.csr_matrix((V,(I,J)), shape=(tnF, tnE)) + C = sp.csr_matrix((V,(I,J)), shape=(self.ntF, self.ntE)) S = self.area L = self.edge self._edgeCurl = Utils.sdiag(1/S)*Rf.T*C*Re*Utils.sdiag(L) @@ -1222,16 +1266,16 @@ if __name__ == '__main__': return 0 T = Tree([[(1,128)],[(1,128)],[(1,128)]],levels=7) - T = Tree([128,128,128],levels=7) + # T = Tree([128,128,128],levels=7) # T = Tree([[(1,16)],[(1,16)]],levels=4) # T = Tree([[(1,128)],[(1,128)]],levels=7) - T.refine(lambda xc:1, balance=False) + # T.refine(lambda xc:1, balance=False) # T._index([0,0,0]) # T._pointer(0) tic = time.time() - # T.refine(function)#, balance=False) + T.refine(function)#, balance=False) print time.time() - tic print T.nC From 2ce694e9d5f020fb26cafd0fbc99a091176c5d82 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Mon, 9 Nov 2015 10:36:59 -0800 Subject: [PATCH 45/83] test edgeCurl --- tests/mesh/test_pointerMesh.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/mesh/test_pointerMesh.py b/tests/mesh/test_pointerMesh.py index 4147a0a9..7f8d7e3f 100644 --- a/tests/mesh/test_pointerMesh.py +++ b/tests/mesh/test_pointerMesh.py @@ -103,6 +103,21 @@ class TestOperatorsOcTree(unittest.TestCase): assert (Mr.faceDiv - M.permuteCC*M.faceDiv*M.permuteF.T).nnz == 0 + def test_edgeCurl(self): + + hx, hy, hz = np.r_[1.,2,3,4], np.r_[5.,6,7,8], np.r_[9.,10,11,12] + M = Tree([hx, hy, hz], levels=2) + M.refine(lambda xc:2) + # M.plotGrid(showIt=True) + Mr = Mesh.TensorMesh([hx, hy, hz]) + + # plt.subplot(211).spy(Mr.faceDiv) + # plt.subplot(212).spy(M.permuteCC.T*M.faceDiv*M.permuteF) + # plt.show() + + assert (Mr.edgeCurl - M.permuteF*M.edgeCurl*M.permuteE.T).nnz == 0 + + if __name__ == '__main__': unittest.main() From 94a79298bd749ac6f9abd38a011f0e23709a1e2f Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Mon, 9 Nov 2015 15:14:24 -0800 Subject: [PATCH 46/83] Inner products --- SimPEG/Mesh/PointerTree.py | 157 ++++++++++++++++++++++++--------- tests/mesh/test_pointerMesh.py | 23 ++++- 2 files changed, 134 insertions(+), 46 deletions(-) diff --git a/SimPEG/Mesh/PointerTree.py b/SimPEG/Mesh/PointerTree.py index eb792113..d3262fee 100644 --- a/SimPEG/Mesh/PointerTree.py +++ b/SimPEG/Mesh/PointerTree.py @@ -2,6 +2,7 @@ from SimPEG import np, sp, Utils, Solver, Mesh import matplotlib.pyplot as plt import matplotlib import TreeUtils +from SimPEG.Mesh.InnerProducts import InnerProducts import time MAX_BITS = 20 @@ -48,7 +49,7 @@ def SortGrid(grid, offset=0): class NotBalancedException(Exception): pass -class Tree(object): +class Tree(InnerProducts): def __init__(self, h_in, levels=3): assert type(h_in) is list, 'h_in must be a list' assert len(h_in) > 1, "len(h_in) must be greater than 1" @@ -512,47 +513,47 @@ class Tree(object): @property def gridN(self): self.number() - R = self._deflationMatrix(self._nodes, self._hangingN, self._n2i, withHanging=False) + R = self._deflationMatrix('N', withHanging=False) return R.T * self._gridN @property def gridFx(self): self.number() - R = self._deflationMatrix(self._facesX, self._hangingFx, self._fx2i, withHanging=False) + R = self._deflationMatrix('Fx', withHanging=False) return R.T * self._gridFx @property def gridFy(self): self.number() - R = self._deflationMatrix(self._facesY, self._hangingFy, self._fy2i, withHanging=False) + R = self._deflationMatrix('Fy', withHanging=False) return R.T * self._gridFy @property def gridFz(self): if self.dim < 3: return None self.number() - R = self._deflationMatrix(self._facesZ, self._hangingFz, self._fz2i, withHanging=False) + R = self._deflationMatrix('Fz', withHanging=False) return R.T * self._gridFz @property def gridEx(self): if self.dim == 2: return self.gridFy self.number() - R = self._deflationMatrix(self._edgesX, self._hangingEx, self._ex2i, withHanging=False) + R = self._deflationMatrix('Ex', withHanging=False) return R.T * self._gridEx @property def gridEy(self): if self.dim == 2: return self.gridFx self.number() - R = self._deflationMatrix(self._edgesY, self._hangingEy, self._ey2i, withHanging=False) + R = self._deflationMatrix('Ey', withHanging=False) return R.T * self._gridEy @property def gridEz(self): if self.dim < 3: return None self.number() - R = self._deflationMatrix(self._edgesZ, self._hangingEz, self._ez2i, withHanging=False) + R = self._deflationMatrix('Ez', withHanging=False) return R.T * self._gridEz @property @@ -568,13 +569,8 @@ class Tree(object): def area(self): self.number() if getattr(self, '_area', None) is None: - Rlist = [0]*self.dim - Rlist[0] = self._deflationMatrix(self._facesX, self._hangingFx, self._fx2i, withHanging=False) - Rlist[1] = self._deflationMatrix(self._facesY, self._hangingFy, self._fy2i, withHanging=False) - if self.dim == 3: - Rlist[2] = self._deflationMatrix(self._facesZ, self._hangingFz, self._fz2i, withHanging=False) - R = sp.block_diag(Rlist) - self._area = R.T * ( + Rf = self._deflationMatrix('F', withHanging=False) + self._area = Rf.T * ( np.r_[self._areaFxFull, self._areaFyFull] if self.dim == 2 else np.r_[self._areaFxFull, self._areaFyFull, self._areaFzFull] ) @@ -586,12 +582,8 @@ class Tree(object): if self.dim == 2: return np.r_[self.area[self.nFx:], self.area[:self.nFx]] if getattr(self, '_edge', None) is None: - R = sp.block_diag([ - self._deflationMatrix(self._edgesX, self._hangingEx, self._ex2i, withHanging=False), - self._deflationMatrix(self._edgesY, self._hangingEy, self._ey2i, withHanging=False), - self._deflationMatrix(self._edgesZ, self._hangingEz, self._ez2i, withHanging=False) - ]) - self._edge = R.T * np.r_[self._edgeExFull, self._edgeEyFull, self._edgeEzFull] + Re = self._deflationMatrix('E', withHanging=False) + self._edge = Re.T * np.r_[self._edgeExFull, self._edgeEyFull, self._edgeEzFull] return self._edge @@ -969,7 +961,24 @@ class Tree(object): self.balance() self._hanging(force=force) - def _deflationMatrix(self, theSet, theHang, theIndex, withHanging=True): + def _deflationMatrix(self, location, withHanging=True): + assert location in ['N','F','Fx','Fy'] + (['Fz','E','Ex','Ey','Ez'] if self.dim == 3 else []) + + args = dict() + args['N'] = (self._nodes, self._hangingN, self._n2i ) + args['Fx'] = (self._facesX, self._hangingFx, self._fx2i) + args['Fy'] = (self._facesY, self._hangingFy, self._fy2i) + if self.dim == 3: + args['Fz'] = (self._facesZ, self._hangingFz, self._fz2i) + args['Ex'] = (self._edgesX, self._hangingEx, self._ex2i) + args['Ey'] = (self._edgesY, self._hangingEy, self._ey2i) + args['Ez'] = (self._edgesZ, self._hangingEz, self._ez2i) + if location in ['F', 'E']: + Rlist = [self._deflationMatrix(location + subLoc, withHanging=withHanging) for subLoc in ['x','y','z'][:self.dim]] + return sp.block_diag(Rlist) + return self.__deflationMatrix(*args[location], withHanging=withHanging) + + def __deflationMatrix(self, theSet, theHang, theIndex, withHanging=True): reducedInd = dict() # final reduced index ii = 0 I,J,V = [],[],[] @@ -1028,12 +1037,7 @@ class Tree(object): V += [pm] D = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.ntF)) - Rlist = [0]*self.dim - Rlist[0] = self._deflationMatrix(self._facesX, self._hangingFx, self._fx2i) - Rlist[1] = self._deflationMatrix(self._facesY, self._hangingFy, self._fy2i) - if self.dim == 3: - Rlist[2] = self._deflationMatrix(self._facesZ, self._hangingFz, self._fz2i) - R = sp.block_diag(Rlist) + R = self._deflationMatrix('F') VOL = self.vol S = self.area self._faceDiv = Utils.sdiag(1.0/VOL)*D*R*Utils.sdiag(S) @@ -1108,17 +1112,8 @@ class Tree(object): J += [edge + off] V += [pm] - Rf = sp.block_diag([ - self._deflationMatrix(self._facesX, self._hangingFx, self._fx2i), - self._deflationMatrix(self._facesY, self._hangingFy, self._fy2i), - self._deflationMatrix(self._facesZ, self._hangingFz, self._fz2i) - ]) - - Re = sp.block_diag([ - self._deflationMatrix(self._edgesX, self._hangingEx, self._ex2i), - self._deflationMatrix(self._edgesY, self._hangingEy, self._ey2i), - self._deflationMatrix(self._edgesZ, self._hangingEz, self._ez2i) - ]) + Rf = self._deflationMatrix('F') + Re = self._deflationMatrix('E') C = sp.csr_matrix((V,(I,J)), shape=(self.ntF, self.ntE)) S = self.area @@ -1127,6 +1122,78 @@ class Tree(object): return self._edgeCurl + def _getFaceP(self, xFace, yFace, zFace): + ind1, ind2, ind3 = [], [], [] + for ind in self._sortedCells: + p = self._pointer(ind) + w = self._levelWidth(p[-1]) + + posX = 0 if xFace == 'fXm' else w + posY = 0 if yFace == 'fYm' else w + if self.dim == 3: + posZ = 0 if zFace == 'fZm' else w + + ind1.append( self._fx2i[self._index([ p[0] + posX, p[1]] + p[2:])] ) + ind2.append( self._fy2i[self._index([ p[0], p[1] + posY] + p[2:])] + self.ntFx ) + if self.dim == 3: + ind3.append( self._fz2i[self._index([ p[0], p[1], p[2] + posZ, p[3]])] + self.ntFx + self.ntFy ) + + if self.dim == 2: + IND = np.r_[ind1, ind2] + if self.dim == 3: + IND = np.r_[ind1, ind2, ind3] + + PXXX = sp.coo_matrix((np.ones(self.dim*self.nC), (range(self.dim*self.nC), IND)), shape=(self.dim*self.nC, self.ntF)).tocsr() + + Rf = self._deflationMatrix('F', withHanging=True) + + return PXXX * Rf + + def _getFacePxx(self): + self.number() + def Pxx(xFace, yFace): + return self._getFaceP(xFace, yFace, None) + return Pxx + + def _getFacePxxx(self): + self.number() + def Pxxx(xFace, yFace, zFace): + return self._getFaceP(xFace, yFace, zFace) + return Pxxx + + def _getEdgeP(self, xEdge, yEdge, zEdge): + if self.dim == 2: raise Exception('Not implemented') # this should be a reordering of the face inner product? + + ind1, ind2, ind3 = [], [], [] + for ind in self._sortedCells: + p = self._pointer(ind) + w = self._levelWidth(p[-1]) + + posX = [0,0] if xEdge == 'eX0' else [1, 0] if xEdge == 'eX1' else [0,1] if xEdge == 'eX2' else [1,1] + posY = [0,0] if yEdge == 'eY0' else [1, 0] if yEdge == 'eY1' else [0,1] if yEdge == 'eY2' else [1,1] + posZ = [0,0] if zEdge == 'eZ0' else [1, 0] if zEdge == 'eZ1' else [0,1] if zEdge == 'eZ2' else [1,1] + + ind1.append( self._ex2i[self._index([ p[0] , p[1] + posX[0], p[2] + posX[1], p[3]])] ) + ind2.append( self._ey2i[self._index([ p[0] + posY[0], p[1] , p[2] + posY[1], p[3]])] + self.ntEx ) + ind3.append( self._ez2i[self._index([ p[0] + posZ[0], p[1] + posZ[1], p[2] , p[3]])] + self.ntEx + self.ntEy ) + + IND = np.r_[ind1, ind2, ind3] + + PXXX = sp.coo_matrix((np.ones(self.dim*self.nC), (range(self.dim*self.nC), IND)), shape=(self.dim*self.nC, self.ntE)).tocsr() + + Rf = self._deflationMatrix('E', withHanging=False) + + return PXXX * Rf + + def _getEdgePxx(self): + raise Exception('Not implemented') # this should be a reordering of the face inner product? + def _getEdgePxxx(self): + self.number() + def Pxxx(xEdge, yEdge, zEdge): + return self._getEdgeP(xEdge, yEdge, zEdge) + return Pxxx + + def plotGrid(self, ax=None, showIt=False, grid=True, cells=True, cellLine=False, @@ -1257,9 +1324,9 @@ if __name__ == '__main__': # if dist < 0.05: # return 5 if dist < 0.1*128: - return 7 + return 4 if dist < 0.3*128: - return 5 + return 3 if dist < 1.0*128: return 2 else: @@ -1279,7 +1346,8 @@ if __name__ == '__main__': print time.time() - tic print T.nC - print T.gridFz + print T.getFaceInnerProduct() + # print T.gridFz # T._refineCell([8,0,1]) @@ -1288,13 +1356,14 @@ if __name__ == '__main__': # T._refineCell([8,4,2]) # T._refineCell([6,0,3]) # T._refineCell([8,8,1]) - T._refineCell([0,0,0,1]) - T.__dirty__ = True + # T._refineCell([0,0,0,1]) + # T.__dirty__ = True print T.gridFx.shape[0], T.nFx + ax = plt.subplot(211) ax.spy(T.edgeCurl) diff --git a/tests/mesh/test_pointerMesh.py b/tests/mesh/test_pointerMesh.py index 7f8d7e3f..c609f372 100644 --- a/tests/mesh/test_pointerMesh.py +++ b/tests/mesh/test_pointerMesh.py @@ -70,7 +70,7 @@ class TestOperatorsQuadTree(unittest.TestCase): assert np.allclose(M.vol, T.permuteCC*T.vol) # plt.subplot(211).spy(M.faceDiv) - # plt.subplot(212).spy(T.permuteCC.T*T.faceDiv*T.permuteF) + # plt.subplot(212).spy(T.permuteCC*T.faceDiv*T.permuteF.T) # plt.show() assert (M.faceDiv - T.permuteCC*T.faceDiv*T.permuteF.T).nnz == 0 @@ -97,7 +97,7 @@ class TestOperatorsOcTree(unittest.TestCase): assert np.allclose(Mr.vol, M.permuteCC*M.vol) # plt.subplot(211).spy(Mr.faceDiv) - # plt.subplot(212).spy(M.permuteCC.T*M.faceDiv*M.permuteF) + # plt.subplot(212).spy(M.permuteCC*M.faceDiv*M.permuteF.T) # plt.show() assert (Mr.faceDiv - M.permuteCC*M.faceDiv*M.permuteF.T).nnz == 0 @@ -117,6 +117,25 @@ class TestOperatorsOcTree(unittest.TestCase): assert (Mr.edgeCurl - M.permuteF*M.edgeCurl*M.permuteE.T).nnz == 0 + def test_faceInnerProduct(self): + + hx, hy, hz = np.r_[1.,2,3,4], np.r_[5.,6,7,8], np.r_[9.,10,11,12] + # hx, hy, hz = [[(1,4)], [(1,4)], [(1,4)]] + + M = Tree([hx, hy, hz], levels=2) + M.refine(lambda xc:2) + # M.plotGrid(showIt=True) + Mr = Mesh.TensorMesh([hx, hy, hz]) + + # plt.subplot(211).spy(Mr.getFaceInnerProduct()) + # plt.subplot(212).spy(M.getFaceInnerProduct()) + # plt.show() + + # print M.nC, M.nF, M.getFaceInnerProduct().shape, M.permuteF.shape + + assert np.allclose(Mr.getFaceInnerProduct().todense(), (M.permuteF * M.getFaceInnerProduct() * M.permuteF.T).todense()) + assert np.allclose(Mr.getEdgeInnerProduct().todense(), (M.permuteE * M.getEdgeInnerProduct() * M.permuteE.T).todense()) + if __name__ == '__main__': From da7fbbb461833bf4eb00f0ab2d1c0b7c4de2480f Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Mon, 9 Nov 2015 19:51:46 -0800 Subject: [PATCH 47/83] edgeCurl is O(h) not O(h^2) ???? --- SimPEG/Mesh/PointerTree.py | 302 ++++++++++++++++++++++--------- SimPEG/Tests.py | 27 +++ tests/mesh/test_TreeOperators.py | 103 +++++++++++ tests/mesh/test_pointerMesh.py | 61 ++++++- 4 files changed, 397 insertions(+), 96 deletions(-) create mode 100644 tests/mesh/test_TreeOperators.py diff --git a/SimPEG/Mesh/PointerTree.py b/SimPEG/Mesh/PointerTree.py index d3262fee..2c71bd75 100644 --- a/SimPEG/Mesh/PointerTree.py +++ b/SimPEG/Mesh/PointerTree.py @@ -1,8 +1,13 @@ from SimPEG import np, sp, Utils, Solver, Mesh import matplotlib.pyplot as plt import matplotlib +from mpl_toolkits.mplot3d import Axes3D +import matplotlib.colors as colors +import matplotlib.cm as cmx + import TreeUtils from SimPEG.Mesh.InnerProducts import InnerProducts +from SimPEG.Mesh.BaseMesh import BaseMesh import time MAX_BITS = 20 @@ -49,8 +54,8 @@ def SortGrid(grid, offset=0): class NotBalancedException(Exception): pass -class Tree(InnerProducts): - def __init__(self, h_in, levels=3): +class Tree(BaseMesh, InnerProducts): + def __init__(self, h_in, x0_in=None, levels=3): assert type(h_in) is list, 'h_in must be a list' assert len(h_in) > 1, "len(h_in) must be greater than 1" @@ -67,6 +72,24 @@ class Tree(InnerProducts): h[i] = h_i[:] # make a copy. self.h = h + x0 = np.zeros(len(h)) + if x0_in is not None: + assert len(h) == len(x0_in), "Dimension mismatch. x0 != len(h)" + for i in range(len(h)): + x_i, h_i = x0_in[i], h[i] + if Utils.isScalar(x_i): + x0[i] = x_i + elif x_i == '0': + x0[i] = 0.0 + elif x_i == 'C': + x0[i] = -h_i.sum()*0.5 + elif x_i == 'N': + x0[i] = -h_i.sum() + else: + raise Exception("x0[%i] must be a scalar or '0' to be zero, 'C' to center, or 'N' to be negative." % i) + + BaseMesh.__init__(self, [len(_) for _ in h], x0) + self._levels = levels self._levelBits = int(np.ceil(np.sqrt(levels)))+1 @@ -295,11 +318,11 @@ class Tree(InnerProducts): return v in self._cells return self._index(v) in self._cells - def refine(self, function=None, recursive=True, cells=None, balance=True, _inRecursion=False): + def refine(self, function=None, recursive=True, cells=None, balance=True, verbose=False, _inRecursion=False): if not _inRecursion: self.__dirty__ = True - print 'Refining Mesh' + if verbose: print 'Refining Mesh' cells = cells if cells is not None else sorted(self._cells) recurse = [] @@ -310,7 +333,7 @@ class Tree(InnerProducts): if do: recurse += self._refineCell(cell) - print ' ', time.time() - tic + if verbose: print ' ', time.time() - tic if recursive and len(recurse) > 0: recurse += self.refine(function=function, recursive=True, cells=recurse, balance=balance, _inRecursion=True) @@ -457,12 +480,12 @@ class Tree(InnerProducts): return self._getNextCell(self._parentPointer(pointer), direction=direction, positive=positive) - def balance(self, recursive=True, cells=None, _inRecursion=False): + def balance(self, recursive=True, cells=None, verbose=False, _inRecursion=False): tic = time.time() if not _inRecursion: self.__dirty__ = True - print 'Balancing Mesh:' + if verbose: print 'Balancing Mesh:' cells = cells if cells is not None else sorted(self._cells) @@ -497,7 +520,7 @@ class Tree(InnerProducts): recurse.update([_ for _ in cs if type(_) in [int, long]]) # only add the bigger ones! recurse.update(newCells) - print ' ', len(cells), time.time() - tic + if verbose: print ' ', len(cells), time.time() - tic if recursive and len(recurse) > 0: self.balance(cells=sorted(recurse), _inRecursion=True) @@ -792,15 +815,28 @@ class Tree(InnerProducts): w = self._levelWidth(sl) if self.dim == 2: - self._hangingFx[self._fx2i[test ]] = ([self._fx2i[fx], 0.5], ) - self._hangingFx[self._fx2i[self._index([p[0] , p[1] + w, sl])]] = ([self._fx2i[fx], 0.5], ) + chy0 = self._cellH([p[0] , p[1] , sl])[1] + chy1 = self._cellH([p[0] , p[1] + w, sl])[1] + A = (chy0 + chy1) + + self._hangingFx[self._fx2i[test ]] = ([self._fx2i[fx], chy0 / A], ) + self._hangingFx[self._fx2i[self._index([p[0] , p[1] + w, sl])]] = ([self._fx2i[fx], chy1 / A], ) n0, n1 = fx, self._index([p[0], p[1] + 2*w, p[-1]]) self._hangingN[self._n2i[test ]] = ([self._n2i[n0], 1.0], ) - self._hangingN[self._n2i[self._index([p[0] , p[1] + w, sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n1], 0.5]) + self._hangingN[self._n2i[self._index([p[0] , p[1] + w, sl])]] = ([self._n2i[n0], 1.0 - chy0 / A], [self._n2i[n1], 1.0 - chy1 / A]) self._hangingN[self._n2i[self._index([p[0] , p[1] + 2*w, sl])]] = ([self._n2i[n1], 1.0], ) elif self.dim == 3: + + chy0 = self._cellH([p[0] , p[1] , p[2] , sl])[1] + chy1 = self._cellH([p[0] , p[1] + w, p[2] , sl])[1] + chz0 = self._cellH([p[0] , p[1] , p[2] , sl])[2] + chz1 = self._cellH([p[0] , p[1] , p[2] + w, sl])[2] + lenY = chy0 + chy1 + lenZ = chz0 + chz1 + A = lenY * lenZ + ey0 = fx ey1 = self._index([p[0], p[1] , p[2] + 2*w, p[-1]]) ez0 = fx @@ -811,24 +847,38 @@ class Tree(InnerProducts): n2 = self._index([p[0], p[1] , p[2] + 2*w, p[-1]]) n3 = self._index([p[0], p[1] + 2*w, p[2] + 2*w, p[-1]]) - self._hangingFx[self._fx2i[test ]] = ([self._fx2i[fx], 0.25], ) - self._hangingFx[self._fx2i[self._index([p[0], p[1] + w, p[2] , sl])]] = ([self._fx2i[fx], 0.25], ) - self._hangingFx[self._fx2i[self._index([p[0], p[1] , p[2] + w, sl])]] = ([self._fx2i[fx], 0.25], ) - self._hangingFx[self._fx2i[self._index([p[0], p[1] + w, p[2] + w, sl])]] = ([self._fx2i[fx], 0.25], ) + self._hangingFx[self._fx2i[test ]] = ([self._fx2i[fx], chy0*chz0 / A ], ) + self._hangingFx[self._fx2i[self._index([p[0], p[1] + w, p[2] , sl])]] = ([self._fx2i[fx], chy1*chz0 / A ], ) + self._hangingFx[self._fx2i[self._index([p[0], p[1] , p[2] + w, sl])]] = ([self._fx2i[fx], chy0*chz1 / A ], ) + self._hangingFx[self._fx2i[self._index([p[0], p[1] + w, p[2] + w, sl])]] = ([self._fx2i[fx], chy1*chz1 / A ], ) - self._hangingEy[self._ey2i[test ]] = ([self._ey2i[ey0], 0.5], ) - self._hangingEy[self._ey2i[self._index([p[0], p[1] + w, p[2] , sl])]] = ([self._ey2i[ey0], 0.5], ) - self._hangingEy[self._ey2i[self._index([p[0], p[1] , p[2] + w, sl])]] = ([self._ey2i[ey0], 0.25], [self._ey2i[ey1], 0.25]) - self._hangingEy[self._ey2i[self._index([p[0], p[1] + w, p[2] + w, sl])]] = ([self._ey2i[ey0], 0.25], [self._ey2i[ey1], 0.25]) - self._hangingEy[self._ey2i[self._index([p[0], p[1] , p[2] + 2*w, sl])]] = ([self._ey2i[ey1], 0.5], ) - self._hangingEy[self._ey2i[self._index([p[0], p[1] + w, p[2] + 2*w, sl])]] = ([self._ey2i[ey1], 0.5], ) + self._hangingEy[self._ey2i[test ]] = ([self._ey2i[ey0], 1.0], ) + self._hangingEy[self._ey2i[self._index([p[0], p[1] + w, p[2] , sl])]] = ([self._ey2i[ey0], 1.0], ) + self._hangingEy[self._ey2i[self._index([p[0], p[1] , p[2] + w, sl])]] = ([self._ey2i[ey0], 0.5], [self._ey2i[ey1], 0.5]) + self._hangingEy[self._ey2i[self._index([p[0], p[1] + w, p[2] + w, sl])]] = ([self._ey2i[ey0], 0.5], [self._ey2i[ey1], 0.5]) + self._hangingEy[self._ey2i[self._index([p[0], p[1] , p[2] + 2*w, sl])]] = ([self._ey2i[ey1], 1.0], ) + self._hangingEy[self._ey2i[self._index([p[0], p[1] + w, p[2] + 2*w, sl])]] = ([self._ey2i[ey1], 1.0], ) - self._hangingEz[self._ez2i[test ]] = ([self._ez2i[ez0], 0.5], ) - self._hangingEz[self._ez2i[self._index([p[0], p[1] , p[2] + w, sl])]] = ([self._ez2i[ez0], 0.5], ) - self._hangingEz[self._ez2i[self._index([p[0], p[1] + w, p[2] , sl])]] = ([self._ez2i[ez0], 0.25], [self._ez2i[ez1], 0.25]) - self._hangingEz[self._ez2i[self._index([p[0], p[1] + w, p[2] + w, sl])]] = ([self._ez2i[ez0], 0.25], [self._ez2i[ez1], 0.25]) - self._hangingEz[self._ez2i[self._index([p[0], p[1] + 2*w, p[2] , sl])]] = ([self._ez2i[ez1], 0.5], ) - self._hangingEz[self._ez2i[self._index([p[0], p[1] + 2*w, p[2] + w, sl])]] = ([self._ez2i[ez1], 0.5], ) + self._hangingEz[self._ez2i[test ]] = ([self._ez2i[ez0], 1.0], ) + self._hangingEz[self._ez2i[self._index([p[0], p[1] , p[2] + w, sl])]] = ([self._ez2i[ez0], 1.0], ) + self._hangingEz[self._ez2i[self._index([p[0], p[1] + w, p[2] , sl])]] = ([self._ez2i[ez0], 0.5], [self._ez2i[ez1], 0.5]) + self._hangingEz[self._ez2i[self._index([p[0], p[1] + w, p[2] + w, sl])]] = ([self._ez2i[ez0], 0.5], [self._ez2i[ez1], 0.5]) + self._hangingEz[self._ez2i[self._index([p[0], p[1] + 2*w, p[2] , sl])]] = ([self._ez2i[ez1], 1.0], ) + self._hangingEz[self._ez2i[self._index([p[0], p[1] + 2*w, p[2] + w, sl])]] = ([self._ez2i[ez1], 1.0], ) + + # self._hangingEy[self._ey2i[test ]] = ([self._ey2i[ey0], chy0 / lenY], ) + # self._hangingEy[self._ey2i[self._index([p[0], p[1] + w, p[2] , sl])]] = ([self._ey2i[ey0], chy1 / lenY], ) + # self._hangingEy[self._ey2i[self._index([p[0], p[1] , p[2] + w, sl])]] = ([self._ey2i[ey0], chy0 / lenY / 2.0], [self._ey2i[ey1], chy0 / lenY / 2.0]) + # self._hangingEy[self._ey2i[self._index([p[0], p[1] + w, p[2] + w, sl])]] = ([self._ey2i[ey0], chy1 / lenY / 2.0], [self._ey2i[ey1], chy1 / lenY / 2.0]) + # self._hangingEy[self._ey2i[self._index([p[0], p[1] , p[2] + 2*w, sl])]] = ([self._ey2i[ey1], chy0 / lenY], ) + # self._hangingEy[self._ey2i[self._index([p[0], p[1] + w, p[2] + 2*w, sl])]] = ([self._ey2i[ey1], chy1 / lenY], ) + + # self._hangingEz[self._ez2i[test ]] = ([self._ez2i[ez0], chz0 / lenZ], ) + # self._hangingEz[self._ez2i[self._index([p[0], p[1] , p[2] + w, sl])]] = ([self._ez2i[ez0], chz1 / lenZ], ) + # self._hangingEz[self._ez2i[self._index([p[0], p[1] + w, p[2] , sl])]] = ([self._ez2i[ez0], chz0 / lenZ / 2.0], [self._ez2i[ez1], chz0 / lenZ / 2.0]) + # self._hangingEz[self._ez2i[self._index([p[0], p[1] + w, p[2] + w, sl])]] = ([self._ez2i[ez0], chz1 / lenZ / 2.0], [self._ez2i[ez1], chz1 / lenZ / 2.0]) + # self._hangingEz[self._ez2i[self._index([p[0], p[1] + 2*w, p[2] , sl])]] = ([self._ez2i[ez1], chz0 / lenZ], ) + # self._hangingEz[self._ez2i[self._index([p[0], p[1] + 2*w, p[2] + w, sl])]] = ([self._ez2i[ez1], chz1 / lenZ], ) self._hangingN[ self._n2i[ test ]] = ([self._n2i[n0], 1.0], ) self._hangingN[ self._n2i[ self._index([p[0], p[1] + w, p[2] , sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n1], 0.5]) @@ -852,8 +902,11 @@ class Tree(InnerProducts): w = self._levelWidth(sl) if self.dim == 2: - self._hangingFy[self._fy2i[test ]] = ([self._fy2i[fy], 0.5], ) - self._hangingFy[self._fy2i[self._index([p[0] + w, p[1] , sl])]] = ([self._fy2i[fy], 0.5], ) + chx0 = self._cellH([p[0] , p[1] , sl])[0] + chx1 = self._cellH([p[0] + w, p[1] , sl])[0] + + self._hangingFy[self._fy2i[test ]] = ([self._fy2i[fy], chx0 / (chx0 + chx1)], ) + self._hangingFy[self._fy2i[self._index([p[0] + w, p[1] , sl])]] = ([self._fy2i[fy], chx1 / (chx0 + chx1)], ) n0, n1 = fy, self._index([p[0] + 2*w, p[1], p[-1]]) self._hangingN[self._n2i[test ]] = ([self._n2i[n0], 1.0], ) @@ -861,6 +914,15 @@ class Tree(InnerProducts): self._hangingN[self._n2i[self._index([p[0] + 2*w, p[1] , sl])]] = ([self._n2i[n1], 1.0], ) elif self.dim == 3: + + chx0 = self._cellH([p[0] , p[1] , p[2] , sl])[0] + chx1 = self._cellH([p[0] + w, p[1] , p[2] , sl])[0] + chz0 = self._cellH([p[0] , p[1] , p[2] , sl])[2] + chz1 = self._cellH([p[0] , p[1] , p[2] + w, sl])[2] + lenX = chx0 + chx1 + lenZ = chz0 + chz1 + A = lenX * lenZ + ex0 = fy ex1 = self._index([p[0] , p[1], p[2] + 2*w, p[-1]]) ez0 = fy @@ -871,24 +933,38 @@ class Tree(InnerProducts): n2 = self._index([p[0] , p[1], p[2] + 2*w, p[-1]]) n3 = self._index([p[0] + 2*w, p[1], p[2] + 2*w, p[-1]]) - self._hangingFy[self._fy2i[test ]] = ([self._fy2i[fy], 0.25], ) - self._hangingFy[self._fy2i[self._index([p[0] + w, p[1], p[2] , sl])]] = ([self._fy2i[fy], 0.25], ) - self._hangingFy[self._fy2i[self._index([p[0] , p[1], p[2] + w, sl])]] = ([self._fy2i[fy], 0.25], ) - self._hangingFy[self._fy2i[self._index([p[0] + w, p[1], p[2] + w, sl])]] = ([self._fy2i[fy], 0.25], ) + self._hangingFy[self._fy2i[test ]] = ([self._fy2i[fy], chx0*chz0 / A ], ) + self._hangingFy[self._fy2i[self._index([p[0] + w, p[1], p[2] , sl])]] = ([self._fy2i[fy], chx1*chz0 / A ], ) + self._hangingFy[self._fy2i[self._index([p[0] , p[1], p[2] + w, sl])]] = ([self._fy2i[fy], chx0*chz1 / A ], ) + self._hangingFy[self._fy2i[self._index([p[0] + w, p[1], p[2] + w, sl])]] = ([self._fy2i[fy], chx1*chz1 / A ], ) - self._hangingEx[self._ex2i[test ]] = ([self._ex2i[ex0], 0.5], ) - self._hangingEx[self._ex2i[self._index([p[0] + w, p[1], p[2] , sl])]] = ([self._ex2i[ex0], 0.5], ) - self._hangingEx[self._ex2i[self._index([p[0] , p[1], p[2] + w, sl])]] = ([self._ex2i[ex0], 0.25], [self._ex2i[ex1], 0.25]) - self._hangingEx[self._ex2i[self._index([p[0] + w, p[1], p[2] + w, sl])]] = ([self._ex2i[ex0], 0.25], [self._ex2i[ex1], 0.25]) - self._hangingEx[self._ex2i[self._index([p[0] , p[1], p[2] + 2*w, sl])]] = ([self._ex2i[ex1], 0.5], ) - self._hangingEx[self._ex2i[self._index([p[0] + w, p[1], p[2] + 2*w, sl])]] = ([self._ex2i[ex1], 0.5], ) + self._hangingEx[self._ex2i[test ]] = ([self._ex2i[ex0], 1.0], ) + self._hangingEx[self._ex2i[self._index([p[0] + w, p[1], p[2] , sl])]] = ([self._ex2i[ex0], 1.0], ) + self._hangingEx[self._ex2i[self._index([p[0] , p[1], p[2] + w, sl])]] = ([self._ex2i[ex0], 0.5], [self._ex2i[ex1], 0.5]) + self._hangingEx[self._ex2i[self._index([p[0] + w, p[1], p[2] + w, sl])]] = ([self._ex2i[ex0], 0.5], [self._ex2i[ex1], 0.5]) + self._hangingEx[self._ex2i[self._index([p[0] , p[1], p[2] + 2*w, sl])]] = ([self._ex2i[ex1], 1.0], ) + self._hangingEx[self._ex2i[self._index([p[0] + w, p[1], p[2] + 2*w, sl])]] = ([self._ex2i[ex1], 1.0], ) - self._hangingEz[self._ez2i[test ]] = ([self._ez2i[ez0], 0.5], ) - self._hangingEz[self._ez2i[self._index([p[0] , p[1], p[2] + w, sl])]] = ([self._ez2i[ez0], 0.5], ) - self._hangingEz[self._ez2i[self._index([p[0] + w, p[1], p[2] , sl])]] = ([self._ez2i[ez0], 0.25], [self._ez2i[ez1], 0.25]) - self._hangingEz[self._ez2i[self._index([p[0] + w, p[1], p[2] + w, sl])]] = ([self._ez2i[ez0], 0.25], [self._ez2i[ez1], 0.25]) - self._hangingEz[self._ez2i[self._index([p[0] + 2*w, p[1], p[2] , sl])]] = ([self._ez2i[ez1], 0.5], ) - self._hangingEz[self._ez2i[self._index([p[0] + 2*w, p[1], p[2] + w, sl])]] = ([self._ez2i[ez1], 0.5], ) + self._hangingEz[self._ez2i[test ]] = ([self._ez2i[ez0], 1.0], ) + self._hangingEz[self._ez2i[self._index([p[0] , p[1], p[2] + w, sl])]] = ([self._ez2i[ez0], 1.0], ) + self._hangingEz[self._ez2i[self._index([p[0] + w, p[1], p[2] , sl])]] = ([self._ez2i[ez0], 0.5], [self._ez2i[ez1], 0.5]) + self._hangingEz[self._ez2i[self._index([p[0] + w, p[1], p[2] + w, sl])]] = ([self._ez2i[ez0], 0.5], [self._ez2i[ez1], 0.5]) + self._hangingEz[self._ez2i[self._index([p[0] + 2*w, p[1], p[2] , sl])]] = ([self._ez2i[ez1], 1.0], ) + self._hangingEz[self._ez2i[self._index([p[0] + 2*w, p[1], p[2] + w, sl])]] = ([self._ez2i[ez1], 1.0], ) + + # self._hangingEx[self._ex2i[test ]] = ([self._ex2i[ex0], chx0 / lenX], ) + # self._hangingEx[self._ex2i[self._index([p[0] + w, p[1], p[2] , sl])]] = ([self._ex2i[ex0], chx1 / lenX], ) + # self._hangingEx[self._ex2i[self._index([p[0] , p[1], p[2] + w, sl])]] = ([self._ex2i[ex0], chx0 / lenX / 2.0], [self._ex2i[ex1], chx0 / lenX / 2.0]) + # self._hangingEx[self._ex2i[self._index([p[0] + w, p[1], p[2] + w, sl])]] = ([self._ex2i[ex0], chx1 / lenX / 2.0], [self._ex2i[ex1], chx1 / lenX / 2.0]) + # self._hangingEx[self._ex2i[self._index([p[0] , p[1], p[2] + 2*w, sl])]] = ([self._ex2i[ex1], chx0 / lenX], ) + # self._hangingEx[self._ex2i[self._index([p[0] + w, p[1], p[2] + 2*w, sl])]] = ([self._ex2i[ex1], chx1 / lenX], ) + + # self._hangingEz[self._ez2i[test ]] = ([self._ez2i[ez0], chz0 / lenZ], ) + # self._hangingEz[self._ez2i[self._index([p[0] , p[1], p[2] + w, sl])]] = ([self._ez2i[ez0], chz1 / lenZ], ) + # self._hangingEz[self._ez2i[self._index([p[0] + w, p[1], p[2] , sl])]] = ([self._ez2i[ez0], chz0 / lenZ / 2.0], [self._ez2i[ez1], chz0 / lenZ / 2.0]) + # self._hangingEz[self._ez2i[self._index([p[0] + w, p[1], p[2] + w, sl])]] = ([self._ez2i[ez0], chz1 / lenZ / 2.0], [self._ez2i[ez1], chz1 / lenZ / 2.0]) + # self._hangingEz[self._ez2i[self._index([p[0] + 2*w, p[1], p[2] , sl])]] = ([self._ez2i[ez1], chz0 / lenZ], ) + # self._hangingEz[self._ez2i[self._index([p[0] + 2*w, p[1], p[2] + w, sl])]] = ([self._ez2i[ez1], chz1 / lenZ], ) self._hangingN[ self._n2i[ test ]] = ([self._n2i[n0], 1.0], ) self._hangingN[ self._n2i[ self._index([p[0] + w, p[1], p[2] , sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n1], 0.5]) @@ -915,6 +991,14 @@ class Tree(InnerProducts): continue w = self._levelWidth(sl) + chx0 = self._cellH([p[0] , p[1] , p[2] , sl])[0] + chx1 = self._cellH([p[0] + w, p[1] , p[2] , sl])[0] + chy0 = self._cellH([p[0] , p[1] , p[2] , sl])[1] + chy1 = self._cellH([p[0] , p[1] + w, p[2] , sl])[1] + lenX = chx0 + chx1 + lenY = chy0 + chy1 + A = lenX * lenY + ex0 = fz ex1 = self._index([p[0] , p[1] + 2*w, p[2], p[-1]]) ey0 = fz @@ -925,24 +1009,38 @@ class Tree(InnerProducts): n2 = self._index([p[0] , p[1] + 2*w, p[2], p[-1]]) n3 = self._index([p[0] + 2*w, p[1] + 2*w, p[2], p[-1]]) - self._hangingFz[self._fz2i[test ]] = ([self._fz2i[fz], 0.25], ) - self._hangingFz[self._fz2i[self._index([p[0] + w, p[1] , p[2], sl])]] = ([self._fz2i[fz], 0.25], ) - self._hangingFz[self._fz2i[self._index([p[0] , p[1] + w, p[2], sl])]] = ([self._fz2i[fz], 0.25], ) - self._hangingFz[self._fz2i[self._index([p[0] + w, p[1] + w, p[2], sl])]] = ([self._fz2i[fz], 0.25], ) + self._hangingFz[self._fz2i[test ]] = ([self._fz2i[fz], chx0*chy0 / A ], ) + self._hangingFz[self._fz2i[self._index([p[0] + w, p[1] , p[2], sl])]] = ([self._fz2i[fz], chx1*chy0 / A ], ) + self._hangingFz[self._fz2i[self._index([p[0] , p[1] + w, p[2], sl])]] = ([self._fz2i[fz], chx0*chy1 / A ], ) + self._hangingFz[self._fz2i[self._index([p[0] + w, p[1] + w, p[2], sl])]] = ([self._fz2i[fz], chx1*chy1 / A ], ) - self._hangingEx[self._ex2i[test ]] = ([self._ex2i[ex0], 0.5], ) - self._hangingEx[self._ex2i[self._index([p[0] + w, p[1] , p[2], sl])]] = ([self._ex2i[ex0], 0.5], ) - self._hangingEx[self._ex2i[self._index([p[0] , p[1] + w, p[2], sl])]] = ([self._ex2i[ex0], 0.25], [self._ex2i[ex1], 0.25]) - self._hangingEx[self._ex2i[self._index([p[0] + w, p[1] + w, p[2], sl])]] = ([self._ex2i[ex0], 0.25], [self._ex2i[ex1], 0.25]) - self._hangingEx[self._ex2i[self._index([p[0] , p[1] + 2*w, p[2], sl])]] = ([self._ex2i[ex1], 0.5], ) - self._hangingEx[self._ex2i[self._index([p[0] + w, p[1] + 2*w, p[2], sl])]] = ([self._ex2i[ex1], 0.5], ) + self._hangingEx[self._ex2i[test ]] = ([self._ex2i[ex0], 1.0], ) + self._hangingEx[self._ex2i[self._index([p[0] + w, p[1] , p[2], sl])]] = ([self._ex2i[ex0], 1.0], ) + self._hangingEx[self._ex2i[self._index([p[0] , p[1] + w, p[2], sl])]] = ([self._ex2i[ex0], 0.5], [self._ex2i[ex1], 0.5]) + self._hangingEx[self._ex2i[self._index([p[0] + w, p[1] + w, p[2], sl])]] = ([self._ex2i[ex0], 0.5], [self._ex2i[ex1], 0.5]) + self._hangingEx[self._ex2i[self._index([p[0] , p[1] + 2*w, p[2], sl])]] = ([self._ex2i[ex1], 1.0], ) + self._hangingEx[self._ex2i[self._index([p[0] + w, p[1] + 2*w, p[2], sl])]] = ([self._ex2i[ex1], 1.0], ) - self._hangingEy[self._ey2i[test ]] = ([self._ey2i[ey0], 0.5], ) - self._hangingEy[self._ey2i[self._index([p[0] , p[1] + w, p[2], sl])]] = ([self._ey2i[ey0], 0.5], ) - self._hangingEy[self._ey2i[self._index([p[0] + w, p[1] , p[2], sl])]] = ([self._ey2i[ey0], 0.25], [self._ey2i[ey1], 0.25]) - self._hangingEy[self._ey2i[self._index([p[0] + w, p[1] + w, p[2], sl])]] = ([self._ey2i[ey0], 0.25], [self._ey2i[ey1], 0.25]) - self._hangingEy[self._ey2i[self._index([p[0] + 2*w, p[1] , p[2], sl])]] = ([self._ey2i[ey1], 0.5], ) - self._hangingEy[self._ey2i[self._index([p[0] + 2*w, p[1] + w, p[2], sl])]] = ([self._ey2i[ey1], 0.5], ) + self._hangingEy[self._ey2i[test ]] = ([self._ey2i[ey0], 1.0], ) + self._hangingEy[self._ey2i[self._index([p[0] , p[1] + w, p[2], sl])]] = ([self._ey2i[ey0], 1.0], ) + self._hangingEy[self._ey2i[self._index([p[0] + w, p[1] , p[2], sl])]] = ([self._ey2i[ey0], 0.5], [self._ey2i[ey1], 0.5]) + self._hangingEy[self._ey2i[self._index([p[0] + w, p[1] + w, p[2], sl])]] = ([self._ey2i[ey0], 0.5], [self._ey2i[ey1], 0.5]) + self._hangingEy[self._ey2i[self._index([p[0] + 2*w, p[1] , p[2], sl])]] = ([self._ey2i[ey1], 1.0], ) + self._hangingEy[self._ey2i[self._index([p[0] + 2*w, p[1] + w, p[2], sl])]] = ([self._ey2i[ey1], 1.0], ) + + # self._hangingEx[self._ex2i[test ]] = ([self._ex2i[ex0], chx0 / lenX], ) + # self._hangingEx[self._ex2i[self._index([p[0] + w, p[1] , p[2], sl])]] = ([self._ex2i[ex0], chx1 / lenX], ) + # self._hangingEx[self._ex2i[self._index([p[0] , p[1] + w, p[2], sl])]] = ([self._ex2i[ex0], chx0 / lenX / 2.0], [self._ex2i[ex1], chx0 / lenX / 2.0]) + # self._hangingEx[self._ex2i[self._index([p[0] + w, p[1] + w, p[2], sl])]] = ([self._ex2i[ex0], chx1 / lenX / 2.0], [self._ex2i[ex1], chx1 / lenX / 2.0]) + # self._hangingEx[self._ex2i[self._index([p[0] , p[1] + 2*w, p[2], sl])]] = ([self._ex2i[ex1], chx0 / lenX], ) + # self._hangingEx[self._ex2i[self._index([p[0] + w, p[1] + 2*w, p[2], sl])]] = ([self._ex2i[ex1], chx1 / lenX], ) + + # self._hangingEy[self._ey2i[test ]] = ([self._ey2i[ey0], chy0 / lenY], ) + # self._hangingEy[self._ey2i[self._index([p[0] , p[1] + w, p[2], sl])]] = ([self._ey2i[ey0], chy1 / lenY], ) + # self._hangingEy[self._ey2i[self._index([p[0] + w, p[1] , p[2], sl])]] = ([self._ey2i[ey0], chy0 / lenY / 2.0], [self._ey2i[ey1], chy0 / lenY / 2.0]) + # self._hangingEy[self._ey2i[self._index([p[0] + w, p[1] + w, p[2], sl])]] = ([self._ey2i[ey0], chy1 / lenY / 2.0], [self._ey2i[ey1], chy1 / lenY / 2.0]) + # self._hangingEy[self._ey2i[self._index([p[0] + 2*w, p[1] , p[2], sl])]] = ([self._ey2i[ey1], chy0 / lenY], ) + # self._hangingEy[self._ey2i[self._index([p[0] + 2*w, p[1] + w, p[2], sl])]] = ([self._ey2i[ey1], chy1 / lenY], ) self._hangingN[ self._n2i[ test ]] = ([self._n2i[n0], 1.0], ) self._hangingN[ self._n2i[ self._index([p[0] + w, p[1] , p[2], sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n1], 0.5]) @@ -956,12 +1054,12 @@ class Tree(InnerProducts): self.__dirtyHanging__ = False - def number(self, force=False): + def number(self, balance=True, force=False): if not self.__dirty__ and not force: return - self.balance() + if balance: self.balance() self._hanging(force=force) - def _deflationMatrix(self, location, withHanging=True): + def _deflationMatrix(self, location, withHanging=True, asOnes=False): assert location in ['N','F','Fx','Fy'] + (['Fz','E','Ex','Ey','Ez'] if self.dim == 3 else []) args = dict() @@ -974,11 +1072,11 @@ class Tree(InnerProducts): args['Ey'] = (self._edgesY, self._hangingEy, self._ey2i) args['Ez'] = (self._edgesZ, self._hangingEz, self._ez2i) if location in ['F', 'E']: - Rlist = [self._deflationMatrix(location + subLoc, withHanging=withHanging) for subLoc in ['x','y','z'][:self.dim]] + Rlist = [self._deflationMatrix(location + subLoc, withHanging=withHanging, asOnes=asOnes) for subLoc in ['x','y','z'][:self.dim]] return sp.block_diag(Rlist) - return self.__deflationMatrix(*args[location], withHanging=withHanging) + return self.__deflationMatrix(*args[location], withHanging=withHanging, asOnes=asOnes) - def __deflationMatrix(self, theSet, theHang, theIndex, withHanging=True): + def __deflationMatrix(self, theSet, theHang, theIndex, withHanging=True, asOnes=False): reducedInd = dict() # final reduced index ii = 0 I,J,V = [],[],[] @@ -994,7 +1092,10 @@ class Tree(InnerProducts): hf = theHang[hfkey] I += [hfkey]*len(hf) J += [reducedInd[_[0]] for _ in hf] - V += [_[1] for _ in hf] + if asOnes: + V += [1.0]*len(hf) + else: + V += [_[1] for _ in hf] return sp.csr_matrix((V,(I,J)), shape=(len(theSet), len(reducedInd))) @property @@ -1037,10 +1138,13 @@ class Tree(InnerProducts): V += [pm] D = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.ntF)) - R = self._deflationMatrix('F') + R = self._deflationMatrix('F',asOnes=True) VOL = self.vol - S = self.area - self._faceDiv = Utils.sdiag(1.0/VOL)*D*R*Utils.sdiag(S) + if self.dim == 2: + S = np.r_[self._areaFxFull, self._areaFyFull] + elif self.dim == 3: + S = np.r_[self._areaFxFull, self._areaFyFull, self._areaFzFull] + self._faceDiv = Utils.sdiag(1.0/VOL)*D*Utils.sdiag(S)*R return self._faceDiv @property @@ -1072,7 +1176,7 @@ class Tree(InnerProducts): J += [edge + off] V += [pm] - faceOffset = self.nFx + faceOffset = self.ntFx offset = [0]*2 + [self.ntEx+self.ntEy]*2 PM = [-1, 1, 1, -1] for ii, fy in enumerate(sorted(self._facesY)): @@ -1092,7 +1196,7 @@ class Tree(InnerProducts): J += [edge + off] V += [pm] - faceOffset = self.nFx + self.nFy + faceOffset = self.ntFx + self.ntFy offset = [0]*2 + [self.ntEx]*2 PM = [1, -1, -1, 1] for ii, fz in enumerate(sorted(self._facesZ)): @@ -1112,15 +1216,19 @@ class Tree(InnerProducts): J += [edge + off] V += [pm] - Rf = self._deflationMatrix('F') + Rf = self._deflationMatrix('F', withHanging=False, asOnes=False) Re = self._deflationMatrix('E') - C = sp.csr_matrix((V,(I,J)), shape=(self.ntF, self.ntE)) - S = self.area - L = self.edge - self._edgeCurl = Utils.sdiag(1/S)*Rf.T*C*Re*Utils.sdiag(L) - return self._edgeCurl + Rf_ave = Utils.sdiag(1./Rf.sum(axis=0)) * Rf.T + # print Rf_ave + + C = sp.csr_matrix((V,(I,J)), shape=(self.ntF, self.ntE)) + S = np.r_[self._areaFxFull, self._areaFyFull, self._areaFzFull] + L = np.r_[self._edgeExFull, self._edgeEyFull, self._edgeEzFull] + # self._edgeCurl = Rf.T*Utils.sdiag(1.0/S)*C*Utils.sdiag(L)*Re + self._edgeCurl = Rf_ave*Utils.sdiag(1.0/S)*C*Utils.sdiag(L)*Re + return self._edgeCurl def _getFaceP(self, xFace, yFace, zFace): ind1, ind2, ind3 = [], [], [] @@ -1145,7 +1253,7 @@ class Tree(InnerProducts): PXXX = sp.coo_matrix((np.ones(self.dim*self.nC), (range(self.dim*self.nC), IND)), shape=(self.dim*self.nC, self.ntF)).tocsr() - Rf = self._deflationMatrix('F', withHanging=True) + Rf = self._deflationMatrix('F', withHanging=True, asOnes=True) return PXXX * Rf @@ -1169,9 +1277,9 @@ class Tree(InnerProducts): p = self._pointer(ind) w = self._levelWidth(p[-1]) - posX = [0,0] if xEdge == 'eX0' else [1, 0] if xEdge == 'eX1' else [0,1] if xEdge == 'eX2' else [1,1] - posY = [0,0] if yEdge == 'eY0' else [1, 0] if yEdge == 'eY1' else [0,1] if yEdge == 'eY2' else [1,1] - posZ = [0,0] if zEdge == 'eZ0' else [1, 0] if zEdge == 'eZ1' else [0,1] if zEdge == 'eZ2' else [1,1] + posX = [0,0] if xEdge == 'eX0' else [w, 0] if xEdge == 'eX1' else [0,w] if xEdge == 'eX2' else [w,w] + posY = [0,0] if yEdge == 'eY0' else [w, 0] if yEdge == 'eY1' else [0,w] if yEdge == 'eY2' else [w,w] + posZ = [0,0] if zEdge == 'eZ0' else [w, 0] if zEdge == 'eZ1' else [0,w] if zEdge == 'eZ2' else [w,w] ind1.append( self._ex2i[self._index([ p[0] , p[1] + posX[0], p[2] + posX[1], p[3]])] ) ind2.append( self._ey2i[self._index([ p[0] + posY[0], p[1] , p[2] + posY[1], p[3]])] + self.ntEx ) @@ -1181,9 +1289,9 @@ class Tree(InnerProducts): PXXX = sp.coo_matrix((np.ones(self.dim*self.nC), (range(self.dim*self.nC), IND)), shape=(self.dim*self.nC, self.ntE)).tocsr() - Rf = self._deflationMatrix('E', withHanging=False) + Re = self._deflationMatrix('E') - return PXXX * Rf + return PXXX * Re def _getEdgePxx(self): raise Exception('Not implemented') # this should be a reordering of the face inner product? @@ -1314,6 +1422,24 @@ class Tree(InnerProducts): if showIt:plt.show() + def plotImage(self, I, ax=None, showIt=True): + if self.dim == 3: raise Exception() + + if ax is None: ax = plt.subplot(111) + jet = cm = plt.get_cmap('jet') + cNorm = colors.Normalize(vmin=I.min(), vmax=I.max()) + scalarMap = cmx.ScalarMappable(norm=cNorm, cmap=jet) + ax.set_xlim((self.x0[0], self.h[0].sum())) + ax.set_ylim((self.x0[1], self.h[1].sum())) + for ii, node in enumerate(self._sortedCells): + x0, sz = self._cellN(node), self._cellH(node) + ax.add_patch(plt.Rectangle((x0[0], x0[1]), sz[0], sz[1], facecolor=scalarMap.to_rgba(I[ii]), edgecolor='k')) + # if text: ax.text(self.center[0],self.center[1],self.num) + scalarMap._A = [] # http://stackoverflow.com/questions/8342549/matplotlib-add-colorbar-to-a-sequence-of-line-plots + plt.colorbar(scalarMap) + if showIt: plt.show() + + if __name__ == '__main__': @@ -1332,9 +1458,9 @@ if __name__ == '__main__': else: return 0 - T = Tree([[(1,128)],[(1,128)],[(1,128)]],levels=7) + # T = Tree([[(1,128)],[(1,128)],[(1,128)]],levels=7) # T = Tree([128,128,128],levels=7) - # T = Tree([[(1,16)],[(1,16)]],levels=4) + T = Tree([[(1,16)],[(1,16)]],levels=4) # T = Tree([[(1,128)],[(1,128)]],levels=7) # T.refine(lambda xc:1, balance=False) # T._index([0,0,0]) @@ -1346,6 +1472,8 @@ if __name__ == '__main__': print time.time() - tic print T.nC + T.plotImage(np.random.rand(T.nC),showIt=True) + print T.getFaceInnerProduct() # print T.gridFz diff --git a/SimPEG/Tests.py b/SimPEG/Tests.py index c6aa5bc4..722d302b 100644 --- a/SimPEG/Tests.py +++ b/SimPEG/Tests.py @@ -4,6 +4,7 @@ from numpy.linalg import norm from SimPEG.Utils import mkvc, sdiag, diagEst from SimPEG import Utils from SimPEG.Mesh import TensorMesh, CurvilinearMesh, CylMesh +from SimPEG.Mesh.PointerTree import Tree import numpy as np import scipy.sparse as sp import unittest @@ -132,6 +133,32 @@ class OrderTest(unittest.TestCase): self.M = CurvilinearMesh([X, Y, Z]) return 1./nc + elif 'Tree' in self._meshType: + nc *= 2 + if 'uniform' in self._meshType: + h = [nc, nc, nc] + elif 'random' in self._meshType: + h1 = np.random.rand(nc)*nc*0.5 + nc*0.5 + h2 = np.random.rand(nc)*nc*0.5 + nc*0.5 + h3 = np.random.rand(nc)*nc*0.5 + nc*0.5 + h = [hi/np.sum(hi) for hi in [h1, h2, h3]] # normalize + else: + raise Exception('Unexpected meshType') + + levels = int(np.log(nc)/np.log(2)) + self.M = Tree(h[:self.meshDimension], levels=levels) + def function(xc): + r = xc - np.array([0.5]*len(xc)) + dist = np.sqrt(r.dot(r)) + if dist < 0.3: + return levels + return levels-1 + self.M.refine(function,balance=False) + self.M.number(balance=False) + # self.M.plotGrid(showIt=True) + max_h = max([np.max(hi) for hi in self.M.h]) + return max_h + def getError(self): """For given h, generate A[h], f and A(f) and return norm of error.""" return 1. diff --git a/tests/mesh/test_TreeOperators.py b/tests/mesh/test_TreeOperators.py new file mode 100644 index 00000000..9babe1a2 --- /dev/null +++ b/tests/mesh/test_TreeOperators.py @@ -0,0 +1,103 @@ +import numpy as np +import unittest +from SimPEG.Tests import OrderTest +import matplotlib.pyplot as plt + +#TODO: 'randomTensorMesh' +MESHTYPES = ['uniformTree'] #['randomTree', 'uniformTree'] +call2 = lambda fun, xyz: fun(xyz[:, 0], xyz[:, 1]) +call3 = lambda fun, xyz: fun(xyz[:, 0], xyz[:, 1], xyz[:, 2]) +cart_row2 = lambda g, xfun, yfun: np.c_[call2(xfun, g), call2(yfun, g)] +cart_row3 = lambda g, xfun, yfun, zfun: np.c_[call3(xfun, g), call3(yfun, g), call3(zfun, g)] +cartF2 = lambda M, fx, fy: np.vstack((cart_row2(M.gridFx, fx, fy), cart_row2(M.gridFy, fx, fy))) +cartE2 = lambda M, ex, ey: np.vstack((cart_row2(M.gridEx, ex, ey), cart_row2(M.gridEy, ex, ey))) +cartF3 = lambda M, fx, fy, fz: np.vstack((cart_row3(M.gridFx, fx, fy, fz), cart_row3(M.gridFy, fx, fy, fz), cart_row3(M.gridFz, fx, fy, fz))) +cartE3 = lambda M, ex, ey, ez: np.vstack((cart_row3(M.gridEx, ex, ey, ez), cart_row3(M.gridEy, ex, ey, ez), cart_row3(M.gridEz, ex, ey, ez))) + + +class TestFaceDiv2D(OrderTest): + name = "Face Divergence 2D" + meshTypes = MESHTYPES + meshDimension = 2 + meshSizes = [16, 32] + + def getError(self): + #Test function + fx = lambda x, y: np.sin(2*np.pi*x) + fy = lambda x, y: np.sin(2*np.pi*y) + sol = lambda x, y: 2*np.pi*(np.cos(2*np.pi*x)+np.cos(2*np.pi*y)) + + Fc = cartF2(self.M, fx, fy) + F = self.M.projectFaceVector(Fc) + + divF = self.M.faceDiv.dot(F) + divF_ana = call2(sol, self.M.gridCC) + + err = np.linalg.norm((divF-divF_ana), np.inf) + + # self.M.plotImage(divF-divF_ana, showIt=True) + + return err + + def test_order(self): + self.orderTest() + +class TestFaceDiv3D(OrderTest): + name = "Face Divergence 3D" + meshTypes = MESHTYPES + meshSizes = [8, 16] + + def getError(self): + #Test function + fx = lambda x, y, z: np.sin(2*np.pi*x) + fy = lambda x, y, z: np.sin(2*np.pi*y) + fz = lambda x, y, z: np.sin(2*np.pi*z) + sol = lambda x, y, z: (2*np.pi*np.cos(2*np.pi*x)+2*np.pi*np.cos(2*np.pi*y)+2*np.pi*np.cos(2*np.pi*z)) + + Fc = cartF3(self.M, fx, fy, fz) + F = self.M.projectFaceVector(Fc) + + divF = self.M.faceDiv.dot(F) + divF_ana = call3(sol, self.M.gridCC) + + return np.linalg.norm((divF-divF_ana), np.inf) + + + def test_order(self): + self.orderTest() + + +class TestCurl(OrderTest): + name = "Curl" + meshTypes = MESHTYPES + meshSizes = [4, 8, 16, 32] + + def getError(self): + # fun: i (cos(y)) + j (cos(z)) + k (cos(x)) + # sol: i (sin(z)) + j (sin(x)) + k (sin(y)) + + funX = lambda x, y, z: np.cos(2*np.pi*y) + funY = lambda x, y, z: np.cos(2*np.pi*z) + funZ = lambda x, y, z: np.cos(2*np.pi*x) + + solX = lambda x, y, z: 2*np.pi*np.sin(2*np.pi*z) + solY = lambda x, y, z: 2*np.pi*np.sin(2*np.pi*x) + solZ = lambda x, y, z: 2*np.pi*np.sin(2*np.pi*y) + + Ec = cartE3(self.M, funX, funY, funZ) + E = self.M.projectEdgeVector(Ec) + + Fc = cartF3(self.M, solX, solY, solZ) + curlE_ana = self.M.projectFaceVector(Fc) + + curlE = self.M.edgeCurl.dot(E) + + err = np.linalg.norm((curlE - curlE_ana), np.inf) + + return err + + def test_order(self): + self.orderTest() + +if __name__ == '__main__': + unittest.main() diff --git a/tests/mesh/test_pointerMesh.py b/tests/mesh/test_pointerMesh.py index c609f372..83672fe7 100644 --- a/tests/mesh/test_pointerMesh.py +++ b/tests/mesh/test_pointerMesh.py @@ -11,16 +11,21 @@ TOL = 1e-10 class TestSimpleQuadTree(unittest.TestCase): def test_counts(self): - - M = Tree([8,8]) + nc = 8 + h1 = np.random.rand(nc)*nc*0.5 + nc*0.5 + h2 = np.random.rand(nc)*nc*0.5 + nc*0.5 + h = [hi/np.sum(hi) for hi in [h1, h2]] # normalize + M = Tree(h) M._refineCell([0,0,0]) M._refineCell([0,0,1]) M.number() # M.plotGrid(showIt=True) - # assert sorted(M._cells) == [2, 34, 66, 99, 107, 115, 123, 129, 257, 386, 418, 450, 482] assert M.nhFx == 2 assert M.nFx == 9 - assert M.vol.sum() == 1.0 + + assert np.allclose(M.vol.sum(), 1.0) + + assert np.allclose(np.r_[M._areaFxFull, M._areaFyFull], M._deflationMatrix('F') * M.area) # def test_connectivity(self): @@ -48,10 +53,7 @@ class TestSimpleQuadTree(unittest.TestCase): # assert T._getNextCell([0,2,2], direction=1) == T._index([0,4,1]) # assert T._getNextCell([0,4,1], direction=1, positive=False) == [T._index([0,2,2]), [T._index([2,3,3]), T._index([3,3,3])]] - -class TestOperatorsQuadTree(unittest.TestCase): - - def test_counts(self): + def test_faceDiv(self): hx, hy = np.r_[1.,2,3,4], np.r_[5.,6,7,8] T = Tree([hx, hy], levels=2) @@ -76,7 +78,31 @@ class TestOperatorsQuadTree(unittest.TestCase): assert (M.faceDiv - T.permuteCC*T.faceDiv*T.permuteF.T).nnz == 0 -class TestOperatorsOcTree(unittest.TestCase): +class TestOcTree(unittest.TestCase): + + def test_counts(self): + nc = 8 + h1 = np.random.rand(nc)*nc*0.5 + nc*0.5 + h2 = np.random.rand(nc)*nc*0.5 + nc*0.5 + h3 = np.random.rand(nc)*nc*0.5 + nc*0.5 + h = [hi/np.sum(hi) for hi in [h1, h2, h3]] # normalize + M = Tree(h, levels=3) + M._refineCell([0,0,0,0]) + M._refineCell([0,0,0,1]) + M.number() + # M.plotGrid(showIt=True) + # assert M.nhFx == 2 + # assert M.nFx == 9 + + assert np.allclose(M.vol.sum(), 1.0) + + # assert np.allclose(M._areaFxFull, (M._deflationMatrix('F') * M.area)[:M.ntFx]) + # assert np.allclose(M._areaFyFull, (M._deflationMatrix('F') * M.area)[M.ntFx:(M.ntFx+M.ntFy)]) + # assert np.allclose(M._areaFzFull, (M._deflationMatrix('F') * M.area)[(M.ntFx+M.ntFy):]) + + # assert np.allclose(M._edgeExFull, (M._deflationMatrix('E') * M.edge)[:M.ntEx]) + # assert np.allclose(M._edgeEyFull, (M._deflationMatrix('E') * M.edge)[M.ntEx:(M.ntEx+M.ntEy)]) + # assert np.allclose(M._edgeEzFull, (M._deflationMatrix('E') * M.edge)[(M.ntEx+M.ntEy):]) def test_faceDiv(self): @@ -136,6 +162,23 @@ class TestOperatorsOcTree(unittest.TestCase): assert np.allclose(Mr.getFaceInnerProduct().todense(), (M.permuteF * M.getFaceInnerProduct() * M.permuteF.T).todense()) assert np.allclose(Mr.getEdgeInnerProduct().todense(), (M.permuteE * M.getEdgeInnerProduct() * M.permuteE.T).todense()) + def test_VectorIdenties(self): + hx, hy, hz = [[(1,4)], [(1,4)], [(1,4)]] + + M = Tree([hx, hy, hz], levels=2) + Mr = Mesh.TensorMesh([hx, hy, hz]) + + assert (M.faceDiv * M.edgeCurl).nnz == 0 + assert (Mr.faceDiv * Mr.edgeCurl).nnz == 0 + + hx, hy, hz = np.r_[1.,2,3,4], np.r_[5.,6,7,8], np.r_[9.,10,11,12] + + M = Tree([hx, hy, hz], levels=2) + Mr = Mesh.TensorMesh([hx, hy, hz]) + + assert np.max(np.abs((M.faceDiv * M.edgeCurl).todense().flatten())) < TOL + assert np.max(np.abs((Mr.faceDiv * Mr.edgeCurl).todense().flatten())) < TOL + if __name__ == '__main__': From f6c5b011e87f20e49a7e78697ad566483bcbbc2e Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Tue, 10 Nov 2015 17:11:08 -0800 Subject: [PATCH 48/83] Tests octree order --- SimPEG/Mesh/PointerTree.py | 5 +- SimPEG/Tests.py | 2 +- tests/mesh/test_TreeOperators.py | 304 ++++++++++++++++++++++++++++++- tests/mesh/test_pointerMesh.py | 25 --- 4 files changed, 299 insertions(+), 37 deletions(-) diff --git a/SimPEG/Mesh/PointerTree.py b/SimPEG/Mesh/PointerTree.py index 2c71bd75..a276f0c1 100644 --- a/SimPEG/Mesh/PointerTree.py +++ b/SimPEG/Mesh/PointerTree.py @@ -1216,17 +1216,14 @@ class Tree(BaseMesh, InnerProducts): J += [edge + off] V += [pm] - Rf = self._deflationMatrix('F', withHanging=False, asOnes=False) + Rf = self._deflationMatrix('F', withHanging=True, asOnes=False) Re = self._deflationMatrix('E') Rf_ave = Utils.sdiag(1./Rf.sum(axis=0)) * Rf.T - # print Rf_ave - C = sp.csr_matrix((V,(I,J)), shape=(self.ntF, self.ntE)) S = np.r_[self._areaFxFull, self._areaFyFull, self._areaFzFull] L = np.r_[self._edgeExFull, self._edgeEyFull, self._edgeEzFull] - # self._edgeCurl = Rf.T*Utils.sdiag(1.0/S)*C*Utils.sdiag(L)*Re self._edgeCurl = Rf_ave*Utils.sdiag(1.0/S)*C*Utils.sdiag(L)*Re return self._edgeCurl diff --git a/SimPEG/Tests.py b/SimPEG/Tests.py index 722d302b..3d89b045 100644 --- a/SimPEG/Tests.py +++ b/SimPEG/Tests.py @@ -150,7 +150,7 @@ class OrderTest(unittest.TestCase): def function(xc): r = xc - np.array([0.5]*len(xc)) dist = np.sqrt(r.dot(r)) - if dist < 0.3: + if dist < 0.2: return levels return levels-1 self.M.refine(function,balance=False) diff --git a/tests/mesh/test_TreeOperators.py b/tests/mesh/test_TreeOperators.py index 9babe1a2..f2ff66da 100644 --- a/tests/mesh/test_TreeOperators.py +++ b/tests/mesh/test_TreeOperators.py @@ -1,9 +1,8 @@ import numpy as np import unittest -from SimPEG.Tests import OrderTest +from SimPEG import Utils, Tests import matplotlib.pyplot as plt -#TODO: 'randomTensorMesh' MESHTYPES = ['uniformTree'] #['randomTree', 'uniformTree'] call2 = lambda fun, xyz: fun(xyz[:, 0], xyz[:, 1]) call3 = lambda fun, xyz: fun(xyz[:, 0], xyz[:, 1], xyz[:, 2]) @@ -15,7 +14,7 @@ cartF3 = lambda M, fx, fy, fz: np.vstack((cart_row3(M.gridFx, fx, fy, fz), cart_ cartE3 = lambda M, ex, ey, ez: np.vstack((cart_row3(M.gridEx, ex, ey, ez), cart_row3(M.gridEy, ex, ey, ez), cart_row3(M.gridEz, ex, ey, ez))) -class TestFaceDiv2D(OrderTest): +class TestFaceDiv2D(Tests.OrderTest): name = "Face Divergence 2D" meshTypes = MESHTYPES meshDimension = 2 @@ -42,13 +41,12 @@ class TestFaceDiv2D(OrderTest): def test_order(self): self.orderTest() -class TestFaceDiv3D(OrderTest): +class TestFaceDiv3D(Tests.OrderTest): name = "Face Divergence 3D" meshTypes = MESHTYPES meshSizes = [8, 16] def getError(self): - #Test function fx = lambda x, y, z: np.sin(2*np.pi*x) fy = lambda x, y, z: np.sin(2*np.pi*y) fz = lambda x, y, z: np.sin(2*np.pi*z) @@ -67,10 +65,11 @@ class TestFaceDiv3D(OrderTest): self.orderTest() -class TestCurl(OrderTest): +class TestCurl(Tests.OrderTest): name = "Curl" meshTypes = MESHTYPES - meshSizes = [4, 8, 16, 32] + meshSizes = [8, 16]#, 32] + expectedOrders = 1 # This is due to linear interpolation in the Re projection def getError(self): # fun: i (cos(y)) + j (cos(z)) + k (cos(x)) @@ -93,11 +92,302 @@ class TestCurl(OrderTest): curlE = self.M.edgeCurl.dot(E) err = np.linalg.norm((curlE - curlE_ana), np.inf) + # err = np.linalg.norm((curlE - curlE_ana)*self.M.area, 2) return err def test_order(self): self.orderTest() + +class TestTreeInnerProducts(Tests.OrderTest): + """Integrate an function over a unit cube domain using edgeInnerProducts and faceInnerProducts.""" + + meshTypes = ['uniformTree'] #['uniformTensorMesh', 'uniformCurv', 'rotateCurv'] + meshDimension = 3 + meshSizes = [4, 8] + + def getError(self): + + call = lambda fun, xyz: fun(xyz[:, 0], xyz[:, 1], xyz[:, 2]) + + ex = lambda x, y, z: x**2+y*z + ey = lambda x, y, z: (z**2)*x+y*z + ez = lambda x, y, z: y**2+x*z + + sigma1 = lambda x, y, z: x*y+1 + sigma2 = lambda x, y, z: x*z+2 + sigma3 = lambda x, y, z: 3+z*y + sigma4 = lambda x, y, z: 0.1*x*y*z + sigma5 = lambda x, y, z: 0.2*x*y + sigma6 = lambda x, y, z: 0.1*z + + Gc = self.M.gridCC + if self.sigmaTest == 1: + sigma = np.c_[call(sigma1, Gc)] + analytic = 647./360 # Found using sympy. + elif self.sigmaTest == 3: + sigma = np.r_[call(sigma1, Gc), call(sigma2, Gc), call(sigma3, Gc)] + analytic = 37./12 # Found using sympy. + elif self.sigmaTest == 6: + sigma = np.c_[call(sigma1, Gc), call(sigma2, Gc), call(sigma3, Gc), + call(sigma4, Gc), call(sigma5, Gc), call(sigma6, Gc)] + analytic = 69881./21600 # Found using sympy. + + if self.location == 'edges': + cart = lambda g: np.c_[call(ex, g), call(ey, g), call(ez, g)] + Ec = np.vstack((cart(self.M.gridEx), + cart(self.M.gridEy), + cart(self.M.gridEz))) + E = self.M.projectEdgeVector(Ec) + + if self.invProp: + A = self.M.getEdgeInnerProduct(Utils.invPropertyTensor(self.M, sigma), invProp=True) + else: + A = self.M.getEdgeInnerProduct(sigma) + numeric = E.T.dot(A.dot(E)) + elif self.location == 'faces': + cart = lambda g: np.c_[call(ex, g), call(ey, g), call(ez, g)] + Fc = np.vstack((cart(self.M.gridFx), + cart(self.M.gridFy), + cart(self.M.gridFz))) + F = self.M.projectFaceVector(Fc) + + if self.invProp: + A = self.M.getFaceInnerProduct(Utils.invPropertyTensor(self.M, sigma), invProp=True) + else: + A = self.M.getFaceInnerProduct(sigma) + numeric = F.T.dot(A.dot(F)) + + err = np.abs(numeric - analytic) + return err + + def test_order1_edges(self): + self.name = "Edge Inner Product - Isotropic" + self.location = 'edges' + self.sigmaTest = 1 + self.invProp = False + self.orderTest() + + def test_order1_edges_invProp(self): + self.name = "Edge Inner Product - Isotropic - invProp" + self.location = 'edges' + self.sigmaTest = 1 + self.invProp = True + self.orderTest() + + def test_order3_edges(self): + self.name = "Edge Inner Product - Anisotropic" + self.location = 'edges' + self.sigmaTest = 3 + self.invProp = False + self.orderTest() + + def test_order3_edges_invProp(self): + self.name = "Edge Inner Product - Anisotropic - invProp" + self.location = 'edges' + self.sigmaTest = 3 + self.invProp = True + self.orderTest() + + def test_order6_edges(self): + self.name = "Edge Inner Product - Full Tensor" + self.location = 'edges' + self.sigmaTest = 6 + self.invProp = False + self.orderTest() + + def test_order6_edges_invProp(self): + self.name = "Edge Inner Product - Full Tensor - invProp" + self.location = 'edges' + self.sigmaTest = 6 + self.invProp = True + self.orderTest() + + def test_order1_faces(self): + self.name = "Face Inner Product - Isotropic" + self.location = 'faces' + self.sigmaTest = 1 + self.invProp = False + self.orderTest() + + def test_order1_faces_invProp(self): + self.name = "Face Inner Product - Isotropic - invProp" + self.location = 'faces' + self.sigmaTest = 1 + self.invProp = True + self.orderTest() + + def test_order3_faces(self): + self.name = "Face Inner Product - Anisotropic" + self.location = 'faces' + self.sigmaTest = 3 + self.invProp = False + self.orderTest() + + def test_order3_faces_invProp(self): + self.name = "Face Inner Product - Anisotropic - invProp" + self.location = 'faces' + self.sigmaTest = 3 + self.invProp = True + self.orderTest() + + def test_order6_faces(self): + self.name = "Face Inner Product - Full Tensor" + self.location = 'faces' + self.sigmaTest = 6 + self.invProp = False + self.orderTest() + + def test_order6_faces_invProp(self): + self.name = "Face Inner Product - Full Tensor - invProp" + self.location = 'faces' + self.sigmaTest = 6 + self.invProp = True + self.orderTest() + + +class TestTreeInnerProducts2D(Tests.OrderTest): + """Integrate an function over a unit cube domain using edgeInnerProducts and faceInnerProducts.""" + + meshTypes = ['uniformTree', 'randomTree'] #['uniformTensorMesh', 'uniformCurv', 'rotateCurv'] + meshDimension = 2 + meshSizes = [4, 8] + + def getError(self): + + z = 5 # Because 5 is just such a great number. + + call = lambda fun, xy: fun(xy[:, 0], xy[:, 1]) + + ex = lambda x, y: x**2+y*z + ey = lambda x, y: (z**2)*x+y*z + + sigma1 = lambda x, y: x*y+1 + sigma2 = lambda x, y: x*z+2 + sigma3 = lambda x, y: 3+z*y + + Gc = self.M.gridCC + if self.sigmaTest == 1: + sigma = np.c_[call(sigma1, Gc)] + analytic = 144877./360 # Found using sympy. z=5 + elif self.sigmaTest == 2: + sigma = np.c_[call(sigma1, Gc), call(sigma2, Gc)] + analytic = 189959./120 # Found using sympy. z=5 + elif self.sigmaTest == 3: + sigma = np.r_[call(sigma1, Gc), call(sigma2, Gc), call(sigma3, Gc)] + analytic = 781427./360 # Found using sympy. z=5 + + if self.location == 'edges': + cart = lambda g: np.c_[call(ex, g), call(ey, g)] + Ec = np.vstack((cart(self.M.gridEx), + cart(self.M.gridEy))) + E = self.M.projectEdgeVector(Ec) + if self.invProp: + A = self.M.getEdgeInnerProduct(Utils.invPropertyTensor(self.M, sigma), invProp=True) + else: + A = self.M.getEdgeInnerProduct(sigma) + numeric = E.T.dot(A.dot(E)) + elif self.location == 'faces': + cart = lambda g: np.c_[call(ex, g), call(ey, g)] + Fc = np.vstack((cart(self.M.gridFx), + cart(self.M.gridFy))) + F = self.M.projectFaceVector(Fc) + + if self.invProp: + A = self.M.getFaceInnerProduct(Utils.invPropertyTensor(self.M, sigma), invProp=True) + else: + A = self.M.getFaceInnerProduct(sigma) + numeric = F.T.dot(A.dot(F)) + + err = np.abs(numeric - analytic) + return err + + # def test_order1_edges(self): + # self.name = "2D Edge Inner Product - Isotropic" + # self.location = 'edges' + # self.sigmaTest = 1 + # self.invProp = False + # self.orderTest() + + # def test_order1_edges_invProp(self): + # self.name = "2D Edge Inner Product - Isotropic - invProp" + # self.location = 'edges' + # self.sigmaTest = 1 + # self.invProp = True + # self.orderTest() + + # def test_order3_edges(self): + # self.name = "2D Edge Inner Product - Anisotropic" + # self.location = 'edges' + # self.sigmaTest = 2 + # self.invProp = False + # self.orderTest() + + # def test_order3_edges_invProp(self): + # self.name = "2D Edge Inner Product - Anisotropic - invProp" + # self.location = 'edges' + # self.sigmaTest = 2 + # self.invProp = True + # self.orderTest() + + # def test_order6_edges(self): + # self.name = "2D Edge Inner Product - Full Tensor" + # self.location = 'edges' + # self.sigmaTest = 3 + # self.invProp = False + # self.orderTest() + + # def test_order6_edges_invProp(self): + # self.name = "2D Edge Inner Product - Full Tensor - invProp" + # self.location = 'edges' + # self.sigmaTest = 3 + # self.invProp = True + # self.orderTest() + + def test_order1_faces(self): + self.name = "2D Face Inner Product - Isotropic" + self.location = 'faces' + self.sigmaTest = 1 + self.invProp = False + self.orderTest() + + def test_order1_faces_invProp(self): + self.name = "2D Face Inner Product - Isotropic - invProp" + self.location = 'faces' + self.sigmaTest = 1 + self.invProp = True + self.orderTest() + + def test_order2_faces(self): + self.name = "2D Face Inner Product - Anisotropic" + self.location = 'faces' + self.sigmaTest = 2 + self.invProp = False + self.orderTest() + + def test_order2_faces_invProp(self): + self.name = "2D Face Inner Product - Anisotropic - invProp" + self.location = 'faces' + self.sigmaTest = 2 + self.invProp = True + self.orderTest() + + def test_order3_faces(self): + self.name = "2D Face Inner Product - Full Tensor" + self.location = 'faces' + self.sigmaTest = 3 + self.invProp = False + self.orderTest() + + def test_order3_faces_invProp(self): + self.name = "2D Face Inner Product - Full Tensor - invProp" + self.location = 'faces' + self.sigmaTest = 3 + self.invProp = True + self.orderTest() + + + if __name__ == '__main__': unittest.main() diff --git a/tests/mesh/test_pointerMesh.py b/tests/mesh/test_pointerMesh.py index 83672fe7..753873b1 100644 --- a/tests/mesh/test_pointerMesh.py +++ b/tests/mesh/test_pointerMesh.py @@ -28,31 +28,6 @@ class TestSimpleQuadTree(unittest.TestCase): assert np.allclose(np.r_[M._areaFxFull, M._areaFyFull], M._deflationMatrix('F') * M.area) - # def test_connectivity(self): - # T = Tree([8,8]) - # T._refineCell([0,0,0]) - # T._refineCell([4,4,1]) - # T._refineCell([0,0,1]) - # T._refineCell([2,2,2]) - # T.number() - # assert T._getNextCell([4,0,1]) is None - # assert T._getNextCell([0,4,1]) == [T._index([4,4,2]), T._index([4,6,2])] - # assert T._getNextCell([0,2,2]) == [T._index([2,2,3]), T._index([2,3,3])] - # assert T._getNextCell([4,4,2]) == T._index([6,4,2]) - # assert T._getNextCell([6,4,2]) is None - # assert T._getNextCell([2,0,2]) == T._index([4,0,1]) - # assert T._getNextCell([4,0,1], positive=False) == [T._index([2,0,2]), [T._index([3,2,3]), T._index([3,3,3])]] - # assert T._getNextCell([3,3,3]) == T._index([4,0,1]) - # assert T._getNextCell([3,2,3]) == T._index([4,0,1]) - # assert T._getNextCell([2,2,3]) == T._index([3,2,3]) - # assert T._getNextCell([3,2,3], positive=False) == T._index([2,2,3]) - - - # assert T._getNextCell([0,0,2], direction=1) == T._index([0,2,2]) - # assert T._getNextCell([0,2,2], direction=1, positive=False) == T._index([0,0,2]) - # assert T._getNextCell([0,2,2], direction=1) == T._index([0,4,1]) - # assert T._getNextCell([0,4,1], direction=1, positive=False) == [T._index([0,2,2]), [T._index([2,3,3]), T._index([3,3,3])]] - def test_faceDiv(self): hx, hy = np.r_[1.,2,3,4], np.r_[5.,6,7,8] From 37a68dd5b7f0d7bcb3a733c1c3b70db398c45035 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Tue, 10 Nov 2015 17:25:18 -0800 Subject: [PATCH 49/83] Cython dep. the setup.py --- .gitignore | 1 - SimPEG/Utils/interputils_cython.c | 8464 +++++++++++++++++++++++++++++ setup.py | 25 +- 3 files changed, 8487 insertions(+), 3 deletions(-) create mode 100644 SimPEG/Utils/interputils_cython.c diff --git a/.gitignore b/.gitignore index 0fb60aa3..fc798cea 100644 --- a/.gitignore +++ b/.gitignore @@ -38,5 +38,4 @@ nosetests.xml *.sublime-project *.sublime-workspace docs/_build/ -*_cython.c Makefile diff --git a/SimPEG/Utils/interputils_cython.c b/SimPEG/Utils/interputils_cython.c new file mode 100644 index 00000000..ab5fdd3a --- /dev/null +++ b/SimPEG/Utils/interputils_cython.c @@ -0,0 +1,8464 @@ +/* Generated by Cython 0.22.1 */ + +/* BEGIN: Cython Metadata +{ + "distutils": { + "depends": [] + } +} +END: Cython Metadata */ + +#define PY_SSIZE_T_CLEAN +#ifndef CYTHON_USE_PYLONG_INTERNALS +#ifdef PYLONG_BITS_IN_DIGIT +#define CYTHON_USE_PYLONG_INTERNALS 0 +#else +#include "pyconfig.h" +#ifdef PYLONG_BITS_IN_DIGIT +#define CYTHON_USE_PYLONG_INTERNALS 1 +#else +#define CYTHON_USE_PYLONG_INTERNALS 0 +#endif +#endif +#endif +#include "Python.h" +#ifndef Py_PYTHON_H + #error Python headers needed to compile C extensions, please install development version of Python. +#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03020000) + #error Cython requires Python 2.6+ or Python 3.2+. +#else +#define CYTHON_ABI "0_22_1" +#include +#ifndef offsetof +#define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) +#endif +#if !defined(WIN32) && !defined(MS_WINDOWS) + #ifndef __stdcall + #define __stdcall + #endif + #ifndef __cdecl + #define __cdecl + #endif + #ifndef __fastcall + #define __fastcall + #endif +#endif +#ifndef DL_IMPORT + #define DL_IMPORT(t) t +#endif +#ifndef DL_EXPORT + #define DL_EXPORT(t) t +#endif +#ifndef PY_LONG_LONG + #define PY_LONG_LONG LONG_LONG +#endif +#ifndef Py_HUGE_VAL + #define Py_HUGE_VAL HUGE_VAL +#endif +#ifdef PYPY_VERSION +#define CYTHON_COMPILING_IN_PYPY 1 +#define CYTHON_COMPILING_IN_CPYTHON 0 +#else +#define CYTHON_COMPILING_IN_PYPY 0 +#define CYTHON_COMPILING_IN_CPYTHON 1 +#endif +#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600 && !defined(Py_OptimizeFlag) +#define Py_OptimizeFlag 0 +#endif +#define __PYX_BUILD_PY_SSIZE_T "n" +#define CYTHON_FORMAT_SSIZE_T "z" +#if PY_MAJOR_VERSION < 3 + #define __Pyx_BUILTIN_MODULE_NAME "__builtin__" + #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \ + PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) + #define __Pyx_DefaultClassType PyClass_Type +#else + #define __Pyx_BUILTIN_MODULE_NAME "builtins" + #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \ + PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) + #define __Pyx_DefaultClassType PyType_Type +#endif +#ifndef Py_TPFLAGS_CHECKTYPES + #define Py_TPFLAGS_CHECKTYPES 0 +#endif +#ifndef Py_TPFLAGS_HAVE_INDEX + #define Py_TPFLAGS_HAVE_INDEX 0 +#endif +#ifndef Py_TPFLAGS_HAVE_NEWBUFFER + #define Py_TPFLAGS_HAVE_NEWBUFFER 0 +#endif +#ifndef Py_TPFLAGS_HAVE_FINALIZE + #define Py_TPFLAGS_HAVE_FINALIZE 0 +#endif +#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND) + #define CYTHON_PEP393_ENABLED 1 + #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ? \ + 0 : _PyUnicode_Ready((PyObject *)(op))) + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) + #define __Pyx_PyUnicode_KIND(u) PyUnicode_KIND(u) + #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u) + #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) +#else + #define CYTHON_PEP393_ENABLED 0 + #define __Pyx_PyUnicode_READY(op) (0) + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i])) + #define __Pyx_PyUnicode_KIND(u) (sizeof(Py_UNICODE)) + #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u)) + #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i])) +#endif +#if CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b) + #define __Pyx_PyFrozenSet_Size(s) PyObject_Size(s) +#else + #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ? \ + PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b)) + #define __Pyx_PyFrozenSet_Size(s) PySet_Size(s) +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyUnicode_Contains) + #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) +#endif +#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) +#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b) +#else + #define __Pyx_PyString_Format(a, b) PyString_Format(a, b) +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyBaseString_Type PyUnicode_Type + #define PyStringObject PyUnicodeObject + #define PyString_Type PyUnicode_Type + #define PyString_Check PyUnicode_Check + #define PyString_CheckExact PyUnicode_CheckExact +#endif +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj) + #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj) +#else + #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj)) + #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj)) +#endif +#ifndef PySet_CheckExact + #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type) +#endif +#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) +#if PY_MAJOR_VERSION >= 3 + #define PyIntObject PyLongObject + #define PyInt_Type PyLong_Type + #define PyInt_Check(op) PyLong_Check(op) + #define PyInt_CheckExact(op) PyLong_CheckExact(op) + #define PyInt_FromString PyLong_FromString + #define PyInt_FromUnicode PyLong_FromUnicode + #define PyInt_FromLong PyLong_FromLong + #define PyInt_FromSize_t PyLong_FromSize_t + #define PyInt_FromSsize_t PyLong_FromSsize_t + #define PyInt_AsLong PyLong_AsLong + #define PyInt_AS_LONG PyLong_AS_LONG + #define PyInt_AsSsize_t PyLong_AsSsize_t + #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask + #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask + #define PyNumber_Int PyNumber_Long +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyBoolObject PyLongObject +#endif +#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY + #ifndef PyUnicode_InternFromString + #define PyUnicode_InternFromString(s) PyUnicode_FromString(s) + #endif +#endif +#if PY_VERSION_HEX < 0x030200A4 + typedef long Py_hash_t; + #define __Pyx_PyInt_FromHash_t PyInt_FromLong + #define __Pyx_PyInt_AsHash_t PyInt_AsLong +#else + #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t + #define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t +#endif +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func)) +#else + #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass) +#endif +#ifndef CYTHON_INLINE + #if defined(__GNUC__) + #define CYTHON_INLINE __inline__ + #elif defined(_MSC_VER) + #define CYTHON_INLINE __inline + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_INLINE inline + #else + #define CYTHON_INLINE + #endif +#endif +#ifndef CYTHON_RESTRICT + #if defined(__GNUC__) + #define CYTHON_RESTRICT __restrict__ + #elif defined(_MSC_VER) && _MSC_VER >= 1400 + #define CYTHON_RESTRICT __restrict + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_RESTRICT restrict + #else + #define CYTHON_RESTRICT + #endif +#endif +#ifdef NAN +#define __PYX_NAN() ((float) NAN) +#else +static CYTHON_INLINE float __PYX_NAN() { + /* Initialize NaN. The sign is irrelevant, an exponent with all bits 1 and + a nonzero mantissa means NaN. If the first bit in the mantissa is 1, it is + a quiet NaN. */ + float value; + memset(&value, 0xFF, sizeof(value)); + return value; +} +#endif +#define __Pyx_void_to_None(void_result) (void_result, Py_INCREF(Py_None), Py_None) +#ifdef __cplusplus +template +void __Pyx_call_destructor(T* x) { + x->~T(); +} +template +class __Pyx_FakeReference { + public: + __Pyx_FakeReference() : ptr(NULL) { } + __Pyx_FakeReference(T& ref) : ptr(&ref) { } + T *operator->() { return ptr; } + operator T&() { return *ptr; } + private: + T *ptr; +}; +#endif + + +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) + #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) +#else + #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y) + #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y) +#endif + +#ifndef __PYX_EXTERN_C + #ifdef __cplusplus + #define __PYX_EXTERN_C extern "C" + #else + #define __PYX_EXTERN_C extern + #endif +#endif + +#if defined(WIN32) || defined(MS_WINDOWS) +#define _USE_MATH_DEFINES +#endif +#include +#define __PYX_HAVE__SimPEG__Utils__interputils_cython +#define __PYX_HAVE_API__SimPEG__Utils__interputils_cython +#include "string.h" +#include "stdio.h" +#include "stdlib.h" +#include "numpy/arrayobject.h" +#include "numpy/ufuncobject.h" +#ifdef _OPENMP +#include +#endif /* _OPENMP */ + +#ifdef PYREX_WITHOUT_ASSERTIONS +#define CYTHON_WITHOUT_ASSERTIONS +#endif + +#ifndef CYTHON_UNUSED +# if defined(__GNUC__) +# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +#endif +#ifndef CYTHON_NCP_UNUSED +# if CYTHON_COMPILING_IN_CPYTHON +# define CYTHON_NCP_UNUSED +# else +# define CYTHON_NCP_UNUSED CYTHON_UNUSED +# endif +#endif +typedef struct {PyObject **p; char *s; const Py_ssize_t n; const char* encoding; + const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; + +#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0 +#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 0 +#define __PYX_DEFAULT_STRING_ENCODING "" +#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString +#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize +#define __Pyx_fits_Py_ssize_t(v, type, is_signed) ( \ + (sizeof(type) < sizeof(Py_ssize_t)) || \ + (sizeof(type) > sizeof(Py_ssize_t) && \ + likely(v < (type)PY_SSIZE_T_MAX || \ + v == (type)PY_SSIZE_T_MAX) && \ + (!is_signed || likely(v > (type)PY_SSIZE_T_MIN || \ + v == (type)PY_SSIZE_T_MIN))) || \ + (sizeof(type) == sizeof(Py_ssize_t) && \ + (is_signed || likely(v < (type)PY_SSIZE_T_MAX || \ + v == (type)PY_SSIZE_T_MAX))) ) +static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject*); +static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); +#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s)) +#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l) +#define __Pyx_PyBytes_FromString PyBytes_FromString +#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); +#if PY_MAJOR_VERSION < 3 + #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString + #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize +#else + #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString + #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize +#endif +#define __Pyx_PyObject_AsSString(s) ((signed char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_FromCString(s) __Pyx_PyObject_FromString((const char*)s) +#define __Pyx_PyBytes_FromCString(s) __Pyx_PyBytes_FromString((const char*)s) +#define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) +#define __Pyx_PyStr_FromCString(s) __Pyx_PyStr_FromString((const char*)s) +#define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s) +#if PY_MAJOR_VERSION < 3 +static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u) +{ + const Py_UNICODE *u_end = u; + while (*u_end++) ; + return (size_t)(u_end - u - 1); +} +#else +#define __Pyx_Py_UNICODE_strlen Py_UNICODE_strlen +#endif +#define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u)) +#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode +#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode +#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None) +#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False)) +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); +static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x); +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); +static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); +#if CYTHON_COMPILING_IN_CPYTHON +#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) +#else +#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x) +#endif +#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x)) +#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII +static int __Pyx_sys_getdefaultencoding_not_ascii; +static int __Pyx_init_sys_getdefaultencoding_params(void) { + PyObject* sys; + PyObject* default_encoding = NULL; + PyObject* ascii_chars_u = NULL; + PyObject* ascii_chars_b = NULL; + const char* default_encoding_c; + sys = PyImport_ImportModule("sys"); + if (!sys) goto bad; + default_encoding = PyObject_CallMethod(sys, (char*) "getdefaultencoding", NULL); + Py_DECREF(sys); + if (!default_encoding) goto bad; + default_encoding_c = PyBytes_AsString(default_encoding); + if (!default_encoding_c) goto bad; + if (strcmp(default_encoding_c, "ascii") == 0) { + __Pyx_sys_getdefaultencoding_not_ascii = 0; + } else { + char ascii_chars[128]; + int c; + for (c = 0; c < 128; c++) { + ascii_chars[c] = c; + } + __Pyx_sys_getdefaultencoding_not_ascii = 1; + ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL); + if (!ascii_chars_u) goto bad; + ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL); + if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) { + PyErr_Format( + PyExc_ValueError, + "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.", + default_encoding_c); + goto bad; + } + Py_DECREF(ascii_chars_u); + Py_DECREF(ascii_chars_b); + } + Py_DECREF(default_encoding); + return 0; +bad: + Py_XDECREF(default_encoding); + Py_XDECREF(ascii_chars_u); + Py_XDECREF(ascii_chars_b); + return -1; +} +#endif +#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3 +#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL) +#else +#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL) +#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT +static char* __PYX_DEFAULT_STRING_ENCODING; +static int __Pyx_init_sys_getdefaultencoding_params(void) { + PyObject* sys; + PyObject* default_encoding = NULL; + char* default_encoding_c; + sys = PyImport_ImportModule("sys"); + if (!sys) goto bad; + default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL); + Py_DECREF(sys); + if (!default_encoding) goto bad; + default_encoding_c = PyBytes_AsString(default_encoding); + if (!default_encoding_c) goto bad; + __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c)); + if (!__PYX_DEFAULT_STRING_ENCODING) goto bad; + strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c); + Py_DECREF(default_encoding); + return 0; +bad: + Py_XDECREF(default_encoding); + return -1; +} +#endif +#endif + + +/* Test for GCC > 2.95 */ +#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))) + #define likely(x) __builtin_expect(!!(x), 1) + #define unlikely(x) __builtin_expect(!!(x), 0) +#else /* !__GNUC__ or GCC < 2.95 */ + #define likely(x) (x) + #define unlikely(x) (x) +#endif /* __GNUC__ */ + +static PyObject *__pyx_m; +static PyObject *__pyx_d; +static PyObject *__pyx_b; +static PyObject *__pyx_empty_tuple; +static PyObject *__pyx_empty_bytes; +static int __pyx_lineno; +static int __pyx_clineno = 0; +static const char * __pyx_cfilenm= __FILE__; +static const char *__pyx_filename; + +#if !defined(CYTHON_CCOMPLEX) + #if defined(__cplusplus) + #define CYTHON_CCOMPLEX 1 + #elif defined(_Complex_I) + #define CYTHON_CCOMPLEX 1 + #else + #define CYTHON_CCOMPLEX 0 + #endif +#endif +#if CYTHON_CCOMPLEX + #ifdef __cplusplus + #include + #else + #include + #endif +#endif +#if CYTHON_CCOMPLEX && !defined(__cplusplus) && defined(__sun__) && defined(__GNUC__) + #undef _Complex_I + #define _Complex_I 1.0fj +#endif + + +static const char *__pyx_f[] = { + "SimPEG/Utils/interputils_cython.pyx", + "__init__.pxd", + "type.pxd", +}; +#define IS_UNSIGNED(type) (((type) -1) > 0) +struct __Pyx_StructField_; +#define __PYX_BUF_FLAGS_PACKED_STRUCT (1 << 0) +typedef struct { + const char* name; + struct __Pyx_StructField_* fields; + size_t size; + size_t arraysize[8]; + int ndim; + char typegroup; + char is_unsigned; + int flags; +} __Pyx_TypeInfo; +typedef struct __Pyx_StructField_ { + __Pyx_TypeInfo* type; + const char* name; + size_t offset; +} __Pyx_StructField; +typedef struct { + __Pyx_StructField* field; + size_t parent_offset; +} __Pyx_BufFmt_StackElem; +typedef struct { + __Pyx_StructField root; + __Pyx_BufFmt_StackElem* head; + size_t fmt_offset; + size_t new_count, enc_count; + size_t struct_alignment; + int is_complex; + char enc_type; + char new_packmode; + char enc_packmode; + char is_valid_array; +} __Pyx_BufFmt_Context; + + +/* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":726 + * # in Cython to enable them only on the right systems. + * + * ctypedef npy_int8 int8_t # <<<<<<<<<<<<<< + * ctypedef npy_int16 int16_t + * ctypedef npy_int32 int32_t + */ +typedef npy_int8 __pyx_t_5numpy_int8_t; + +/* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":727 + * + * ctypedef npy_int8 int8_t + * ctypedef npy_int16 int16_t # <<<<<<<<<<<<<< + * ctypedef npy_int32 int32_t + * ctypedef npy_int64 int64_t + */ +typedef npy_int16 __pyx_t_5numpy_int16_t; + +/* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":728 + * ctypedef npy_int8 int8_t + * ctypedef npy_int16 int16_t + * ctypedef npy_int32 int32_t # <<<<<<<<<<<<<< + * ctypedef npy_int64 int64_t + * #ctypedef npy_int96 int96_t + */ +typedef npy_int32 __pyx_t_5numpy_int32_t; + +/* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":729 + * ctypedef npy_int16 int16_t + * ctypedef npy_int32 int32_t + * ctypedef npy_int64 int64_t # <<<<<<<<<<<<<< + * #ctypedef npy_int96 int96_t + * #ctypedef npy_int128 int128_t + */ +typedef npy_int64 __pyx_t_5numpy_int64_t; + +/* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":733 + * #ctypedef npy_int128 int128_t + * + * ctypedef npy_uint8 uint8_t # <<<<<<<<<<<<<< + * ctypedef npy_uint16 uint16_t + * ctypedef npy_uint32 uint32_t + */ +typedef npy_uint8 __pyx_t_5numpy_uint8_t; + +/* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":734 + * + * ctypedef npy_uint8 uint8_t + * ctypedef npy_uint16 uint16_t # <<<<<<<<<<<<<< + * ctypedef npy_uint32 uint32_t + * ctypedef npy_uint64 uint64_t + */ +typedef npy_uint16 __pyx_t_5numpy_uint16_t; + +/* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":735 + * ctypedef npy_uint8 uint8_t + * ctypedef npy_uint16 uint16_t + * ctypedef npy_uint32 uint32_t # <<<<<<<<<<<<<< + * ctypedef npy_uint64 uint64_t + * #ctypedef npy_uint96 uint96_t + */ +typedef npy_uint32 __pyx_t_5numpy_uint32_t; + +/* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":736 + * ctypedef npy_uint16 uint16_t + * ctypedef npy_uint32 uint32_t + * ctypedef npy_uint64 uint64_t # <<<<<<<<<<<<<< + * #ctypedef npy_uint96 uint96_t + * #ctypedef npy_uint128 uint128_t + */ +typedef npy_uint64 __pyx_t_5numpy_uint64_t; + +/* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":740 + * #ctypedef npy_uint128 uint128_t + * + * ctypedef npy_float32 float32_t # <<<<<<<<<<<<<< + * ctypedef npy_float64 float64_t + * #ctypedef npy_float80 float80_t + */ +typedef npy_float32 __pyx_t_5numpy_float32_t; + +/* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":741 + * + * ctypedef npy_float32 float32_t + * ctypedef npy_float64 float64_t # <<<<<<<<<<<<<< + * #ctypedef npy_float80 float80_t + * #ctypedef npy_float128 float128_t + */ +typedef npy_float64 __pyx_t_5numpy_float64_t; + +/* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":750 + * # The int types are mapped a bit surprising -- + * # numpy.int corresponds to 'l' and numpy.long to 'q' + * ctypedef npy_long int_t # <<<<<<<<<<<<<< + * ctypedef npy_longlong long_t + * ctypedef npy_longlong longlong_t + */ +typedef npy_long __pyx_t_5numpy_int_t; + +/* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":751 + * # numpy.int corresponds to 'l' and numpy.long to 'q' + * ctypedef npy_long int_t + * ctypedef npy_longlong long_t # <<<<<<<<<<<<<< + * ctypedef npy_longlong longlong_t + * + */ +typedef npy_longlong __pyx_t_5numpy_long_t; + +/* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":752 + * ctypedef npy_long int_t + * ctypedef npy_longlong long_t + * ctypedef npy_longlong longlong_t # <<<<<<<<<<<<<< + * + * ctypedef npy_ulong uint_t + */ +typedef npy_longlong __pyx_t_5numpy_longlong_t; + +/* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":754 + * ctypedef npy_longlong longlong_t + * + * ctypedef npy_ulong uint_t # <<<<<<<<<<<<<< + * ctypedef npy_ulonglong ulong_t + * ctypedef npy_ulonglong ulonglong_t + */ +typedef npy_ulong __pyx_t_5numpy_uint_t; + +/* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":755 + * + * ctypedef npy_ulong uint_t + * ctypedef npy_ulonglong ulong_t # <<<<<<<<<<<<<< + * ctypedef npy_ulonglong ulonglong_t + * + */ +typedef npy_ulonglong __pyx_t_5numpy_ulong_t; + +/* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":756 + * ctypedef npy_ulong uint_t + * ctypedef npy_ulonglong ulong_t + * ctypedef npy_ulonglong ulonglong_t # <<<<<<<<<<<<<< + * + * ctypedef npy_intp intp_t + */ +typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t; + +/* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":758 + * ctypedef npy_ulonglong ulonglong_t + * + * ctypedef npy_intp intp_t # <<<<<<<<<<<<<< + * ctypedef npy_uintp uintp_t + * + */ +typedef npy_intp __pyx_t_5numpy_intp_t; + +/* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":759 + * + * ctypedef npy_intp intp_t + * ctypedef npy_uintp uintp_t # <<<<<<<<<<<<<< + * + * ctypedef npy_double float_t + */ +typedef npy_uintp __pyx_t_5numpy_uintp_t; + +/* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":761 + * ctypedef npy_uintp uintp_t + * + * ctypedef npy_double float_t # <<<<<<<<<<<<<< + * ctypedef npy_double double_t + * ctypedef npy_longdouble longdouble_t + */ +typedef npy_double __pyx_t_5numpy_float_t; + +/* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":762 + * + * ctypedef npy_double float_t + * ctypedef npy_double double_t # <<<<<<<<<<<<<< + * ctypedef npy_longdouble longdouble_t + * + */ +typedef npy_double __pyx_t_5numpy_double_t; + +/* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":763 + * ctypedef npy_double float_t + * ctypedef npy_double double_t + * ctypedef npy_longdouble longdouble_t # <<<<<<<<<<<<<< + * + * ctypedef npy_cfloat cfloat_t + */ +typedef npy_longdouble __pyx_t_5numpy_longdouble_t; +#if CYTHON_CCOMPLEX + #ifdef __cplusplus + typedef ::std::complex< float > __pyx_t_float_complex; + #else + typedef float _Complex __pyx_t_float_complex; + #endif +#else + typedef struct { float real, imag; } __pyx_t_float_complex; +#endif + +#if CYTHON_CCOMPLEX + #ifdef __cplusplus + typedef ::std::complex< double > __pyx_t_double_complex; + #else + typedef double _Complex __pyx_t_double_complex; + #endif +#else + typedef struct { double real, imag; } __pyx_t_double_complex; +#endif + + +/*--- Type declarations ---*/ + +/* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":765 + * ctypedef npy_longdouble longdouble_t + * + * ctypedef npy_cfloat cfloat_t # <<<<<<<<<<<<<< + * ctypedef npy_cdouble cdouble_t + * ctypedef npy_clongdouble clongdouble_t + */ +typedef npy_cfloat __pyx_t_5numpy_cfloat_t; + +/* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":766 + * + * ctypedef npy_cfloat cfloat_t + * ctypedef npy_cdouble cdouble_t # <<<<<<<<<<<<<< + * ctypedef npy_clongdouble clongdouble_t + * + */ +typedef npy_cdouble __pyx_t_5numpy_cdouble_t; + +/* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":767 + * ctypedef npy_cfloat cfloat_t + * ctypedef npy_cdouble cdouble_t + * ctypedef npy_clongdouble clongdouble_t # <<<<<<<<<<<<<< + * + * ctypedef npy_cdouble complex_t + */ +typedef npy_clongdouble __pyx_t_5numpy_clongdouble_t; + +/* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":769 + * ctypedef npy_clongdouble clongdouble_t + * + * ctypedef npy_cdouble complex_t # <<<<<<<<<<<<<< + * + * cdef inline object PyArray_MultiIterNew1(a): + */ +typedef npy_cdouble __pyx_t_5numpy_complex_t; + +/* --- Runtime support code (head) --- */ +#ifndef CYTHON_REFNANNY + #define CYTHON_REFNANNY 0 +#endif +#if CYTHON_REFNANNY + typedef struct { + void (*INCREF)(void*, PyObject*, int); + void (*DECREF)(void*, PyObject*, int); + void (*GOTREF)(void*, PyObject*, int); + void (*GIVEREF)(void*, PyObject*, int); + void* (*SetupContext)(const char*, int, const char*); + void (*FinishContext)(void**); + } __Pyx_RefNannyAPIStruct; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); + #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL; +#ifdef WITH_THREAD + #define __Pyx_RefNannySetupContext(name, acquire_gil) \ + if (acquire_gil) { \ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \ + PyGILState_Release(__pyx_gilstate_save); \ + } else { \ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \ + } +#else + #define __Pyx_RefNannySetupContext(name, acquire_gil) \ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__) +#endif + #define __Pyx_RefNannyFinishContext() \ + __Pyx_RefNanny->FinishContext(&__pyx_refnanny) + #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0) + #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0) + #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0) + #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0) +#else + #define __Pyx_RefNannyDeclarations + #define __Pyx_RefNannySetupContext(name, acquire_gil) + #define __Pyx_RefNannyFinishContext() + #define __Pyx_INCREF(r) Py_INCREF(r) + #define __Pyx_DECREF(r) Py_DECREF(r) + #define __Pyx_GOTREF(r) + #define __Pyx_GIVEREF(r) + #define __Pyx_XINCREF(r) Py_XINCREF(r) + #define __Pyx_XDECREF(r) Py_XDECREF(r) + #define __Pyx_XGOTREF(r) + #define __Pyx_XGIVEREF(r) +#endif +#define __Pyx_XDECREF_SET(r, v) do { \ + PyObject *tmp = (PyObject *) r; \ + r = v; __Pyx_XDECREF(tmp); \ + } while (0) +#define __Pyx_DECREF_SET(r, v) do { \ + PyObject *tmp = (PyObject *) r; \ + r = v; __Pyx_DECREF(tmp); \ + } while (0) +#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0) +#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0) + +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) { + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_getattro)) + return tp->tp_getattro(obj, attr_name); +#if PY_MAJOR_VERSION < 3 + if (likely(tp->tp_getattr)) + return tp->tp_getattr(obj, PyString_AS_STRING(attr_name)); +#endif + return PyObject_GetAttr(obj, attr_name); +} +#else +#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n) +#endif + +static PyObject *__Pyx_GetBuiltinName(PyObject *name); + +static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, + Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); + +static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); + +static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \ + PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \ + const char* function_name); + +static CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed, + const char *name, int exact); + +static CYTHON_INLINE int __Pyx_GetBufferAndValidate(Py_buffer* buf, PyObject* obj, + __Pyx_TypeInfo* dtype, int flags, int nd, int cast, __Pyx_BufFmt_StackElem* stack); +static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info); + +static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name); + +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw); +#else +#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw) +#endif + +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg); +#endif + +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg); + +static void __Pyx_RaiseBufferIndexError(int axis); + +#define __Pyx_BufPtrStrided1d(type, buf, i0, s0) (type)((char*)buf + i0 * s0) +#ifndef __PYX_FORCE_INIT_THREADS + #define __PYX_FORCE_INIT_THREADS 0 +#endif + +static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); +static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); + +static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected); + +static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index); + +static CYTHON_INLINE int __Pyx_IterFinish(void); + +static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected); + +#define __Pyx_BufPtrStrided2d(type, buf, i0, s0, i1, s1) (type)((char*)buf + i0 * s0 + i1 * s1) +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); + +#if PY_MAJOR_VERSION >= 3 && !CYTHON_COMPILING_IN_PYPY +static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key) { + PyObject *value; + value = PyDict_GetItemWithError(d, key); + if (unlikely(!value)) { + if (!PyErr_Occurred()) { + PyObject* args = PyTuple_Pack(1, key); + if (likely(args)) + PyErr_SetObject(PyExc_KeyError, args); + Py_XDECREF(args); + } + return NULL; + } + Py_INCREF(value); + return value; +} +#else + #define __Pyx_PyDict_GetItem(d, key) PyObject_GetItem(d, key) +#endif + +static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void); + +static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); + +typedef struct { + int code_line; + PyCodeObject* code_object; +} __Pyx_CodeObjectCacheEntry; +struct __Pyx_CodeObjectCache { + int count; + int max_count; + __Pyx_CodeObjectCacheEntry* entries; +}; +static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL}; +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line); +static PyCodeObject *__pyx_find_code_object(int code_line); +static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object); + +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename); + +typedef struct { + Py_ssize_t shape, strides, suboffsets; +} __Pyx_Buf_DimInfo; +typedef struct { + size_t refcount; + Py_buffer pybuffer; +} __Pyx_Buffer; +typedef struct { + __Pyx_Buffer *rcbuffer; + char *data; + __Pyx_Buf_DimInfo diminfo[8]; +} __Pyx_LocalBuf_ND; + +#if PY_MAJOR_VERSION < 3 + static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags); + static void __Pyx_ReleaseBuffer(Py_buffer *view); +#else + #define __Pyx_GetBuffer PyObject_GetBuffer + #define __Pyx_ReleaseBuffer PyBuffer_Release +#endif + + +static Py_ssize_t __Pyx_zeros[] = {0, 0, 0, 0, 0, 0, 0, 0}; +static Py_ssize_t __Pyx_minusones[] = {-1, -1, -1, -1, -1, -1, -1, -1}; + +static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); + +static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *); + +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value); + +#if CYTHON_CCOMPLEX + #ifdef __cplusplus + #define __Pyx_CREAL(z) ((z).real()) + #define __Pyx_CIMAG(z) ((z).imag()) + #else + #define __Pyx_CREAL(z) (__real__(z)) + #define __Pyx_CIMAG(z) (__imag__(z)) + #endif +#else + #define __Pyx_CREAL(z) ((z).real) + #define __Pyx_CIMAG(z) ((z).imag) +#endif +#if (defined(_WIN32) || defined(__clang__)) && defined(__cplusplus) && CYTHON_CCOMPLEX + #define __Pyx_SET_CREAL(z,x) ((z).real(x)) + #define __Pyx_SET_CIMAG(z,y) ((z).imag(y)) +#else + #define __Pyx_SET_CREAL(z,x) __Pyx_CREAL(z) = (x) + #define __Pyx_SET_CIMAG(z,y) __Pyx_CIMAG(z) = (y) +#endif + +static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float, float); + +#if CYTHON_CCOMPLEX + #define __Pyx_c_eqf(a, b) ((a)==(b)) + #define __Pyx_c_sumf(a, b) ((a)+(b)) + #define __Pyx_c_difff(a, b) ((a)-(b)) + #define __Pyx_c_prodf(a, b) ((a)*(b)) + #define __Pyx_c_quotf(a, b) ((a)/(b)) + #define __Pyx_c_negf(a) (-(a)) + #ifdef __cplusplus + #define __Pyx_c_is_zerof(z) ((z)==(float)0) + #define __Pyx_c_conjf(z) (::std::conj(z)) + #if 1 + #define __Pyx_c_absf(z) (::std::abs(z)) + #define __Pyx_c_powf(a, b) (::std::pow(a, b)) + #endif + #else + #define __Pyx_c_is_zerof(z) ((z)==0) + #define __Pyx_c_conjf(z) (conjf(z)) + #if 1 + #define __Pyx_c_absf(z) (cabsf(z)) + #define __Pyx_c_powf(a, b) (cpowf(a, b)) + #endif + #endif +#else + static CYTHON_INLINE int __Pyx_c_eqf(__pyx_t_float_complex, __pyx_t_float_complex); + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sumf(__pyx_t_float_complex, __pyx_t_float_complex); + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_difff(__pyx_t_float_complex, __pyx_t_float_complex); + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prodf(__pyx_t_float_complex, __pyx_t_float_complex); + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quotf(__pyx_t_float_complex, __pyx_t_float_complex); + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_negf(__pyx_t_float_complex); + static CYTHON_INLINE int __Pyx_c_is_zerof(__pyx_t_float_complex); + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conjf(__pyx_t_float_complex); + #if 1 + static CYTHON_INLINE float __Pyx_c_absf(__pyx_t_float_complex); + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_powf(__pyx_t_float_complex, __pyx_t_float_complex); + #endif +#endif + +static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double, double); + +#if CYTHON_CCOMPLEX + #define __Pyx_c_eq(a, b) ((a)==(b)) + #define __Pyx_c_sum(a, b) ((a)+(b)) + #define __Pyx_c_diff(a, b) ((a)-(b)) + #define __Pyx_c_prod(a, b) ((a)*(b)) + #define __Pyx_c_quot(a, b) ((a)/(b)) + #define __Pyx_c_neg(a) (-(a)) + #ifdef __cplusplus + #define __Pyx_c_is_zero(z) ((z)==(double)0) + #define __Pyx_c_conj(z) (::std::conj(z)) + #if 1 + #define __Pyx_c_abs(z) (::std::abs(z)) + #define __Pyx_c_pow(a, b) (::std::pow(a, b)) + #endif + #else + #define __Pyx_c_is_zero(z) ((z)==0) + #define __Pyx_c_conj(z) (conj(z)) + #if 1 + #define __Pyx_c_abs(z) (cabs(z)) + #define __Pyx_c_pow(a, b) (cpow(a, b)) + #endif + #endif +#else + static CYTHON_INLINE int __Pyx_c_eq(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg(__pyx_t_double_complex); + static CYTHON_INLINE int __Pyx_c_is_zero(__pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj(__pyx_t_double_complex); + #if 1 + static CYTHON_INLINE double __Pyx_c_abs(__pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow(__pyx_t_double_complex, __pyx_t_double_complex); + #endif +#endif + +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value); + +static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *); + +static int __Pyx_check_binary_version(void); + +#if !defined(__Pyx_PyIdentifier_FromString) +#if PY_MAJOR_VERSION < 3 + #define __Pyx_PyIdentifier_FromString(s) PyString_FromString(s) +#else + #define __Pyx_PyIdentifier_FromString(s) PyUnicode_FromString(s) +#endif +#endif + +static PyObject *__Pyx_ImportModule(const char *name); + +static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, size_t size, int strict); + +static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); + + +/* Module declarations from 'cpython.buffer' */ + +/* Module declarations from 'cpython.ref' */ + +/* Module declarations from 'libc.string' */ + +/* Module declarations from 'libc.stdio' */ + +/* Module declarations from 'cpython.object' */ + +/* Module declarations from '__builtin__' */ + +/* Module declarations from 'cpython.type' */ +static PyTypeObject *__pyx_ptype_7cpython_4type_type = 0; + +/* Module declarations from 'libc.stdlib' */ + +/* Module declarations from 'numpy' */ + +/* Module declarations from 'numpy' */ +static PyTypeObject *__pyx_ptype_5numpy_dtype = 0; +static PyTypeObject *__pyx_ptype_5numpy_flatiter = 0; +static PyTypeObject *__pyx_ptype_5numpy_broadcast = 0; +static PyTypeObject *__pyx_ptype_5numpy_ndarray = 0; +static PyTypeObject *__pyx_ptype_5numpy_ufunc = 0; +static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *, char *, char *, int *); /*proto*/ + +/* Module declarations from 'SimPEG.Utils.interputils_cython' */ +static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t = { "float64_t", NULL, sizeof(__pyx_t_5numpy_float64_t), { 0 }, 0, 'R', 0, 0 }; +#define __Pyx_MODULE_NAME "SimPEG.Utils.interputils_cython" +int __pyx_module_is_main_SimPEG__Utils__interputils_cython = 0; + +/* Implementation of 'SimPEG.Utils.interputils_cython' */ +static PyObject *__pyx_builtin_range; +static PyObject *__pyx_builtin_ValueError; +static PyObject *__pyx_builtin_RuntimeError; +static PyObject *__pyx_pf_6SimPEG_5Utils_18interputils_cython__interp_point_1D(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_x, float __pyx_v_xr_i); /* proto */ +static PyObject *__pyx_pf_6SimPEG_5Utils_18interputils_cython_2_interpmat1D(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_locs, PyArrayObject *__pyx_v_x); /* proto */ +static PyObject *__pyx_pf_6SimPEG_5Utils_18interputils_cython_4_interpmat2D(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_locs, PyArrayObject *__pyx_v_x, PyArrayObject *__pyx_v_y); /* proto */ +static PyObject *__pyx_pf_6SimPEG_5Utils_18interputils_cython_6_interpmat3D(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_locs, PyArrayObject *__pyx_v_x, PyArrayObject *__pyx_v_y, PyArrayObject *__pyx_v_z); /* proto */ +static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */ +static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info); /* proto */ +static char __pyx_k_B[] = "B"; +static char __pyx_k_H[] = "H"; +static char __pyx_k_I[] = "I"; +static char __pyx_k_L[] = "L"; +static char __pyx_k_O[] = "O"; +static char __pyx_k_Q[] = "Q"; +static char __pyx_k_b[] = "b"; +static char __pyx_k_d[] = "d"; +static char __pyx_k_f[] = "f"; +static char __pyx_k_g[] = "g"; +static char __pyx_k_h[] = "h"; +static char __pyx_k_i[] = "i"; +static char __pyx_k_l[] = "l"; +static char __pyx_k_q[] = "q"; +static char __pyx_k_x[] = "x"; +static char __pyx_k_y[] = "y"; +static char __pyx_k_z[] = "z"; +static char __pyx_k_Zd[] = "Zd"; +static char __pyx_k_Zf[] = "Zf"; +static char __pyx_k_Zg[] = "Zg"; +static char __pyx_k_hx[] = "hx"; +static char __pyx_k_im[] = "im"; +static char __pyx_k_np[] = "np"; +static char __pyx_k_nx[] = "nx"; +static char __pyx_k_ny[] = "ny"; +static char __pyx_k_nz[] = "nz"; +static char __pyx_k_wx1[] = "wx1"; +static char __pyx_k_wx2[] = "wx2"; +static char __pyx_k_wy1[] = "wy1"; +static char __pyx_k_wy2[] = "wy2"; +static char __pyx_k_wz1[] = "wz1"; +static char __pyx_k_wz2[] = "wz2"; +static char __pyx_k_inds[] = "inds"; +static char __pyx_k_locs[] = "locs"; +static char __pyx_k_main[] = "__main__"; +static char __pyx_k_npts[] = "npts"; +static char __pyx_k_size[] = "size"; +static char __pyx_k_test[] = "__test__"; +static char __pyx_k_vals[] = "vals"; +static char __pyx_k_xr_i[] = "xr_i"; +static char __pyx_k_numpy[] = "numpy"; +static char __pyx_k_range[] = "range"; +static char __pyx_k_xSize[] = "xSize"; +static char __pyx_k_argmin[] = "argmin"; +static char __pyx_k_import[] = "__import__"; +static char __pyx_k_ind_x1[] = "ind_x1"; +static char __pyx_k_ind_x2[] = "ind_x2"; +static char __pyx_k_ind_y1[] = "ind_y1"; +static char __pyx_k_ind_y2[] = "ind_y2"; +static char __pyx_k_ind_z1[] = "ind_z1"; +static char __pyx_k_ind_z2[] = "ind_z2"; +static char __pyx_k_ValueError[] = "ValueError"; +static char __pyx_k_interpmat1D[] = "_interpmat1D"; +static char __pyx_k_interpmat2D[] = "_interpmat2D"; +static char __pyx_k_interpmat3D[] = "_interpmat3D"; +static char __pyx_k_RuntimeError[] = "RuntimeError"; +static char __pyx_k_interp_point_1D[] = "_interp_point_1D"; +static char __pyx_k_ndarray_is_not_C_contiguous[] = "ndarray is not C contiguous"; +static char __pyx_k_SimPEG_Utils_interputils_cython[] = "SimPEG.Utils.interputils_cython"; +static char __pyx_k_Users_rowan_git_simpeg_simpeg_S[] = "/Users/rowan/git/simpeg/simpeg/SimPEG/Utils/interputils_cython.pyx"; +static char __pyx_k_unknown_dtype_code_in_numpy_pxd[] = "unknown dtype code in numpy.pxd (%d)"; +static char __pyx_k_Format_string_allocated_too_shor[] = "Format string allocated too short, see comment in numpy.pxd"; +static char __pyx_k_Non_native_byte_order_not_suppor[] = "Non-native byte order not supported"; +static char __pyx_k_ndarray_is_not_Fortran_contiguou[] = "ndarray is not Fortran contiguous"; +static char __pyx_k_Format_string_allocated_too_shor_2[] = "Format string allocated too short."; +static PyObject *__pyx_kp_u_Format_string_allocated_too_shor; +static PyObject *__pyx_kp_u_Format_string_allocated_too_shor_2; +static PyObject *__pyx_kp_u_Non_native_byte_order_not_suppor; +static PyObject *__pyx_n_s_RuntimeError; +static PyObject *__pyx_n_s_SimPEG_Utils_interputils_cython; +static PyObject *__pyx_kp_s_Users_rowan_git_simpeg_simpeg_S; +static PyObject *__pyx_n_s_ValueError; +static PyObject *__pyx_n_s_argmin; +static PyObject *__pyx_n_s_hx; +static PyObject *__pyx_n_s_i; +static PyObject *__pyx_n_s_im; +static PyObject *__pyx_n_s_import; +static PyObject *__pyx_n_s_ind_x1; +static PyObject *__pyx_n_s_ind_x2; +static PyObject *__pyx_n_s_ind_y1; +static PyObject *__pyx_n_s_ind_y2; +static PyObject *__pyx_n_s_ind_z1; +static PyObject *__pyx_n_s_ind_z2; +static PyObject *__pyx_n_s_inds; +static PyObject *__pyx_n_s_interp_point_1D; +static PyObject *__pyx_n_s_interpmat1D; +static PyObject *__pyx_n_s_interpmat2D; +static PyObject *__pyx_n_s_interpmat3D; +static PyObject *__pyx_n_s_locs; +static PyObject *__pyx_n_s_main; +static PyObject *__pyx_kp_u_ndarray_is_not_C_contiguous; +static PyObject *__pyx_kp_u_ndarray_is_not_Fortran_contiguou; +static PyObject *__pyx_n_s_np; +static PyObject *__pyx_n_s_npts; +static PyObject *__pyx_n_s_numpy; +static PyObject *__pyx_n_s_nx; +static PyObject *__pyx_n_s_ny; +static PyObject *__pyx_n_s_nz; +static PyObject *__pyx_n_s_range; +static PyObject *__pyx_n_s_size; +static PyObject *__pyx_n_s_test; +static PyObject *__pyx_kp_u_unknown_dtype_code_in_numpy_pxd; +static PyObject *__pyx_n_s_vals; +static PyObject *__pyx_n_s_wx1; +static PyObject *__pyx_n_s_wx2; +static PyObject *__pyx_n_s_wy1; +static PyObject *__pyx_n_s_wy2; +static PyObject *__pyx_n_s_wz1; +static PyObject *__pyx_n_s_wz2; +static PyObject *__pyx_n_s_x; +static PyObject *__pyx_n_s_xSize; +static PyObject *__pyx_n_s_xr_i; +static PyObject *__pyx_n_s_y; +static PyObject *__pyx_n_s_z; +static PyObject *__pyx_float_0_5; +static PyObject *__pyx_tuple_; +static PyObject *__pyx_tuple__2; +static PyObject *__pyx_tuple__3; +static PyObject *__pyx_tuple__4; +static PyObject *__pyx_tuple__5; +static PyObject *__pyx_tuple__6; +static PyObject *__pyx_tuple__7; +static PyObject *__pyx_tuple__9; +static PyObject *__pyx_tuple__11; +static PyObject *__pyx_tuple__13; +static PyObject *__pyx_codeobj__8; +static PyObject *__pyx_codeobj__10; +static PyObject *__pyx_codeobj__12; +static PyObject *__pyx_codeobj__14; + +/* "SimPEG/Utils/interputils_cython.pyx":6 + * # from libcpp.vector cimport vector + * + * def _interp_point_1D(np.ndarray[np.float64_t, ndim=1] x, float xr_i): # <<<<<<<<<<<<<< + * """ + * given a point, xr_i, this will find which two integers it lies between. + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_6SimPEG_5Utils_18interputils_cython_1_interp_point_1D(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static char __pyx_doc_6SimPEG_5Utils_18interputils_cython__interp_point_1D[] = "\n given a point, xr_i, this will find which two integers it lies between.\n\n :param numpy.ndarray x: Tensor vector of 1st dimension of grid.\n :param float xr_i: Location of a point\n :rtype: int,int,float,float\n :return: index1, index2, portion1, portion2\n "; +static PyMethodDef __pyx_mdef_6SimPEG_5Utils_18interputils_cython_1_interp_point_1D = {"_interp_point_1D", (PyCFunction)__pyx_pw_6SimPEG_5Utils_18interputils_cython_1_interp_point_1D, METH_VARARGS|METH_KEYWORDS, __pyx_doc_6SimPEG_5Utils_18interputils_cython__interp_point_1D}; +static PyObject *__pyx_pw_6SimPEG_5Utils_18interputils_cython_1_interp_point_1D(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyArrayObject *__pyx_v_x = 0; + float __pyx_v_xr_i; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_interp_point_1D (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_x,&__pyx_n_s_xr_i,0}; + PyObject* values[2] = {0,0}; + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_x)) != 0)) kw_args--; + else goto __pyx_L5_argtuple_error; + case 1: + if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_xr_i)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("_interp_point_1D", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_interp_point_1D") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + } else if (PyTuple_GET_SIZE(__pyx_args) != 2) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + } + __pyx_v_x = ((PyArrayObject *)values[0]); + __pyx_v_xr_i = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_xr_i == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_interp_point_1D", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_L3_error:; + __Pyx_AddTraceback("SimPEG.Utils.interputils_cython._interp_point_1D", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_x), __pyx_ptype_5numpy_ndarray, 1, "x", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_r = __pyx_pf_6SimPEG_5Utils_18interputils_cython__interp_point_1D(__pyx_self, __pyx_v_x, __pyx_v_xr_i); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __pyx_r = NULL; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_6SimPEG_5Utils_18interputils_cython__interp_point_1D(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_x, float __pyx_v_xr_i) { + int __pyx_v_im; + int __pyx_v_ind_x1; + int __pyx_v_ind_x2; + int __pyx_v_xSize; + float __pyx_v_wx1; + float __pyx_v_wx2; + float __pyx_v_hx; + __Pyx_LocalBuf_ND __pyx_pybuffernd_x; + __Pyx_Buffer __pyx_pybuffer_x; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + int __pyx_t_6; + int __pyx_t_7; + int __pyx_t_8; + int __pyx_t_9; + long __pyx_t_10; + int __pyx_t_11; + int __pyx_t_12; + long __pyx_t_13; + int __pyx_t_14; + __pyx_t_5numpy_float64_t __pyx_t_15; + int __pyx_t_16; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_interp_point_1D", 0); + __pyx_pybuffer_x.pybuffer.buf = NULL; + __pyx_pybuffer_x.refcount = 0; + __pyx_pybuffernd_x.data = NULL; + __pyx_pybuffernd_x.rcbuffer = &__pyx_pybuffer_x; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_x.rcbuffer->pybuffer, (PyObject*)__pyx_v_x, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_pybuffernd_x.diminfo[0].strides = __pyx_pybuffernd_x.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_x.diminfo[0].shape = __pyx_pybuffernd_x.rcbuffer->pybuffer.shape[0]; + + /* "SimPEG/Utils/interputils_cython.pyx":17 + * # TODO: This fails if the point is on the outside of the mesh. + * # We may want to replace this by extrapolation? + * cdef int im = np.argmin(abs(x-xr_i)) # <<<<<<<<<<<<<< + * cdef int ind_x1 = 0 + * cdef int ind_x2 = 0 + */ + __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_argmin); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyFloat_FromDouble(__pyx_v_xr_i); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = PyNumber_Subtract(((PyObject *)__pyx_v_x), __pyx_t_2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Absolute(__pyx_t_4); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = NULL; + if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3); + if (likely(__pyx_t_4)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_4); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_3, function); + } + } + if (!__pyx_t_4) { + __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_GOTREF(__pyx_t_1); + } else { + __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_5); + __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __pyx_t_4 = NULL; + __Pyx_GIVEREF(__pyx_t_2); + PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_2); + __pyx_t_2 = 0; + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + } + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_im = __pyx_t_6; + + /* "SimPEG/Utils/interputils_cython.pyx":18 + * # We may want to replace this by extrapolation? + * cdef int im = np.argmin(abs(x-xr_i)) + * cdef int ind_x1 = 0 # <<<<<<<<<<<<<< + * cdef int ind_x2 = 0 + * cdef int xSize = x.shape[0]-1 + */ + __pyx_v_ind_x1 = 0; + + /* "SimPEG/Utils/interputils_cython.pyx":19 + * cdef int im = np.argmin(abs(x-xr_i)) + * cdef int ind_x1 = 0 + * cdef int ind_x2 = 0 # <<<<<<<<<<<<<< + * cdef int xSize = x.shape[0]-1 + * cdef float wx1 = 0.0 + */ + __pyx_v_ind_x2 = 0; + + /* "SimPEG/Utils/interputils_cython.pyx":20 + * cdef int ind_x1 = 0 + * cdef int ind_x2 = 0 + * cdef int xSize = x.shape[0]-1 # <<<<<<<<<<<<<< + * cdef float wx1 = 0.0 + * cdef float wx2 = 0.0 + */ + __pyx_v_xSize = ((__pyx_v_x->dimensions[0]) - 1); + + /* "SimPEG/Utils/interputils_cython.pyx":21 + * cdef int ind_x2 = 0 + * cdef int xSize = x.shape[0]-1 + * cdef float wx1 = 0.0 # <<<<<<<<<<<<<< + * cdef float wx2 = 0.0 + * cdef float hx = 0.0 + */ + __pyx_v_wx1 = 0.0; + + /* "SimPEG/Utils/interputils_cython.pyx":22 + * cdef int xSize = x.shape[0]-1 + * cdef float wx1 = 0.0 + * cdef float wx2 = 0.0 # <<<<<<<<<<<<<< + * cdef float hx = 0.0 + * + */ + __pyx_v_wx2 = 0.0; + + /* "SimPEG/Utils/interputils_cython.pyx":23 + * cdef float wx1 = 0.0 + * cdef float wx2 = 0.0 + * cdef float hx = 0.0 # <<<<<<<<<<<<<< + * + * if xr_i - x[im] >= 0: # Point on the left + */ + __pyx_v_hx = 0.0; + + /* "SimPEG/Utils/interputils_cython.pyx":25 + * cdef float hx = 0.0 + * + * if xr_i - x[im] >= 0: # Point on the left # <<<<<<<<<<<<<< + * ind_x1 = im + * ind_x2 = im+1 + */ + __pyx_t_6 = __pyx_v_im; + __pyx_t_7 = -1; + if (__pyx_t_6 < 0) { + __pyx_t_6 += __pyx_pybuffernd_x.diminfo[0].shape; + if (unlikely(__pyx_t_6 < 0)) __pyx_t_7 = 0; + } else if (unlikely(__pyx_t_6 >= __pyx_pybuffernd_x.diminfo[0].shape)) __pyx_t_7 = 0; + if (unlikely(__pyx_t_7 != -1)) { + __Pyx_RaiseBufferIndexError(__pyx_t_7); + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_t_8 = (((__pyx_v_xr_i - (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_x.rcbuffer->pybuffer.buf, __pyx_t_6, __pyx_pybuffernd_x.diminfo[0].strides))) >= 0.0) != 0); + if (__pyx_t_8) { + + /* "SimPEG/Utils/interputils_cython.pyx":26 + * + * if xr_i - x[im] >= 0: # Point on the left + * ind_x1 = im # <<<<<<<<<<<<<< + * ind_x2 = im+1 + * elif xr_i - x[im] < 0: # Point on the right + */ + __pyx_v_ind_x1 = __pyx_v_im; + + /* "SimPEG/Utils/interputils_cython.pyx":27 + * if xr_i - x[im] >= 0: # Point on the left + * ind_x1 = im + * ind_x2 = im+1 # <<<<<<<<<<<<<< + * elif xr_i - x[im] < 0: # Point on the right + * ind_x1 = im-1 + */ + __pyx_v_ind_x2 = (__pyx_v_im + 1); + goto __pyx_L3; + } + + /* "SimPEG/Utils/interputils_cython.pyx":28 + * ind_x1 = im + * ind_x2 = im+1 + * elif xr_i - x[im] < 0: # Point on the right # <<<<<<<<<<<<<< + * ind_x1 = im-1 + * ind_x2 = im + */ + __pyx_t_7 = __pyx_v_im; + __pyx_t_9 = -1; + if (__pyx_t_7 < 0) { + __pyx_t_7 += __pyx_pybuffernd_x.diminfo[0].shape; + if (unlikely(__pyx_t_7 < 0)) __pyx_t_9 = 0; + } else if (unlikely(__pyx_t_7 >= __pyx_pybuffernd_x.diminfo[0].shape)) __pyx_t_9 = 0; + if (unlikely(__pyx_t_9 != -1)) { + __Pyx_RaiseBufferIndexError(__pyx_t_9); + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 28; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_t_8 = (((__pyx_v_xr_i - (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_x.rcbuffer->pybuffer.buf, __pyx_t_7, __pyx_pybuffernd_x.diminfo[0].strides))) < 0.0) != 0); + if (__pyx_t_8) { + + /* "SimPEG/Utils/interputils_cython.pyx":29 + * ind_x2 = im+1 + * elif xr_i - x[im] < 0: # Point on the right + * ind_x1 = im-1 # <<<<<<<<<<<<<< + * ind_x2 = im + * ind_x1 = max(min(ind_x1, xSize), 0) + */ + __pyx_v_ind_x1 = (__pyx_v_im - 1); + + /* "SimPEG/Utils/interputils_cython.pyx":30 + * elif xr_i - x[im] < 0: # Point on the right + * ind_x1 = im-1 + * ind_x2 = im # <<<<<<<<<<<<<< + * ind_x1 = max(min(ind_x1, xSize), 0) + * ind_x2 = max(min(ind_x2, xSize), 0) + */ + __pyx_v_ind_x2 = __pyx_v_im; + goto __pyx_L3; + } + __pyx_L3:; + + /* "SimPEG/Utils/interputils_cython.pyx":31 + * ind_x1 = im-1 + * ind_x2 = im + * ind_x1 = max(min(ind_x1, xSize), 0) # <<<<<<<<<<<<<< + * ind_x2 = max(min(ind_x2, xSize), 0) + * + */ + __pyx_t_10 = 0; + __pyx_t_9 = __pyx_v_xSize; + __pyx_t_11 = __pyx_v_ind_x1; + if (((__pyx_t_9 < __pyx_t_11) != 0)) { + __pyx_t_12 = __pyx_t_9; + } else { + __pyx_t_12 = __pyx_t_11; + } + __pyx_t_9 = __pyx_t_12; + if (((__pyx_t_10 > __pyx_t_9) != 0)) { + __pyx_t_13 = __pyx_t_10; + } else { + __pyx_t_13 = __pyx_t_9; + } + __pyx_v_ind_x1 = __pyx_t_13; + + /* "SimPEG/Utils/interputils_cython.pyx":32 + * ind_x2 = im + * ind_x1 = max(min(ind_x1, xSize), 0) + * ind_x2 = max(min(ind_x2, xSize), 0) # <<<<<<<<<<<<<< + * + * if ind_x1 == ind_x2: + */ + __pyx_t_13 = 0; + __pyx_t_9 = __pyx_v_xSize; + __pyx_t_12 = __pyx_v_ind_x2; + if (((__pyx_t_9 < __pyx_t_12) != 0)) { + __pyx_t_11 = __pyx_t_9; + } else { + __pyx_t_11 = __pyx_t_12; + } + __pyx_t_9 = __pyx_t_11; + if (((__pyx_t_13 > __pyx_t_9) != 0)) { + __pyx_t_10 = __pyx_t_13; + } else { + __pyx_t_10 = __pyx_t_9; + } + __pyx_v_ind_x2 = __pyx_t_10; + + /* "SimPEG/Utils/interputils_cython.pyx":34 + * ind_x2 = max(min(ind_x2, xSize), 0) + * + * if ind_x1 == ind_x2: # <<<<<<<<<<<<<< + * return ind_x1, ind_x1, 0.5, 0.5 + * + */ + __pyx_t_8 = ((__pyx_v_ind_x1 == __pyx_v_ind_x2) != 0); + if (__pyx_t_8) { + + /* "SimPEG/Utils/interputils_cython.pyx":35 + * + * if ind_x1 == ind_x2: + * return ind_x1, ind_x1, 0.5, 0.5 # <<<<<<<<<<<<<< + * + * hx = x[ind_x2] - x[ind_x1] + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_ind_x1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_ind_x1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_5); + __Pyx_GIVEREF(__pyx_t_1); + PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1); + __Pyx_GIVEREF(__pyx_t_3); + PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_3); + __Pyx_INCREF(__pyx_float_0_5); + __Pyx_GIVEREF(__pyx_float_0_5); + PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_float_0_5); + __Pyx_INCREF(__pyx_float_0_5); + __Pyx_GIVEREF(__pyx_float_0_5); + PyTuple_SET_ITEM(__pyx_t_5, 3, __pyx_float_0_5); + __pyx_t_1 = 0; + __pyx_t_3 = 0; + __pyx_r = __pyx_t_5; + __pyx_t_5 = 0; + goto __pyx_L0; + } + + /* "SimPEG/Utils/interputils_cython.pyx":37 + * return ind_x1, ind_x1, 0.5, 0.5 + * + * hx = x[ind_x2] - x[ind_x1] # <<<<<<<<<<<<<< + * wx1 = 1 - (xr_i - x[ind_x1])/hx + * wx2 = 1 - (x[ind_x2] - xr_i)/hx + */ + __pyx_t_9 = __pyx_v_ind_x2; + __pyx_t_11 = -1; + if (__pyx_t_9 < 0) { + __pyx_t_9 += __pyx_pybuffernd_x.diminfo[0].shape; + if (unlikely(__pyx_t_9 < 0)) __pyx_t_11 = 0; + } else if (unlikely(__pyx_t_9 >= __pyx_pybuffernd_x.diminfo[0].shape)) __pyx_t_11 = 0; + if (unlikely(__pyx_t_11 != -1)) { + __Pyx_RaiseBufferIndexError(__pyx_t_11); + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_t_11 = __pyx_v_ind_x1; + __pyx_t_12 = -1; + if (__pyx_t_11 < 0) { + __pyx_t_11 += __pyx_pybuffernd_x.diminfo[0].shape; + if (unlikely(__pyx_t_11 < 0)) __pyx_t_12 = 0; + } else if (unlikely(__pyx_t_11 >= __pyx_pybuffernd_x.diminfo[0].shape)) __pyx_t_12 = 0; + if (unlikely(__pyx_t_12 != -1)) { + __Pyx_RaiseBufferIndexError(__pyx_t_12); + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_v_hx = ((*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_x.rcbuffer->pybuffer.buf, __pyx_t_9, __pyx_pybuffernd_x.diminfo[0].strides)) - (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_x.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_x.diminfo[0].strides))); + + /* "SimPEG/Utils/interputils_cython.pyx":38 + * + * hx = x[ind_x2] - x[ind_x1] + * wx1 = 1 - (xr_i - x[ind_x1])/hx # <<<<<<<<<<<<<< + * wx2 = 1 - (x[ind_x2] - xr_i)/hx + * + */ + __pyx_t_12 = __pyx_v_ind_x1; + __pyx_t_14 = -1; + if (__pyx_t_12 < 0) { + __pyx_t_12 += __pyx_pybuffernd_x.diminfo[0].shape; + if (unlikely(__pyx_t_12 < 0)) __pyx_t_14 = 0; + } else if (unlikely(__pyx_t_12 >= __pyx_pybuffernd_x.diminfo[0].shape)) __pyx_t_14 = 0; + if (unlikely(__pyx_t_14 != -1)) { + __Pyx_RaiseBufferIndexError(__pyx_t_14); + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_t_15 = (__pyx_v_xr_i - (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_x.rcbuffer->pybuffer.buf, __pyx_t_12, __pyx_pybuffernd_x.diminfo[0].strides))); + if (unlikely(__pyx_v_hx == 0)) { + #ifdef WITH_THREAD + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); + #endif + PyErr_SetString(PyExc_ZeroDivisionError, "float division"); + #ifdef WITH_THREAD + PyGILState_Release(__pyx_gilstate_save); + #endif + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_v_wx1 = (1.0 - (__pyx_t_15 / __pyx_v_hx)); + + /* "SimPEG/Utils/interputils_cython.pyx":39 + * hx = x[ind_x2] - x[ind_x1] + * wx1 = 1 - (xr_i - x[ind_x1])/hx + * wx2 = 1 - (x[ind_x2] - xr_i)/hx # <<<<<<<<<<<<<< + * + * return ind_x1, ind_x2, wx1, wx2 + */ + __pyx_t_14 = __pyx_v_ind_x2; + __pyx_t_16 = -1; + if (__pyx_t_14 < 0) { + __pyx_t_14 += __pyx_pybuffernd_x.diminfo[0].shape; + if (unlikely(__pyx_t_14 < 0)) __pyx_t_16 = 0; + } else if (unlikely(__pyx_t_14 >= __pyx_pybuffernd_x.diminfo[0].shape)) __pyx_t_16 = 0; + if (unlikely(__pyx_t_16 != -1)) { + __Pyx_RaiseBufferIndexError(__pyx_t_16); + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_t_15 = ((*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_x.rcbuffer->pybuffer.buf, __pyx_t_14, __pyx_pybuffernd_x.diminfo[0].strides)) - __pyx_v_xr_i); + if (unlikely(__pyx_v_hx == 0)) { + #ifdef WITH_THREAD + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); + #endif + PyErr_SetString(PyExc_ZeroDivisionError, "float division"); + #ifdef WITH_THREAD + PyGILState_Release(__pyx_gilstate_save); + #endif + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_v_wx2 = (1.0 - (__pyx_t_15 / __pyx_v_hx)); + + /* "SimPEG/Utils/interputils_cython.pyx":41 + * wx2 = 1 - (x[ind_x2] - xr_i)/hx + * + * return ind_x1, ind_x2, wx1, wx2 # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_ind_x1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_ind_x2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = PyFloat_FromDouble(__pyx_v_wx1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyFloat_FromDouble(__pyx_v_wx2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = PyTuple_New(4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_4); + __Pyx_GIVEREF(__pyx_t_5); + PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_5); + __Pyx_GIVEREF(__pyx_t_3); + PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_3); + __Pyx_GIVEREF(__pyx_t_1); + PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_t_1); + __Pyx_GIVEREF(__pyx_t_2); + PyTuple_SET_ITEM(__pyx_t_4, 3, __pyx_t_2); + __pyx_t_5 = 0; + __pyx_t_3 = 0; + __pyx_t_1 = 0; + __pyx_t_2 = 0; + __pyx_r = __pyx_t_4; + __pyx_t_4 = 0; + goto __pyx_L0; + + /* "SimPEG/Utils/interputils_cython.pyx":6 + * # from libcpp.vector cimport vector + * + * def _interp_point_1D(np.ndarray[np.float64_t, ndim=1] x, float xr_i): # <<<<<<<<<<<<<< + * """ + * given a point, xr_i, this will find which two integers it lies between. + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + { PyObject *__pyx_type, *__pyx_value, *__pyx_tb; + __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_x.rcbuffer->pybuffer); + __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} + __Pyx_AddTraceback("SimPEG.Utils.interputils_cython._interp_point_1D", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + goto __pyx_L2; + __pyx_L0:; + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_x.rcbuffer->pybuffer); + __pyx_L2:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "SimPEG/Utils/interputils_cython.pyx":44 + * + * + * def _interpmat1D(np.ndarray[np.float64_t, ndim=1] locs, # <<<<<<<<<<<<<< + * np.ndarray[np.float64_t, ndim=1] x): + * """Use interpmat with only x component provided.""" + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_6SimPEG_5Utils_18interputils_cython_3_interpmat1D(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static char __pyx_doc_6SimPEG_5Utils_18interputils_cython_2_interpmat1D[] = "Use interpmat with only x component provided."; +static PyMethodDef __pyx_mdef_6SimPEG_5Utils_18interputils_cython_3_interpmat1D = {"_interpmat1D", (PyCFunction)__pyx_pw_6SimPEG_5Utils_18interputils_cython_3_interpmat1D, METH_VARARGS|METH_KEYWORDS, __pyx_doc_6SimPEG_5Utils_18interputils_cython_2_interpmat1D}; +static PyObject *__pyx_pw_6SimPEG_5Utils_18interputils_cython_3_interpmat1D(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyArrayObject *__pyx_v_locs = 0; + PyArrayObject *__pyx_v_x = 0; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_interpmat1D (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_locs,&__pyx_n_s_x,0}; + PyObject* values[2] = {0,0}; + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_locs)) != 0)) kw_args--; + else goto __pyx_L5_argtuple_error; + case 1: + if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_x)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("_interpmat1D", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 44; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_interpmat1D") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 44; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + } else if (PyTuple_GET_SIZE(__pyx_args) != 2) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + } + __pyx_v_locs = ((PyArrayObject *)values[0]); + __pyx_v_x = ((PyArrayObject *)values[1]); + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_interpmat1D", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 44; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_L3_error:; + __Pyx_AddTraceback("SimPEG.Utils.interputils_cython._interpmat1D", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_locs), __pyx_ptype_5numpy_ndarray, 1, "locs", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 44; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_x), __pyx_ptype_5numpy_ndarray, 1, "x", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_r = __pyx_pf_6SimPEG_5Utils_18interputils_cython_2_interpmat1D(__pyx_self, __pyx_v_locs, __pyx_v_x); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __pyx_r = NULL; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_6SimPEG_5Utils_18interputils_cython_2_interpmat1D(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_locs, PyArrayObject *__pyx_v_x) { + CYTHON_UNUSED int __pyx_v_nx; + int __pyx_v_npts; + PyObject *__pyx_v_inds = NULL; + PyObject *__pyx_v_vals = NULL; + int __pyx_v_i; + PyObject *__pyx_v_ind_x1 = NULL; + PyObject *__pyx_v_ind_x2 = NULL; + PyObject *__pyx_v_wx1 = NULL; + PyObject *__pyx_v_wx2 = NULL; + __Pyx_LocalBuf_ND __pyx_pybuffernd_locs; + __Pyx_Buffer __pyx_pybuffer_locs; + __Pyx_LocalBuf_ND __pyx_pybuffernd_x; + __Pyx_Buffer __pyx_pybuffer_x; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + int __pyx_t_5; + int __pyx_t_6; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + Py_ssize_t __pyx_t_9; + PyObject *__pyx_t_10 = NULL; + PyObject *__pyx_t_11 = NULL; + PyObject *(*__pyx_t_12)(PyObject *); + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_interpmat1D", 0); + __pyx_pybuffer_locs.pybuffer.buf = NULL; + __pyx_pybuffer_locs.refcount = 0; + __pyx_pybuffernd_locs.data = NULL; + __pyx_pybuffernd_locs.rcbuffer = &__pyx_pybuffer_locs; + __pyx_pybuffer_x.pybuffer.buf = NULL; + __pyx_pybuffer_x.refcount = 0; + __pyx_pybuffernd_x.data = NULL; + __pyx_pybuffernd_x.rcbuffer = &__pyx_pybuffer_x; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_locs.rcbuffer->pybuffer, (PyObject*)__pyx_v_locs, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 44; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_pybuffernd_locs.diminfo[0].strides = __pyx_pybuffernd_locs.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_locs.diminfo[0].shape = __pyx_pybuffernd_locs.rcbuffer->pybuffer.shape[0]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_x.rcbuffer->pybuffer, (PyObject*)__pyx_v_x, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 44; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_pybuffernd_x.diminfo[0].strides = __pyx_pybuffernd_x.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_x.diminfo[0].shape = __pyx_pybuffernd_x.rcbuffer->pybuffer.shape[0]; + + /* "SimPEG/Utils/interputils_cython.pyx":47 + * np.ndarray[np.float64_t, ndim=1] x): + * """Use interpmat with only x component provided.""" + * cdef int nx = x.size # <<<<<<<<<<<<<< + * cdef int npts = locs.shape[0] + * + */ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_x), __pyx_n_s_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_nx = __pyx_t_2; + + /* "SimPEG/Utils/interputils_cython.pyx":48 + * """Use interpmat with only x component provided.""" + * cdef int nx = x.size + * cdef int npts = locs.shape[0] # <<<<<<<<<<<<<< + * + * inds, vals = [], [] + */ + __pyx_v_npts = (__pyx_v_locs->dimensions[0]); + + /* "SimPEG/Utils/interputils_cython.pyx":50 + * cdef int npts = locs.shape[0] + * + * inds, vals = [], [] # <<<<<<<<<<<<<< + * + * for i in range(npts): + */ + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __pyx_v_inds = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + __pyx_v_vals = ((PyObject*)__pyx_t_3); + __pyx_t_3 = 0; + + /* "SimPEG/Utils/interputils_cython.pyx":52 + * inds, vals = [], [] + * + * for i in range(npts): # <<<<<<<<<<<<<< + * ind_x1, ind_x2, wx1, wx2 = _interp_point_1D(x, locs[i]) + * inds += [ind_x1, ind_x2] + */ + __pyx_t_2 = __pyx_v_npts; + for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_2; __pyx_t_4+=1) { + __pyx_v_i = __pyx_t_4; + + /* "SimPEG/Utils/interputils_cython.pyx":53 + * + * for i in range(npts): + * ind_x1, ind_x2, wx1, wx2 = _interp_point_1D(x, locs[i]) # <<<<<<<<<<<<<< + * inds += [ind_x1, ind_x2] + * vals += [wx1,wx2] + */ + __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_interp_point_1D); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 53; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_5 = __pyx_v_i; + __pyx_t_6 = -1; + if (__pyx_t_5 < 0) { + __pyx_t_5 += __pyx_pybuffernd_locs.diminfo[0].shape; + if (unlikely(__pyx_t_5 < 0)) __pyx_t_6 = 0; + } else if (unlikely(__pyx_t_5 >= __pyx_pybuffernd_locs.diminfo[0].shape)) __pyx_t_6 = 0; + if (unlikely(__pyx_t_6 != -1)) { + __Pyx_RaiseBufferIndexError(__pyx_t_6); + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 53; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_t_7 = PyFloat_FromDouble((*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_locs.rcbuffer->pybuffer.buf, __pyx_t_5, __pyx_pybuffernd_locs.diminfo[0].strides))); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 53; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_8 = NULL; + __pyx_t_9 = 0; + if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_1))) { + __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_1); + if (likely(__pyx_t_8)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1); + __Pyx_INCREF(__pyx_t_8); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_1, function); + __pyx_t_9 = 1; + } + } + __pyx_t_10 = PyTuple_New(2+__pyx_t_9); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 53; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_10); + if (__pyx_t_8) { + __Pyx_GIVEREF(__pyx_t_8); PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_8); __pyx_t_8 = NULL; + } + __Pyx_INCREF(((PyObject *)__pyx_v_x)); + __Pyx_GIVEREF(((PyObject *)__pyx_v_x)); + PyTuple_SET_ITEM(__pyx_t_10, 0+__pyx_t_9, ((PyObject *)__pyx_v_x)); + __Pyx_GIVEREF(__pyx_t_7); + PyTuple_SET_ITEM(__pyx_t_10, 1+__pyx_t_9, __pyx_t_7); + __pyx_t_7 = 0; + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_10, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 53; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if ((likely(PyTuple_CheckExact(__pyx_t_3))) || (PyList_CheckExact(__pyx_t_3))) { + PyObject* sequence = __pyx_t_3; + #if CYTHON_COMPILING_IN_CPYTHON + Py_ssize_t size = Py_SIZE(sequence); + #else + Py_ssize_t size = PySequence_Size(sequence); + #endif + if (unlikely(size != 4)) { + if (size > 4) __Pyx_RaiseTooManyValuesError(4); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 53; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + #if CYTHON_COMPILING_IN_CPYTHON + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_10 = PyTuple_GET_ITEM(sequence, 1); + __pyx_t_7 = PyTuple_GET_ITEM(sequence, 2); + __pyx_t_8 = PyTuple_GET_ITEM(sequence, 3); + } else { + __pyx_t_1 = PyList_GET_ITEM(sequence, 0); + __pyx_t_10 = PyList_GET_ITEM(sequence, 1); + __pyx_t_7 = PyList_GET_ITEM(sequence, 2); + __pyx_t_8 = PyList_GET_ITEM(sequence, 3); + } + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx_t_10); + __Pyx_INCREF(__pyx_t_7); + __Pyx_INCREF(__pyx_t_8); + #else + { + Py_ssize_t i; + PyObject** temps[4] = {&__pyx_t_1,&__pyx_t_10,&__pyx_t_7,&__pyx_t_8}; + for (i=0; i < 4; i++) { + PyObject* item = PySequence_ITEM(sequence, i); if (unlikely(!item)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 53; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(item); + *(temps[i]) = item; + } + } + #endif + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } else { + Py_ssize_t index = -1; + PyObject** temps[4] = {&__pyx_t_1,&__pyx_t_10,&__pyx_t_7,&__pyx_t_8}; + __pyx_t_11 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 53; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_11); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_12 = Py_TYPE(__pyx_t_11)->tp_iternext; + for (index=0; index < 4; index++) { + PyObject* item = __pyx_t_12(__pyx_t_11); if (unlikely(!item)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(item); + *(temps[index]) = item; + } + if (__Pyx_IternextUnpackEndCheck(__pyx_t_12(__pyx_t_11), 4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 53; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_t_12 = NULL; + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + goto __pyx_L6_unpacking_done; + __pyx_L5_unpacking_failed:; + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + __pyx_t_12 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 53; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_L6_unpacking_done:; + } + __Pyx_XDECREF_SET(__pyx_v_ind_x1, __pyx_t_1); + __pyx_t_1 = 0; + __Pyx_XDECREF_SET(__pyx_v_ind_x2, __pyx_t_10); + __pyx_t_10 = 0; + __Pyx_XDECREF_SET(__pyx_v_wx1, __pyx_t_7); + __pyx_t_7 = 0; + __Pyx_XDECREF_SET(__pyx_v_wx2, __pyx_t_8); + __pyx_t_8 = 0; + + /* "SimPEG/Utils/interputils_cython.pyx":54 + * for i in range(npts): + * ind_x1, ind_x2, wx1, wx2 = _interp_point_1D(x, locs[i]) + * inds += [ind_x1, ind_x2] # <<<<<<<<<<<<<< + * vals += [wx1,wx2] + * + */ + __pyx_t_3 = PyList_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_v_ind_x1); + __Pyx_GIVEREF(__pyx_v_ind_x1); + PyList_SET_ITEM(__pyx_t_3, 0, __pyx_v_ind_x1); + __Pyx_INCREF(__pyx_v_ind_x2); + __Pyx_GIVEREF(__pyx_v_ind_x2); + PyList_SET_ITEM(__pyx_t_3, 1, __pyx_v_ind_x2); + __pyx_t_8 = PyNumber_InPlaceAdd(__pyx_v_inds, __pyx_t_3); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF_SET(__pyx_v_inds, ((PyObject*)__pyx_t_8)); + __pyx_t_8 = 0; + + /* "SimPEG/Utils/interputils_cython.pyx":55 + * ind_x1, ind_x2, wx1, wx2 = _interp_point_1D(x, locs[i]) + * inds += [ind_x1, ind_x2] + * vals += [wx1,wx2] # <<<<<<<<<<<<<< + * + * return inds, vals + */ + __pyx_t_8 = PyList_New(2); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_8); + __Pyx_INCREF(__pyx_v_wx1); + __Pyx_GIVEREF(__pyx_v_wx1); + PyList_SET_ITEM(__pyx_t_8, 0, __pyx_v_wx1); + __Pyx_INCREF(__pyx_v_wx2); + __Pyx_GIVEREF(__pyx_v_wx2); + PyList_SET_ITEM(__pyx_t_8, 1, __pyx_v_wx2); + __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_v_vals, __pyx_t_8); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF_SET(__pyx_v_vals, ((PyObject*)__pyx_t_3)); + __pyx_t_3 = 0; + } + + /* "SimPEG/Utils/interputils_cython.pyx":57 + * vals += [wx1,wx2] + * + * return inds, vals # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 57; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_v_inds); + __Pyx_GIVEREF(__pyx_v_inds); + PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_inds); + __Pyx_INCREF(__pyx_v_vals); + __Pyx_GIVEREF(__pyx_v_vals); + PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_vals); + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + + /* "SimPEG/Utils/interputils_cython.pyx":44 + * + * + * def _interpmat1D(np.ndarray[np.float64_t, ndim=1] locs, # <<<<<<<<<<<<<< + * np.ndarray[np.float64_t, ndim=1] x): + * """Use interpmat with only x component provided.""" + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_10); + __Pyx_XDECREF(__pyx_t_11); + { PyObject *__pyx_type, *__pyx_value, *__pyx_tb; + __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_locs.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_x.rcbuffer->pybuffer); + __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} + __Pyx_AddTraceback("SimPEG.Utils.interputils_cython._interpmat1D", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + goto __pyx_L2; + __pyx_L0:; + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_locs.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_x.rcbuffer->pybuffer); + __pyx_L2:; + __Pyx_XDECREF(__pyx_v_inds); + __Pyx_XDECREF(__pyx_v_vals); + __Pyx_XDECREF(__pyx_v_ind_x1); + __Pyx_XDECREF(__pyx_v_ind_x2); + __Pyx_XDECREF(__pyx_v_wx1); + __Pyx_XDECREF(__pyx_v_wx2); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "SimPEG/Utils/interputils_cython.pyx":60 + * + * + * def _interpmat2D(np.ndarray[np.float64_t, ndim=2] locs, # <<<<<<<<<<<<<< + * np.ndarray[np.float64_t, ndim=1] x, + * np.ndarray[np.float64_t, ndim=1] y): + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_6SimPEG_5Utils_18interputils_cython_5_interpmat2D(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static char __pyx_doc_6SimPEG_5Utils_18interputils_cython_4_interpmat2D[] = "Use interpmat with only x and y components provided."; +static PyMethodDef __pyx_mdef_6SimPEG_5Utils_18interputils_cython_5_interpmat2D = {"_interpmat2D", (PyCFunction)__pyx_pw_6SimPEG_5Utils_18interputils_cython_5_interpmat2D, METH_VARARGS|METH_KEYWORDS, __pyx_doc_6SimPEG_5Utils_18interputils_cython_4_interpmat2D}; +static PyObject *__pyx_pw_6SimPEG_5Utils_18interputils_cython_5_interpmat2D(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyArrayObject *__pyx_v_locs = 0; + PyArrayObject *__pyx_v_x = 0; + PyArrayObject *__pyx_v_y = 0; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_interpmat2D (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_locs,&__pyx_n_s_x,&__pyx_n_s_y,0}; + PyObject* values[3] = {0,0,0}; + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_locs)) != 0)) kw_args--; + else goto __pyx_L5_argtuple_error; + case 1: + if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_x)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("_interpmat2D", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + case 2: + if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_y)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("_interpmat2D", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_interpmat2D") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + } else if (PyTuple_GET_SIZE(__pyx_args) != 3) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + } + __pyx_v_locs = ((PyArrayObject *)values[0]); + __pyx_v_x = ((PyArrayObject *)values[1]); + __pyx_v_y = ((PyArrayObject *)values[2]); + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_interpmat2D", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_L3_error:; + __Pyx_AddTraceback("SimPEG.Utils.interputils_cython._interpmat2D", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_locs), __pyx_ptype_5numpy_ndarray, 1, "locs", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_x), __pyx_ptype_5numpy_ndarray, 1, "x", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_y), __pyx_ptype_5numpy_ndarray, 1, "y", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_r = __pyx_pf_6SimPEG_5Utils_18interputils_cython_4_interpmat2D(__pyx_self, __pyx_v_locs, __pyx_v_x, __pyx_v_y); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __pyx_r = NULL; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_6SimPEG_5Utils_18interputils_cython_4_interpmat2D(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_locs, PyArrayObject *__pyx_v_x, PyArrayObject *__pyx_v_y) { + CYTHON_UNUSED int __pyx_v_nx; + CYTHON_UNUSED int __pyx_v_ny; + int __pyx_v_npts; + PyObject *__pyx_v_inds = NULL; + PyObject *__pyx_v_vals = NULL; + int __pyx_v_i; + PyObject *__pyx_v_ind_x1 = NULL; + PyObject *__pyx_v_ind_x2 = NULL; + PyObject *__pyx_v_wx1 = NULL; + PyObject *__pyx_v_wx2 = NULL; + PyObject *__pyx_v_ind_y1 = NULL; + PyObject *__pyx_v_ind_y2 = NULL; + PyObject *__pyx_v_wy1 = NULL; + PyObject *__pyx_v_wy2 = NULL; + __Pyx_LocalBuf_ND __pyx_pybuffernd_locs; + __Pyx_Buffer __pyx_pybuffer_locs; + __Pyx_LocalBuf_ND __pyx_pybuffernd_x; + __Pyx_Buffer __pyx_pybuffer_x; + __Pyx_LocalBuf_ND __pyx_pybuffernd_y; + __Pyx_Buffer __pyx_pybuffer_y; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + int __pyx_t_5; + long __pyx_t_6; + int __pyx_t_7; + PyObject *__pyx_t_8 = NULL; + PyObject *__pyx_t_9 = NULL; + Py_ssize_t __pyx_t_10; + PyObject *__pyx_t_11 = NULL; + PyObject *__pyx_t_12 = NULL; + PyObject *(*__pyx_t_13)(PyObject *); + long __pyx_t_14; + int __pyx_t_15; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_interpmat2D", 0); + __pyx_pybuffer_locs.pybuffer.buf = NULL; + __pyx_pybuffer_locs.refcount = 0; + __pyx_pybuffernd_locs.data = NULL; + __pyx_pybuffernd_locs.rcbuffer = &__pyx_pybuffer_locs; + __pyx_pybuffer_x.pybuffer.buf = NULL; + __pyx_pybuffer_x.refcount = 0; + __pyx_pybuffernd_x.data = NULL; + __pyx_pybuffernd_x.rcbuffer = &__pyx_pybuffer_x; + __pyx_pybuffer_y.pybuffer.buf = NULL; + __pyx_pybuffer_y.refcount = 0; + __pyx_pybuffernd_y.data = NULL; + __pyx_pybuffernd_y.rcbuffer = &__pyx_pybuffer_y; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_locs.rcbuffer->pybuffer, (PyObject*)__pyx_v_locs, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_pybuffernd_locs.diminfo[0].strides = __pyx_pybuffernd_locs.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_locs.diminfo[0].shape = __pyx_pybuffernd_locs.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_locs.diminfo[1].strides = __pyx_pybuffernd_locs.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_locs.diminfo[1].shape = __pyx_pybuffernd_locs.rcbuffer->pybuffer.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_x.rcbuffer->pybuffer, (PyObject*)__pyx_v_x, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_pybuffernd_x.diminfo[0].strides = __pyx_pybuffernd_x.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_x.diminfo[0].shape = __pyx_pybuffernd_x.rcbuffer->pybuffer.shape[0]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_y.rcbuffer->pybuffer, (PyObject*)__pyx_v_y, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_pybuffernd_y.diminfo[0].strides = __pyx_pybuffernd_y.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_y.diminfo[0].shape = __pyx_pybuffernd_y.rcbuffer->pybuffer.shape[0]; + + /* "SimPEG/Utils/interputils_cython.pyx":64 + * np.ndarray[np.float64_t, ndim=1] y): + * """Use interpmat with only x and y components provided.""" + * cdef int nx = x.size # <<<<<<<<<<<<<< + * cdef int ny = y.size + * cdef int npts = locs.shape[0] + */ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_x), __pyx_n_s_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_nx = __pyx_t_2; + + /* "SimPEG/Utils/interputils_cython.pyx":65 + * """Use interpmat with only x and y components provided.""" + * cdef int nx = x.size + * cdef int ny = y.size # <<<<<<<<<<<<<< + * cdef int npts = locs.shape[0] + * + */ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_y), __pyx_n_s_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_ny = __pyx_t_2; + + /* "SimPEG/Utils/interputils_cython.pyx":66 + * cdef int nx = x.size + * cdef int ny = y.size + * cdef int npts = locs.shape[0] # <<<<<<<<<<<<<< + * + * inds, vals = [], [] + */ + __pyx_v_npts = (__pyx_v_locs->dimensions[0]); + + /* "SimPEG/Utils/interputils_cython.pyx":68 + * cdef int npts = locs.shape[0] + * + * inds, vals = [], [] # <<<<<<<<<<<<<< + * + * for i in range(npts): + */ + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 68; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 68; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __pyx_v_inds = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + __pyx_v_vals = ((PyObject*)__pyx_t_3); + __pyx_t_3 = 0; + + /* "SimPEG/Utils/interputils_cython.pyx":70 + * inds, vals = [], [] + * + * for i in range(npts): # <<<<<<<<<<<<<< + * ind_x1, ind_x2, wx1, wx2 = _interp_point_1D(x, locs[i, 0]) + * ind_y1, ind_y2, wy1, wy2 = _interp_point_1D(y, locs[i, 1]) + */ + __pyx_t_2 = __pyx_v_npts; + for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_2; __pyx_t_4+=1) { + __pyx_v_i = __pyx_t_4; + + /* "SimPEG/Utils/interputils_cython.pyx":71 + * + * for i in range(npts): + * ind_x1, ind_x2, wx1, wx2 = _interp_point_1D(x, locs[i, 0]) # <<<<<<<<<<<<<< + * ind_y1, ind_y2, wy1, wy2 = _interp_point_1D(y, locs[i, 1]) + * + */ + __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_interp_point_1D); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_5 = __pyx_v_i; + __pyx_t_6 = 0; + __pyx_t_7 = -1; + if (__pyx_t_5 < 0) { + __pyx_t_5 += __pyx_pybuffernd_locs.diminfo[0].shape; + if (unlikely(__pyx_t_5 < 0)) __pyx_t_7 = 0; + } else if (unlikely(__pyx_t_5 >= __pyx_pybuffernd_locs.diminfo[0].shape)) __pyx_t_7 = 0; + if (__pyx_t_6 < 0) { + __pyx_t_6 += __pyx_pybuffernd_locs.diminfo[1].shape; + if (unlikely(__pyx_t_6 < 0)) __pyx_t_7 = 1; + } else if (unlikely(__pyx_t_6 >= __pyx_pybuffernd_locs.diminfo[1].shape)) __pyx_t_7 = 1; + if (unlikely(__pyx_t_7 != -1)) { + __Pyx_RaiseBufferIndexError(__pyx_t_7); + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_t_8 = PyFloat_FromDouble((*__Pyx_BufPtrStrided2d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_locs.rcbuffer->pybuffer.buf, __pyx_t_5, __pyx_pybuffernd_locs.diminfo[0].strides, __pyx_t_6, __pyx_pybuffernd_locs.diminfo[1].strides))); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_9 = NULL; + __pyx_t_10 = 0; + if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_1))) { + __pyx_t_9 = PyMethod_GET_SELF(__pyx_t_1); + if (likely(__pyx_t_9)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1); + __Pyx_INCREF(__pyx_t_9); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_1, function); + __pyx_t_10 = 1; + } + } + __pyx_t_11 = PyTuple_New(2+__pyx_t_10); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_11); + if (__pyx_t_9) { + __Pyx_GIVEREF(__pyx_t_9); PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_9); __pyx_t_9 = NULL; + } + __Pyx_INCREF(((PyObject *)__pyx_v_x)); + __Pyx_GIVEREF(((PyObject *)__pyx_v_x)); + PyTuple_SET_ITEM(__pyx_t_11, 0+__pyx_t_10, ((PyObject *)__pyx_v_x)); + __Pyx_GIVEREF(__pyx_t_8); + PyTuple_SET_ITEM(__pyx_t_11, 1+__pyx_t_10, __pyx_t_8); + __pyx_t_8 = 0; + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_11, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if ((likely(PyTuple_CheckExact(__pyx_t_3))) || (PyList_CheckExact(__pyx_t_3))) { + PyObject* sequence = __pyx_t_3; + #if CYTHON_COMPILING_IN_CPYTHON + Py_ssize_t size = Py_SIZE(sequence); + #else + Py_ssize_t size = PySequence_Size(sequence); + #endif + if (unlikely(size != 4)) { + if (size > 4) __Pyx_RaiseTooManyValuesError(4); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + #if CYTHON_COMPILING_IN_CPYTHON + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_11 = PyTuple_GET_ITEM(sequence, 1); + __pyx_t_8 = PyTuple_GET_ITEM(sequence, 2); + __pyx_t_9 = PyTuple_GET_ITEM(sequence, 3); + } else { + __pyx_t_1 = PyList_GET_ITEM(sequence, 0); + __pyx_t_11 = PyList_GET_ITEM(sequence, 1); + __pyx_t_8 = PyList_GET_ITEM(sequence, 2); + __pyx_t_9 = PyList_GET_ITEM(sequence, 3); + } + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx_t_11); + __Pyx_INCREF(__pyx_t_8); + __Pyx_INCREF(__pyx_t_9); + #else + { + Py_ssize_t i; + PyObject** temps[4] = {&__pyx_t_1,&__pyx_t_11,&__pyx_t_8,&__pyx_t_9}; + for (i=0; i < 4; i++) { + PyObject* item = PySequence_ITEM(sequence, i); if (unlikely(!item)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(item); + *(temps[i]) = item; + } + } + #endif + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } else { + Py_ssize_t index = -1; + PyObject** temps[4] = {&__pyx_t_1,&__pyx_t_11,&__pyx_t_8,&__pyx_t_9}; + __pyx_t_12 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_12); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_13 = Py_TYPE(__pyx_t_12)->tp_iternext; + for (index=0; index < 4; index++) { + PyObject* item = __pyx_t_13(__pyx_t_12); if (unlikely(!item)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(item); + *(temps[index]) = item; + } + if (__Pyx_IternextUnpackEndCheck(__pyx_t_13(__pyx_t_12), 4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_t_13 = NULL; + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + goto __pyx_L6_unpacking_done; + __pyx_L5_unpacking_failed:; + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + __pyx_t_13 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_L6_unpacking_done:; + } + __Pyx_XDECREF_SET(__pyx_v_ind_x1, __pyx_t_1); + __pyx_t_1 = 0; + __Pyx_XDECREF_SET(__pyx_v_ind_x2, __pyx_t_11); + __pyx_t_11 = 0; + __Pyx_XDECREF_SET(__pyx_v_wx1, __pyx_t_8); + __pyx_t_8 = 0; + __Pyx_XDECREF_SET(__pyx_v_wx2, __pyx_t_9); + __pyx_t_9 = 0; + + /* "SimPEG/Utils/interputils_cython.pyx":72 + * for i in range(npts): + * ind_x1, ind_x2, wx1, wx2 = _interp_point_1D(x, locs[i, 0]) + * ind_y1, ind_y2, wy1, wy2 = _interp_point_1D(y, locs[i, 1]) # <<<<<<<<<<<<<< + * + * inds += [( ind_x1, ind_y2), + */ + __pyx_t_9 = __Pyx_GetModuleGlobalName(__pyx_n_s_interp_point_1D); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_7 = __pyx_v_i; + __pyx_t_14 = 1; + __pyx_t_15 = -1; + if (__pyx_t_7 < 0) { + __pyx_t_7 += __pyx_pybuffernd_locs.diminfo[0].shape; + if (unlikely(__pyx_t_7 < 0)) __pyx_t_15 = 0; + } else if (unlikely(__pyx_t_7 >= __pyx_pybuffernd_locs.diminfo[0].shape)) __pyx_t_15 = 0; + if (__pyx_t_14 < 0) { + __pyx_t_14 += __pyx_pybuffernd_locs.diminfo[1].shape; + if (unlikely(__pyx_t_14 < 0)) __pyx_t_15 = 1; + } else if (unlikely(__pyx_t_14 >= __pyx_pybuffernd_locs.diminfo[1].shape)) __pyx_t_15 = 1; + if (unlikely(__pyx_t_15 != -1)) { + __Pyx_RaiseBufferIndexError(__pyx_t_15); + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_t_8 = PyFloat_FromDouble((*__Pyx_BufPtrStrided2d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_locs.rcbuffer->pybuffer.buf, __pyx_t_7, __pyx_pybuffernd_locs.diminfo[0].strides, __pyx_t_14, __pyx_pybuffernd_locs.diminfo[1].strides))); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_11 = NULL; + __pyx_t_10 = 0; + if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_9))) { + __pyx_t_11 = PyMethod_GET_SELF(__pyx_t_9); + if (likely(__pyx_t_11)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_9); + __Pyx_INCREF(__pyx_t_11); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_9, function); + __pyx_t_10 = 1; + } + } + __pyx_t_1 = PyTuple_New(2+__pyx_t_10); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + if (__pyx_t_11) { + __Pyx_GIVEREF(__pyx_t_11); PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_11); __pyx_t_11 = NULL; + } + __Pyx_INCREF(((PyObject *)__pyx_v_y)); + __Pyx_GIVEREF(((PyObject *)__pyx_v_y)); + PyTuple_SET_ITEM(__pyx_t_1, 0+__pyx_t_10, ((PyObject *)__pyx_v_y)); + __Pyx_GIVEREF(__pyx_t_8); + PyTuple_SET_ITEM(__pyx_t_1, 1+__pyx_t_10, __pyx_t_8); + __pyx_t_8 = 0; + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_9, __pyx_t_1, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + if ((likely(PyTuple_CheckExact(__pyx_t_3))) || (PyList_CheckExact(__pyx_t_3))) { + PyObject* sequence = __pyx_t_3; + #if CYTHON_COMPILING_IN_CPYTHON + Py_ssize_t size = Py_SIZE(sequence); + #else + Py_ssize_t size = PySequence_Size(sequence); + #endif + if (unlikely(size != 4)) { + if (size > 4) __Pyx_RaiseTooManyValuesError(4); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + #if CYTHON_COMPILING_IN_CPYTHON + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_9 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 1); + __pyx_t_8 = PyTuple_GET_ITEM(sequence, 2); + __pyx_t_11 = PyTuple_GET_ITEM(sequence, 3); + } else { + __pyx_t_9 = PyList_GET_ITEM(sequence, 0); + __pyx_t_1 = PyList_GET_ITEM(sequence, 1); + __pyx_t_8 = PyList_GET_ITEM(sequence, 2); + __pyx_t_11 = PyList_GET_ITEM(sequence, 3); + } + __Pyx_INCREF(__pyx_t_9); + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx_t_8); + __Pyx_INCREF(__pyx_t_11); + #else + { + Py_ssize_t i; + PyObject** temps[4] = {&__pyx_t_9,&__pyx_t_1,&__pyx_t_8,&__pyx_t_11}; + for (i=0; i < 4; i++) { + PyObject* item = PySequence_ITEM(sequence, i); if (unlikely(!item)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(item); + *(temps[i]) = item; + } + } + #endif + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } else { + Py_ssize_t index = -1; + PyObject** temps[4] = {&__pyx_t_9,&__pyx_t_1,&__pyx_t_8,&__pyx_t_11}; + __pyx_t_12 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_12); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_13 = Py_TYPE(__pyx_t_12)->tp_iternext; + for (index=0; index < 4; index++) { + PyObject* item = __pyx_t_13(__pyx_t_12); if (unlikely(!item)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(item); + *(temps[index]) = item; + } + if (__Pyx_IternextUnpackEndCheck(__pyx_t_13(__pyx_t_12), 4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_t_13 = NULL; + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + goto __pyx_L8_unpacking_done; + __pyx_L7_unpacking_failed:; + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + __pyx_t_13 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_L8_unpacking_done:; + } + __Pyx_XDECREF_SET(__pyx_v_ind_y1, __pyx_t_9); + __pyx_t_9 = 0; + __Pyx_XDECREF_SET(__pyx_v_ind_y2, __pyx_t_1); + __pyx_t_1 = 0; + __Pyx_XDECREF_SET(__pyx_v_wy1, __pyx_t_8); + __pyx_t_8 = 0; + __Pyx_XDECREF_SET(__pyx_v_wy2, __pyx_t_11); + __pyx_t_11 = 0; + + /* "SimPEG/Utils/interputils_cython.pyx":74 + * ind_y1, ind_y2, wy1, wy2 = _interp_point_1D(y, locs[i, 1]) + * + * inds += [( ind_x1, ind_y2), # <<<<<<<<<<<<<< + * ( ind_x1, ind_y1), + * ( ind_x2, ind_y1), + */ + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_v_ind_x1); + __Pyx_GIVEREF(__pyx_v_ind_x1); + PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_ind_x1); + __Pyx_INCREF(__pyx_v_ind_y2); + __Pyx_GIVEREF(__pyx_v_ind_y2); + PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_ind_y2); + + /* "SimPEG/Utils/interputils_cython.pyx":75 + * + * inds += [( ind_x1, ind_y2), + * ( ind_x1, ind_y1), # <<<<<<<<<<<<<< + * ( ind_x2, ind_y1), + * ( ind_x2, ind_y2)] + */ + __pyx_t_11 = PyTuple_New(2); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 75; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_11); + __Pyx_INCREF(__pyx_v_ind_x1); + __Pyx_GIVEREF(__pyx_v_ind_x1); + PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_v_ind_x1); + __Pyx_INCREF(__pyx_v_ind_y1); + __Pyx_GIVEREF(__pyx_v_ind_y1); + PyTuple_SET_ITEM(__pyx_t_11, 1, __pyx_v_ind_y1); + + /* "SimPEG/Utils/interputils_cython.pyx":76 + * inds += [( ind_x1, ind_y2), + * ( ind_x1, ind_y1), + * ( ind_x2, ind_y1), # <<<<<<<<<<<<<< + * ( ind_x2, ind_y2)] + * + */ + __pyx_t_8 = PyTuple_New(2); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 76; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_8); + __Pyx_INCREF(__pyx_v_ind_x2); + __Pyx_GIVEREF(__pyx_v_ind_x2); + PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_v_ind_x2); + __Pyx_INCREF(__pyx_v_ind_y1); + __Pyx_GIVEREF(__pyx_v_ind_y1); + PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_v_ind_y1); + + /* "SimPEG/Utils/interputils_cython.pyx":77 + * ( ind_x1, ind_y1), + * ( ind_x2, ind_y1), + * ( ind_x2, ind_y2)] # <<<<<<<<<<<<<< + * + * vals += [wx1*wy2, wx1*wy1, wx2*wy1, wx2*wy2] + */ + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 77; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_v_ind_x2); + __Pyx_GIVEREF(__pyx_v_ind_x2); + PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_ind_x2); + __Pyx_INCREF(__pyx_v_ind_y2); + __Pyx_GIVEREF(__pyx_v_ind_y2); + PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_ind_y2); + + /* "SimPEG/Utils/interputils_cython.pyx":74 + * ind_y1, ind_y2, wy1, wy2 = _interp_point_1D(y, locs[i, 1]) + * + * inds += [( ind_x1, ind_y2), # <<<<<<<<<<<<<< + * ( ind_x1, ind_y1), + * ( ind_x2, ind_y1), + */ + __pyx_t_9 = PyList_New(4); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_9); + __Pyx_GIVEREF(__pyx_t_3); + PyList_SET_ITEM(__pyx_t_9, 0, __pyx_t_3); + __Pyx_GIVEREF(__pyx_t_11); + PyList_SET_ITEM(__pyx_t_9, 1, __pyx_t_11); + __Pyx_GIVEREF(__pyx_t_8); + PyList_SET_ITEM(__pyx_t_9, 2, __pyx_t_8); + __Pyx_GIVEREF(__pyx_t_1); + PyList_SET_ITEM(__pyx_t_9, 3, __pyx_t_1); + __pyx_t_3 = 0; + __pyx_t_11 = 0; + __pyx_t_8 = 0; + __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_v_inds, __pyx_t_9); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_DECREF_SET(__pyx_v_inds, ((PyObject*)__pyx_t_1)); + __pyx_t_1 = 0; + + /* "SimPEG/Utils/interputils_cython.pyx":79 + * ( ind_x2, ind_y2)] + * + * vals += [wx1*wy2, wx1*wy1, wx2*wy1, wx2*wy2] # <<<<<<<<<<<<<< + * + * return inds, vals + */ + __pyx_t_1 = PyNumber_Multiply(__pyx_v_wx1, __pyx_v_wy2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_9 = PyNumber_Multiply(__pyx_v_wx1, __pyx_v_wy1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_8 = PyNumber_Multiply(__pyx_v_wx2, __pyx_v_wy1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_11 = PyNumber_Multiply(__pyx_v_wx2, __pyx_v_wy2); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_11); + __pyx_t_3 = PyList_New(4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_1); + PyList_SET_ITEM(__pyx_t_3, 0, __pyx_t_1); + __Pyx_GIVEREF(__pyx_t_9); + PyList_SET_ITEM(__pyx_t_3, 1, __pyx_t_9); + __Pyx_GIVEREF(__pyx_t_8); + PyList_SET_ITEM(__pyx_t_3, 2, __pyx_t_8); + __Pyx_GIVEREF(__pyx_t_11); + PyList_SET_ITEM(__pyx_t_3, 3, __pyx_t_11); + __pyx_t_1 = 0; + __pyx_t_9 = 0; + __pyx_t_8 = 0; + __pyx_t_11 = 0; + __pyx_t_11 = PyNumber_InPlaceAdd(__pyx_v_vals, __pyx_t_3); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_11); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF_SET(__pyx_v_vals, ((PyObject*)__pyx_t_11)); + __pyx_t_11 = 0; + } + + /* "SimPEG/Utils/interputils_cython.pyx":81 + * vals += [wx1*wy2, wx1*wy1, wx2*wy1, wx2*wy2] + * + * return inds, vals # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_11 = PyTuple_New(2); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_11); + __Pyx_INCREF(__pyx_v_inds); + __Pyx_GIVEREF(__pyx_v_inds); + PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_v_inds); + __Pyx_INCREF(__pyx_v_vals); + __Pyx_GIVEREF(__pyx_v_vals); + PyTuple_SET_ITEM(__pyx_t_11, 1, __pyx_v_vals); + __pyx_r = __pyx_t_11; + __pyx_t_11 = 0; + goto __pyx_L0; + + /* "SimPEG/Utils/interputils_cython.pyx":60 + * + * + * def _interpmat2D(np.ndarray[np.float64_t, ndim=2] locs, # <<<<<<<<<<<<<< + * np.ndarray[np.float64_t, ndim=1] x, + * np.ndarray[np.float64_t, ndim=1] y): + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_XDECREF(__pyx_t_11); + __Pyx_XDECREF(__pyx_t_12); + { PyObject *__pyx_type, *__pyx_value, *__pyx_tb; + __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_locs.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_x.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_y.rcbuffer->pybuffer); + __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} + __Pyx_AddTraceback("SimPEG.Utils.interputils_cython._interpmat2D", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + goto __pyx_L2; + __pyx_L0:; + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_locs.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_x.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_y.rcbuffer->pybuffer); + __pyx_L2:; + __Pyx_XDECREF(__pyx_v_inds); + __Pyx_XDECREF(__pyx_v_vals); + __Pyx_XDECREF(__pyx_v_ind_x1); + __Pyx_XDECREF(__pyx_v_ind_x2); + __Pyx_XDECREF(__pyx_v_wx1); + __Pyx_XDECREF(__pyx_v_wx2); + __Pyx_XDECREF(__pyx_v_ind_y1); + __Pyx_XDECREF(__pyx_v_ind_y2); + __Pyx_XDECREF(__pyx_v_wy1); + __Pyx_XDECREF(__pyx_v_wy2); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "SimPEG/Utils/interputils_cython.pyx":84 + * + * + * def _interpmat3D(np.ndarray[np.float64_t, ndim=2] locs, # <<<<<<<<<<<<<< + * np.ndarray[np.float64_t, ndim=1] x, + * np.ndarray[np.float64_t, ndim=1] y, + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_6SimPEG_5Utils_18interputils_cython_7_interpmat3D(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static char __pyx_doc_6SimPEG_5Utils_18interputils_cython_6_interpmat3D[] = "Use interpmat."; +static PyMethodDef __pyx_mdef_6SimPEG_5Utils_18interputils_cython_7_interpmat3D = {"_interpmat3D", (PyCFunction)__pyx_pw_6SimPEG_5Utils_18interputils_cython_7_interpmat3D, METH_VARARGS|METH_KEYWORDS, __pyx_doc_6SimPEG_5Utils_18interputils_cython_6_interpmat3D}; +static PyObject *__pyx_pw_6SimPEG_5Utils_18interputils_cython_7_interpmat3D(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyArrayObject *__pyx_v_locs = 0; + PyArrayObject *__pyx_v_x = 0; + PyArrayObject *__pyx_v_y = 0; + PyArrayObject *__pyx_v_z = 0; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_interpmat3D (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_locs,&__pyx_n_s_x,&__pyx_n_s_y,&__pyx_n_s_z,0}; + PyObject* values[4] = {0,0,0,0}; + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); + case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_locs)) != 0)) kw_args--; + else goto __pyx_L5_argtuple_error; + case 1: + if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_x)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("_interpmat3D", 1, 4, 4, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + case 2: + if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_y)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("_interpmat3D", 1, 4, 4, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + case 3: + if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_z)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("_interpmat3D", 1, 4, 4, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_interpmat3D") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + } else if (PyTuple_GET_SIZE(__pyx_args) != 4) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + values[3] = PyTuple_GET_ITEM(__pyx_args, 3); + } + __pyx_v_locs = ((PyArrayObject *)values[0]); + __pyx_v_x = ((PyArrayObject *)values[1]); + __pyx_v_y = ((PyArrayObject *)values[2]); + __pyx_v_z = ((PyArrayObject *)values[3]); + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_interpmat3D", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_L3_error:; + __Pyx_AddTraceback("SimPEG.Utils.interputils_cython._interpmat3D", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_locs), __pyx_ptype_5numpy_ndarray, 1, "locs", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_x), __pyx_ptype_5numpy_ndarray, 1, "x", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 85; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_y), __pyx_ptype_5numpy_ndarray, 1, "y", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_z), __pyx_ptype_5numpy_ndarray, 1, "z", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 87; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_r = __pyx_pf_6SimPEG_5Utils_18interputils_cython_6_interpmat3D(__pyx_self, __pyx_v_locs, __pyx_v_x, __pyx_v_y, __pyx_v_z); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __pyx_r = NULL; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_6SimPEG_5Utils_18interputils_cython_6_interpmat3D(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_locs, PyArrayObject *__pyx_v_x, PyArrayObject *__pyx_v_y, PyArrayObject *__pyx_v_z) { + CYTHON_UNUSED int __pyx_v_nx; + CYTHON_UNUSED int __pyx_v_ny; + CYTHON_UNUSED int __pyx_v_nz; + int __pyx_v_npts; + PyObject *__pyx_v_inds = NULL; + PyObject *__pyx_v_vals = NULL; + int __pyx_v_i; + PyObject *__pyx_v_ind_x1 = NULL; + PyObject *__pyx_v_ind_x2 = NULL; + PyObject *__pyx_v_wx1 = NULL; + PyObject *__pyx_v_wx2 = NULL; + PyObject *__pyx_v_ind_y1 = NULL; + PyObject *__pyx_v_ind_y2 = NULL; + PyObject *__pyx_v_wy1 = NULL; + PyObject *__pyx_v_wy2 = NULL; + PyObject *__pyx_v_ind_z1 = NULL; + PyObject *__pyx_v_ind_z2 = NULL; + PyObject *__pyx_v_wz1 = NULL; + PyObject *__pyx_v_wz2 = NULL; + __Pyx_LocalBuf_ND __pyx_pybuffernd_locs; + __Pyx_Buffer __pyx_pybuffer_locs; + __Pyx_LocalBuf_ND __pyx_pybuffernd_x; + __Pyx_Buffer __pyx_pybuffer_x; + __Pyx_LocalBuf_ND __pyx_pybuffernd_y; + __Pyx_Buffer __pyx_pybuffer_y; + __Pyx_LocalBuf_ND __pyx_pybuffernd_z; + __Pyx_Buffer __pyx_pybuffer_z; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + int __pyx_t_5; + long __pyx_t_6; + int __pyx_t_7; + PyObject *__pyx_t_8 = NULL; + PyObject *__pyx_t_9 = NULL; + Py_ssize_t __pyx_t_10; + PyObject *__pyx_t_11 = NULL; + PyObject *__pyx_t_12 = NULL; + PyObject *(*__pyx_t_13)(PyObject *); + long __pyx_t_14; + int __pyx_t_15; + long __pyx_t_16; + int __pyx_t_17; + PyObject *__pyx_t_18 = NULL; + PyObject *__pyx_t_19 = NULL; + PyObject *__pyx_t_20 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_interpmat3D", 0); + __pyx_pybuffer_locs.pybuffer.buf = NULL; + __pyx_pybuffer_locs.refcount = 0; + __pyx_pybuffernd_locs.data = NULL; + __pyx_pybuffernd_locs.rcbuffer = &__pyx_pybuffer_locs; + __pyx_pybuffer_x.pybuffer.buf = NULL; + __pyx_pybuffer_x.refcount = 0; + __pyx_pybuffernd_x.data = NULL; + __pyx_pybuffernd_x.rcbuffer = &__pyx_pybuffer_x; + __pyx_pybuffer_y.pybuffer.buf = NULL; + __pyx_pybuffer_y.refcount = 0; + __pyx_pybuffernd_y.data = NULL; + __pyx_pybuffernd_y.rcbuffer = &__pyx_pybuffer_y; + __pyx_pybuffer_z.pybuffer.buf = NULL; + __pyx_pybuffer_z.refcount = 0; + __pyx_pybuffernd_z.data = NULL; + __pyx_pybuffernd_z.rcbuffer = &__pyx_pybuffer_z; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_locs.rcbuffer->pybuffer, (PyObject*)__pyx_v_locs, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_pybuffernd_locs.diminfo[0].strides = __pyx_pybuffernd_locs.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_locs.diminfo[0].shape = __pyx_pybuffernd_locs.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_locs.diminfo[1].strides = __pyx_pybuffernd_locs.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_locs.diminfo[1].shape = __pyx_pybuffernd_locs.rcbuffer->pybuffer.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_x.rcbuffer->pybuffer, (PyObject*)__pyx_v_x, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_pybuffernd_x.diminfo[0].strides = __pyx_pybuffernd_x.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_x.diminfo[0].shape = __pyx_pybuffernd_x.rcbuffer->pybuffer.shape[0]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_y.rcbuffer->pybuffer, (PyObject*)__pyx_v_y, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_pybuffernd_y.diminfo[0].strides = __pyx_pybuffernd_y.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_y.diminfo[0].shape = __pyx_pybuffernd_y.rcbuffer->pybuffer.shape[0]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_z.rcbuffer->pybuffer, (PyObject*)__pyx_v_z, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_pybuffernd_z.diminfo[0].strides = __pyx_pybuffernd_z.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_z.diminfo[0].shape = __pyx_pybuffernd_z.rcbuffer->pybuffer.shape[0]; + + /* "SimPEG/Utils/interputils_cython.pyx":89 + * np.ndarray[np.float64_t, ndim=1] z): + * """Use interpmat.""" + * cdef int nx = x.size # <<<<<<<<<<<<<< + * cdef int ny = y.size + * cdef int nz = z.size + */ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_x), __pyx_n_s_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 89; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 89; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_nx = __pyx_t_2; + + /* "SimPEG/Utils/interputils_cython.pyx":90 + * """Use interpmat.""" + * cdef int nx = x.size + * cdef int ny = y.size # <<<<<<<<<<<<<< + * cdef int nz = z.size + * cdef int npts = locs.shape[0] + */ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_y), __pyx_n_s_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_ny = __pyx_t_2; + + /* "SimPEG/Utils/interputils_cython.pyx":91 + * cdef int nx = x.size + * cdef int ny = y.size + * cdef int nz = z.size # <<<<<<<<<<<<<< + * cdef int npts = locs.shape[0] + * + */ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_z), __pyx_n_s_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_nz = __pyx_t_2; + + /* "SimPEG/Utils/interputils_cython.pyx":92 + * cdef int ny = y.size + * cdef int nz = z.size + * cdef int npts = locs.shape[0] # <<<<<<<<<<<<<< + * + * inds, vals = [], [] + */ + __pyx_v_npts = (__pyx_v_locs->dimensions[0]); + + /* "SimPEG/Utils/interputils_cython.pyx":94 + * cdef int npts = locs.shape[0] + * + * inds, vals = [], [] # <<<<<<<<<<<<<< + * + * for i in range(npts): + */ + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __pyx_v_inds = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + __pyx_v_vals = ((PyObject*)__pyx_t_3); + __pyx_t_3 = 0; + + /* "SimPEG/Utils/interputils_cython.pyx":96 + * inds, vals = [], [] + * + * for i in range(npts): # <<<<<<<<<<<<<< + * ind_x1, ind_x2, wx1, wx2 = _interp_point_1D(x, locs[i, 0]) + * ind_y1, ind_y2, wy1, wy2 = _interp_point_1D(y, locs[i, 1]) + */ + __pyx_t_2 = __pyx_v_npts; + for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_2; __pyx_t_4+=1) { + __pyx_v_i = __pyx_t_4; + + /* "SimPEG/Utils/interputils_cython.pyx":97 + * + * for i in range(npts): + * ind_x1, ind_x2, wx1, wx2 = _interp_point_1D(x, locs[i, 0]) # <<<<<<<<<<<<<< + * ind_y1, ind_y2, wy1, wy2 = _interp_point_1D(y, locs[i, 1]) + * ind_z1, ind_z2, wz1, wz2 = _interp_point_1D(z, locs[i, 2]) + */ + __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_interp_point_1D); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 97; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_5 = __pyx_v_i; + __pyx_t_6 = 0; + __pyx_t_7 = -1; + if (__pyx_t_5 < 0) { + __pyx_t_5 += __pyx_pybuffernd_locs.diminfo[0].shape; + if (unlikely(__pyx_t_5 < 0)) __pyx_t_7 = 0; + } else if (unlikely(__pyx_t_5 >= __pyx_pybuffernd_locs.diminfo[0].shape)) __pyx_t_7 = 0; + if (__pyx_t_6 < 0) { + __pyx_t_6 += __pyx_pybuffernd_locs.diminfo[1].shape; + if (unlikely(__pyx_t_6 < 0)) __pyx_t_7 = 1; + } else if (unlikely(__pyx_t_6 >= __pyx_pybuffernd_locs.diminfo[1].shape)) __pyx_t_7 = 1; + if (unlikely(__pyx_t_7 != -1)) { + __Pyx_RaiseBufferIndexError(__pyx_t_7); + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 97; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_t_8 = PyFloat_FromDouble((*__Pyx_BufPtrStrided2d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_locs.rcbuffer->pybuffer.buf, __pyx_t_5, __pyx_pybuffernd_locs.diminfo[0].strides, __pyx_t_6, __pyx_pybuffernd_locs.diminfo[1].strides))); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 97; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_9 = NULL; + __pyx_t_10 = 0; + if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_1))) { + __pyx_t_9 = PyMethod_GET_SELF(__pyx_t_1); + if (likely(__pyx_t_9)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1); + __Pyx_INCREF(__pyx_t_9); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_1, function); + __pyx_t_10 = 1; + } + } + __pyx_t_11 = PyTuple_New(2+__pyx_t_10); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 97; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_11); + if (__pyx_t_9) { + __Pyx_GIVEREF(__pyx_t_9); PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_9); __pyx_t_9 = NULL; + } + __Pyx_INCREF(((PyObject *)__pyx_v_x)); + __Pyx_GIVEREF(((PyObject *)__pyx_v_x)); + PyTuple_SET_ITEM(__pyx_t_11, 0+__pyx_t_10, ((PyObject *)__pyx_v_x)); + __Pyx_GIVEREF(__pyx_t_8); + PyTuple_SET_ITEM(__pyx_t_11, 1+__pyx_t_10, __pyx_t_8); + __pyx_t_8 = 0; + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_11, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 97; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if ((likely(PyTuple_CheckExact(__pyx_t_3))) || (PyList_CheckExact(__pyx_t_3))) { + PyObject* sequence = __pyx_t_3; + #if CYTHON_COMPILING_IN_CPYTHON + Py_ssize_t size = Py_SIZE(sequence); + #else + Py_ssize_t size = PySequence_Size(sequence); + #endif + if (unlikely(size != 4)) { + if (size > 4) __Pyx_RaiseTooManyValuesError(4); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 97; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + #if CYTHON_COMPILING_IN_CPYTHON + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_11 = PyTuple_GET_ITEM(sequence, 1); + __pyx_t_8 = PyTuple_GET_ITEM(sequence, 2); + __pyx_t_9 = PyTuple_GET_ITEM(sequence, 3); + } else { + __pyx_t_1 = PyList_GET_ITEM(sequence, 0); + __pyx_t_11 = PyList_GET_ITEM(sequence, 1); + __pyx_t_8 = PyList_GET_ITEM(sequence, 2); + __pyx_t_9 = PyList_GET_ITEM(sequence, 3); + } + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx_t_11); + __Pyx_INCREF(__pyx_t_8); + __Pyx_INCREF(__pyx_t_9); + #else + { + Py_ssize_t i; + PyObject** temps[4] = {&__pyx_t_1,&__pyx_t_11,&__pyx_t_8,&__pyx_t_9}; + for (i=0; i < 4; i++) { + PyObject* item = PySequence_ITEM(sequence, i); if (unlikely(!item)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 97; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(item); + *(temps[i]) = item; + } + } + #endif + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } else { + Py_ssize_t index = -1; + PyObject** temps[4] = {&__pyx_t_1,&__pyx_t_11,&__pyx_t_8,&__pyx_t_9}; + __pyx_t_12 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 97; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_12); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_13 = Py_TYPE(__pyx_t_12)->tp_iternext; + for (index=0; index < 4; index++) { + PyObject* item = __pyx_t_13(__pyx_t_12); if (unlikely(!item)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(item); + *(temps[index]) = item; + } + if (__Pyx_IternextUnpackEndCheck(__pyx_t_13(__pyx_t_12), 4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 97; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_t_13 = NULL; + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + goto __pyx_L6_unpacking_done; + __pyx_L5_unpacking_failed:; + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + __pyx_t_13 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 97; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_L6_unpacking_done:; + } + __Pyx_XDECREF_SET(__pyx_v_ind_x1, __pyx_t_1); + __pyx_t_1 = 0; + __Pyx_XDECREF_SET(__pyx_v_ind_x2, __pyx_t_11); + __pyx_t_11 = 0; + __Pyx_XDECREF_SET(__pyx_v_wx1, __pyx_t_8); + __pyx_t_8 = 0; + __Pyx_XDECREF_SET(__pyx_v_wx2, __pyx_t_9); + __pyx_t_9 = 0; + + /* "SimPEG/Utils/interputils_cython.pyx":98 + * for i in range(npts): + * ind_x1, ind_x2, wx1, wx2 = _interp_point_1D(x, locs[i, 0]) + * ind_y1, ind_y2, wy1, wy2 = _interp_point_1D(y, locs[i, 1]) # <<<<<<<<<<<<<< + * ind_z1, ind_z2, wz1, wz2 = _interp_point_1D(z, locs[i, 2]) + * + */ + __pyx_t_9 = __Pyx_GetModuleGlobalName(__pyx_n_s_interp_point_1D); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_7 = __pyx_v_i; + __pyx_t_14 = 1; + __pyx_t_15 = -1; + if (__pyx_t_7 < 0) { + __pyx_t_7 += __pyx_pybuffernd_locs.diminfo[0].shape; + if (unlikely(__pyx_t_7 < 0)) __pyx_t_15 = 0; + } else if (unlikely(__pyx_t_7 >= __pyx_pybuffernd_locs.diminfo[0].shape)) __pyx_t_15 = 0; + if (__pyx_t_14 < 0) { + __pyx_t_14 += __pyx_pybuffernd_locs.diminfo[1].shape; + if (unlikely(__pyx_t_14 < 0)) __pyx_t_15 = 1; + } else if (unlikely(__pyx_t_14 >= __pyx_pybuffernd_locs.diminfo[1].shape)) __pyx_t_15 = 1; + if (unlikely(__pyx_t_15 != -1)) { + __Pyx_RaiseBufferIndexError(__pyx_t_15); + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_t_8 = PyFloat_FromDouble((*__Pyx_BufPtrStrided2d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_locs.rcbuffer->pybuffer.buf, __pyx_t_7, __pyx_pybuffernd_locs.diminfo[0].strides, __pyx_t_14, __pyx_pybuffernd_locs.diminfo[1].strides))); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_11 = NULL; + __pyx_t_10 = 0; + if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_9))) { + __pyx_t_11 = PyMethod_GET_SELF(__pyx_t_9); + if (likely(__pyx_t_11)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_9); + __Pyx_INCREF(__pyx_t_11); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_9, function); + __pyx_t_10 = 1; + } + } + __pyx_t_1 = PyTuple_New(2+__pyx_t_10); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + if (__pyx_t_11) { + __Pyx_GIVEREF(__pyx_t_11); PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_11); __pyx_t_11 = NULL; + } + __Pyx_INCREF(((PyObject *)__pyx_v_y)); + __Pyx_GIVEREF(((PyObject *)__pyx_v_y)); + PyTuple_SET_ITEM(__pyx_t_1, 0+__pyx_t_10, ((PyObject *)__pyx_v_y)); + __Pyx_GIVEREF(__pyx_t_8); + PyTuple_SET_ITEM(__pyx_t_1, 1+__pyx_t_10, __pyx_t_8); + __pyx_t_8 = 0; + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_9, __pyx_t_1, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + if ((likely(PyTuple_CheckExact(__pyx_t_3))) || (PyList_CheckExact(__pyx_t_3))) { + PyObject* sequence = __pyx_t_3; + #if CYTHON_COMPILING_IN_CPYTHON + Py_ssize_t size = Py_SIZE(sequence); + #else + Py_ssize_t size = PySequence_Size(sequence); + #endif + if (unlikely(size != 4)) { + if (size > 4) __Pyx_RaiseTooManyValuesError(4); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + #if CYTHON_COMPILING_IN_CPYTHON + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_9 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 1); + __pyx_t_8 = PyTuple_GET_ITEM(sequence, 2); + __pyx_t_11 = PyTuple_GET_ITEM(sequence, 3); + } else { + __pyx_t_9 = PyList_GET_ITEM(sequence, 0); + __pyx_t_1 = PyList_GET_ITEM(sequence, 1); + __pyx_t_8 = PyList_GET_ITEM(sequence, 2); + __pyx_t_11 = PyList_GET_ITEM(sequence, 3); + } + __Pyx_INCREF(__pyx_t_9); + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx_t_8); + __Pyx_INCREF(__pyx_t_11); + #else + { + Py_ssize_t i; + PyObject** temps[4] = {&__pyx_t_9,&__pyx_t_1,&__pyx_t_8,&__pyx_t_11}; + for (i=0; i < 4; i++) { + PyObject* item = PySequence_ITEM(sequence, i); if (unlikely(!item)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(item); + *(temps[i]) = item; + } + } + #endif + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } else { + Py_ssize_t index = -1; + PyObject** temps[4] = {&__pyx_t_9,&__pyx_t_1,&__pyx_t_8,&__pyx_t_11}; + __pyx_t_12 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_12); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_13 = Py_TYPE(__pyx_t_12)->tp_iternext; + for (index=0; index < 4; index++) { + PyObject* item = __pyx_t_13(__pyx_t_12); if (unlikely(!item)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(item); + *(temps[index]) = item; + } + if (__Pyx_IternextUnpackEndCheck(__pyx_t_13(__pyx_t_12), 4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_t_13 = NULL; + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + goto __pyx_L8_unpacking_done; + __pyx_L7_unpacking_failed:; + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + __pyx_t_13 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_L8_unpacking_done:; + } + __Pyx_XDECREF_SET(__pyx_v_ind_y1, __pyx_t_9); + __pyx_t_9 = 0; + __Pyx_XDECREF_SET(__pyx_v_ind_y2, __pyx_t_1); + __pyx_t_1 = 0; + __Pyx_XDECREF_SET(__pyx_v_wy1, __pyx_t_8); + __pyx_t_8 = 0; + __Pyx_XDECREF_SET(__pyx_v_wy2, __pyx_t_11); + __pyx_t_11 = 0; + + /* "SimPEG/Utils/interputils_cython.pyx":99 + * ind_x1, ind_x2, wx1, wx2 = _interp_point_1D(x, locs[i, 0]) + * ind_y1, ind_y2, wy1, wy2 = _interp_point_1D(y, locs[i, 1]) + * ind_z1, ind_z2, wz1, wz2 = _interp_point_1D(z, locs[i, 2]) # <<<<<<<<<<<<<< + * + * inds += [( ind_x1, ind_y2, ind_z1), + */ + __pyx_t_11 = __Pyx_GetModuleGlobalName(__pyx_n_s_interp_point_1D); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_11); + __pyx_t_15 = __pyx_v_i; + __pyx_t_16 = 2; + __pyx_t_17 = -1; + if (__pyx_t_15 < 0) { + __pyx_t_15 += __pyx_pybuffernd_locs.diminfo[0].shape; + if (unlikely(__pyx_t_15 < 0)) __pyx_t_17 = 0; + } else if (unlikely(__pyx_t_15 >= __pyx_pybuffernd_locs.diminfo[0].shape)) __pyx_t_17 = 0; + if (__pyx_t_16 < 0) { + __pyx_t_16 += __pyx_pybuffernd_locs.diminfo[1].shape; + if (unlikely(__pyx_t_16 < 0)) __pyx_t_17 = 1; + } else if (unlikely(__pyx_t_16 >= __pyx_pybuffernd_locs.diminfo[1].shape)) __pyx_t_17 = 1; + if (unlikely(__pyx_t_17 != -1)) { + __Pyx_RaiseBufferIndexError(__pyx_t_17); + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_t_8 = PyFloat_FromDouble((*__Pyx_BufPtrStrided2d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_locs.rcbuffer->pybuffer.buf, __pyx_t_15, __pyx_pybuffernd_locs.diminfo[0].strides, __pyx_t_16, __pyx_pybuffernd_locs.diminfo[1].strides))); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_1 = NULL; + __pyx_t_10 = 0; + if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_11))) { + __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_11); + if (likely(__pyx_t_1)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_11); + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_11, function); + __pyx_t_10 = 1; + } + } + __pyx_t_9 = PyTuple_New(2+__pyx_t_10); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_9); + if (__pyx_t_1) { + __Pyx_GIVEREF(__pyx_t_1); PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_1); __pyx_t_1 = NULL; + } + __Pyx_INCREF(((PyObject *)__pyx_v_z)); + __Pyx_GIVEREF(((PyObject *)__pyx_v_z)); + PyTuple_SET_ITEM(__pyx_t_9, 0+__pyx_t_10, ((PyObject *)__pyx_v_z)); + __Pyx_GIVEREF(__pyx_t_8); + PyTuple_SET_ITEM(__pyx_t_9, 1+__pyx_t_10, __pyx_t_8); + __pyx_t_8 = 0; + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_11, __pyx_t_9, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + if ((likely(PyTuple_CheckExact(__pyx_t_3))) || (PyList_CheckExact(__pyx_t_3))) { + PyObject* sequence = __pyx_t_3; + #if CYTHON_COMPILING_IN_CPYTHON + Py_ssize_t size = Py_SIZE(sequence); + #else + Py_ssize_t size = PySequence_Size(sequence); + #endif + if (unlikely(size != 4)) { + if (size > 4) __Pyx_RaiseTooManyValuesError(4); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + #if CYTHON_COMPILING_IN_CPYTHON + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_11 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_9 = PyTuple_GET_ITEM(sequence, 1); + __pyx_t_8 = PyTuple_GET_ITEM(sequence, 2); + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 3); + } else { + __pyx_t_11 = PyList_GET_ITEM(sequence, 0); + __pyx_t_9 = PyList_GET_ITEM(sequence, 1); + __pyx_t_8 = PyList_GET_ITEM(sequence, 2); + __pyx_t_1 = PyList_GET_ITEM(sequence, 3); + } + __Pyx_INCREF(__pyx_t_11); + __Pyx_INCREF(__pyx_t_9); + __Pyx_INCREF(__pyx_t_8); + __Pyx_INCREF(__pyx_t_1); + #else + { + Py_ssize_t i; + PyObject** temps[4] = {&__pyx_t_11,&__pyx_t_9,&__pyx_t_8,&__pyx_t_1}; + for (i=0; i < 4; i++) { + PyObject* item = PySequence_ITEM(sequence, i); if (unlikely(!item)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(item); + *(temps[i]) = item; + } + } + #endif + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } else { + Py_ssize_t index = -1; + PyObject** temps[4] = {&__pyx_t_11,&__pyx_t_9,&__pyx_t_8,&__pyx_t_1}; + __pyx_t_12 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_12); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_13 = Py_TYPE(__pyx_t_12)->tp_iternext; + for (index=0; index < 4; index++) { + PyObject* item = __pyx_t_13(__pyx_t_12); if (unlikely(!item)) goto __pyx_L9_unpacking_failed; + __Pyx_GOTREF(item); + *(temps[index]) = item; + } + if (__Pyx_IternextUnpackEndCheck(__pyx_t_13(__pyx_t_12), 4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_t_13 = NULL; + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + goto __pyx_L10_unpacking_done; + __pyx_L9_unpacking_failed:; + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + __pyx_t_13 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_L10_unpacking_done:; + } + __Pyx_XDECREF_SET(__pyx_v_ind_z1, __pyx_t_11); + __pyx_t_11 = 0; + __Pyx_XDECREF_SET(__pyx_v_ind_z2, __pyx_t_9); + __pyx_t_9 = 0; + __Pyx_XDECREF_SET(__pyx_v_wz1, __pyx_t_8); + __pyx_t_8 = 0; + __Pyx_XDECREF_SET(__pyx_v_wz2, __pyx_t_1); + __pyx_t_1 = 0; + + /* "SimPEG/Utils/interputils_cython.pyx":101 + * ind_z1, ind_z2, wz1, wz2 = _interp_point_1D(z, locs[i, 2]) + * + * inds += [( ind_x1, ind_y2, ind_z1), # <<<<<<<<<<<<<< + * ( ind_x1, ind_y1, ind_z1), + * ( ind_x2, ind_y1, ind_z1), + */ + __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_v_ind_x1); + __Pyx_GIVEREF(__pyx_v_ind_x1); + PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_ind_x1); + __Pyx_INCREF(__pyx_v_ind_y2); + __Pyx_GIVEREF(__pyx_v_ind_y2); + PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_ind_y2); + __Pyx_INCREF(__pyx_v_ind_z1); + __Pyx_GIVEREF(__pyx_v_ind_z1); + PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_v_ind_z1); + + /* "SimPEG/Utils/interputils_cython.pyx":102 + * + * inds += [( ind_x1, ind_y2, ind_z1), + * ( ind_x1, ind_y1, ind_z1), # <<<<<<<<<<<<<< + * ( ind_x2, ind_y1, ind_z1), + * ( ind_x2, ind_y2, ind_z1), + */ + __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_v_ind_x1); + __Pyx_GIVEREF(__pyx_v_ind_x1); + PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_ind_x1); + __Pyx_INCREF(__pyx_v_ind_y1); + __Pyx_GIVEREF(__pyx_v_ind_y1); + PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_ind_y1); + __Pyx_INCREF(__pyx_v_ind_z1); + __Pyx_GIVEREF(__pyx_v_ind_z1); + PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_v_ind_z1); + + /* "SimPEG/Utils/interputils_cython.pyx":103 + * inds += [( ind_x1, ind_y2, ind_z1), + * ( ind_x1, ind_y1, ind_z1), + * ( ind_x2, ind_y1, ind_z1), # <<<<<<<<<<<<<< + * ( ind_x2, ind_y2, ind_z1), + * ( ind_x1, ind_y1, ind_z2), + */ + __pyx_t_8 = PyTuple_New(3); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 103; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_8); + __Pyx_INCREF(__pyx_v_ind_x2); + __Pyx_GIVEREF(__pyx_v_ind_x2); + PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_v_ind_x2); + __Pyx_INCREF(__pyx_v_ind_y1); + __Pyx_GIVEREF(__pyx_v_ind_y1); + PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_v_ind_y1); + __Pyx_INCREF(__pyx_v_ind_z1); + __Pyx_GIVEREF(__pyx_v_ind_z1); + PyTuple_SET_ITEM(__pyx_t_8, 2, __pyx_v_ind_z1); + + /* "SimPEG/Utils/interputils_cython.pyx":104 + * ( ind_x1, ind_y1, ind_z1), + * ( ind_x2, ind_y1, ind_z1), + * ( ind_x2, ind_y2, ind_z1), # <<<<<<<<<<<<<< + * ( ind_x1, ind_y1, ind_z2), + * ( ind_x1, ind_y2, ind_z2), + */ + __pyx_t_9 = PyTuple_New(3); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_9); + __Pyx_INCREF(__pyx_v_ind_x2); + __Pyx_GIVEREF(__pyx_v_ind_x2); + PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_v_ind_x2); + __Pyx_INCREF(__pyx_v_ind_y2); + __Pyx_GIVEREF(__pyx_v_ind_y2); + PyTuple_SET_ITEM(__pyx_t_9, 1, __pyx_v_ind_y2); + __Pyx_INCREF(__pyx_v_ind_z1); + __Pyx_GIVEREF(__pyx_v_ind_z1); + PyTuple_SET_ITEM(__pyx_t_9, 2, __pyx_v_ind_z1); + + /* "SimPEG/Utils/interputils_cython.pyx":105 + * ( ind_x2, ind_y1, ind_z1), + * ( ind_x2, ind_y2, ind_z1), + * ( ind_x1, ind_y1, ind_z2), # <<<<<<<<<<<<<< + * ( ind_x1, ind_y2, ind_z2), + * ( ind_x2, ind_y1, ind_z2), + */ + __pyx_t_11 = PyTuple_New(3); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 105; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_11); + __Pyx_INCREF(__pyx_v_ind_x1); + __Pyx_GIVEREF(__pyx_v_ind_x1); + PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_v_ind_x1); + __Pyx_INCREF(__pyx_v_ind_y1); + __Pyx_GIVEREF(__pyx_v_ind_y1); + PyTuple_SET_ITEM(__pyx_t_11, 1, __pyx_v_ind_y1); + __Pyx_INCREF(__pyx_v_ind_z2); + __Pyx_GIVEREF(__pyx_v_ind_z2); + PyTuple_SET_ITEM(__pyx_t_11, 2, __pyx_v_ind_z2); + + /* "SimPEG/Utils/interputils_cython.pyx":106 + * ( ind_x2, ind_y2, ind_z1), + * ( ind_x1, ind_y1, ind_z2), + * ( ind_x1, ind_y2, ind_z2), # <<<<<<<<<<<<<< + * ( ind_x2, ind_y1, ind_z2), + * ( ind_x2, ind_y2, ind_z2)] + */ + __pyx_t_12 = PyTuple_New(3); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_12); + __Pyx_INCREF(__pyx_v_ind_x1); + __Pyx_GIVEREF(__pyx_v_ind_x1); + PyTuple_SET_ITEM(__pyx_t_12, 0, __pyx_v_ind_x1); + __Pyx_INCREF(__pyx_v_ind_y2); + __Pyx_GIVEREF(__pyx_v_ind_y2); + PyTuple_SET_ITEM(__pyx_t_12, 1, __pyx_v_ind_y2); + __Pyx_INCREF(__pyx_v_ind_z2); + __Pyx_GIVEREF(__pyx_v_ind_z2); + PyTuple_SET_ITEM(__pyx_t_12, 2, __pyx_v_ind_z2); + + /* "SimPEG/Utils/interputils_cython.pyx":107 + * ( ind_x1, ind_y1, ind_z2), + * ( ind_x1, ind_y2, ind_z2), + * ( ind_x2, ind_y1, ind_z2), # <<<<<<<<<<<<<< + * ( ind_x2, ind_y2, ind_z2)] + * + */ + __pyx_t_18 = PyTuple_New(3); if (unlikely(!__pyx_t_18)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_18); + __Pyx_INCREF(__pyx_v_ind_x2); + __Pyx_GIVEREF(__pyx_v_ind_x2); + PyTuple_SET_ITEM(__pyx_t_18, 0, __pyx_v_ind_x2); + __Pyx_INCREF(__pyx_v_ind_y1); + __Pyx_GIVEREF(__pyx_v_ind_y1); + PyTuple_SET_ITEM(__pyx_t_18, 1, __pyx_v_ind_y1); + __Pyx_INCREF(__pyx_v_ind_z2); + __Pyx_GIVEREF(__pyx_v_ind_z2); + PyTuple_SET_ITEM(__pyx_t_18, 2, __pyx_v_ind_z2); + + /* "SimPEG/Utils/interputils_cython.pyx":108 + * ( ind_x1, ind_y2, ind_z2), + * ( ind_x2, ind_y1, ind_z2), + * ( ind_x2, ind_y2, ind_z2)] # <<<<<<<<<<<<<< + * + * vals += [wx1*wy2*wz1, + */ + __pyx_t_19 = PyTuple_New(3); if (unlikely(!__pyx_t_19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_19); + __Pyx_INCREF(__pyx_v_ind_x2); + __Pyx_GIVEREF(__pyx_v_ind_x2); + PyTuple_SET_ITEM(__pyx_t_19, 0, __pyx_v_ind_x2); + __Pyx_INCREF(__pyx_v_ind_y2); + __Pyx_GIVEREF(__pyx_v_ind_y2); + PyTuple_SET_ITEM(__pyx_t_19, 1, __pyx_v_ind_y2); + __Pyx_INCREF(__pyx_v_ind_z2); + __Pyx_GIVEREF(__pyx_v_ind_z2); + PyTuple_SET_ITEM(__pyx_t_19, 2, __pyx_v_ind_z2); + + /* "SimPEG/Utils/interputils_cython.pyx":101 + * ind_z1, ind_z2, wz1, wz2 = _interp_point_1D(z, locs[i, 2]) + * + * inds += [( ind_x1, ind_y2, ind_z1), # <<<<<<<<<<<<<< + * ( ind_x1, ind_y1, ind_z1), + * ( ind_x2, ind_y1, ind_z1), + */ + __pyx_t_20 = PyList_New(8); if (unlikely(!__pyx_t_20)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_20); + __Pyx_GIVEREF(__pyx_t_3); + PyList_SET_ITEM(__pyx_t_20, 0, __pyx_t_3); + __Pyx_GIVEREF(__pyx_t_1); + PyList_SET_ITEM(__pyx_t_20, 1, __pyx_t_1); + __Pyx_GIVEREF(__pyx_t_8); + PyList_SET_ITEM(__pyx_t_20, 2, __pyx_t_8); + __Pyx_GIVEREF(__pyx_t_9); + PyList_SET_ITEM(__pyx_t_20, 3, __pyx_t_9); + __Pyx_GIVEREF(__pyx_t_11); + PyList_SET_ITEM(__pyx_t_20, 4, __pyx_t_11); + __Pyx_GIVEREF(__pyx_t_12); + PyList_SET_ITEM(__pyx_t_20, 5, __pyx_t_12); + __Pyx_GIVEREF(__pyx_t_18); + PyList_SET_ITEM(__pyx_t_20, 6, __pyx_t_18); + __Pyx_GIVEREF(__pyx_t_19); + PyList_SET_ITEM(__pyx_t_20, 7, __pyx_t_19); + __pyx_t_3 = 0; + __pyx_t_1 = 0; + __pyx_t_8 = 0; + __pyx_t_9 = 0; + __pyx_t_11 = 0; + __pyx_t_12 = 0; + __pyx_t_18 = 0; + __pyx_t_19 = 0; + __pyx_t_19 = PyNumber_InPlaceAdd(__pyx_v_inds, __pyx_t_20); if (unlikely(!__pyx_t_19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_19); + __Pyx_DECREF(__pyx_t_20); __pyx_t_20 = 0; + __Pyx_DECREF_SET(__pyx_v_inds, ((PyObject*)__pyx_t_19)); + __pyx_t_19 = 0; + + /* "SimPEG/Utils/interputils_cython.pyx":110 + * ( ind_x2, ind_y2, ind_z2)] + * + * vals += [wx1*wy2*wz1, # <<<<<<<<<<<<<< + * wx1*wy1*wz1, + * wx2*wy1*wz1, + */ + __pyx_t_19 = PyNumber_Multiply(__pyx_v_wx1, __pyx_v_wy2); if (unlikely(!__pyx_t_19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_19); + __pyx_t_20 = PyNumber_Multiply(__pyx_t_19, __pyx_v_wz1); if (unlikely(!__pyx_t_20)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_20); + __Pyx_DECREF(__pyx_t_19); __pyx_t_19 = 0; + + /* "SimPEG/Utils/interputils_cython.pyx":111 + * + * vals += [wx1*wy2*wz1, + * wx1*wy1*wz1, # <<<<<<<<<<<<<< + * wx2*wy1*wz1, + * wx2*wy2*wz1, + */ + __pyx_t_19 = PyNumber_Multiply(__pyx_v_wx1, __pyx_v_wy1); if (unlikely(!__pyx_t_19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_19); + __pyx_t_18 = PyNumber_Multiply(__pyx_t_19, __pyx_v_wz1); if (unlikely(!__pyx_t_18)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_18); + __Pyx_DECREF(__pyx_t_19); __pyx_t_19 = 0; + + /* "SimPEG/Utils/interputils_cython.pyx":112 + * vals += [wx1*wy2*wz1, + * wx1*wy1*wz1, + * wx2*wy1*wz1, # <<<<<<<<<<<<<< + * wx2*wy2*wz1, + * wx1*wy1*wz2, + */ + __pyx_t_19 = PyNumber_Multiply(__pyx_v_wx2, __pyx_v_wy1); if (unlikely(!__pyx_t_19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_19); + __pyx_t_12 = PyNumber_Multiply(__pyx_t_19, __pyx_v_wz1); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_12); + __Pyx_DECREF(__pyx_t_19); __pyx_t_19 = 0; + + /* "SimPEG/Utils/interputils_cython.pyx":113 + * wx1*wy1*wz1, + * wx2*wy1*wz1, + * wx2*wy2*wz1, # <<<<<<<<<<<<<< + * wx1*wy1*wz2, + * wx1*wy2*wz2, + */ + __pyx_t_19 = PyNumber_Multiply(__pyx_v_wx2, __pyx_v_wy2); if (unlikely(!__pyx_t_19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_19); + __pyx_t_11 = PyNumber_Multiply(__pyx_t_19, __pyx_v_wz1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_11); + __Pyx_DECREF(__pyx_t_19); __pyx_t_19 = 0; + + /* "SimPEG/Utils/interputils_cython.pyx":114 + * wx2*wy1*wz1, + * wx2*wy2*wz1, + * wx1*wy1*wz2, # <<<<<<<<<<<<<< + * wx1*wy2*wz2, + * wx2*wy1*wz2, + */ + __pyx_t_19 = PyNumber_Multiply(__pyx_v_wx1, __pyx_v_wy1); if (unlikely(!__pyx_t_19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_19); + __pyx_t_9 = PyNumber_Multiply(__pyx_t_19, __pyx_v_wz2); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_19); __pyx_t_19 = 0; + + /* "SimPEG/Utils/interputils_cython.pyx":115 + * wx2*wy2*wz1, + * wx1*wy1*wz2, + * wx1*wy2*wz2, # <<<<<<<<<<<<<< + * wx2*wy1*wz2, + * wx2*wy2*wz2] + */ + __pyx_t_19 = PyNumber_Multiply(__pyx_v_wx1, __pyx_v_wy2); if (unlikely(!__pyx_t_19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_19); + __pyx_t_8 = PyNumber_Multiply(__pyx_t_19, __pyx_v_wz2); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_19); __pyx_t_19 = 0; + + /* "SimPEG/Utils/interputils_cython.pyx":116 + * wx1*wy1*wz2, + * wx1*wy2*wz2, + * wx2*wy1*wz2, # <<<<<<<<<<<<<< + * wx2*wy2*wz2] + * + */ + __pyx_t_19 = PyNumber_Multiply(__pyx_v_wx2, __pyx_v_wy1); if (unlikely(!__pyx_t_19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_19); + __pyx_t_1 = PyNumber_Multiply(__pyx_t_19, __pyx_v_wz2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_19); __pyx_t_19 = 0; + + /* "SimPEG/Utils/interputils_cython.pyx":117 + * wx1*wy2*wz2, + * wx2*wy1*wz2, + * wx2*wy2*wz2] # <<<<<<<<<<<<<< + * + * return inds, vals + */ + __pyx_t_19 = PyNumber_Multiply(__pyx_v_wx2, __pyx_v_wy2); if (unlikely(!__pyx_t_19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_19); + __pyx_t_3 = PyNumber_Multiply(__pyx_t_19, __pyx_v_wz2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_19); __pyx_t_19 = 0; + + /* "SimPEG/Utils/interputils_cython.pyx":110 + * ( ind_x2, ind_y2, ind_z2)] + * + * vals += [wx1*wy2*wz1, # <<<<<<<<<<<<<< + * wx1*wy1*wz1, + * wx2*wy1*wz1, + */ + __pyx_t_19 = PyList_New(8); if (unlikely(!__pyx_t_19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_19); + __Pyx_GIVEREF(__pyx_t_20); + PyList_SET_ITEM(__pyx_t_19, 0, __pyx_t_20); + __Pyx_GIVEREF(__pyx_t_18); + PyList_SET_ITEM(__pyx_t_19, 1, __pyx_t_18); + __Pyx_GIVEREF(__pyx_t_12); + PyList_SET_ITEM(__pyx_t_19, 2, __pyx_t_12); + __Pyx_GIVEREF(__pyx_t_11); + PyList_SET_ITEM(__pyx_t_19, 3, __pyx_t_11); + __Pyx_GIVEREF(__pyx_t_9); + PyList_SET_ITEM(__pyx_t_19, 4, __pyx_t_9); + __Pyx_GIVEREF(__pyx_t_8); + PyList_SET_ITEM(__pyx_t_19, 5, __pyx_t_8); + __Pyx_GIVEREF(__pyx_t_1); + PyList_SET_ITEM(__pyx_t_19, 6, __pyx_t_1); + __Pyx_GIVEREF(__pyx_t_3); + PyList_SET_ITEM(__pyx_t_19, 7, __pyx_t_3); + __pyx_t_20 = 0; + __pyx_t_18 = 0; + __pyx_t_12 = 0; + __pyx_t_11 = 0; + __pyx_t_9 = 0; + __pyx_t_8 = 0; + __pyx_t_1 = 0; + __pyx_t_3 = 0; + __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_v_vals, __pyx_t_19); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_19); __pyx_t_19 = 0; + __Pyx_DECREF_SET(__pyx_v_vals, ((PyObject*)__pyx_t_3)); + __pyx_t_3 = 0; + } + + /* "SimPEG/Utils/interputils_cython.pyx":119 + * wx2*wy2*wz2] + * + * return inds, vals # <<<<<<<<<<<<<< + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_v_inds); + __Pyx_GIVEREF(__pyx_v_inds); + PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_inds); + __Pyx_INCREF(__pyx_v_vals); + __Pyx_GIVEREF(__pyx_v_vals); + PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_vals); + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + + /* "SimPEG/Utils/interputils_cython.pyx":84 + * + * + * def _interpmat3D(np.ndarray[np.float64_t, ndim=2] locs, # <<<<<<<<<<<<<< + * np.ndarray[np.float64_t, ndim=1] x, + * np.ndarray[np.float64_t, ndim=1] y, + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_XDECREF(__pyx_t_11); + __Pyx_XDECREF(__pyx_t_12); + __Pyx_XDECREF(__pyx_t_18); + __Pyx_XDECREF(__pyx_t_19); + __Pyx_XDECREF(__pyx_t_20); + { PyObject *__pyx_type, *__pyx_value, *__pyx_tb; + __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_locs.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_x.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_y.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_z.rcbuffer->pybuffer); + __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} + __Pyx_AddTraceback("SimPEG.Utils.interputils_cython._interpmat3D", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + goto __pyx_L2; + __pyx_L0:; + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_locs.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_x.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_y.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_z.rcbuffer->pybuffer); + __pyx_L2:; + __Pyx_XDECREF(__pyx_v_inds); + __Pyx_XDECREF(__pyx_v_vals); + __Pyx_XDECREF(__pyx_v_ind_x1); + __Pyx_XDECREF(__pyx_v_ind_x2); + __Pyx_XDECREF(__pyx_v_wx1); + __Pyx_XDECREF(__pyx_v_wx2); + __Pyx_XDECREF(__pyx_v_ind_y1); + __Pyx_XDECREF(__pyx_v_ind_y2); + __Pyx_XDECREF(__pyx_v_wy1); + __Pyx_XDECREF(__pyx_v_wy2); + __Pyx_XDECREF(__pyx_v_ind_z1); + __Pyx_XDECREF(__pyx_v_ind_z2); + __Pyx_XDECREF(__pyx_v_wz1); + __Pyx_XDECREF(__pyx_v_wz2); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":197 + * # experimental exception made for __getbuffer__ and __releasebuffer__ + * # -- the details of this may change. + * def __getbuffer__(ndarray self, Py_buffer* info, int flags): # <<<<<<<<<<<<<< + * # This implementation of getbuffer is geared towards Cython + * # requirements, and does not yet fullfill the PEP. + */ + +/* Python wrapper */ +static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/ +static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) { + int __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0); + __pyx_r = __pyx_pf_5numpy_7ndarray___getbuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) { + int __pyx_v_copy_shape; + int __pyx_v_i; + int __pyx_v_ndim; + int __pyx_v_endian_detector; + int __pyx_v_little_endian; + int __pyx_v_t; + char *__pyx_v_f; + PyArray_Descr *__pyx_v_descr = 0; + int __pyx_v_offset; + int __pyx_v_hasfields; + int __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + int __pyx_t_5; + PyObject *__pyx_t_6 = NULL; + char *__pyx_t_7; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__getbuffer__", 0); + if (__pyx_v_info != NULL) { + __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None); + __Pyx_GIVEREF(__pyx_v_info->obj); + } + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":203 + * # of flags + * + * if info == NULL: return # <<<<<<<<<<<<<< + * + * cdef int copy_shape, i, ndim + */ + __pyx_t_1 = ((__pyx_v_info == NULL) != 0); + if (__pyx_t_1) { + __pyx_r = 0; + goto __pyx_L0; + } + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":206 + * + * cdef int copy_shape, i, ndim + * cdef int endian_detector = 1 # <<<<<<<<<<<<<< + * cdef bint little_endian = ((&endian_detector)[0] != 0) + * + */ + __pyx_v_endian_detector = 1; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":207 + * cdef int copy_shape, i, ndim + * cdef int endian_detector = 1 + * cdef bint little_endian = ((&endian_detector)[0] != 0) # <<<<<<<<<<<<<< + * + * ndim = PyArray_NDIM(self) + */ + __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0); + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":209 + * cdef bint little_endian = ((&endian_detector)[0] != 0) + * + * ndim = PyArray_NDIM(self) # <<<<<<<<<<<<<< + * + * if sizeof(npy_intp) != sizeof(Py_ssize_t): + */ + __pyx_v_ndim = PyArray_NDIM(__pyx_v_self); + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":211 + * ndim = PyArray_NDIM(self) + * + * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<< + * copy_shape = 1 + * else: + */ + __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0); + if (__pyx_t_1) { + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":212 + * + * if sizeof(npy_intp) != sizeof(Py_ssize_t): + * copy_shape = 1 # <<<<<<<<<<<<<< + * else: + * copy_shape = 0 + */ + __pyx_v_copy_shape = 1; + goto __pyx_L4; + } + /*else*/ { + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":214 + * copy_shape = 1 + * else: + * copy_shape = 0 # <<<<<<<<<<<<<< + * + * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) + */ + __pyx_v_copy_shape = 0; + } + __pyx_L4:; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":216 + * copy_shape = 0 + * + * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) # <<<<<<<<<<<<<< + * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): + * raise ValueError(u"ndarray is not C contiguous") + */ + __pyx_t_2 = (((__pyx_v_flags & PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS) != 0); + if (__pyx_t_2) { + } else { + __pyx_t_1 = __pyx_t_2; + goto __pyx_L6_bool_binop_done; + } + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":217 + * + * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) + * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): # <<<<<<<<<<<<<< + * raise ValueError(u"ndarray is not C contiguous") + * + */ + __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_C_CONTIGUOUS) != 0)) != 0); + __pyx_t_1 = __pyx_t_2; + __pyx_L6_bool_binop_done:; + if (__pyx_t_1) { + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":218 + * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) + * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): + * raise ValueError(u"ndarray is not C contiguous") # <<<<<<<<<<<<<< + * + * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) + */ + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple_, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + {__pyx_filename = __pyx_f[1]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":220 + * raise ValueError(u"ndarray is not C contiguous") + * + * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) # <<<<<<<<<<<<<< + * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): + * raise ValueError(u"ndarray is not Fortran contiguous") + */ + __pyx_t_2 = (((__pyx_v_flags & PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS) != 0); + if (__pyx_t_2) { + } else { + __pyx_t_1 = __pyx_t_2; + goto __pyx_L9_bool_binop_done; + } + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":221 + * + * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) + * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): # <<<<<<<<<<<<<< + * raise ValueError(u"ndarray is not Fortran contiguous") + * + */ + __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_F_CONTIGUOUS) != 0)) != 0); + __pyx_t_1 = __pyx_t_2; + __pyx_L9_bool_binop_done:; + if (__pyx_t_1) { + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":222 + * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) + * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): + * raise ValueError(u"ndarray is not Fortran contiguous") # <<<<<<<<<<<<<< + * + * info.buf = PyArray_DATA(self) + */ + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__2, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + {__pyx_filename = __pyx_f[1]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":224 + * raise ValueError(u"ndarray is not Fortran contiguous") + * + * info.buf = PyArray_DATA(self) # <<<<<<<<<<<<<< + * info.ndim = ndim + * if copy_shape: + */ + __pyx_v_info->buf = PyArray_DATA(__pyx_v_self); + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":225 + * + * info.buf = PyArray_DATA(self) + * info.ndim = ndim # <<<<<<<<<<<<<< + * if copy_shape: + * # Allocate new buffer for strides and shape info. + */ + __pyx_v_info->ndim = __pyx_v_ndim; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":226 + * info.buf = PyArray_DATA(self) + * info.ndim = ndim + * if copy_shape: # <<<<<<<<<<<<<< + * # Allocate new buffer for strides and shape info. + * # This is allocated as one block, strides first. + */ + __pyx_t_1 = (__pyx_v_copy_shape != 0); + if (__pyx_t_1) { + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":229 + * # Allocate new buffer for strides and shape info. + * # This is allocated as one block, strides first. + * info.strides = stdlib.malloc(sizeof(Py_ssize_t) * ndim * 2) # <<<<<<<<<<<<<< + * info.shape = info.strides + ndim + * for i in range(ndim): + */ + __pyx_v_info->strides = ((Py_ssize_t *)malloc((((sizeof(Py_ssize_t)) * ((size_t)__pyx_v_ndim)) * 2))); + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":230 + * # This is allocated as one block, strides first. + * info.strides = stdlib.malloc(sizeof(Py_ssize_t) * ndim * 2) + * info.shape = info.strides + ndim # <<<<<<<<<<<<<< + * for i in range(ndim): + * info.strides[i] = PyArray_STRIDES(self)[i] + */ + __pyx_v_info->shape = (__pyx_v_info->strides + __pyx_v_ndim); + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":231 + * info.strides = stdlib.malloc(sizeof(Py_ssize_t) * ndim * 2) + * info.shape = info.strides + ndim + * for i in range(ndim): # <<<<<<<<<<<<<< + * info.strides[i] = PyArray_STRIDES(self)[i] + * info.shape[i] = PyArray_DIMS(self)[i] + */ + __pyx_t_4 = __pyx_v_ndim; + for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) { + __pyx_v_i = __pyx_t_5; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":232 + * info.shape = info.strides + ndim + * for i in range(ndim): + * info.strides[i] = PyArray_STRIDES(self)[i] # <<<<<<<<<<<<<< + * info.shape[i] = PyArray_DIMS(self)[i] + * else: + */ + (__pyx_v_info->strides[__pyx_v_i]) = (PyArray_STRIDES(__pyx_v_self)[__pyx_v_i]); + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":233 + * for i in range(ndim): + * info.strides[i] = PyArray_STRIDES(self)[i] + * info.shape[i] = PyArray_DIMS(self)[i] # <<<<<<<<<<<<<< + * else: + * info.strides = PyArray_STRIDES(self) + */ + (__pyx_v_info->shape[__pyx_v_i]) = (PyArray_DIMS(__pyx_v_self)[__pyx_v_i]); + } + goto __pyx_L11; + } + /*else*/ { + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":235 + * info.shape[i] = PyArray_DIMS(self)[i] + * else: + * info.strides = PyArray_STRIDES(self) # <<<<<<<<<<<<<< + * info.shape = PyArray_DIMS(self) + * info.suboffsets = NULL + */ + __pyx_v_info->strides = ((Py_ssize_t *)PyArray_STRIDES(__pyx_v_self)); + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":236 + * else: + * info.strides = PyArray_STRIDES(self) + * info.shape = PyArray_DIMS(self) # <<<<<<<<<<<<<< + * info.suboffsets = NULL + * info.itemsize = PyArray_ITEMSIZE(self) + */ + __pyx_v_info->shape = ((Py_ssize_t *)PyArray_DIMS(__pyx_v_self)); + } + __pyx_L11:; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":237 + * info.strides = PyArray_STRIDES(self) + * info.shape = PyArray_DIMS(self) + * info.suboffsets = NULL # <<<<<<<<<<<<<< + * info.itemsize = PyArray_ITEMSIZE(self) + * info.readonly = not PyArray_ISWRITEABLE(self) + */ + __pyx_v_info->suboffsets = NULL; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":238 + * info.shape = PyArray_DIMS(self) + * info.suboffsets = NULL + * info.itemsize = PyArray_ITEMSIZE(self) # <<<<<<<<<<<<<< + * info.readonly = not PyArray_ISWRITEABLE(self) + * + */ + __pyx_v_info->itemsize = PyArray_ITEMSIZE(__pyx_v_self); + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":239 + * info.suboffsets = NULL + * info.itemsize = PyArray_ITEMSIZE(self) + * info.readonly = not PyArray_ISWRITEABLE(self) # <<<<<<<<<<<<<< + * + * cdef int t + */ + __pyx_v_info->readonly = (!(PyArray_ISWRITEABLE(__pyx_v_self) != 0)); + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":242 + * + * cdef int t + * cdef char* f = NULL # <<<<<<<<<<<<<< + * cdef dtype descr = self.descr + * cdef list stack + */ + __pyx_v_f = NULL; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":243 + * cdef int t + * cdef char* f = NULL + * cdef dtype descr = self.descr # <<<<<<<<<<<<<< + * cdef list stack + * cdef int offset + */ + __pyx_t_3 = ((PyObject *)__pyx_v_self->descr); + __Pyx_INCREF(__pyx_t_3); + __pyx_v_descr = ((PyArray_Descr *)__pyx_t_3); + __pyx_t_3 = 0; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":247 + * cdef int offset + * + * cdef bint hasfields = PyDataType_HASFIELDS(descr) # <<<<<<<<<<<<<< + * + * if not hasfields and not copy_shape: + */ + __pyx_v_hasfields = PyDataType_HASFIELDS(__pyx_v_descr); + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":249 + * cdef bint hasfields = PyDataType_HASFIELDS(descr) + * + * if not hasfields and not copy_shape: # <<<<<<<<<<<<<< + * # do not call releasebuffer + * info.obj = None + */ + __pyx_t_2 = ((!(__pyx_v_hasfields != 0)) != 0); + if (__pyx_t_2) { + } else { + __pyx_t_1 = __pyx_t_2; + goto __pyx_L15_bool_binop_done; + } + __pyx_t_2 = ((!(__pyx_v_copy_shape != 0)) != 0); + __pyx_t_1 = __pyx_t_2; + __pyx_L15_bool_binop_done:; + if (__pyx_t_1) { + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":251 + * if not hasfields and not copy_shape: + * # do not call releasebuffer + * info.obj = None # <<<<<<<<<<<<<< + * else: + * # need to call releasebuffer + */ + __Pyx_INCREF(Py_None); + __Pyx_GIVEREF(Py_None); + __Pyx_GOTREF(__pyx_v_info->obj); + __Pyx_DECREF(__pyx_v_info->obj); + __pyx_v_info->obj = Py_None; + goto __pyx_L14; + } + /*else*/ { + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":254 + * else: + * # need to call releasebuffer + * info.obj = self # <<<<<<<<<<<<<< + * + * if not hasfields: + */ + __Pyx_INCREF(((PyObject *)__pyx_v_self)); + __Pyx_GIVEREF(((PyObject *)__pyx_v_self)); + __Pyx_GOTREF(__pyx_v_info->obj); + __Pyx_DECREF(__pyx_v_info->obj); + __pyx_v_info->obj = ((PyObject *)__pyx_v_self); + } + __pyx_L14:; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":256 + * info.obj = self + * + * if not hasfields: # <<<<<<<<<<<<<< + * t = descr.type_num + * if ((descr.byteorder == c'>' and little_endian) or + */ + __pyx_t_1 = ((!(__pyx_v_hasfields != 0)) != 0); + if (__pyx_t_1) { + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":257 + * + * if not hasfields: + * t = descr.type_num # <<<<<<<<<<<<<< + * if ((descr.byteorder == c'>' and little_endian) or + * (descr.byteorder == c'<' and not little_endian)): + */ + __pyx_t_4 = __pyx_v_descr->type_num; + __pyx_v_t = __pyx_t_4; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":258 + * if not hasfields: + * t = descr.type_num + * if ((descr.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< + * (descr.byteorder == c'<' and not little_endian)): + * raise ValueError(u"Non-native byte order not supported") + */ + __pyx_t_2 = ((__pyx_v_descr->byteorder == '>') != 0); + if (!__pyx_t_2) { + goto __pyx_L20_next_or; + } else { + } + __pyx_t_2 = (__pyx_v_little_endian != 0); + if (!__pyx_t_2) { + } else { + __pyx_t_1 = __pyx_t_2; + goto __pyx_L19_bool_binop_done; + } + __pyx_L20_next_or:; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":259 + * t = descr.type_num + * if ((descr.byteorder == c'>' and little_endian) or + * (descr.byteorder == c'<' and not little_endian)): # <<<<<<<<<<<<<< + * raise ValueError(u"Non-native byte order not supported") + * if t == NPY_BYTE: f = "b" + */ + __pyx_t_2 = ((__pyx_v_descr->byteorder == '<') != 0); + if (__pyx_t_2) { + } else { + __pyx_t_1 = __pyx_t_2; + goto __pyx_L19_bool_binop_done; + } + __pyx_t_2 = ((!(__pyx_v_little_endian != 0)) != 0); + __pyx_t_1 = __pyx_t_2; + __pyx_L19_bool_binop_done:; + if (__pyx_t_1) { + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":260 + * if ((descr.byteorder == c'>' and little_endian) or + * (descr.byteorder == c'<' and not little_endian)): + * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<< + * if t == NPY_BYTE: f = "b" + * elif t == NPY_UBYTE: f = "B" + */ + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__3, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + {__pyx_filename = __pyx_f[1]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":277 + * elif t == NPY_CDOUBLE: f = "Zd" + * elif t == NPY_CLONGDOUBLE: f = "Zg" + * elif t == NPY_OBJECT: f = "O" # <<<<<<<<<<<<<< + * else: + * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) + */ + switch (__pyx_v_t) { + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":261 + * (descr.byteorder == c'<' and not little_endian)): + * raise ValueError(u"Non-native byte order not supported") + * if t == NPY_BYTE: f = "b" # <<<<<<<<<<<<<< + * elif t == NPY_UBYTE: f = "B" + * elif t == NPY_SHORT: f = "h" + */ + case NPY_BYTE: + __pyx_v_f = __pyx_k_b; + break; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":262 + * raise ValueError(u"Non-native byte order not supported") + * if t == NPY_BYTE: f = "b" + * elif t == NPY_UBYTE: f = "B" # <<<<<<<<<<<<<< + * elif t == NPY_SHORT: f = "h" + * elif t == NPY_USHORT: f = "H" + */ + case NPY_UBYTE: + __pyx_v_f = __pyx_k_B; + break; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":263 + * if t == NPY_BYTE: f = "b" + * elif t == NPY_UBYTE: f = "B" + * elif t == NPY_SHORT: f = "h" # <<<<<<<<<<<<<< + * elif t == NPY_USHORT: f = "H" + * elif t == NPY_INT: f = "i" + */ + case NPY_SHORT: + __pyx_v_f = __pyx_k_h; + break; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":264 + * elif t == NPY_UBYTE: f = "B" + * elif t == NPY_SHORT: f = "h" + * elif t == NPY_USHORT: f = "H" # <<<<<<<<<<<<<< + * elif t == NPY_INT: f = "i" + * elif t == NPY_UINT: f = "I" + */ + case NPY_USHORT: + __pyx_v_f = __pyx_k_H; + break; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":265 + * elif t == NPY_SHORT: f = "h" + * elif t == NPY_USHORT: f = "H" + * elif t == NPY_INT: f = "i" # <<<<<<<<<<<<<< + * elif t == NPY_UINT: f = "I" + * elif t == NPY_LONG: f = "l" + */ + case NPY_INT: + __pyx_v_f = __pyx_k_i; + break; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":266 + * elif t == NPY_USHORT: f = "H" + * elif t == NPY_INT: f = "i" + * elif t == NPY_UINT: f = "I" # <<<<<<<<<<<<<< + * elif t == NPY_LONG: f = "l" + * elif t == NPY_ULONG: f = "L" + */ + case NPY_UINT: + __pyx_v_f = __pyx_k_I; + break; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":267 + * elif t == NPY_INT: f = "i" + * elif t == NPY_UINT: f = "I" + * elif t == NPY_LONG: f = "l" # <<<<<<<<<<<<<< + * elif t == NPY_ULONG: f = "L" + * elif t == NPY_LONGLONG: f = "q" + */ + case NPY_LONG: + __pyx_v_f = __pyx_k_l; + break; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":268 + * elif t == NPY_UINT: f = "I" + * elif t == NPY_LONG: f = "l" + * elif t == NPY_ULONG: f = "L" # <<<<<<<<<<<<<< + * elif t == NPY_LONGLONG: f = "q" + * elif t == NPY_ULONGLONG: f = "Q" + */ + case NPY_ULONG: + __pyx_v_f = __pyx_k_L; + break; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":269 + * elif t == NPY_LONG: f = "l" + * elif t == NPY_ULONG: f = "L" + * elif t == NPY_LONGLONG: f = "q" # <<<<<<<<<<<<<< + * elif t == NPY_ULONGLONG: f = "Q" + * elif t == NPY_FLOAT: f = "f" + */ + case NPY_LONGLONG: + __pyx_v_f = __pyx_k_q; + break; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":270 + * elif t == NPY_ULONG: f = "L" + * elif t == NPY_LONGLONG: f = "q" + * elif t == NPY_ULONGLONG: f = "Q" # <<<<<<<<<<<<<< + * elif t == NPY_FLOAT: f = "f" + * elif t == NPY_DOUBLE: f = "d" + */ + case NPY_ULONGLONG: + __pyx_v_f = __pyx_k_Q; + break; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":271 + * elif t == NPY_LONGLONG: f = "q" + * elif t == NPY_ULONGLONG: f = "Q" + * elif t == NPY_FLOAT: f = "f" # <<<<<<<<<<<<<< + * elif t == NPY_DOUBLE: f = "d" + * elif t == NPY_LONGDOUBLE: f = "g" + */ + case NPY_FLOAT: + __pyx_v_f = __pyx_k_f; + break; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":272 + * elif t == NPY_ULONGLONG: f = "Q" + * elif t == NPY_FLOAT: f = "f" + * elif t == NPY_DOUBLE: f = "d" # <<<<<<<<<<<<<< + * elif t == NPY_LONGDOUBLE: f = "g" + * elif t == NPY_CFLOAT: f = "Zf" + */ + case NPY_DOUBLE: + __pyx_v_f = __pyx_k_d; + break; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":273 + * elif t == NPY_FLOAT: f = "f" + * elif t == NPY_DOUBLE: f = "d" + * elif t == NPY_LONGDOUBLE: f = "g" # <<<<<<<<<<<<<< + * elif t == NPY_CFLOAT: f = "Zf" + * elif t == NPY_CDOUBLE: f = "Zd" + */ + case NPY_LONGDOUBLE: + __pyx_v_f = __pyx_k_g; + break; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":274 + * elif t == NPY_DOUBLE: f = "d" + * elif t == NPY_LONGDOUBLE: f = "g" + * elif t == NPY_CFLOAT: f = "Zf" # <<<<<<<<<<<<<< + * elif t == NPY_CDOUBLE: f = "Zd" + * elif t == NPY_CLONGDOUBLE: f = "Zg" + */ + case NPY_CFLOAT: + __pyx_v_f = __pyx_k_Zf; + break; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":275 + * elif t == NPY_LONGDOUBLE: f = "g" + * elif t == NPY_CFLOAT: f = "Zf" + * elif t == NPY_CDOUBLE: f = "Zd" # <<<<<<<<<<<<<< + * elif t == NPY_CLONGDOUBLE: f = "Zg" + * elif t == NPY_OBJECT: f = "O" + */ + case NPY_CDOUBLE: + __pyx_v_f = __pyx_k_Zd; + break; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":276 + * elif t == NPY_CFLOAT: f = "Zf" + * elif t == NPY_CDOUBLE: f = "Zd" + * elif t == NPY_CLONGDOUBLE: f = "Zg" # <<<<<<<<<<<<<< + * elif t == NPY_OBJECT: f = "O" + * else: + */ + case NPY_CLONGDOUBLE: + __pyx_v_f = __pyx_k_Zg; + break; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":277 + * elif t == NPY_CDOUBLE: f = "Zd" + * elif t == NPY_CLONGDOUBLE: f = "Zg" + * elif t == NPY_OBJECT: f = "O" # <<<<<<<<<<<<<< + * else: + * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) + */ + case NPY_OBJECT: + __pyx_v_f = __pyx_k_O; + break; + default: + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":279 + * elif t == NPY_OBJECT: f = "O" + * else: + * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) # <<<<<<<<<<<<<< + * info.format = f + * return + */ + __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_t); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_6 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_t_3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_6); + PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_6); + __pyx_t_6 = 0; + __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_Raise(__pyx_t_6, 0, 0, 0); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + {__pyx_filename = __pyx_f[1]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + break; + } + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":280 + * else: + * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) + * info.format = f # <<<<<<<<<<<<<< + * return + * else: + */ + __pyx_v_info->format = __pyx_v_f; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":281 + * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) + * info.format = f + * return # <<<<<<<<<<<<<< + * else: + * info.format = stdlib.malloc(_buffer_format_string_len) + */ + __pyx_r = 0; + goto __pyx_L0; + } + /*else*/ { + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":283 + * return + * else: + * info.format = stdlib.malloc(_buffer_format_string_len) # <<<<<<<<<<<<<< + * info.format[0] = c'^' # Native data types, manual alignment + * offset = 0 + */ + __pyx_v_info->format = ((char *)malloc(255)); + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":284 + * else: + * info.format = stdlib.malloc(_buffer_format_string_len) + * info.format[0] = c'^' # Native data types, manual alignment # <<<<<<<<<<<<<< + * offset = 0 + * f = _util_dtypestring(descr, info.format + 1, + */ + (__pyx_v_info->format[0]) = '^'; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":285 + * info.format = stdlib.malloc(_buffer_format_string_len) + * info.format[0] = c'^' # Native data types, manual alignment + * offset = 0 # <<<<<<<<<<<<<< + * f = _util_dtypestring(descr, info.format + 1, + * info.format + _buffer_format_string_len, + */ + __pyx_v_offset = 0; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":286 + * info.format[0] = c'^' # Native data types, manual alignment + * offset = 0 + * f = _util_dtypestring(descr, info.format + 1, # <<<<<<<<<<<<<< + * info.format + _buffer_format_string_len, + * &offset) + */ + __pyx_t_7 = __pyx_f_5numpy__util_dtypestring(__pyx_v_descr, (__pyx_v_info->format + 1), (__pyx_v_info->format + 255), (&__pyx_v_offset)); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 286; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_v_f = __pyx_t_7; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":289 + * info.format + _buffer_format_string_len, + * &offset) + * f[0] = c'\0' # Terminate format string # <<<<<<<<<<<<<< + * + * def __releasebuffer__(ndarray self, Py_buffer* info): + */ + (__pyx_v_f[0]) = '\x00'; + } + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":197 + * # experimental exception made for __getbuffer__ and __releasebuffer__ + * # -- the details of this may change. + * def __getbuffer__(ndarray self, Py_buffer* info, int flags): # <<<<<<<<<<<<<< + * # This implementation of getbuffer is geared towards Cython + * # requirements, and does not yet fullfill the PEP. + */ + + /* function exit code */ + __pyx_r = 0; + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_AddTraceback("numpy.ndarray.__getbuffer__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + if (__pyx_v_info != NULL && __pyx_v_info->obj != NULL) { + __Pyx_GOTREF(__pyx_v_info->obj); + __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = NULL; + } + goto __pyx_L2; + __pyx_L0:; + if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) { + __Pyx_GOTREF(Py_None); + __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL; + } + __pyx_L2:; + __Pyx_XDECREF((PyObject *)__pyx_v_descr); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":291 + * f[0] = c'\0' # Terminate format string + * + * def __releasebuffer__(ndarray self, Py_buffer* info): # <<<<<<<<<<<<<< + * if PyArray_HASFIELDS(self): + * stdlib.free(info.format) + */ + +/* Python wrapper */ +static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info); /*proto*/ +static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__releasebuffer__ (wrapper)", 0); + __pyx_pf_5numpy_7ndarray_2__releasebuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); +} + +static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info) { + __Pyx_RefNannyDeclarations + int __pyx_t_1; + __Pyx_RefNannySetupContext("__releasebuffer__", 0); + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":292 + * + * def __releasebuffer__(ndarray self, Py_buffer* info): + * if PyArray_HASFIELDS(self): # <<<<<<<<<<<<<< + * stdlib.free(info.format) + * if sizeof(npy_intp) != sizeof(Py_ssize_t): + */ + __pyx_t_1 = (PyArray_HASFIELDS(__pyx_v_self) != 0); + if (__pyx_t_1) { + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":293 + * def __releasebuffer__(ndarray self, Py_buffer* info): + * if PyArray_HASFIELDS(self): + * stdlib.free(info.format) # <<<<<<<<<<<<<< + * if sizeof(npy_intp) != sizeof(Py_ssize_t): + * stdlib.free(info.strides) + */ + free(__pyx_v_info->format); + goto __pyx_L3; + } + __pyx_L3:; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":294 + * if PyArray_HASFIELDS(self): + * stdlib.free(info.format) + * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<< + * stdlib.free(info.strides) + * # info.shape was stored after info.strides in the same block + */ + __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0); + if (__pyx_t_1) { + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":295 + * stdlib.free(info.format) + * if sizeof(npy_intp) != sizeof(Py_ssize_t): + * stdlib.free(info.strides) # <<<<<<<<<<<<<< + * # info.shape was stored after info.strides in the same block + * + */ + free(__pyx_v_info->strides); + goto __pyx_L4; + } + __pyx_L4:; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":291 + * f[0] = c'\0' # Terminate format string + * + * def __releasebuffer__(ndarray self, Py_buffer* info): # <<<<<<<<<<<<<< + * if PyArray_HASFIELDS(self): + * stdlib.free(info.format) + */ + + /* function exit code */ + __Pyx_RefNannyFinishContext(); +} + +/* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":771 + * ctypedef npy_cdouble complex_t + * + * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(1, a) + * + */ + +static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__pyx_v_a) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("PyArray_MultiIterNew1", 0); + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":772 + * + * cdef inline object PyArray_MultiIterNew1(a): + * return PyArray_MultiIterNew(1, a) # <<<<<<<<<<<<<< + * + * cdef inline object PyArray_MultiIterNew2(a, b): + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyArray_MultiIterNew(1, ((void *)__pyx_v_a)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 772; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":771 + * ctypedef npy_cdouble complex_t + * + * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(1, a) + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("numpy.PyArray_MultiIterNew1", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":774 + * return PyArray_MultiIterNew(1, a) + * + * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(2, a, b) + * + */ + +static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__pyx_v_a, PyObject *__pyx_v_b) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("PyArray_MultiIterNew2", 0); + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":775 + * + * cdef inline object PyArray_MultiIterNew2(a, b): + * return PyArray_MultiIterNew(2, a, b) # <<<<<<<<<<<<<< + * + * cdef inline object PyArray_MultiIterNew3(a, b, c): + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyArray_MultiIterNew(2, ((void *)__pyx_v_a), ((void *)__pyx_v_b)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 775; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":774 + * return PyArray_MultiIterNew(1, a) + * + * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(2, a, b) + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("numpy.PyArray_MultiIterNew2", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":777 + * return PyArray_MultiIterNew(2, a, b) + * + * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(3, a, b, c) + * + */ + +static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("PyArray_MultiIterNew3", 0); + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":778 + * + * cdef inline object PyArray_MultiIterNew3(a, b, c): + * return PyArray_MultiIterNew(3, a, b, c) # <<<<<<<<<<<<<< + * + * cdef inline object PyArray_MultiIterNew4(a, b, c, d): + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyArray_MultiIterNew(3, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 778; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":777 + * return PyArray_MultiIterNew(2, a, b) + * + * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(3, a, b, c) + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("numpy.PyArray_MultiIterNew3", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":780 + * return PyArray_MultiIterNew(3, a, b, c) + * + * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(4, a, b, c, d) + * + */ + +static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("PyArray_MultiIterNew4", 0); + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":781 + * + * cdef inline object PyArray_MultiIterNew4(a, b, c, d): + * return PyArray_MultiIterNew(4, a, b, c, d) # <<<<<<<<<<<<<< + * + * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyArray_MultiIterNew(4, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":780 + * return PyArray_MultiIterNew(3, a, b, c) + * + * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(4, a, b, c, d) + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("numpy.PyArray_MultiIterNew4", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":783 + * return PyArray_MultiIterNew(4, a, b, c, d) + * + * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(5, a, b, c, d, e) + * + */ + +static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d, PyObject *__pyx_v_e) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("PyArray_MultiIterNew5", 0); + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":784 + * + * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): + * return PyArray_MultiIterNew(5, a, b, c, d, e) # <<<<<<<<<<<<<< + * + * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL: + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyArray_MultiIterNew(5, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d), ((void *)__pyx_v_e)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 784; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":783 + * return PyArray_MultiIterNew(4, a, b, c, d) + * + * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(5, a, b, c, d, e) + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("numpy.PyArray_MultiIterNew5", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":786 + * return PyArray_MultiIterNew(5, a, b, c, d, e) + * + * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL: # <<<<<<<<<<<<<< + * # Recursive utility function used in __getbuffer__ to get format + * # string. The new location in the format string is returned. + */ + +static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx_v_descr, char *__pyx_v_f, char *__pyx_v_end, int *__pyx_v_offset) { + PyArray_Descr *__pyx_v_child = 0; + int __pyx_v_endian_detector; + int __pyx_v_little_endian; + PyObject *__pyx_v_fields = 0; + PyObject *__pyx_v_childname = NULL; + PyObject *__pyx_v_new_offset = NULL; + PyObject *__pyx_v_t = NULL; + char *__pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + Py_ssize_t __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + int __pyx_t_5; + int __pyx_t_6; + int __pyx_t_7; + long __pyx_t_8; + char *__pyx_t_9; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_util_dtypestring", 0); + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":793 + * cdef int delta_offset + * cdef tuple i + * cdef int endian_detector = 1 # <<<<<<<<<<<<<< + * cdef bint little_endian = ((&endian_detector)[0] != 0) + * cdef tuple fields + */ + __pyx_v_endian_detector = 1; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":794 + * cdef tuple i + * cdef int endian_detector = 1 + * cdef bint little_endian = ((&endian_detector)[0] != 0) # <<<<<<<<<<<<<< + * cdef tuple fields + * + */ + __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0); + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":797 + * cdef tuple fields + * + * for childname in descr.names: # <<<<<<<<<<<<<< + * fields = descr.fields[childname] + * child, new_offset = fields + */ + if (unlikely(__pyx_v_descr->names == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); + {__pyx_filename = __pyx_f[1]; __pyx_lineno = 797; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_t_1 = __pyx_v_descr->names; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0; + for (;;) { + if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break; + #if CYTHON_COMPILING_IN_CPYTHON + __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 797; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + #else + __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 797; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + #endif + __Pyx_XDECREF_SET(__pyx_v_childname, __pyx_t_3); + __pyx_t_3 = 0; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":798 + * + * for childname in descr.names: + * fields = descr.fields[childname] # <<<<<<<<<<<<<< + * child, new_offset = fields + * + */ + if (unlikely(__pyx_v_descr->fields == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); + {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_t_3 = __Pyx_PyDict_GetItem(__pyx_v_descr->fields, __pyx_v_childname); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; + __Pyx_GOTREF(__pyx_t_3); + if (!(likely(PyTuple_CheckExact(__pyx_t_3))||((__pyx_t_3) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_t_3)->tp_name), 0))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_XDECREF_SET(__pyx_v_fields, ((PyObject*)__pyx_t_3)); + __pyx_t_3 = 0; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":799 + * for childname in descr.names: + * fields = descr.fields[childname] + * child, new_offset = fields # <<<<<<<<<<<<<< + * + * if (end - f) - (new_offset - offset[0]) < 15: + */ + if (likely(__pyx_v_fields != Py_None)) { + PyObject* sequence = __pyx_v_fields; + #if CYTHON_COMPILING_IN_CPYTHON + Py_ssize_t size = Py_SIZE(sequence); + #else + Py_ssize_t size = PySequence_Size(sequence); + #endif + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + #if CYTHON_COMPILING_IN_CPYTHON + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(__pyx_t_4); + #else + __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_4); + #endif + } else { + __Pyx_RaiseNoneNotIterableError(); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_5numpy_dtype))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_XDECREF_SET(__pyx_v_child, ((PyArray_Descr *)__pyx_t_3)); + __pyx_t_3 = 0; + __Pyx_XDECREF_SET(__pyx_v_new_offset, __pyx_t_4); + __pyx_t_4 = 0; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":801 + * child, new_offset = fields + * + * if (end - f) - (new_offset - offset[0]) < 15: # <<<<<<<<<<<<<< + * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") + * + */ + __pyx_t_4 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 801; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyNumber_Subtract(__pyx_v_new_offset, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 801; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_5 = __Pyx_PyInt_As_int(__pyx_t_3); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 801; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = ((((__pyx_v_end - __pyx_v_f) - ((int)__pyx_t_5)) < 15) != 0); + if (__pyx_t_6) { + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":802 + * + * if (end - f) - (new_offset - offset[0]) < 15: + * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") # <<<<<<<<<<<<<< + * + * if ((child.byteorder == c'>' and little_endian) or + */ + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 802; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + {__pyx_filename = __pyx_f[1]; __pyx_lineno = 802; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":804 + * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") + * + * if ((child.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< + * (child.byteorder == c'<' and not little_endian)): + * raise ValueError(u"Non-native byte order not supported") + */ + __pyx_t_7 = ((__pyx_v_child->byteorder == '>') != 0); + if (!__pyx_t_7) { + goto __pyx_L8_next_or; + } else { + } + __pyx_t_7 = (__pyx_v_little_endian != 0); + if (!__pyx_t_7) { + } else { + __pyx_t_6 = __pyx_t_7; + goto __pyx_L7_bool_binop_done; + } + __pyx_L8_next_or:; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":805 + * + * if ((child.byteorder == c'>' and little_endian) or + * (child.byteorder == c'<' and not little_endian)): # <<<<<<<<<<<<<< + * raise ValueError(u"Non-native byte order not supported") + * # One could encode it in the format string and have Cython + */ + __pyx_t_7 = ((__pyx_v_child->byteorder == '<') != 0); + if (__pyx_t_7) { + } else { + __pyx_t_6 = __pyx_t_7; + goto __pyx_L7_bool_binop_done; + } + __pyx_t_7 = ((!(__pyx_v_little_endian != 0)) != 0); + __pyx_t_6 = __pyx_t_7; + __pyx_L7_bool_binop_done:; + if (__pyx_t_6) { + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":806 + * if ((child.byteorder == c'>' and little_endian) or + * (child.byteorder == c'<' and not little_endian)): + * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<< + * # One could encode it in the format string and have Cython + * # complain instead, BUT: < and > in format strings also imply + */ + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__5, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 806; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + {__pyx_filename = __pyx_f[1]; __pyx_lineno = 806; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":816 + * + * # Output padding bytes + * while offset[0] < new_offset: # <<<<<<<<<<<<<< + * f[0] = 120 # "x"; pad byte + * f += 1 + */ + while (1) { + __pyx_t_3 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 816; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyObject_RichCompare(__pyx_t_3, __pyx_v_new_offset, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 816; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 816; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (!__pyx_t_6) break; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":817 + * # Output padding bytes + * while offset[0] < new_offset: + * f[0] = 120 # "x"; pad byte # <<<<<<<<<<<<<< + * f += 1 + * offset[0] += 1 + */ + (__pyx_v_f[0]) = 120; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":818 + * while offset[0] < new_offset: + * f[0] = 120 # "x"; pad byte + * f += 1 # <<<<<<<<<<<<<< + * offset[0] += 1 + * + */ + __pyx_v_f = (__pyx_v_f + 1); + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":819 + * f[0] = 120 # "x"; pad byte + * f += 1 + * offset[0] += 1 # <<<<<<<<<<<<<< + * + * offset[0] += child.itemsize + */ + __pyx_t_8 = 0; + (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + 1); + } + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":821 + * offset[0] += 1 + * + * offset[0] += child.itemsize # <<<<<<<<<<<<<< + * + * if not PyDataType_HASFIELDS(child): + */ + __pyx_t_8 = 0; + (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + __pyx_v_child->elsize); + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":823 + * offset[0] += child.itemsize + * + * if not PyDataType_HASFIELDS(child): # <<<<<<<<<<<<<< + * t = child.type_num + * if end - f < 5: + */ + __pyx_t_6 = ((!(PyDataType_HASFIELDS(__pyx_v_child) != 0)) != 0); + if (__pyx_t_6) { + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":824 + * + * if not PyDataType_HASFIELDS(child): + * t = child.type_num # <<<<<<<<<<<<<< + * if end - f < 5: + * raise RuntimeError(u"Format string allocated too short.") + */ + __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_child->type_num); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 824; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_4); + __Pyx_XDECREF_SET(__pyx_v_t, __pyx_t_4); + __pyx_t_4 = 0; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":825 + * if not PyDataType_HASFIELDS(child): + * t = child.type_num + * if end - f < 5: # <<<<<<<<<<<<<< + * raise RuntimeError(u"Format string allocated too short.") + * + */ + __pyx_t_6 = (((__pyx_v_end - __pyx_v_f) < 5) != 0); + if (__pyx_t_6) { + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":826 + * t = child.type_num + * if end - f < 5: + * raise RuntimeError(u"Format string allocated too short.") # <<<<<<<<<<<<<< + * + * # Until ticket #99 is fixed, use integers to avoid warnings + */ + __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_4); + __Pyx_Raise(__pyx_t_4, 0, 0, 0); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":829 + * + * # Until ticket #99 is fixed, use integers to avoid warnings + * if t == NPY_BYTE: f[0] = 98 #"b" # <<<<<<<<<<<<<< + * elif t == NPY_UBYTE: f[0] = 66 #"B" + * elif t == NPY_SHORT: f[0] = 104 #"h" + */ + __pyx_t_4 = PyInt_FromLong(NPY_BYTE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 98; + goto __pyx_L15; + } + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":830 + * # Until ticket #99 is fixed, use integers to avoid warnings + * if t == NPY_BYTE: f[0] = 98 #"b" + * elif t == NPY_UBYTE: f[0] = 66 #"B" # <<<<<<<<<<<<<< + * elif t == NPY_SHORT: f[0] = 104 #"h" + * elif t == NPY_USHORT: f[0] = 72 #"H" + */ + __pyx_t_3 = PyInt_FromLong(NPY_UBYTE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 66; + goto __pyx_L15; + } + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":831 + * if t == NPY_BYTE: f[0] = 98 #"b" + * elif t == NPY_UBYTE: f[0] = 66 #"B" + * elif t == NPY_SHORT: f[0] = 104 #"h" # <<<<<<<<<<<<<< + * elif t == NPY_USHORT: f[0] = 72 #"H" + * elif t == NPY_INT: f[0] = 105 #"i" + */ + __pyx_t_4 = PyInt_FromLong(NPY_SHORT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 104; + goto __pyx_L15; + } + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":832 + * elif t == NPY_UBYTE: f[0] = 66 #"B" + * elif t == NPY_SHORT: f[0] = 104 #"h" + * elif t == NPY_USHORT: f[0] = 72 #"H" # <<<<<<<<<<<<<< + * elif t == NPY_INT: f[0] = 105 #"i" + * elif t == NPY_UINT: f[0] = 73 #"I" + */ + __pyx_t_3 = PyInt_FromLong(NPY_USHORT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 72; + goto __pyx_L15; + } + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":833 + * elif t == NPY_SHORT: f[0] = 104 #"h" + * elif t == NPY_USHORT: f[0] = 72 #"H" + * elif t == NPY_INT: f[0] = 105 #"i" # <<<<<<<<<<<<<< + * elif t == NPY_UINT: f[0] = 73 #"I" + * elif t == NPY_LONG: f[0] = 108 #"l" + */ + __pyx_t_4 = PyInt_FromLong(NPY_INT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 105; + goto __pyx_L15; + } + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":834 + * elif t == NPY_USHORT: f[0] = 72 #"H" + * elif t == NPY_INT: f[0] = 105 #"i" + * elif t == NPY_UINT: f[0] = 73 #"I" # <<<<<<<<<<<<<< + * elif t == NPY_LONG: f[0] = 108 #"l" + * elif t == NPY_ULONG: f[0] = 76 #"L" + */ + __pyx_t_3 = PyInt_FromLong(NPY_UINT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 73; + goto __pyx_L15; + } + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":835 + * elif t == NPY_INT: f[0] = 105 #"i" + * elif t == NPY_UINT: f[0] = 73 #"I" + * elif t == NPY_LONG: f[0] = 108 #"l" # <<<<<<<<<<<<<< + * elif t == NPY_ULONG: f[0] = 76 #"L" + * elif t == NPY_LONGLONG: f[0] = 113 #"q" + */ + __pyx_t_4 = PyInt_FromLong(NPY_LONG); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 108; + goto __pyx_L15; + } + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":836 + * elif t == NPY_UINT: f[0] = 73 #"I" + * elif t == NPY_LONG: f[0] = 108 #"l" + * elif t == NPY_ULONG: f[0] = 76 #"L" # <<<<<<<<<<<<<< + * elif t == NPY_LONGLONG: f[0] = 113 #"q" + * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" + */ + __pyx_t_3 = PyInt_FromLong(NPY_ULONG); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 76; + goto __pyx_L15; + } + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":837 + * elif t == NPY_LONG: f[0] = 108 #"l" + * elif t == NPY_ULONG: f[0] = 76 #"L" + * elif t == NPY_LONGLONG: f[0] = 113 #"q" # <<<<<<<<<<<<<< + * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" + * elif t == NPY_FLOAT: f[0] = 102 #"f" + */ + __pyx_t_4 = PyInt_FromLong(NPY_LONGLONG); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 113; + goto __pyx_L15; + } + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":838 + * elif t == NPY_ULONG: f[0] = 76 #"L" + * elif t == NPY_LONGLONG: f[0] = 113 #"q" + * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" # <<<<<<<<<<<<<< + * elif t == NPY_FLOAT: f[0] = 102 #"f" + * elif t == NPY_DOUBLE: f[0] = 100 #"d" + */ + __pyx_t_3 = PyInt_FromLong(NPY_ULONGLONG); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 81; + goto __pyx_L15; + } + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":839 + * elif t == NPY_LONGLONG: f[0] = 113 #"q" + * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" + * elif t == NPY_FLOAT: f[0] = 102 #"f" # <<<<<<<<<<<<<< + * elif t == NPY_DOUBLE: f[0] = 100 #"d" + * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" + */ + __pyx_t_4 = PyInt_FromLong(NPY_FLOAT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 102; + goto __pyx_L15; + } + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":840 + * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" + * elif t == NPY_FLOAT: f[0] = 102 #"f" + * elif t == NPY_DOUBLE: f[0] = 100 #"d" # <<<<<<<<<<<<<< + * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" + * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf + */ + __pyx_t_3 = PyInt_FromLong(NPY_DOUBLE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 100; + goto __pyx_L15; + } + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":841 + * elif t == NPY_FLOAT: f[0] = 102 #"f" + * elif t == NPY_DOUBLE: f[0] = 100 #"d" + * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" # <<<<<<<<<<<<<< + * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf + * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd + */ + __pyx_t_4 = PyInt_FromLong(NPY_LONGDOUBLE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 103; + goto __pyx_L15; + } + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":842 + * elif t == NPY_DOUBLE: f[0] = 100 #"d" + * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" + * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf # <<<<<<<<<<<<<< + * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd + * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg + */ + __pyx_t_3 = PyInt_FromLong(NPY_CFLOAT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 90; + (__pyx_v_f[1]) = 102; + __pyx_v_f = (__pyx_v_f + 1); + goto __pyx_L15; + } + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":843 + * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" + * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf + * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd # <<<<<<<<<<<<<< + * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg + * elif t == NPY_OBJECT: f[0] = 79 #"O" + */ + __pyx_t_4 = PyInt_FromLong(NPY_CDOUBLE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 843; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 843; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 843; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 90; + (__pyx_v_f[1]) = 100; + __pyx_v_f = (__pyx_v_f + 1); + goto __pyx_L15; + } + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":844 + * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf + * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd + * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg # <<<<<<<<<<<<<< + * elif t == NPY_OBJECT: f[0] = 79 #"O" + * else: + */ + __pyx_t_3 = PyInt_FromLong(NPY_CLONGDOUBLE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 90; + (__pyx_v_f[1]) = 103; + __pyx_v_f = (__pyx_v_f + 1); + goto __pyx_L15; + } + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":845 + * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd + * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg + * elif t == NPY_OBJECT: f[0] = 79 #"O" # <<<<<<<<<<<<<< + * else: + * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) + */ + __pyx_t_4 = PyInt_FromLong(NPY_OBJECT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 845; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 845; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 845; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 79; + goto __pyx_L15; + } + /*else*/ { + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":847 + * elif t == NPY_OBJECT: f[0] = 79 #"O" + * else: + * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) # <<<<<<<<<<<<<< + * f += 1 + * else: + */ + __pyx_t_3 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_v_t); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 847; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 847; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_4); + __Pyx_GIVEREF(__pyx_t_3); + PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3); + __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 847; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + {__pyx_filename = __pyx_f[1]; __pyx_lineno = 847; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_L15:; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":848 + * else: + * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) + * f += 1 # <<<<<<<<<<<<<< + * else: + * # Cython ignores struct boundary information ("T{...}"), + */ + __pyx_v_f = (__pyx_v_f + 1); + goto __pyx_L13; + } + /*else*/ { + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":852 + * # Cython ignores struct boundary information ("T{...}"), + * # so don't output it + * f = _util_dtypestring(child, f, end, offset) # <<<<<<<<<<<<<< + * return f + * + */ + __pyx_t_9 = __pyx_f_5numpy__util_dtypestring(__pyx_v_child, __pyx_v_f, __pyx_v_end, __pyx_v_offset); if (unlikely(__pyx_t_9 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 852; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_v_f = __pyx_t_9; + } + __pyx_L13:; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":797 + * cdef tuple fields + * + * for childname in descr.names: # <<<<<<<<<<<<<< + * fields = descr.fields[childname] + * child, new_offset = fields + */ + } + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":853 + * # so don't output it + * f = _util_dtypestring(child, f, end, offset) + * return f # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = __pyx_v_f; + goto __pyx_L0; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":786 + * return PyArray_MultiIterNew(5, a, b, c, d, e) + * + * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL: # <<<<<<<<<<<<<< + * # Recursive utility function used in __getbuffer__ to get format + * # string. The new location in the format string is returned. + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_AddTraceback("numpy._util_dtypestring", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF((PyObject *)__pyx_v_child); + __Pyx_XDECREF(__pyx_v_fields); + __Pyx_XDECREF(__pyx_v_childname); + __Pyx_XDECREF(__pyx_v_new_offset); + __Pyx_XDECREF(__pyx_v_t); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":969 + * + * + * cdef inline void set_array_base(ndarray arr, object base): # <<<<<<<<<<<<<< + * cdef PyObject* baseptr + * if base is None: + */ + +static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_arr, PyObject *__pyx_v_base) { + PyObject *__pyx_v_baseptr; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + int __pyx_t_2; + __Pyx_RefNannySetupContext("set_array_base", 0); + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":971 + * cdef inline void set_array_base(ndarray arr, object base): + * cdef PyObject* baseptr + * if base is None: # <<<<<<<<<<<<<< + * baseptr = NULL + * else: + */ + __pyx_t_1 = (__pyx_v_base == Py_None); + __pyx_t_2 = (__pyx_t_1 != 0); + if (__pyx_t_2) { + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":972 + * cdef PyObject* baseptr + * if base is None: + * baseptr = NULL # <<<<<<<<<<<<<< + * else: + * Py_INCREF(base) # important to do this before decref below! + */ + __pyx_v_baseptr = NULL; + goto __pyx_L3; + } + /*else*/ { + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":974 + * baseptr = NULL + * else: + * Py_INCREF(base) # important to do this before decref below! # <<<<<<<<<<<<<< + * baseptr = base + * Py_XDECREF(arr.base) + */ + Py_INCREF(__pyx_v_base); + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":975 + * else: + * Py_INCREF(base) # important to do this before decref below! + * baseptr = base # <<<<<<<<<<<<<< + * Py_XDECREF(arr.base) + * arr.base = baseptr + */ + __pyx_v_baseptr = ((PyObject *)__pyx_v_base); + } + __pyx_L3:; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976 + * Py_INCREF(base) # important to do this before decref below! + * baseptr = base + * Py_XDECREF(arr.base) # <<<<<<<<<<<<<< + * arr.base = baseptr + * + */ + Py_XDECREF(__pyx_v_arr->base); + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":977 + * baseptr = base + * Py_XDECREF(arr.base) + * arr.base = baseptr # <<<<<<<<<<<<<< + * + * cdef inline object get_array_base(ndarray arr): + */ + __pyx_v_arr->base = __pyx_v_baseptr; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":969 + * + * + * cdef inline void set_array_base(ndarray arr, object base): # <<<<<<<<<<<<<< + * cdef PyObject* baseptr + * if base is None: + */ + + /* function exit code */ + __Pyx_RefNannyFinishContext(); +} + +/* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":979 + * arr.base = baseptr + * + * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<< + * if arr.base is NULL: + * return None + */ + +static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__pyx_v_arr) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + __Pyx_RefNannySetupContext("get_array_base", 0); + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":980 + * + * cdef inline object get_array_base(ndarray arr): + * if arr.base is NULL: # <<<<<<<<<<<<<< + * return None + * else: + */ + __pyx_t_1 = ((__pyx_v_arr->base == NULL) != 0); + if (__pyx_t_1) { + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":981 + * cdef inline object get_array_base(ndarray arr): + * if arr.base is NULL: + * return None # <<<<<<<<<<<<<< + * else: + * return arr.base + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(Py_None); + __pyx_r = Py_None; + goto __pyx_L0; + } + /*else*/ { + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":983 + * return None + * else: + * return arr.base # <<<<<<<<<<<<<< + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(((PyObject *)__pyx_v_arr->base)); + __pyx_r = ((PyObject *)__pyx_v_arr->base); + goto __pyx_L0; + } + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":979 + * arr.base = baseptr + * + * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<< + * if arr.base is NULL: + * return None + */ + + /* function exit code */ + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyMethodDef __pyx_methods[] = { + {0, 0, 0, 0} +}; + +#if PY_MAJOR_VERSION >= 3 +static struct PyModuleDef __pyx_moduledef = { + #if PY_VERSION_HEX < 0x03020000 + { PyObject_HEAD_INIT(NULL) NULL, 0, NULL }, + #else + PyModuleDef_HEAD_INIT, + #endif + "interputils_cython", + 0, /* m_doc */ + -1, /* m_size */ + __pyx_methods /* m_methods */, + NULL, /* m_reload */ + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL /* m_free */ +}; +#endif + +static __Pyx_StringTabEntry __pyx_string_tab[] = { + {&__pyx_kp_u_Format_string_allocated_too_shor, __pyx_k_Format_string_allocated_too_shor, sizeof(__pyx_k_Format_string_allocated_too_shor), 0, 1, 0, 0}, + {&__pyx_kp_u_Format_string_allocated_too_shor_2, __pyx_k_Format_string_allocated_too_shor_2, sizeof(__pyx_k_Format_string_allocated_too_shor_2), 0, 1, 0, 0}, + {&__pyx_kp_u_Non_native_byte_order_not_suppor, __pyx_k_Non_native_byte_order_not_suppor, sizeof(__pyx_k_Non_native_byte_order_not_suppor), 0, 1, 0, 0}, + {&__pyx_n_s_RuntimeError, __pyx_k_RuntimeError, sizeof(__pyx_k_RuntimeError), 0, 0, 1, 1}, + {&__pyx_n_s_SimPEG_Utils_interputils_cython, __pyx_k_SimPEG_Utils_interputils_cython, sizeof(__pyx_k_SimPEG_Utils_interputils_cython), 0, 0, 1, 1}, + {&__pyx_kp_s_Users_rowan_git_simpeg_simpeg_S, __pyx_k_Users_rowan_git_simpeg_simpeg_S, sizeof(__pyx_k_Users_rowan_git_simpeg_simpeg_S), 0, 0, 1, 0}, + {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1}, + {&__pyx_n_s_argmin, __pyx_k_argmin, sizeof(__pyx_k_argmin), 0, 0, 1, 1}, + {&__pyx_n_s_hx, __pyx_k_hx, sizeof(__pyx_k_hx), 0, 0, 1, 1}, + {&__pyx_n_s_i, __pyx_k_i, sizeof(__pyx_k_i), 0, 0, 1, 1}, + {&__pyx_n_s_im, __pyx_k_im, sizeof(__pyx_k_im), 0, 0, 1, 1}, + {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1}, + {&__pyx_n_s_ind_x1, __pyx_k_ind_x1, sizeof(__pyx_k_ind_x1), 0, 0, 1, 1}, + {&__pyx_n_s_ind_x2, __pyx_k_ind_x2, sizeof(__pyx_k_ind_x2), 0, 0, 1, 1}, + {&__pyx_n_s_ind_y1, __pyx_k_ind_y1, sizeof(__pyx_k_ind_y1), 0, 0, 1, 1}, + {&__pyx_n_s_ind_y2, __pyx_k_ind_y2, sizeof(__pyx_k_ind_y2), 0, 0, 1, 1}, + {&__pyx_n_s_ind_z1, __pyx_k_ind_z1, sizeof(__pyx_k_ind_z1), 0, 0, 1, 1}, + {&__pyx_n_s_ind_z2, __pyx_k_ind_z2, sizeof(__pyx_k_ind_z2), 0, 0, 1, 1}, + {&__pyx_n_s_inds, __pyx_k_inds, sizeof(__pyx_k_inds), 0, 0, 1, 1}, + {&__pyx_n_s_interp_point_1D, __pyx_k_interp_point_1D, sizeof(__pyx_k_interp_point_1D), 0, 0, 1, 1}, + {&__pyx_n_s_interpmat1D, __pyx_k_interpmat1D, sizeof(__pyx_k_interpmat1D), 0, 0, 1, 1}, + {&__pyx_n_s_interpmat2D, __pyx_k_interpmat2D, sizeof(__pyx_k_interpmat2D), 0, 0, 1, 1}, + {&__pyx_n_s_interpmat3D, __pyx_k_interpmat3D, sizeof(__pyx_k_interpmat3D), 0, 0, 1, 1}, + {&__pyx_n_s_locs, __pyx_k_locs, sizeof(__pyx_k_locs), 0, 0, 1, 1}, + {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1}, + {&__pyx_kp_u_ndarray_is_not_C_contiguous, __pyx_k_ndarray_is_not_C_contiguous, sizeof(__pyx_k_ndarray_is_not_C_contiguous), 0, 1, 0, 0}, + {&__pyx_kp_u_ndarray_is_not_Fortran_contiguou, __pyx_k_ndarray_is_not_Fortran_contiguou, sizeof(__pyx_k_ndarray_is_not_Fortran_contiguou), 0, 1, 0, 0}, + {&__pyx_n_s_np, __pyx_k_np, sizeof(__pyx_k_np), 0, 0, 1, 1}, + {&__pyx_n_s_npts, __pyx_k_npts, sizeof(__pyx_k_npts), 0, 0, 1, 1}, + {&__pyx_n_s_numpy, __pyx_k_numpy, sizeof(__pyx_k_numpy), 0, 0, 1, 1}, + {&__pyx_n_s_nx, __pyx_k_nx, sizeof(__pyx_k_nx), 0, 0, 1, 1}, + {&__pyx_n_s_ny, __pyx_k_ny, sizeof(__pyx_k_ny), 0, 0, 1, 1}, + {&__pyx_n_s_nz, __pyx_k_nz, sizeof(__pyx_k_nz), 0, 0, 1, 1}, + {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1}, + {&__pyx_n_s_size, __pyx_k_size, sizeof(__pyx_k_size), 0, 0, 1, 1}, + {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1}, + {&__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_k_unknown_dtype_code_in_numpy_pxd, sizeof(__pyx_k_unknown_dtype_code_in_numpy_pxd), 0, 1, 0, 0}, + {&__pyx_n_s_vals, __pyx_k_vals, sizeof(__pyx_k_vals), 0, 0, 1, 1}, + {&__pyx_n_s_wx1, __pyx_k_wx1, sizeof(__pyx_k_wx1), 0, 0, 1, 1}, + {&__pyx_n_s_wx2, __pyx_k_wx2, sizeof(__pyx_k_wx2), 0, 0, 1, 1}, + {&__pyx_n_s_wy1, __pyx_k_wy1, sizeof(__pyx_k_wy1), 0, 0, 1, 1}, + {&__pyx_n_s_wy2, __pyx_k_wy2, sizeof(__pyx_k_wy2), 0, 0, 1, 1}, + {&__pyx_n_s_wz1, __pyx_k_wz1, sizeof(__pyx_k_wz1), 0, 0, 1, 1}, + {&__pyx_n_s_wz2, __pyx_k_wz2, sizeof(__pyx_k_wz2), 0, 0, 1, 1}, + {&__pyx_n_s_x, __pyx_k_x, sizeof(__pyx_k_x), 0, 0, 1, 1}, + {&__pyx_n_s_xSize, __pyx_k_xSize, sizeof(__pyx_k_xSize), 0, 0, 1, 1}, + {&__pyx_n_s_xr_i, __pyx_k_xr_i, sizeof(__pyx_k_xr_i), 0, 0, 1, 1}, + {&__pyx_n_s_y, __pyx_k_y, sizeof(__pyx_k_y), 0, 0, 1, 1}, + {&__pyx_n_s_z, __pyx_k_z, sizeof(__pyx_k_z), 0, 0, 1, 1}, + {0, 0, 0, 0, 0, 0, 0} +}; +static int __Pyx_InitCachedBuiltins(void) { + __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 52; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_builtin_RuntimeError = __Pyx_GetBuiltinName(__pyx_n_s_RuntimeError); if (!__pyx_builtin_RuntimeError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 802; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + return 0; + __pyx_L1_error:; + return -1; +} + +static int __Pyx_InitCachedConstants(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":218 + * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) + * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): + * raise ValueError(u"ndarray is not C contiguous") # <<<<<<<<<<<<<< + * + * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) + */ + __pyx_tuple_ = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_C_contiguous); if (unlikely(!__pyx_tuple_)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_tuple_); + __Pyx_GIVEREF(__pyx_tuple_); + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":222 + * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) + * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): + * raise ValueError(u"ndarray is not Fortran contiguous") # <<<<<<<<<<<<<< + * + * info.buf = PyArray_DATA(self) + */ + __pyx_tuple__2 = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_Fortran_contiguou); if (unlikely(!__pyx_tuple__2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_tuple__2); + __Pyx_GIVEREF(__pyx_tuple__2); + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":260 + * if ((descr.byteorder == c'>' and little_endian) or + * (descr.byteorder == c'<' and not little_endian)): + * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<< + * if t == NPY_BYTE: f = "b" + * elif t == NPY_UBYTE: f = "B" + */ + __pyx_tuple__3 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_tuple__3); + __Pyx_GIVEREF(__pyx_tuple__3); + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":802 + * + * if (end - f) - (new_offset - offset[0]) < 15: + * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") # <<<<<<<<<<<<<< + * + * if ((child.byteorder == c'>' and little_endian) or + */ + __pyx_tuple__4 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor); if (unlikely(!__pyx_tuple__4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 802; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_tuple__4); + __Pyx_GIVEREF(__pyx_tuple__4); + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":806 + * if ((child.byteorder == c'>' and little_endian) or + * (child.byteorder == c'<' and not little_endian)): + * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<< + * # One could encode it in the format string and have Cython + * # complain instead, BUT: < and > in format strings also imply + */ + __pyx_tuple__5 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 806; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_tuple__5); + __Pyx_GIVEREF(__pyx_tuple__5); + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":826 + * t = child.type_num + * if end - f < 5: + * raise RuntimeError(u"Format string allocated too short.") # <<<<<<<<<<<<<< + * + * # Until ticket #99 is fixed, use integers to avoid warnings + */ + __pyx_tuple__6 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor_2); if (unlikely(!__pyx_tuple__6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_tuple__6); + __Pyx_GIVEREF(__pyx_tuple__6); + + /* "SimPEG/Utils/interputils_cython.pyx":6 + * # from libcpp.vector cimport vector + * + * def _interp_point_1D(np.ndarray[np.float64_t, ndim=1] x, float xr_i): # <<<<<<<<<<<<<< + * """ + * given a point, xr_i, this will find which two integers it lies between. + */ + __pyx_tuple__7 = PyTuple_Pack(9, __pyx_n_s_x, __pyx_n_s_xr_i, __pyx_n_s_im, __pyx_n_s_ind_x1, __pyx_n_s_ind_x2, __pyx_n_s_xSize, __pyx_n_s_wx1, __pyx_n_s_wx2, __pyx_n_s_hx); if (unlikely(!__pyx_tuple__7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_tuple__7); + __Pyx_GIVEREF(__pyx_tuple__7); + __pyx_codeobj__8 = (PyObject*)__Pyx_PyCode_New(2, 0, 9, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__7, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_rowan_git_simpeg_simpeg_S, __pyx_n_s_interp_point_1D, 6, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + + /* "SimPEG/Utils/interputils_cython.pyx":44 + * + * + * def _interpmat1D(np.ndarray[np.float64_t, ndim=1] locs, # <<<<<<<<<<<<<< + * np.ndarray[np.float64_t, ndim=1] x): + * """Use interpmat with only x component provided.""" + */ + __pyx_tuple__9 = PyTuple_Pack(11, __pyx_n_s_locs, __pyx_n_s_x, __pyx_n_s_nx, __pyx_n_s_npts, __pyx_n_s_inds, __pyx_n_s_vals, __pyx_n_s_i, __pyx_n_s_ind_x1, __pyx_n_s_ind_x2, __pyx_n_s_wx1, __pyx_n_s_wx2); if (unlikely(!__pyx_tuple__9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 44; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_tuple__9); + __Pyx_GIVEREF(__pyx_tuple__9); + __pyx_codeobj__10 = (PyObject*)__Pyx_PyCode_New(2, 0, 11, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__9, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_rowan_git_simpeg_simpeg_S, __pyx_n_s_interpmat1D, 44, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 44; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + + /* "SimPEG/Utils/interputils_cython.pyx":60 + * + * + * def _interpmat2D(np.ndarray[np.float64_t, ndim=2] locs, # <<<<<<<<<<<<<< + * np.ndarray[np.float64_t, ndim=1] x, + * np.ndarray[np.float64_t, ndim=1] y): + */ + __pyx_tuple__11 = PyTuple_Pack(17, __pyx_n_s_locs, __pyx_n_s_x, __pyx_n_s_y, __pyx_n_s_nx, __pyx_n_s_ny, __pyx_n_s_npts, __pyx_n_s_inds, __pyx_n_s_vals, __pyx_n_s_i, __pyx_n_s_ind_x1, __pyx_n_s_ind_x2, __pyx_n_s_wx1, __pyx_n_s_wx2, __pyx_n_s_ind_y1, __pyx_n_s_ind_y2, __pyx_n_s_wy1, __pyx_n_s_wy2); if (unlikely(!__pyx_tuple__11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_tuple__11); + __Pyx_GIVEREF(__pyx_tuple__11); + __pyx_codeobj__12 = (PyObject*)__Pyx_PyCode_New(3, 0, 17, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__11, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_rowan_git_simpeg_simpeg_S, __pyx_n_s_interpmat2D, 60, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + + /* "SimPEG/Utils/interputils_cython.pyx":84 + * + * + * def _interpmat3D(np.ndarray[np.float64_t, ndim=2] locs, # <<<<<<<<<<<<<< + * np.ndarray[np.float64_t, ndim=1] x, + * np.ndarray[np.float64_t, ndim=1] y, + */ + __pyx_tuple__13 = PyTuple_Pack(23, __pyx_n_s_locs, __pyx_n_s_x, __pyx_n_s_y, __pyx_n_s_z, __pyx_n_s_nx, __pyx_n_s_ny, __pyx_n_s_nz, __pyx_n_s_npts, __pyx_n_s_inds, __pyx_n_s_vals, __pyx_n_s_i, __pyx_n_s_ind_x1, __pyx_n_s_ind_x2, __pyx_n_s_wx1, __pyx_n_s_wx2, __pyx_n_s_ind_y1, __pyx_n_s_ind_y2, __pyx_n_s_wy1, __pyx_n_s_wy2, __pyx_n_s_ind_z1, __pyx_n_s_ind_z2, __pyx_n_s_wz1, __pyx_n_s_wz2); if (unlikely(!__pyx_tuple__13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_tuple__13); + __Pyx_GIVEREF(__pyx_tuple__13); + __pyx_codeobj__14 = (PyObject*)__Pyx_PyCode_New(4, 0, 23, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__13, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_rowan_git_simpeg_simpeg_S, __pyx_n_s_interpmat3D, 84, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_RefNannyFinishContext(); + return 0; + __pyx_L1_error:; + __Pyx_RefNannyFinishContext(); + return -1; +} + +static int __Pyx_InitGlobals(void) { + if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; + __pyx_float_0_5 = PyFloat_FromDouble(0.5); if (unlikely(!__pyx_float_0_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + return 0; + __pyx_L1_error:; + return -1; +} + +#if PY_MAJOR_VERSION < 3 +PyMODINIT_FUNC initinterputils_cython(void); /*proto*/ +PyMODINIT_FUNC initinterputils_cython(void) +#else +PyMODINIT_FUNC PyInit_interputils_cython(void); /*proto*/ +PyMODINIT_FUNC PyInit_interputils_cython(void) +#endif +{ + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannyDeclarations + #if CYTHON_REFNANNY + __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); + if (!__Pyx_RefNanny) { + PyErr_Clear(); + __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); + if (!__Pyx_RefNanny) + Py_FatalError("failed to import 'refnanny' module"); + } + #endif + __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit_interputils_cython(void)", 0); + if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + #ifdef __Pyx_CyFunction_USED + if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + #endif + #ifdef __Pyx_FusedFunction_USED + if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + #endif + #ifdef __Pyx_Generator_USED + if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + #endif + /*--- Library function declarations ---*/ + /*--- Threads initialization code ---*/ + #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS + #ifdef WITH_THREAD /* Python build with threading support? */ + PyEval_InitThreads(); + #endif + #endif + /*--- Module creation code ---*/ + #if PY_MAJOR_VERSION < 3 + __pyx_m = Py_InitModule4("interputils_cython", __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m); + #else + __pyx_m = PyModule_Create(&__pyx_moduledef); + #endif + if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + Py_INCREF(__pyx_d); + __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + #if CYTHON_COMPILING_IN_PYPY + Py_INCREF(__pyx_b); + #endif + if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; + /*--- Initialize various global constants etc. ---*/ + if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) + if (__Pyx_init_sys_getdefaultencoding_params() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + #endif + if (__pyx_module_is_main_SimPEG__Utils__interputils_cython) { + if (PyObject_SetAttrString(__pyx_m, "__name__", __pyx_n_s_main) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; + } + #if PY_MAJOR_VERSION >= 3 + { + PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + if (!PyDict_GetItemString(modules, "SimPEG.Utils.interputils_cython")) { + if (unlikely(PyDict_SetItemString(modules, "SimPEG.Utils.interputils_cython", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + } + #endif + /*--- Builtin init code ---*/ + if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + /*--- Constants init code ---*/ + if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + /*--- Global init code ---*/ + /*--- Variable export code ---*/ + /*--- Function export code ---*/ + /*--- Type init code ---*/ + /*--- Type import code ---*/ + __pyx_ptype_7cpython_4type_type = __Pyx_ImportType(__Pyx_BUILTIN_MODULE_NAME, "type", + #if CYTHON_COMPILING_IN_PYPY + sizeof(PyTypeObject), + #else + sizeof(PyHeapTypeObject), + #endif + 0); if (unlikely(!__pyx_ptype_7cpython_4type_type)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_ptype_5numpy_dtype = __Pyx_ImportType("numpy", "dtype", sizeof(PyArray_Descr), 0); if (unlikely(!__pyx_ptype_5numpy_dtype)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_ptype_5numpy_flatiter = __Pyx_ImportType("numpy", "flatiter", sizeof(PyArrayIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_flatiter)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 168; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_ptype_5numpy_broadcast = __Pyx_ImportType("numpy", "broadcast", sizeof(PyArrayMultiIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_broadcast)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_ptype_5numpy_ndarray = __Pyx_ImportType("numpy", "ndarray", sizeof(PyArrayObject), 0); if (unlikely(!__pyx_ptype_5numpy_ndarray)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 181; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_ptype_5numpy_ufunc = __Pyx_ImportType("numpy", "ufunc", sizeof(PyUFuncObject), 0); if (unlikely(!__pyx_ptype_5numpy_ufunc)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 864; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + /*--- Variable import code ---*/ + /*--- Function import code ---*/ + /*--- Execution code ---*/ + + /* "SimPEG/Utils/interputils_cython.pyx":2 + * # from __future__ import division + * import numpy as np # <<<<<<<<<<<<<< + * cimport numpy as np + * # from libcpp.vector cimport vector + */ + __pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "SimPEG/Utils/interputils_cython.pyx":6 + * # from libcpp.vector cimport vector + * + * def _interp_point_1D(np.ndarray[np.float64_t, ndim=1] x, float xr_i): # <<<<<<<<<<<<<< + * """ + * given a point, xr_i, this will find which two integers it lies between. + */ + __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_6SimPEG_5Utils_18interputils_cython_1_interp_point_1D, NULL, __pyx_n_s_SimPEG_Utils_interputils_cython); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_interp_point_1D, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "SimPEG/Utils/interputils_cython.pyx":44 + * + * + * def _interpmat1D(np.ndarray[np.float64_t, ndim=1] locs, # <<<<<<<<<<<<<< + * np.ndarray[np.float64_t, ndim=1] x): + * """Use interpmat with only x component provided.""" + */ + __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_6SimPEG_5Utils_18interputils_cython_3_interpmat1D, NULL, __pyx_n_s_SimPEG_Utils_interputils_cython); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 44; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_interpmat1D, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 44; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "SimPEG/Utils/interputils_cython.pyx":60 + * + * + * def _interpmat2D(np.ndarray[np.float64_t, ndim=2] locs, # <<<<<<<<<<<<<< + * np.ndarray[np.float64_t, ndim=1] x, + * np.ndarray[np.float64_t, ndim=1] y): + */ + __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_6SimPEG_5Utils_18interputils_cython_5_interpmat2D, NULL, __pyx_n_s_SimPEG_Utils_interputils_cython); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_interpmat2D, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "SimPEG/Utils/interputils_cython.pyx":84 + * + * + * def _interpmat3D(np.ndarray[np.float64_t, ndim=2] locs, # <<<<<<<<<<<<<< + * np.ndarray[np.float64_t, ndim=1] x, + * np.ndarray[np.float64_t, ndim=1] y, + */ + __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_6SimPEG_5Utils_18interputils_cython_7_interpmat3D, NULL, __pyx_n_s_SimPEG_Utils_interputils_cython); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_interpmat3D, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "SimPEG/Utils/interputils_cython.pyx":1 + * # from __future__ import division # <<<<<<<<<<<<<< + * import numpy as np + * cimport numpy as np + */ + __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "../../../anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":979 + * arr.base = baseptr + * + * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<< + * if arr.base is NULL: + * return None + */ + + /*--- Wrapped vars code ---*/ + + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + if (__pyx_m) { + if (__pyx_d) { + __Pyx_AddTraceback("init SimPEG.Utils.interputils_cython", __pyx_clineno, __pyx_lineno, __pyx_filename); + } + Py_DECREF(__pyx_m); __pyx_m = 0; + } else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ImportError, "init SimPEG.Utils.interputils_cython"); + } + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + #if PY_MAJOR_VERSION < 3 + return; + #else + return __pyx_m; + #endif +} + +/* --- Runtime support code --- */ +#if CYTHON_REFNANNY +static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { + PyObject *m = NULL, *p = NULL; + void *r = NULL; + m = PyImport_ImportModule((char *)modname); + if (!m) goto end; + p = PyObject_GetAttrString(m, (char *)"RefNannyAPI"); + if (!p) goto end; + r = PyLong_AsVoidPtr(p); +end: + Py_XDECREF(p); + Py_XDECREF(m); + return (__Pyx_RefNannyAPIStruct *)r; +} +#endif + +static PyObject *__Pyx_GetBuiltinName(PyObject *name) { + PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name); + if (unlikely(!result)) { + PyErr_Format(PyExc_NameError, +#if PY_MAJOR_VERSION >= 3 + "name '%U' is not defined", name); +#else + "name '%.200s' is not defined", PyString_AS_STRING(name)); +#endif + } + return result; +} + +static void __Pyx_RaiseArgtupleInvalid( + const char* func_name, + int exact, + Py_ssize_t num_min, + Py_ssize_t num_max, + Py_ssize_t num_found) +{ + Py_ssize_t num_expected; + const char *more_or_less; + if (num_found < num_min) { + num_expected = num_min; + more_or_less = "at least"; + } else { + num_expected = num_max; + more_or_less = "at most"; + } + if (exact) { + more_or_less = "exactly"; + } + PyErr_Format(PyExc_TypeError, + "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)", + func_name, more_or_less, num_expected, + (num_expected == 1) ? "" : "s", num_found); +} + +static void __Pyx_RaiseDoubleKeywordsError( + const char* func_name, + PyObject* kw_name) +{ + PyErr_Format(PyExc_TypeError, + #if PY_MAJOR_VERSION >= 3 + "%s() got multiple values for keyword argument '%U'", func_name, kw_name); + #else + "%s() got multiple values for keyword argument '%s'", func_name, + PyString_AsString(kw_name)); + #endif +} + +static int __Pyx_ParseOptionalKeywords( + PyObject *kwds, + PyObject **argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + const char* function_name) +{ + PyObject *key = 0, *value = 0; + Py_ssize_t pos = 0; + PyObject*** name; + PyObject*** first_kw_arg = argnames + num_pos_args; + while (PyDict_Next(kwds, &pos, &key, &value)) { + name = first_kw_arg; + while (*name && (**name != key)) name++; + if (*name) { + values[name-argnames] = value; + continue; + } + name = first_kw_arg; + #if PY_MAJOR_VERSION < 3 + if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) { + while (*name) { + if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key)) + && _PyString_Eq(**name, key)) { + values[name-argnames] = value; + break; + } + name++; + } + if (*name) continue; + else { + PyObject*** argname = argnames; + while (argname != first_kw_arg) { + if ((**argname == key) || ( + (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key)) + && _PyString_Eq(**argname, key))) { + goto arg_passed_twice; + } + argname++; + } + } + } else + #endif + if (likely(PyUnicode_Check(key))) { + while (*name) { + int cmp = (**name == key) ? 0 : + #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 + (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 : + #endif + PyUnicode_Compare(**name, key); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) { + values[name-argnames] = value; + break; + } + name++; + } + if (*name) continue; + else { + PyObject*** argname = argnames; + while (argname != first_kw_arg) { + int cmp = (**argname == key) ? 0 : + #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 + (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 : + #endif + PyUnicode_Compare(**argname, key); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) goto arg_passed_twice; + argname++; + } + } + } else + goto invalid_keyword_type; + if (kwds2) { + if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; + } else { + goto invalid_keyword; + } + } + return 0; +arg_passed_twice: + __Pyx_RaiseDoubleKeywordsError(function_name, key); + goto bad; +invalid_keyword_type: + PyErr_Format(PyExc_TypeError, + "%.200s() keywords must be strings", function_name); + goto bad; +invalid_keyword: + PyErr_Format(PyExc_TypeError, + #if PY_MAJOR_VERSION < 3 + "%.200s() got an unexpected keyword argument '%.200s'", + function_name, PyString_AsString(key)); + #else + "%s() got an unexpected keyword argument '%U'", + function_name, key); + #endif +bad: + return -1; +} + +static void __Pyx_RaiseArgumentTypeInvalid(const char* name, PyObject *obj, PyTypeObject *type) { + PyErr_Format(PyExc_TypeError, + "Argument '%.200s' has incorrect type (expected %.200s, got %.200s)", + name, type->tp_name, Py_TYPE(obj)->tp_name); +} +static CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed, + const char *name, int exact) +{ + if (unlikely(!type)) { + PyErr_SetString(PyExc_SystemError, "Missing type object"); + return 0; + } + if (none_allowed && obj == Py_None) return 1; + else if (exact) { + if (likely(Py_TYPE(obj) == type)) return 1; + #if PY_MAJOR_VERSION == 2 + else if ((type == &PyBaseString_Type) && likely(__Pyx_PyBaseString_CheckExact(obj))) return 1; + #endif + } + else { + if (likely(PyObject_TypeCheck(obj, type))) return 1; + } + __Pyx_RaiseArgumentTypeInvalid(name, obj, type); + return 0; +} + +static CYTHON_INLINE int __Pyx_IsLittleEndian(void) { + unsigned int n = 1; + return *(unsigned char*)(&n) != 0; +} +static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx, + __Pyx_BufFmt_StackElem* stack, + __Pyx_TypeInfo* type) { + stack[0].field = &ctx->root; + stack[0].parent_offset = 0; + ctx->root.type = type; + ctx->root.name = "buffer dtype"; + ctx->root.offset = 0; + ctx->head = stack; + ctx->head->field = &ctx->root; + ctx->fmt_offset = 0; + ctx->head->parent_offset = 0; + ctx->new_packmode = '@'; + ctx->enc_packmode = '@'; + ctx->new_count = 1; + ctx->enc_count = 0; + ctx->enc_type = 0; + ctx->is_complex = 0; + ctx->is_valid_array = 0; + ctx->struct_alignment = 0; + while (type->typegroup == 'S') { + ++ctx->head; + ctx->head->field = type->fields; + ctx->head->parent_offset = 0; + type = type->fields->type; + } +} +static int __Pyx_BufFmt_ParseNumber(const char** ts) { + int count; + const char* t = *ts; + if (*t < '0' || *t > '9') { + return -1; + } else { + count = *t++ - '0'; + while (*t >= '0' && *t < '9') { + count *= 10; + count += *t++ - '0'; + } + } + *ts = t; + return count; +} +static int __Pyx_BufFmt_ExpectNumber(const char **ts) { + int number = __Pyx_BufFmt_ParseNumber(ts); + if (number == -1) + PyErr_Format(PyExc_ValueError,\ + "Does not understand character buffer dtype format string ('%c')", **ts); + return number; +} +static void __Pyx_BufFmt_RaiseUnexpectedChar(char ch) { + PyErr_Format(PyExc_ValueError, + "Unexpected format string character: '%c'", ch); +} +static const char* __Pyx_BufFmt_DescribeTypeChar(char ch, int is_complex) { + switch (ch) { + case 'c': return "'char'"; + case 'b': return "'signed char'"; + case 'B': return "'unsigned char'"; + case 'h': return "'short'"; + case 'H': return "'unsigned short'"; + case 'i': return "'int'"; + case 'I': return "'unsigned int'"; + case 'l': return "'long'"; + case 'L': return "'unsigned long'"; + case 'q': return "'long long'"; + case 'Q': return "'unsigned long long'"; + case 'f': return (is_complex ? "'complex float'" : "'float'"); + case 'd': return (is_complex ? "'complex double'" : "'double'"); + case 'g': return (is_complex ? "'complex long double'" : "'long double'"); + case 'T': return "a struct"; + case 'O': return "Python object"; + case 'P': return "a pointer"; + case 's': case 'p': return "a string"; + case 0: return "end"; + default: return "unparseable format string"; + } +} +static size_t __Pyx_BufFmt_TypeCharToStandardSize(char ch, int is_complex) { + switch (ch) { + case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; + case 'h': case 'H': return 2; + case 'i': case 'I': case 'l': case 'L': return 4; + case 'q': case 'Q': return 8; + case 'f': return (is_complex ? 8 : 4); + case 'd': return (is_complex ? 16 : 8); + case 'g': { + PyErr_SetString(PyExc_ValueError, "Python does not define a standard format string size for long double ('g').."); + return 0; + } + case 'O': case 'P': return sizeof(void*); + default: + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; + } +} +static size_t __Pyx_BufFmt_TypeCharToNativeSize(char ch, int is_complex) { + switch (ch) { + case 'c': case 'b': case 'B': case 's': case 'p': return 1; + case 'h': case 'H': return sizeof(short); + case 'i': case 'I': return sizeof(int); + case 'l': case 'L': return sizeof(long); + #ifdef HAVE_LONG_LONG + case 'q': case 'Q': return sizeof(PY_LONG_LONG); + #endif + case 'f': return sizeof(float) * (is_complex ? 2 : 1); + case 'd': return sizeof(double) * (is_complex ? 2 : 1); + case 'g': return sizeof(long double) * (is_complex ? 2 : 1); + case 'O': case 'P': return sizeof(void*); + default: { + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; + } + } +} +typedef struct { char c; short x; } __Pyx_st_short; +typedef struct { char c; int x; } __Pyx_st_int; +typedef struct { char c; long x; } __Pyx_st_long; +typedef struct { char c; float x; } __Pyx_st_float; +typedef struct { char c; double x; } __Pyx_st_double; +typedef struct { char c; long double x; } __Pyx_st_longdouble; +typedef struct { char c; void *x; } __Pyx_st_void_p; +#ifdef HAVE_LONG_LONG +typedef struct { char c; PY_LONG_LONG x; } __Pyx_st_longlong; +#endif +static size_t __Pyx_BufFmt_TypeCharToAlignment(char ch, CYTHON_UNUSED int is_complex) { + switch (ch) { + case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; + case 'h': case 'H': return sizeof(__Pyx_st_short) - sizeof(short); + case 'i': case 'I': return sizeof(__Pyx_st_int) - sizeof(int); + case 'l': case 'L': return sizeof(__Pyx_st_long) - sizeof(long); +#ifdef HAVE_LONG_LONG + case 'q': case 'Q': return sizeof(__Pyx_st_longlong) - sizeof(PY_LONG_LONG); +#endif + case 'f': return sizeof(__Pyx_st_float) - sizeof(float); + case 'd': return sizeof(__Pyx_st_double) - sizeof(double); + case 'g': return sizeof(__Pyx_st_longdouble) - sizeof(long double); + case 'P': case 'O': return sizeof(__Pyx_st_void_p) - sizeof(void*); + default: + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; + } +} +/* These are for computing the padding at the end of the struct to align + on the first member of the struct. This will probably the same as above, + but we don't have any guarantees. + */ +typedef struct { short x; char c; } __Pyx_pad_short; +typedef struct { int x; char c; } __Pyx_pad_int; +typedef struct { long x; char c; } __Pyx_pad_long; +typedef struct { float x; char c; } __Pyx_pad_float; +typedef struct { double x; char c; } __Pyx_pad_double; +typedef struct { long double x; char c; } __Pyx_pad_longdouble; +typedef struct { void *x; char c; } __Pyx_pad_void_p; +#ifdef HAVE_LONG_LONG +typedef struct { PY_LONG_LONG x; char c; } __Pyx_pad_longlong; +#endif +static size_t __Pyx_BufFmt_TypeCharToPadding(char ch, CYTHON_UNUSED int is_complex) { + switch (ch) { + case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; + case 'h': case 'H': return sizeof(__Pyx_pad_short) - sizeof(short); + case 'i': case 'I': return sizeof(__Pyx_pad_int) - sizeof(int); + case 'l': case 'L': return sizeof(__Pyx_pad_long) - sizeof(long); +#ifdef HAVE_LONG_LONG + case 'q': case 'Q': return sizeof(__Pyx_pad_longlong) - sizeof(PY_LONG_LONG); +#endif + case 'f': return sizeof(__Pyx_pad_float) - sizeof(float); + case 'd': return sizeof(__Pyx_pad_double) - sizeof(double); + case 'g': return sizeof(__Pyx_pad_longdouble) - sizeof(long double); + case 'P': case 'O': return sizeof(__Pyx_pad_void_p) - sizeof(void*); + default: + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; + } +} +static char __Pyx_BufFmt_TypeCharToGroup(char ch, int is_complex) { + switch (ch) { + case 'c': + return 'H'; + case 'b': case 'h': case 'i': + case 'l': case 'q': case 's': case 'p': + return 'I'; + case 'B': case 'H': case 'I': case 'L': case 'Q': + return 'U'; + case 'f': case 'd': case 'g': + return (is_complex ? 'C' : 'R'); + case 'O': + return 'O'; + case 'P': + return 'P'; + default: { + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; + } + } +} +static void __Pyx_BufFmt_RaiseExpected(__Pyx_BufFmt_Context* ctx) { + if (ctx->head == NULL || ctx->head->field == &ctx->root) { + const char* expected; + const char* quote; + if (ctx->head == NULL) { + expected = "end"; + quote = ""; + } else { + expected = ctx->head->field->type->name; + quote = "'"; + } + PyErr_Format(PyExc_ValueError, + "Buffer dtype mismatch, expected %s%s%s but got %s", + quote, expected, quote, + __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex)); + } else { + __Pyx_StructField* field = ctx->head->field; + __Pyx_StructField* parent = (ctx->head - 1)->field; + PyErr_Format(PyExc_ValueError, + "Buffer dtype mismatch, expected '%s' but got %s in '%s.%s'", + field->type->name, __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex), + parent->type->name, field->name); + } +} +static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) { + char group; + size_t size, offset, arraysize = 1; + if (ctx->enc_type == 0) return 0; + if (ctx->head->field->type->arraysize[0]) { + int i, ndim = 0; + if (ctx->enc_type == 's' || ctx->enc_type == 'p') { + ctx->is_valid_array = ctx->head->field->type->ndim == 1; + ndim = 1; + if (ctx->enc_count != ctx->head->field->type->arraysize[0]) { + PyErr_Format(PyExc_ValueError, + "Expected a dimension of size %zu, got %zu", + ctx->head->field->type->arraysize[0], ctx->enc_count); + return -1; + } + } + if (!ctx->is_valid_array) { + PyErr_Format(PyExc_ValueError, "Expected %d dimensions, got %d", + ctx->head->field->type->ndim, ndim); + return -1; + } + for (i = 0; i < ctx->head->field->type->ndim; i++) { + arraysize *= ctx->head->field->type->arraysize[i]; + } + ctx->is_valid_array = 0; + ctx->enc_count = 1; + } + group = __Pyx_BufFmt_TypeCharToGroup(ctx->enc_type, ctx->is_complex); + do { + __Pyx_StructField* field = ctx->head->field; + __Pyx_TypeInfo* type = field->type; + if (ctx->enc_packmode == '@' || ctx->enc_packmode == '^') { + size = __Pyx_BufFmt_TypeCharToNativeSize(ctx->enc_type, ctx->is_complex); + } else { + size = __Pyx_BufFmt_TypeCharToStandardSize(ctx->enc_type, ctx->is_complex); + } + if (ctx->enc_packmode == '@') { + size_t align_at = __Pyx_BufFmt_TypeCharToAlignment(ctx->enc_type, ctx->is_complex); + size_t align_mod_offset; + if (align_at == 0) return -1; + align_mod_offset = ctx->fmt_offset % align_at; + if (align_mod_offset > 0) ctx->fmt_offset += align_at - align_mod_offset; + if (ctx->struct_alignment == 0) + ctx->struct_alignment = __Pyx_BufFmt_TypeCharToPadding(ctx->enc_type, + ctx->is_complex); + } + if (type->size != size || type->typegroup != group) { + if (type->typegroup == 'C' && type->fields != NULL) { + size_t parent_offset = ctx->head->parent_offset + field->offset; + ++ctx->head; + ctx->head->field = type->fields; + ctx->head->parent_offset = parent_offset; + continue; + } + if ((type->typegroup == 'H' || group == 'H') && type->size == size) { + } else { + __Pyx_BufFmt_RaiseExpected(ctx); + return -1; + } + } + offset = ctx->head->parent_offset + field->offset; + if (ctx->fmt_offset != offset) { + PyErr_Format(PyExc_ValueError, + "Buffer dtype mismatch; next field is at offset %" CYTHON_FORMAT_SSIZE_T "d but %" CYTHON_FORMAT_SSIZE_T "d expected", + (Py_ssize_t)ctx->fmt_offset, (Py_ssize_t)offset); + return -1; + } + ctx->fmt_offset += size; + if (arraysize) + ctx->fmt_offset += (arraysize - 1) * size; + --ctx->enc_count; + while (1) { + if (field == &ctx->root) { + ctx->head = NULL; + if (ctx->enc_count != 0) { + __Pyx_BufFmt_RaiseExpected(ctx); + return -1; + } + break; + } + ctx->head->field = ++field; + if (field->type == NULL) { + --ctx->head; + field = ctx->head->field; + continue; + } else if (field->type->typegroup == 'S') { + size_t parent_offset = ctx->head->parent_offset + field->offset; + if (field->type->fields->type == NULL) continue; + field = field->type->fields; + ++ctx->head; + ctx->head->field = field; + ctx->head->parent_offset = parent_offset; + break; + } else { + break; + } + } + } while (ctx->enc_count); + ctx->enc_type = 0; + ctx->is_complex = 0; + return 0; +} +static CYTHON_INLINE PyObject * +__pyx_buffmt_parse_array(__Pyx_BufFmt_Context* ctx, const char** tsp) +{ + const char *ts = *tsp; + int i = 0, number; + int ndim = ctx->head->field->type->ndim; +; + ++ts; + if (ctx->new_count != 1) { + PyErr_SetString(PyExc_ValueError, + "Cannot handle repeated arrays in format string"); + return NULL; + } + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + while (*ts && *ts != ')') { + switch (*ts) { + case ' ': case '\f': case '\r': case '\n': case '\t': case '\v': continue; + default: break; + } + number = __Pyx_BufFmt_ExpectNumber(&ts); + if (number == -1) return NULL; + if (i < ndim && (size_t) number != ctx->head->field->type->arraysize[i]) + return PyErr_Format(PyExc_ValueError, + "Expected a dimension of size %zu, got %d", + ctx->head->field->type->arraysize[i], number); + if (*ts != ',' && *ts != ')') + return PyErr_Format(PyExc_ValueError, + "Expected a comma in format string, got '%c'", *ts); + if (*ts == ',') ts++; + i++; + } + if (i != ndim) + return PyErr_Format(PyExc_ValueError, "Expected %d dimension(s), got %d", + ctx->head->field->type->ndim, i); + if (!*ts) { + PyErr_SetString(PyExc_ValueError, + "Unexpected end of format string, expected ')'"); + return NULL; + } + ctx->is_valid_array = 1; + ctx->new_count = 1; + *tsp = ++ts; + return Py_None; +} +static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts) { + int got_Z = 0; + while (1) { + switch(*ts) { + case 0: + if (ctx->enc_type != 0 && ctx->head == NULL) { + __Pyx_BufFmt_RaiseExpected(ctx); + return NULL; + } + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + if (ctx->head != NULL) { + __Pyx_BufFmt_RaiseExpected(ctx); + return NULL; + } + return ts; + case ' ': + case '\r': + case '\n': + ++ts; + break; + case '<': + if (!__Pyx_IsLittleEndian()) { + PyErr_SetString(PyExc_ValueError, "Little-endian buffer not supported on big-endian compiler"); + return NULL; + } + ctx->new_packmode = '='; + ++ts; + break; + case '>': + case '!': + if (__Pyx_IsLittleEndian()) { + PyErr_SetString(PyExc_ValueError, "Big-endian buffer not supported on little-endian compiler"); + return NULL; + } + ctx->new_packmode = '='; + ++ts; + break; + case '=': + case '@': + case '^': + ctx->new_packmode = *ts++; + break; + case 'T': + { + const char* ts_after_sub; + size_t i, struct_count = ctx->new_count; + size_t struct_alignment = ctx->struct_alignment; + ctx->new_count = 1; + ++ts; + if (*ts != '{') { + PyErr_SetString(PyExc_ValueError, "Buffer acquisition: Expected '{' after 'T'"); + return NULL; + } + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + ctx->enc_type = 0; + ctx->enc_count = 0; + ctx->struct_alignment = 0; + ++ts; + ts_after_sub = ts; + for (i = 0; i != struct_count; ++i) { + ts_after_sub = __Pyx_BufFmt_CheckString(ctx, ts); + if (!ts_after_sub) return NULL; + } + ts = ts_after_sub; + if (struct_alignment) ctx->struct_alignment = struct_alignment; + } + break; + case '}': + { + size_t alignment = ctx->struct_alignment; + ++ts; + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + ctx->enc_type = 0; + if (alignment && ctx->fmt_offset % alignment) { + ctx->fmt_offset += alignment - (ctx->fmt_offset % alignment); + } + } + return ts; + case 'x': + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + ctx->fmt_offset += ctx->new_count; + ctx->new_count = 1; + ctx->enc_count = 0; + ctx->enc_type = 0; + ctx->enc_packmode = ctx->new_packmode; + ++ts; + break; + case 'Z': + got_Z = 1; + ++ts; + if (*ts != 'f' && *ts != 'd' && *ts != 'g') { + __Pyx_BufFmt_RaiseUnexpectedChar('Z'); + return NULL; + } + case 'c': case 'b': case 'B': case 'h': case 'H': case 'i': case 'I': + case 'l': case 'L': case 'q': case 'Q': + case 'f': case 'd': case 'g': + case 'O': case 'p': + if (ctx->enc_type == *ts && got_Z == ctx->is_complex && + ctx->enc_packmode == ctx->new_packmode) { + ctx->enc_count += ctx->new_count; + ctx->new_count = 1; + got_Z = 0; + ++ts; + break; + } + case 's': + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + ctx->enc_count = ctx->new_count; + ctx->enc_packmode = ctx->new_packmode; + ctx->enc_type = *ts; + ctx->is_complex = got_Z; + ++ts; + ctx->new_count = 1; + got_Z = 0; + break; + case ':': + ++ts; + while(*ts != ':') ++ts; + ++ts; + break; + case '(': + if (!__pyx_buffmt_parse_array(ctx, &ts)) return NULL; + break; + default: + { + int number = __Pyx_BufFmt_ExpectNumber(&ts); + if (number == -1) return NULL; + ctx->new_count = (size_t)number; + } + } + } +} +static CYTHON_INLINE void __Pyx_ZeroBuffer(Py_buffer* buf) { + buf->buf = NULL; + buf->obj = NULL; + buf->strides = __Pyx_zeros; + buf->shape = __Pyx_zeros; + buf->suboffsets = __Pyx_minusones; +} +static CYTHON_INLINE int __Pyx_GetBufferAndValidate( + Py_buffer* buf, PyObject* obj, __Pyx_TypeInfo* dtype, int flags, + int nd, int cast, __Pyx_BufFmt_StackElem* stack) +{ + if (obj == Py_None || obj == NULL) { + __Pyx_ZeroBuffer(buf); + return 0; + } + buf->buf = NULL; + if (__Pyx_GetBuffer(obj, buf, flags) == -1) goto fail; + if (buf->ndim != nd) { + PyErr_Format(PyExc_ValueError, + "Buffer has wrong number of dimensions (expected %d, got %d)", + nd, buf->ndim); + goto fail; + } + if (!cast) { + __Pyx_BufFmt_Context ctx; + __Pyx_BufFmt_Init(&ctx, stack, dtype); + if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail; + } + if ((unsigned)buf->itemsize != dtype->size) { + PyErr_Format(PyExc_ValueError, + "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "d byte%s) does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "d byte%s)", + buf->itemsize, (buf->itemsize > 1) ? "s" : "", + dtype->name, (Py_ssize_t)dtype->size, (dtype->size > 1) ? "s" : ""); + goto fail; + } + if (buf->suboffsets == NULL) buf->suboffsets = __Pyx_minusones; + return 0; +fail:; + __Pyx_ZeroBuffer(buf); + return -1; +} +static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) { + if (info->buf == NULL) return; + if (info->suboffsets == __Pyx_minusones) info->suboffsets = NULL; + __Pyx_ReleaseBuffer(info); +} + +static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name) { + PyObject *result; +#if CYTHON_COMPILING_IN_CPYTHON + result = PyDict_GetItem(__pyx_d, name); + if (likely(result)) { + Py_INCREF(result); + } else { +#else + result = PyObject_GetItem(__pyx_d, name); + if (!result) { + PyErr_Clear(); +#endif + result = __Pyx_GetBuiltinName(name); + } + return result; +} + +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) { + PyObject *result; + ternaryfunc call = func->ob_type->tp_call; + if (unlikely(!call)) + return PyObject_Call(func, arg, kw); + if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) + return NULL; + result = (*call)(func, arg, kw); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) { + PyObject *self, *result; + PyCFunction cfunc; + cfunc = PyCFunction_GET_FUNCTION(func); + self = PyCFunction_GET_SELF(func); + if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) + return NULL; + result = cfunc(self, arg); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +#if CYTHON_COMPILING_IN_CPYTHON +static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) { + PyObject *result; + PyObject *args = PyTuple_New(1); + if (unlikely(!args)) return NULL; + Py_INCREF(arg); + PyTuple_SET_ITEM(args, 0, arg); + result = __Pyx_PyObject_Call(func, args, NULL); + Py_DECREF(args); + return result; +} +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { +#ifdef __Pyx_CyFunction_USED + if (likely(PyCFunction_Check(func) || PyObject_TypeCheck(func, __pyx_CyFunctionType))) { +#else + if (likely(PyCFunction_Check(func))) { +#endif + if (likely(PyCFunction_GET_FLAGS(func) & METH_O)) { + return __Pyx_PyObject_CallMethO(func, arg); + } + } + return __Pyx__PyObject_CallOneArg(func, arg); +} +#else +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { + PyObject* args = PyTuple_Pack(1, arg); + return (likely(args)) ? __Pyx_PyObject_Call(func, args, NULL) : NULL; +} +#endif + +static void __Pyx_RaiseBufferIndexError(int axis) { + PyErr_Format(PyExc_IndexError, + "Out of bounds on buffer access (axis %d)", axis); +} + +static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) { +#if CYTHON_COMPILING_IN_CPYTHON + PyObject *tmp_type, *tmp_value, *tmp_tb; + PyThreadState *tstate = PyThreadState_GET(); + tmp_type = tstate->curexc_type; + tmp_value = tstate->curexc_value; + tmp_tb = tstate->curexc_traceback; + tstate->curexc_type = type; + tstate->curexc_value = value; + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +#else + PyErr_Restore(type, value, tb); +#endif +} +static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) { +#if CYTHON_COMPILING_IN_CPYTHON + PyThreadState *tstate = PyThreadState_GET(); + *type = tstate->curexc_type; + *value = tstate->curexc_value; + *tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; +#else + PyErr_Fetch(type, value, tb); +#endif +} + +static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) { + PyErr_Format(PyExc_ValueError, + "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected); +} + +static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) { + PyErr_Format(PyExc_ValueError, + "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack", + index, (index == 1) ? "" : "s"); +} + +static CYTHON_INLINE int __Pyx_IterFinish(void) { +#if CYTHON_COMPILING_IN_CPYTHON + PyThreadState *tstate = PyThreadState_GET(); + PyObject* exc_type = tstate->curexc_type; + if (unlikely(exc_type)) { + if (likely(exc_type == PyExc_StopIteration) || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration)) { + PyObject *exc_value, *exc_tb; + exc_value = tstate->curexc_value; + exc_tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; + Py_DECREF(exc_type); + Py_XDECREF(exc_value); + Py_XDECREF(exc_tb); + return 0; + } else { + return -1; + } + } + return 0; +#else + if (unlikely(PyErr_Occurred())) { + if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) { + PyErr_Clear(); + return 0; + } else { + return -1; + } + } + return 0; +#endif +} + +static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) { + if (unlikely(retval)) { + Py_DECREF(retval); + __Pyx_RaiseTooManyValuesError(expected); + return -1; + } else { + return __Pyx_IterFinish(); + } + return 0; +} + +#if PY_MAJOR_VERSION < 3 +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, + CYTHON_UNUSED PyObject *cause) { + Py_XINCREF(type); + if (!value || value == Py_None) + value = NULL; + else + Py_INCREF(value); + if (!tb || tb == Py_None) + tb = NULL; + else { + Py_INCREF(tb); + if (!PyTraceBack_Check(tb)) { + PyErr_SetString(PyExc_TypeError, + "raise: arg 3 must be a traceback or None"); + goto raise_error; + } + } + if (PyType_Check(type)) { +#if CYTHON_COMPILING_IN_PYPY + if (!value) { + Py_INCREF(Py_None); + value = Py_None; + } +#endif + PyErr_NormalizeException(&type, &value, &tb); + } else { + if (value) { + PyErr_SetString(PyExc_TypeError, + "instance exception may not have a separate value"); + goto raise_error; + } + value = type; + type = (PyObject*) Py_TYPE(type); + Py_INCREF(type); + if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) { + PyErr_SetString(PyExc_TypeError, + "raise: exception class must be a subclass of BaseException"); + goto raise_error; + } + } + __Pyx_ErrRestore(type, value, tb); + return; +raise_error: + Py_XDECREF(value); + Py_XDECREF(type); + Py_XDECREF(tb); + return; +} +#else +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { + PyObject* owned_instance = NULL; + if (tb == Py_None) { + tb = 0; + } else if (tb && !PyTraceBack_Check(tb)) { + PyErr_SetString(PyExc_TypeError, + "raise: arg 3 must be a traceback or None"); + goto bad; + } + if (value == Py_None) + value = 0; + if (PyExceptionInstance_Check(type)) { + if (value) { + PyErr_SetString(PyExc_TypeError, + "instance exception may not have a separate value"); + goto bad; + } + value = type; + type = (PyObject*) Py_TYPE(value); + } else if (PyExceptionClass_Check(type)) { + PyObject *instance_class = NULL; + if (value && PyExceptionInstance_Check(value)) { + instance_class = (PyObject*) Py_TYPE(value); + if (instance_class != type) { + int is_subclass = PyObject_IsSubclass(instance_class, type); + if (!is_subclass) { + instance_class = NULL; + } else if (unlikely(is_subclass == -1)) { + goto bad; + } else { + type = instance_class; + } + } + } + if (!instance_class) { + PyObject *args; + if (!value) + args = PyTuple_New(0); + else if (PyTuple_Check(value)) { + Py_INCREF(value); + args = value; + } else + args = PyTuple_Pack(1, value); + if (!args) + goto bad; + owned_instance = PyObject_Call(type, args, NULL); + Py_DECREF(args); + if (!owned_instance) + goto bad; + value = owned_instance; + if (!PyExceptionInstance_Check(value)) { + PyErr_Format(PyExc_TypeError, + "calling %R should have returned an instance of " + "BaseException, not %R", + type, Py_TYPE(value)); + goto bad; + } + } + } else { + PyErr_SetString(PyExc_TypeError, + "raise: exception class must be a subclass of BaseException"); + goto bad; + } +#if PY_VERSION_HEX >= 0x03030000 + if (cause) { +#else + if (cause && cause != Py_None) { +#endif + PyObject *fixed_cause; + if (cause == Py_None) { + fixed_cause = NULL; + } else if (PyExceptionClass_Check(cause)) { + fixed_cause = PyObject_CallObject(cause, NULL); + if (fixed_cause == NULL) + goto bad; + } else if (PyExceptionInstance_Check(cause)) { + fixed_cause = cause; + Py_INCREF(fixed_cause); + } else { + PyErr_SetString(PyExc_TypeError, + "exception causes must derive from " + "BaseException"); + goto bad; + } + PyException_SetCause(value, fixed_cause); + } + PyErr_SetObject(type, value); + if (tb) { +#if CYTHON_COMPILING_IN_PYPY + PyObject *tmp_type, *tmp_value, *tmp_tb; + PyErr_Fetch(&tmp_type, &tmp_value, &tmp_tb); + Py_INCREF(tb); + PyErr_Restore(tmp_type, tmp_value, tb); + Py_XDECREF(tmp_tb); +#else + PyThreadState *tstate = PyThreadState_GET(); + PyObject* tmp_tb = tstate->curexc_traceback; + if (tb != tmp_tb) { + Py_INCREF(tb); + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_tb); + } +#endif + } +bad: + Py_XDECREF(owned_instance); + return; +} +#endif + +static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); +} + +static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) { + if (unlikely(!type)) { + PyErr_SetString(PyExc_SystemError, "Missing type object"); + return 0; + } + if (likely(PyObject_TypeCheck(obj, type))) + return 1; + PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s", + Py_TYPE(obj)->tp_name, type->tp_name); + return 0; +} + +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { + int start = 0, mid = 0, end = count - 1; + if (end >= 0 && code_line > entries[end].code_line) { + return count; + } + while (start < end) { + mid = (start + end) / 2; + if (code_line < entries[mid].code_line) { + end = mid; + } else if (code_line > entries[mid].code_line) { + start = mid + 1; + } else { + return mid; + } + } + if (code_line <= entries[mid].code_line) { + return mid; + } else { + return mid + 1; + } +} +static PyCodeObject *__pyx_find_code_object(int code_line) { + PyCodeObject* code_object; + int pos; + if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) { + return NULL; + } + pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); + if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) { + return NULL; + } + code_object = __pyx_code_cache.entries[pos].code_object; + Py_INCREF(code_object); + return code_object; +} +static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) { + int pos, i; + __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries; + if (unlikely(!code_line)) { + return; + } + if (unlikely(!entries)) { + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry)); + if (likely(entries)) { + __pyx_code_cache.entries = entries; + __pyx_code_cache.max_count = 64; + __pyx_code_cache.count = 1; + entries[0].code_line = code_line; + entries[0].code_object = code_object; + Py_INCREF(code_object); + } + return; + } + pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); + if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) { + PyCodeObject* tmp = entries[pos].code_object; + entries[pos].code_object = code_object; + Py_DECREF(tmp); + return; + } + if (__pyx_code_cache.count == __pyx_code_cache.max_count) { + int new_max = __pyx_code_cache.max_count + 64; + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc( + __pyx_code_cache.entries, (size_t)new_max*sizeof(__Pyx_CodeObjectCacheEntry)); + if (unlikely(!entries)) { + return; + } + __pyx_code_cache.entries = entries; + __pyx_code_cache.max_count = new_max; + } + for (i=__pyx_code_cache.count; i>pos; i--) { + entries[i] = entries[i-1]; + } + entries[pos].code_line = code_line; + entries[pos].code_object = code_object; + __pyx_code_cache.count++; + Py_INCREF(code_object); +} + +#include "compile.h" +#include "frameobject.h" +#include "traceback.h" +static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( + const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = 0; + PyObject *py_srcfile = 0; + PyObject *py_funcname = 0; + #if PY_MAJOR_VERSION < 3 + py_srcfile = PyString_FromString(filename); + #else + py_srcfile = PyUnicode_FromString(filename); + #endif + if (!py_srcfile) goto bad; + if (c_line) { + #if PY_MAJOR_VERSION < 3 + py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + #else + py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + #endif + } + else { + #if PY_MAJOR_VERSION < 3 + py_funcname = PyString_FromString(funcname); + #else + py_funcname = PyUnicode_FromString(funcname); + #endif + } + if (!py_funcname) goto bad; + py_code = __Pyx_PyCode_New( + 0, + 0, + 0, + 0, + 0, + __pyx_empty_bytes, /*PyObject *code,*/ + __pyx_empty_tuple, /*PyObject *consts,*/ + __pyx_empty_tuple, /*PyObject *names,*/ + __pyx_empty_tuple, /*PyObject *varnames,*/ + __pyx_empty_tuple, /*PyObject *freevars,*/ + __pyx_empty_tuple, /*PyObject *cellvars,*/ + py_srcfile, /*PyObject *filename,*/ + py_funcname, /*PyObject *name,*/ + py_line, + __pyx_empty_bytes /*PyObject *lnotab*/ + ); + Py_DECREF(py_srcfile); + Py_DECREF(py_funcname); + return py_code; +bad: + Py_XDECREF(py_srcfile); + Py_XDECREF(py_funcname); + return NULL; +} +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = 0; + PyFrameObject *py_frame = 0; + py_code = __pyx_find_code_object(c_line ? c_line : py_line); + if (!py_code) { + py_code = __Pyx_CreateCodeObjectForTraceback( + funcname, c_line, py_line, filename); + if (!py_code) goto bad; + __pyx_insert_code_object(c_line ? c_line : py_line, py_code); + } + py_frame = PyFrame_New( + PyThreadState_GET(), /*PyThreadState *tstate,*/ + py_code, /*PyCodeObject *code,*/ + __pyx_d, /*PyObject *globals,*/ + 0 /*PyObject *locals*/ + ); + if (!py_frame) goto bad; + py_frame->f_lineno = py_line; + PyTraceBack_Here(py_frame); +bad: + Py_XDECREF(py_code); + Py_XDECREF(py_frame); +} + +#if PY_MAJOR_VERSION < 3 +static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags) { + if (PyObject_CheckBuffer(obj)) return PyObject_GetBuffer(obj, view, flags); + if (PyObject_TypeCheck(obj, __pyx_ptype_5numpy_ndarray)) return __pyx_pw_5numpy_7ndarray_1__getbuffer__(obj, view, flags); + PyErr_Format(PyExc_TypeError, "'%.200s' does not have the buffer interface", Py_TYPE(obj)->tp_name); + return -1; +} +static void __Pyx_ReleaseBuffer(Py_buffer *view) { + PyObject *obj = view->obj; + if (!obj) return; + if (PyObject_CheckBuffer(obj)) { + PyBuffer_Release(view); + return; + } + if (PyObject_TypeCheck(obj, __pyx_ptype_5numpy_ndarray)) { __pyx_pw_5numpy_7ndarray_3__releasebuffer__(obj, view); return; } + Py_DECREF(obj); + view->obj = NULL; +} +#endif + + + static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) { + PyObject *empty_list = 0; + PyObject *module = 0; + PyObject *global_dict = 0; + PyObject *empty_dict = 0; + PyObject *list; + #if PY_VERSION_HEX < 0x03030000 + PyObject *py_import; + py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import); + if (!py_import) + goto bad; + #endif + if (from_list) + list = from_list; + else { + empty_list = PyList_New(0); + if (!empty_list) + goto bad; + list = empty_list; + } + global_dict = PyModule_GetDict(__pyx_m); + if (!global_dict) + goto bad; + empty_dict = PyDict_New(); + if (!empty_dict) + goto bad; + { + #if PY_MAJOR_VERSION >= 3 + if (level == -1) { + if (strchr(__Pyx_MODULE_NAME, '.')) { + #if PY_VERSION_HEX < 0x03030000 + PyObject *py_level = PyInt_FromLong(1); + if (!py_level) + goto bad; + module = PyObject_CallFunctionObjArgs(py_import, + name, global_dict, empty_dict, list, py_level, NULL); + Py_DECREF(py_level); + #else + module = PyImport_ImportModuleLevelObject( + name, global_dict, empty_dict, list, 1); + #endif + if (!module) { + if (!PyErr_ExceptionMatches(PyExc_ImportError)) + goto bad; + PyErr_Clear(); + } + } + level = 0; + } + #endif + if (!module) { + #if PY_VERSION_HEX < 0x03030000 + PyObject *py_level = PyInt_FromLong(level); + if (!py_level) + goto bad; + module = PyObject_CallFunctionObjArgs(py_import, + name, global_dict, empty_dict, list, py_level, NULL); + Py_DECREF(py_level); + #else + module = PyImport_ImportModuleLevelObject( + name, global_dict, empty_dict, list, level); + #endif + } + } +bad: + #if PY_VERSION_HEX < 0x03030000 + Py_XDECREF(py_import); + #endif + Py_XDECREF(empty_list); + Py_XDECREF(empty_dict); + return module; +} + +#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value) \ + { \ + func_type value = func_value; \ + if (sizeof(target_type) < sizeof(func_type)) { \ + if (unlikely(value != (func_type) (target_type) value)) { \ + func_type zero = 0; \ + if (is_unsigned && unlikely(value < zero)) \ + goto raise_neg_overflow; \ + else \ + goto raise_overflow; \ + } \ + } \ + return (target_type) value; \ + } + +#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 + #if CYTHON_USE_PYLONG_INTERNALS + #include "longintrepr.h" + #endif +#endif + +static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { + const int neg_one = (int) -1, const_zero = 0; + const int is_unsigned = neg_one > const_zero; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x))) { + if (sizeof(int) < sizeof(long)) { + __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x)) + } else { + long val = PyInt_AS_LONG(x); + if (is_unsigned && unlikely(val < 0)) { + goto raise_neg_overflow; + } + return (int) val; + } + } else +#endif + if (likely(PyLong_Check(x))) { + if (is_unsigned) { +#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 + #if CYTHON_USE_PYLONG_INTERNALS + switch (Py_SIZE(x)) { + case 0: return 0; + case 1: __PYX_VERIFY_RETURN_INT(int, digit, ((PyLongObject*)x)->ob_digit[0]); + } + #endif +#endif +#if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (int) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if (sizeof(int) <= sizeof(unsigned long)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, PyLong_AsUnsignedLong(x)) + } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) + } + } else { +#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 + #if CYTHON_USE_PYLONG_INTERNALS + switch (Py_SIZE(x)) { + case 0: return 0; + case 1: __PYX_VERIFY_RETURN_INT(int, digit, +(((PyLongObject*)x)->ob_digit[0])); + case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]); + } + #endif +#endif + if (sizeof(int) <= sizeof(long)) { + __PYX_VERIFY_RETURN_INT(int, long, PyLong_AsLong(x)) + } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT(int, PY_LONG_LONG, PyLong_AsLongLong(x)) + } + } + { +#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) + PyErr_SetString(PyExc_RuntimeError, + "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); +#else + int val; + PyObject *v = __Pyx_PyNumber_Int(x); + #if PY_MAJOR_VERSION < 3 + if (likely(v) && !PyLong_Check(v)) { + PyObject *tmp = v; + v = PyNumber_Long(tmp); + Py_DECREF(tmp); + } + #endif + if (likely(v)) { + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + int ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); + Py_DECREF(v); + if (likely(!ret)) + return val; + } +#endif + return (int) -1; + } + } else { + int val; + PyObject *tmp = __Pyx_PyNumber_Int(x); + if (!tmp) return (int) -1; + val = __Pyx_PyInt_As_int(tmp); + Py_DECREF(tmp); + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to int"); + return (int) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to int"); + return (int) -1; +} + +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) { + const int neg_one = (int) -1, const_zero = 0; + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(int) < sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(int) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); + } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); + } + } else { + if (sizeof(int) <= sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); + } + } + { + int one = 1; int little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&value; + return _PyLong_FromByteArray(bytes, sizeof(int), + little, !is_unsigned); + } +} + +#if CYTHON_CCOMPLEX + #ifdef __cplusplus + static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) { + return ::std::complex< float >(x, y); + } + #else + static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) { + return x + y*(__pyx_t_float_complex)_Complex_I; + } + #endif +#else + static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) { + __pyx_t_float_complex z; + z.real = x; + z.imag = y; + return z; + } +#endif + +#if CYTHON_CCOMPLEX +#else + static CYTHON_INLINE int __Pyx_c_eqf(__pyx_t_float_complex a, __pyx_t_float_complex b) { + return (a.real == b.real) && (a.imag == b.imag); + } + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sumf(__pyx_t_float_complex a, __pyx_t_float_complex b) { + __pyx_t_float_complex z; + z.real = a.real + b.real; + z.imag = a.imag + b.imag; + return z; + } + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_difff(__pyx_t_float_complex a, __pyx_t_float_complex b) { + __pyx_t_float_complex z; + z.real = a.real - b.real; + z.imag = a.imag - b.imag; + return z; + } + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prodf(__pyx_t_float_complex a, __pyx_t_float_complex b) { + __pyx_t_float_complex z; + z.real = a.real * b.real - a.imag * b.imag; + z.imag = a.real * b.imag + a.imag * b.real; + return z; + } + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quotf(__pyx_t_float_complex a, __pyx_t_float_complex b) { + __pyx_t_float_complex z; + float denom = b.real * b.real + b.imag * b.imag; + z.real = (a.real * b.real + a.imag * b.imag) / denom; + z.imag = (a.imag * b.real - a.real * b.imag) / denom; + return z; + } + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_negf(__pyx_t_float_complex a) { + __pyx_t_float_complex z; + z.real = -a.real; + z.imag = -a.imag; + return z; + } + static CYTHON_INLINE int __Pyx_c_is_zerof(__pyx_t_float_complex a) { + return (a.real == 0) && (a.imag == 0); + } + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conjf(__pyx_t_float_complex a) { + __pyx_t_float_complex z; + z.real = a.real; + z.imag = -a.imag; + return z; + } + #if 1 + static CYTHON_INLINE float __Pyx_c_absf(__pyx_t_float_complex z) { + #if !defined(HAVE_HYPOT) || defined(_MSC_VER) + return sqrtf(z.real*z.real + z.imag*z.imag); + #else + return hypotf(z.real, z.imag); + #endif + } + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_powf(__pyx_t_float_complex a, __pyx_t_float_complex b) { + __pyx_t_float_complex z; + float r, lnr, theta, z_r, z_theta; + if (b.imag == 0 && b.real == (int)b.real) { + if (b.real < 0) { + float denom = a.real * a.real + a.imag * a.imag; + a.real = a.real / denom; + a.imag = -a.imag / denom; + b.real = -b.real; + } + switch ((int)b.real) { + case 0: + z.real = 1; + z.imag = 0; + return z; + case 1: + return a; + case 2: + z = __Pyx_c_prodf(a, a); + return __Pyx_c_prodf(a, a); + case 3: + z = __Pyx_c_prodf(a, a); + return __Pyx_c_prodf(z, a); + case 4: + z = __Pyx_c_prodf(a, a); + return __Pyx_c_prodf(z, z); + } + } + if (a.imag == 0) { + if (a.real == 0) { + return a; + } + r = a.real; + theta = 0; + } else { + r = __Pyx_c_absf(a); + theta = atan2f(a.imag, a.real); + } + lnr = logf(r); + z_r = expf(lnr * b.real - theta * b.imag); + z_theta = theta * b.real + lnr * b.imag; + z.real = z_r * cosf(z_theta); + z.imag = z_r * sinf(z_theta); + return z; + } + #endif +#endif + +#if CYTHON_CCOMPLEX + #ifdef __cplusplus + static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { + return ::std::complex< double >(x, y); + } + #else + static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { + return x + y*(__pyx_t_double_complex)_Complex_I; + } + #endif +#else + static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { + __pyx_t_double_complex z; + z.real = x; + z.imag = y; + return z; + } +#endif + +#if CYTHON_CCOMPLEX +#else + static CYTHON_INLINE int __Pyx_c_eq(__pyx_t_double_complex a, __pyx_t_double_complex b) { + return (a.real == b.real) && (a.imag == b.imag); + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum(__pyx_t_double_complex a, __pyx_t_double_complex b) { + __pyx_t_double_complex z; + z.real = a.real + b.real; + z.imag = a.imag + b.imag; + return z; + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff(__pyx_t_double_complex a, __pyx_t_double_complex b) { + __pyx_t_double_complex z; + z.real = a.real - b.real; + z.imag = a.imag - b.imag; + return z; + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod(__pyx_t_double_complex a, __pyx_t_double_complex b) { + __pyx_t_double_complex z; + z.real = a.real * b.real - a.imag * b.imag; + z.imag = a.real * b.imag + a.imag * b.real; + return z; + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot(__pyx_t_double_complex a, __pyx_t_double_complex b) { + __pyx_t_double_complex z; + double denom = b.real * b.real + b.imag * b.imag; + z.real = (a.real * b.real + a.imag * b.imag) / denom; + z.imag = (a.imag * b.real - a.real * b.imag) / denom; + return z; + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg(__pyx_t_double_complex a) { + __pyx_t_double_complex z; + z.real = -a.real; + z.imag = -a.imag; + return z; + } + static CYTHON_INLINE int __Pyx_c_is_zero(__pyx_t_double_complex a) { + return (a.real == 0) && (a.imag == 0); + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj(__pyx_t_double_complex a) { + __pyx_t_double_complex z; + z.real = a.real; + z.imag = -a.imag; + return z; + } + #if 1 + static CYTHON_INLINE double __Pyx_c_abs(__pyx_t_double_complex z) { + #if !defined(HAVE_HYPOT) || defined(_MSC_VER) + return sqrt(z.real*z.real + z.imag*z.imag); + #else + return hypot(z.real, z.imag); + #endif + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow(__pyx_t_double_complex a, __pyx_t_double_complex b) { + __pyx_t_double_complex z; + double r, lnr, theta, z_r, z_theta; + if (b.imag == 0 && b.real == (int)b.real) { + if (b.real < 0) { + double denom = a.real * a.real + a.imag * a.imag; + a.real = a.real / denom; + a.imag = -a.imag / denom; + b.real = -b.real; + } + switch ((int)b.real) { + case 0: + z.real = 1; + z.imag = 0; + return z; + case 1: + return a; + case 2: + z = __Pyx_c_prod(a, a); + return __Pyx_c_prod(a, a); + case 3: + z = __Pyx_c_prod(a, a); + return __Pyx_c_prod(z, a); + case 4: + z = __Pyx_c_prod(a, a); + return __Pyx_c_prod(z, z); + } + } + if (a.imag == 0) { + if (a.real == 0) { + return a; + } + r = a.real; + theta = 0; + } else { + r = __Pyx_c_abs(a); + theta = atan2(a.imag, a.real); + } + lnr = log(r); + z_r = exp(lnr * b.real - theta * b.imag); + z_theta = theta * b.real + lnr * b.imag; + z.real = z_r * cos(z_theta); + z.imag = z_r * sin(z_theta); + return z; + } + #endif +#endif + +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { + const long neg_one = (long) -1, const_zero = 0; + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(long) < sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(long) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); + } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); + } + } else { + if (sizeof(long) <= sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); + } + } + { + int one = 1; int little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&value; + return _PyLong_FromByteArray(bytes, sizeof(long), + little, !is_unsigned); + } +} + +static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { + const long neg_one = (long) -1, const_zero = 0; + const int is_unsigned = neg_one > const_zero; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x))) { + if (sizeof(long) < sizeof(long)) { + __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x)) + } else { + long val = PyInt_AS_LONG(x); + if (is_unsigned && unlikely(val < 0)) { + goto raise_neg_overflow; + } + return (long) val; + } + } else +#endif + if (likely(PyLong_Check(x))) { + if (is_unsigned) { +#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 + #if CYTHON_USE_PYLONG_INTERNALS + switch (Py_SIZE(x)) { + case 0: return 0; + case 1: __PYX_VERIFY_RETURN_INT(long, digit, ((PyLongObject*)x)->ob_digit[0]); + } + #endif +#endif +#if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (long) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if (sizeof(long) <= sizeof(unsigned long)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, PyLong_AsUnsignedLong(x)) + } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) + } + } else { +#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 + #if CYTHON_USE_PYLONG_INTERNALS + switch (Py_SIZE(x)) { + case 0: return 0; + case 1: __PYX_VERIFY_RETURN_INT(long, digit, +(((PyLongObject*)x)->ob_digit[0])); + case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]); + } + #endif +#endif + if (sizeof(long) <= sizeof(long)) { + __PYX_VERIFY_RETURN_INT(long, long, PyLong_AsLong(x)) + } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT(long, PY_LONG_LONG, PyLong_AsLongLong(x)) + } + } + { +#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) + PyErr_SetString(PyExc_RuntimeError, + "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); +#else + long val; + PyObject *v = __Pyx_PyNumber_Int(x); + #if PY_MAJOR_VERSION < 3 + if (likely(v) && !PyLong_Check(v)) { + PyObject *tmp = v; + v = PyNumber_Long(tmp); + Py_DECREF(tmp); + } + #endif + if (likely(v)) { + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + int ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); + Py_DECREF(v); + if (likely(!ret)) + return val; + } +#endif + return (long) -1; + } + } else { + long val; + PyObject *tmp = __Pyx_PyNumber_Int(x); + if (!tmp) return (long) -1; + val = __Pyx_PyInt_As_long(tmp); + Py_DECREF(tmp); + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to long"); + return (long) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to long"); + return (long) -1; +} + +static int __Pyx_check_binary_version(void) { + char ctversion[4], rtversion[4]; + PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION); + PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion()); + if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) { + char message[200]; + PyOS_snprintf(message, sizeof(message), + "compiletime version %s of module '%.100s' " + "does not match runtime version %s", + ctversion, __Pyx_MODULE_NAME, rtversion); + return PyErr_WarnEx(NULL, message, 1); + } + return 0; +} + +#ifndef __PYX_HAVE_RT_ImportModule +#define __PYX_HAVE_RT_ImportModule +static PyObject *__Pyx_ImportModule(const char *name) { + PyObject *py_name = 0; + PyObject *py_module = 0; + py_name = __Pyx_PyIdentifier_FromString(name); + if (!py_name) + goto bad; + py_module = PyImport_Import(py_name); + Py_DECREF(py_name); + return py_module; +bad: + Py_XDECREF(py_name); + return 0; +} +#endif + +#ifndef __PYX_HAVE_RT_ImportType +#define __PYX_HAVE_RT_ImportType +static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, + size_t size, int strict) +{ + PyObject *py_module = 0; + PyObject *result = 0; + PyObject *py_name = 0; + char warning[200]; + Py_ssize_t basicsize; +#ifdef Py_LIMITED_API + PyObject *py_basicsize; +#endif + py_module = __Pyx_ImportModule(module_name); + if (!py_module) + goto bad; + py_name = __Pyx_PyIdentifier_FromString(class_name); + if (!py_name) + goto bad; + result = PyObject_GetAttr(py_module, py_name); + Py_DECREF(py_name); + py_name = 0; + Py_DECREF(py_module); + py_module = 0; + if (!result) + goto bad; + if (!PyType_Check(result)) { + PyErr_Format(PyExc_TypeError, + "%.200s.%.200s is not a type object", + module_name, class_name); + goto bad; + } +#ifndef Py_LIMITED_API + basicsize = ((PyTypeObject *)result)->tp_basicsize; +#else + py_basicsize = PyObject_GetAttrString(result, "__basicsize__"); + if (!py_basicsize) + goto bad; + basicsize = PyLong_AsSsize_t(py_basicsize); + Py_DECREF(py_basicsize); + py_basicsize = 0; + if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred()) + goto bad; +#endif + if (!strict && (size_t)basicsize > size) { + PyOS_snprintf(warning, sizeof(warning), + "%s.%s size changed, may indicate binary incompatibility", + module_name, class_name); + if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad; + } + else if ((size_t)basicsize != size) { + PyErr_Format(PyExc_ValueError, + "%.200s.%.200s has the wrong size, try recompiling", + module_name, class_name); + goto bad; + } + return (PyTypeObject *)result; +bad: + Py_XDECREF(py_module); + Py_XDECREF(result); + return NULL; +} +#endif + +static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { + while (t->p) { + #if PY_MAJOR_VERSION < 3 + if (t->is_unicode) { + *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL); + } else if (t->intern) { + *t->p = PyString_InternFromString(t->s); + } else { + *t->p = PyString_FromStringAndSize(t->s, t->n - 1); + } + #else + if (t->is_unicode | t->is_str) { + if (t->intern) { + *t->p = PyUnicode_InternFromString(t->s); + } else if (t->encoding) { + *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL); + } else { + *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1); + } + } else { + *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1); + } + #endif + if (!*t->p) + return -1; + ++t; + } + return 0; +} + +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { + return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str)); +} +static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject* o) { + Py_ssize_t ignore; + return __Pyx_PyObject_AsStringAndSize(o, &ignore); +} +static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) { +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT + if ( +#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + __Pyx_sys_getdefaultencoding_not_ascii && +#endif + PyUnicode_Check(o)) { +#if PY_VERSION_HEX < 0x03030000 + char* defenc_c; + PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL); + if (!defenc) return NULL; + defenc_c = PyBytes_AS_STRING(defenc); +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + { + char* end = defenc_c + PyBytes_GET_SIZE(defenc); + char* c; + for (c = defenc_c; c < end; c++) { + if ((unsigned char) (*c) >= 128) { + PyUnicode_AsASCIIString(o); + return NULL; + } + } + } +#endif + *length = PyBytes_GET_SIZE(defenc); + return defenc_c; +#else + if (__Pyx_PyUnicode_READY(o) == -1) return NULL; +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + if (PyUnicode_IS_ASCII(o)) { + *length = PyUnicode_GET_LENGTH(o); + return PyUnicode_AsUTF8(o); + } else { + PyUnicode_AsASCIIString(o); + return NULL; + } +#else + return PyUnicode_AsUTF8AndSize(o, length); +#endif +#endif + } else +#endif +#if !CYTHON_COMPILING_IN_PYPY + if (PyByteArray_Check(o)) { + *length = PyByteArray_GET_SIZE(o); + return PyByteArray_AS_STRING(o); + } else +#endif + { + char* result; + int r = PyBytes_AsStringAndSize(o, &result, length); + if (unlikely(r < 0)) { + return NULL; + } else { + return result; + } + } +} +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { + int is_true = x == Py_True; + if (is_true | (x == Py_False) | (x == Py_None)) return is_true; + else return PyObject_IsTrue(x); +} +static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) { + PyNumberMethods *m; + const char *name = NULL; + PyObject *res = NULL; +#if PY_MAJOR_VERSION < 3 + if (PyInt_Check(x) || PyLong_Check(x)) +#else + if (PyLong_Check(x)) +#endif + return Py_INCREF(x), x; + m = Py_TYPE(x)->tp_as_number; +#if PY_MAJOR_VERSION < 3 + if (m && m->nb_int) { + name = "int"; + res = PyNumber_Int(x); + } + else if (m && m->nb_long) { + name = "long"; + res = PyNumber_Long(x); + } +#else + if (m && m->nb_int) { + name = "int"; + res = PyNumber_Long(x); + } +#endif + if (res) { +#if PY_MAJOR_VERSION < 3 + if (!PyInt_Check(res) && !PyLong_Check(res)) { +#else + if (!PyLong_Check(res)) { +#endif + PyErr_Format(PyExc_TypeError, + "__%.4s__ returned non-%.4s (type %.200s)", + name, name, Py_TYPE(res)->tp_name); + Py_DECREF(res); + return NULL; + } + } + else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, + "an integer is required"); + } + return res; +} +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { + Py_ssize_t ival; + PyObject *x; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_CheckExact(b))) + return PyInt_AS_LONG(b); +#endif + if (likely(PyLong_CheckExact(b))) { + #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 + #if CYTHON_USE_PYLONG_INTERNALS + switch (Py_SIZE(b)) { + case -1: return -(sdigit)((PyLongObject*)b)->ob_digit[0]; + case 0: return 0; + case 1: return ((PyLongObject*)b)->ob_digit[0]; + } + #endif + #endif + return PyLong_AsSsize_t(b); + } + x = PyNumber_Index(b); + if (!x) return -1; + ival = PyInt_AsSsize_t(x); + Py_DECREF(x); + return ival; +} +static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) { + return PyInt_FromSize_t(ival); +} + + +#endif /* Py_PYTHON_H */ diff --git a/setup.py b/setup.py index f2af5b53..bca20d59 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ parameter estimation in the context of geophysical applications. from distutils.core import setup from setuptools import find_packages -from Cython.Build import cythonize +from distutils.extension import Extension import numpy as np CLASSIFIERS = [ @@ -26,6 +26,27 @@ CLASSIFIERS = [ 'Natural Language :: English', ] + +from distutils.core import setup + +try: + from Cython.Build import cythonize + USE_CYTHON = True +except Exception, e: + USE_CYTHON = False + +ext = '.pyx' if USE_CYTHON else '.c' + +cython_files = [ + "SimPEG/Utils/interputils_cython", + "SimPEG/Mesh/TreeUtils" + ] +extensions = [Extension(f, [f+ext]) for f in cython_files] + +if USE_CYTHON: + from Cython.Build import cythonize + extensions = cythonize(extensions) + import os, os.path with open("README.rst") as f: @@ -51,5 +72,5 @@ setup( platforms = ["Windows", "Linux", "Solaris", "Mac OS-X", "Unix"], use_2to3 = False, include_dirs=[np.get_include()], - ext_modules = cythonize(['SimPEG/Utils/interputils_cython.pyx', 'SimPEG/Mesh/TreeUtils.pyx']) + ext_modules = extensions ) From d86045610523525763cc1425da8a9513a2b03a1d Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Tue, 10 Nov 2015 17:30:40 -0800 Subject: [PATCH 50/83] move tests to new folder. --- {SimPEG/Tests => tests/mesh}/test_NewTreeMesh.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {SimPEG/Tests => tests/mesh}/test_NewTreeMesh.py (100%) diff --git a/SimPEG/Tests/test_NewTreeMesh.py b/tests/mesh/test_NewTreeMesh.py similarity index 100% rename from SimPEG/Tests/test_NewTreeMesh.py rename to tests/mesh/test_NewTreeMesh.py From 13c8843fd17da6c1e5c7a0335206a16f14cae298 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Tue, 10 Nov 2015 17:48:37 -0800 Subject: [PATCH 51/83] Rearrange PointerTree --- SimPEG/Mesh/PointerTree.py | 226 +++++++++++++++++++++++++++++-------- 1 file changed, 177 insertions(+), 49 deletions(-) diff --git a/SimPEG/Mesh/PointerTree.py b/SimPEG/Mesh/PointerTree.py index a276f0c1..a5ed562b 100644 --- a/SimPEG/Mesh/PointerTree.py +++ b/SimPEG/Mesh/PointerTree.py @@ -1,3 +1,95 @@ +# ___ ___ ___ ___ ___ +# /\ \ ___ /\__\ /\ \ /\ \ /\ \ +# /::\ \ /\ \ /::| | /::\ \ /::\ \ /::\ \ +# /:/\ \ \ \:\ \ /:|:| | /:/\:\ \ /:/\:\ \ /:/\:\ \ +# _\:\~\ \ \ /::\__\ /:/|:|__|__ /::\~\:\ \ /::\~\:\ \ /:/ \:\ \ +# /\ \:\ \ \__\ __/:/\/__//:/ |::::\__\/:/\:\ \:\__\/:/\:\ \:\__\/:/__/_\:\__\ +# \:\ \:\ \/__//\/:/ / \/__/~~/:/ /\/__\:\/:/ /\:\~\:\ \/__/\:\ /\ \/__/ +# \:\ \:\__\ \::/__/ /:/ / \::/ / \:\ \:\__\ \:\ \:\__\ +# \:\/:/ / \:\__\ /:/ / \/__/ \:\ \/__/ \:\/:/ / +# \::/ / \/__/ /:/ / \:\__\ \::/ / +# \/__/ \/__/ \/__/ \/__/ +# ___ ___ ___ ___ ___ ___ +# /\ \ /\ \ /\ \ /\ \ /\ \ /\ \ +# /::\ \ /::\ \ \:\ \ /::\ \ /::\ \ /::\ \ +# /:/\:\ \ /:/\:\ \ \:\ \ /:/\:\ \ /:/\:\ \ /:/\:\ \ +# /:/ \:\ \ /:/ \:\ \ /::\ \ /::\~\:\ \ /::\~\:\ \ /::\~\:\ \ +# /:/__/ \:\__\/:/__/ \:\__\ /:/\:\__\/:/\:\ \:\__\/:/\:\ \:\__\/:/\:\ \:\__\ +# \:\ \ /:/ /\:\ \ \/__//:/ \/__/\/_|::\/:/ /\:\~\:\ \/__/\:\~\:\ \/__/ +# \:\ /:/ / \:\ \ /:/ / |:|::/ / \:\ \:\__\ \:\ \:\__\ +# \:\/:/ / \:\ \ \/__/ |:|\/__/ \:\ \/__/ \:\ \/__/ +# \::/ / \:\__\ |:| | \:\__\ \:\__\ +# \/__/ \/__/ \|__| \/__/ \/__/ +# +# +# @rowanc1, Nov. 10, 2015 +# +# .----------------.----------------. +# /| /| /| +# / | / | / | +# / | 011 / | 111 / | +# / | / | / | +# .----------------.----+-----------. | +# /| . ---------/|----.----------/|----. +# / | /| / | /| / | /| +# / | / | 001 / | / | 101 / | / | +# / | / | / | / | / | / | +# . -------------- .----------------. |/ | +# | . ---+------|----.----+------|----. | +# | /| .______|___/|____.______|___/|____. +# | / | / 010 | / | / 110| / | / +# | / | / | / | / | / | / +# . ---+---------- . ---+---------- . | / +# | |/ | |/ | |/ z +# | . ----------|----.-----------|----. ^ y +# | / 000 | / 100 | / | / +# | / | / | / | / +# | / | / | / o----> x +# . -------------- . -------------- . +# +# +# Face Refinement: +# +# 2_______________3 _______________ +# | | | | | +# ^ | | | (0,1) | (1,1) | +# | | | | | | +# | | x | ---> |-------+-------| +# t1 | | | | | +# | | | (0,0) | (1,0) | +# |_______________| |_______|_______| +# 0 t0--> 1 +# +# +# Face and Edge naming conventions: +# +# fZp +# | +# 6 ------eX3------ 7 +# /| | / | +# /eZ2 . / eZ3 +# eY2 | fYp eY3 | +# / | / fXp| +# 4 ------eX2----- 5 | +# |fXm 2 -----eX1--|---- 3 z +# eZ0 / | eY1 ^ y +# | eY0 . fYm eZ1 / | / +# | / | | / | / +# 0 ------eX0------1 o----> x +# | +# fZm +# +# +# fX fY fZ +# 2___________3 2___________3 2___________3 +# | e1 | | e1 | | e1 | +# | | | | | | +# e2 | x | e3 z e2 | x | e3 z e2 | x | e3 y +# | | ^ | | ^ | | ^ +# |___________| |___> y |___________| |___> x |___________| |___> x +# 0 e0 1 0 e0 1 0 e0 1 +# + from SimPEG import np, sp, Utils, Solver, Mesh import matplotlib.pyplot as plt import matplotlib @@ -12,48 +104,6 @@ import time MAX_BITS = 20 -def SortGrid(grid, offset=0): - """ - Sorts a grid by the x0 location. - """ - - eps = 1e-7 - def mycmp(c1,c2): - c1 = grid[c1-offset] - c2 = grid[c2-offset] - if c1.size == 2: - if np.abs(c1[1] - c2[1]) < eps: - return c1[0] - c2[0] - return c1[1] - c2[1] - elif c1.size == 3: - if np.abs(c1[2] - c2[2]) < eps: - if np.abs(c1[1] - c2[1]) < eps: - return c1[0] - c2[0] - return c1[1] - c2[1] - return c1[2] - c2[2] - - class K(object): - def __init__(self, obj, *args): - self.obj = obj - def __lt__(self, other): - return mycmp(self.obj, other.obj) < 0 - def __gt__(self, other): - return mycmp(self.obj, other.obj) > 0 - def __eq__(self, other): - return mycmp(self.obj, other.obj) == 0 - def __le__(self, other): - return mycmp(self.obj, other.obj) <= 0 - def __ge__(self, other): - return mycmp(self.obj, other.obj) >= 0 - def __ne__(self, other): - return mycmp(self.obj, other.obj) != 0 - - return sorted(range(offset,grid.shape[0]+offset), key=K) - - -class NotBalancedException(Exception): - pass - class Tree(BaseMesh, InnerProducts): def __init__(self, h_in, x0_in=None, levels=3): assert type(h_in) is list, 'h_in must be a list' @@ -314,9 +364,7 @@ class Tree(BaseMesh, InnerProducts): return TreeUtils.point(self.dim, MAX_BITS, self._levelBits, index) def __contains__(self, v): - if type(v) in [int, long]: - return v in self._cells - return self._index(v) in self._cells + return self._asIndex(v) in self._cells def refine(self, function=None, recursive=True, cells=None, balance=True, verbose=False, _inRecursion=False): @@ -371,9 +419,24 @@ class Tree(BaseMesh, InnerProducts): self.__dirty__ = True raise Exception('Not yet implemented') + def _corsenCell(self, pointer): raise Exception('Not yet implemented') + # something like this: ?? + pointer = self._asPointer(pointer) + ind = self._asIndex(pointer) + assert ind in self + + parent = self._parentPointer(ind) + children = _childPointers(parent) + for child in children: + self._cells.remove(self._asIndex(child)) + + parentInd = self._asIndex(parent) + self._cells.add(parentInd) + return parentInd + def _asPointer(self, ind): if type(ind) in [int, long]: return self._pointer(ind) @@ -393,7 +456,7 @@ class Tree(BaseMesh, InnerProducts): raise Exception - def _childPointers(self, pointer, direction=0, positive=True): + def _childPointers(self, pointer, direction=0, positive=True, returnAll=False): l = self._levelWidth(pointer[-1] + 1) if self.dim == 2: @@ -417,11 +480,12 @@ class Tree(BaseMesh, InnerProducts): [pointer[0] , pointer[1] + l, pointer[2] + l, pointer[-1] + 1], [pointer[0] + l, pointer[1] + l, pointer[2] + l, pointer[-1] + 1] ] - if direction == 0: ind = [0,2,4,6] if not positive else [1,3,5,7] if direction == 1: ind = [0,1,4,5] if not positive else [2,3,6,7] if direction == 2: ind = [0,1,2,3] if not positive else [4,5,6,7] + if returnAll: + return children return [children[_] for _ in ind[:(self.dim-1)*2]] @@ -1227,6 +1291,31 @@ class Tree(BaseMesh, InnerProducts): self._edgeCurl = Rf_ave*Utils.sdiag(1.0/S)*C*Utils.sdiag(L)*Re return self._edgeCurl + + @property + def nodalGrad(self): + raise Exception('Not yet implemented!') + # if getattr(self, '_nodalGrad', None) is None: + # self.number() + # # TODO: Preallocate! + # I, J, V = [], [], [] + # # kinda a hack for the 2D gradient + # # because edges are not stored + # edges = self.faces if self.dim == 2 else self.edges + # for edge in edges: + # if self.dim == 3: + # I += [edge.num, edge.num] + # elif self.dim == 2 and edge.faceType == 'x': + # I += [edge.num + self.nFy, edge.num + self.nFy] + # elif self.dim == 2 and edge.faceType == 'y': + # I += [edge.num - self.nFx, edge.num - self.nFx] + # J += [edge.node0.num, edge.node1.num] + # V += [-1, 1] + # G = sp.csr_matrix((V,(I,J)), shape=(self.nE, self.nN)) + # L = self.edge + # self._nodalGrad = Utils.sdiag(1/L)*G + # return self._nodalGrad + def _getFaceP(self, xFace, yFace, zFace): ind1, ind2, ind3 = [], [], [] for ind in self._sortedCells: @@ -1414,8 +1503,6 @@ class Tree(BaseMesh, InnerProducts): ind = [key, hf[0]] ax.plot(self._gridEz[ind,0], self._gridEz[ind,1], 'k:', zs=self._gridEz[ind,2]) - - # ax.axis('equal') if showIt:plt.show() @@ -1437,6 +1524,47 @@ class Tree(BaseMesh, InnerProducts): if showIt: plt.show() +def SortGrid(grid, offset=0): + """ + Sorts a grid by the x0 location. + """ + + eps = 1e-7 + def mycmp(c1,c2): + c1 = grid[c1-offset] + c2 = grid[c2-offset] + if c1.size == 2: + if np.abs(c1[1] - c2[1]) < eps: + return c1[0] - c2[0] + return c1[1] - c2[1] + elif c1.size == 3: + if np.abs(c1[2] - c2[2]) < eps: + if np.abs(c1[1] - c2[1]) < eps: + return c1[0] - c2[0] + return c1[1] - c2[1] + return c1[2] - c2[2] + + class K(object): + def __init__(self, obj, *args): + self.obj = obj + def __lt__(self, other): + return mycmp(self.obj, other.obj) < 0 + def __gt__(self, other): + return mycmp(self.obj, other.obj) > 0 + def __eq__(self, other): + return mycmp(self.obj, other.obj) == 0 + def __le__(self, other): + return mycmp(self.obj, other.obj) <= 0 + def __ge__(self, other): + return mycmp(self.obj, other.obj) >= 0 + def __ne__(self, other): + return mycmp(self.obj, other.obj) != 0 + + return sorted(range(offset,grid.shape[0]+offset), key=K) + + +class NotBalancedException(Exception): + pass if __name__ == '__main__': From 277318240cb361bbab235935c55ea49e2b6558b2 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Tue, 10 Nov 2015 17:54:35 -0800 Subject: [PATCH 52/83] Delete old implementations --- SimPEG/Mesh/NewTreeMesh.py | 1274 --------------- SimPEG/Mesh/PointerTree.py | 1669 ------------------- SimPEG/Mesh/TreeMesh.py | 2730 +++++++++++++++++++------------- tests/mesh/test_NewTreeMesh.py | 367 ----- tests/mesh/test_TreeMesh.py | 616 ++----- tests/mesh/test_pointerMesh.py | 160 -- 6 files changed, 1763 insertions(+), 5053 deletions(-) delete mode 100644 SimPEG/Mesh/NewTreeMesh.py delete mode 100644 SimPEG/Mesh/PointerTree.py delete mode 100644 tests/mesh/test_NewTreeMesh.py delete mode 100644 tests/mesh/test_pointerMesh.py diff --git a/SimPEG/Mesh/NewTreeMesh.py b/SimPEG/Mesh/NewTreeMesh.py deleted file mode 100644 index 8520f245..00000000 --- a/SimPEG/Mesh/NewTreeMesh.py +++ /dev/null @@ -1,1274 +0,0 @@ -import numpy as np, scipy.sparse as sp -from SimPEG.Utils import ndgrid, mkvc, sdiag, volTetra -from BaseMesh import BaseMesh -from InnerProducts import InnerProducts - -NUM, ACTIVE, NX, NY, NZ = range(5) # Do not put anything after NZ -NUM, ACTIVE, PARENT, EDIR, ENODE0, ENODE1 = range(6) -NUM, ACTIVE, PARENT, FDIR, FEDGE0, FEDGE1, FEDGE2, FEDGE3 = range(8) -NUM, ACTIVE, PARENT, CFACE0, CFACE1, CFACE2, CFACE3, CFACE4, CFACE5 = range(9) - -# The following classes are wrappers to make indexing easier - -class TreeIndexer(object): - def __init__(self, treeMesh, index=slice(None)): - self.M = treeMesh - if index == 'active': - array = getattr(self.M, self._pointer) - index = array[:,ACTIVE] == 1 - self.index = index - - @property - def C(self): return getattr(self.M, '_cells', None) - @property - def F(self): return getattr(self.M, '_faces', None) - @property - def E(self): return getattr(self.M, '_edges', None) - @property - def N(self): return getattr(self.M, '_nodes', None) - - def sort(self, vec): - self.M.number() - P = np.argsort(self.num) - if len(vec.shape) == 1: - return vec[P] - return vec[P,:] - - def _ind(self, column): - array = getattr(self.M, self._pointer) - ind = np.atleast_2d(array[self.index,:])[:,column] - return self._SubTree(self.M, ind) - - def at(self, index=slice(None)): - self.index = index - return self - -class TreeNode(TreeIndexer): - _SubTree = None - _pointer = '_nodes' - @property - def num(self): return self.N[self.index, NUM] - @property - def vec(self): return self.N[self.index,:][:,NX:] - @property - def x(self): return self.N[self.index,:][:,NX] - @property - def y(self): return self.N[self.index,:][:,NY] - @property - def z(self): return self.N[self.index,:][:,NZ] - -class TreeEdge(TreeIndexer): - _SubTree = TreeNode - _pointer = '_edges' - - @property - def num(self):return self.E[self.index, NUM] - @property - def dir(self):return self.E[self.index, EDIR] - @property - def isleaf(self):return self.E[self.index, ACTIVE] == 1 - - @property - def n0(self): return self._ind(ENODE0) - @property - def n1(self): return self._ind(ENODE1) - @property - def nodes(self): - return [self.n0, self.n1] - @property - def length(self): - return np.sum((self.n1.vec - self.n0.vec)**2,axis=1)**0.5 - @property - def center(self): - return (self.n0.vec + self.n1.vec)/2.0 - -class TreeFace(TreeIndexer): - _SubTree = TreeEdge - _pointer = '_faces' - - @property - def num(self):return self.F[self.index, NUM] - @property - def dir(self):return self.F[self.index, FDIR] - @property - def isleaf(self):return self.F[self.index, ACTIVE] == 1 - - # fX fY fZ - # n2___________n3 n2___________n3 n2___________n3 - # | e1 | | e1 | | e1 | - # | | | | | | - # e2 | x | e3 z e2 | x | e3 z e2 | x | e3 y - # | | ^ | | ^ | | ^ - # |___________| |___> y |___________| |___> x |___________| |___> x - # n0 e0 n1 n0 e0 n1 n0 e0 n1 - - @property - def e0(self): return self._ind(FEDGE0) - @property - def e1(self): return self._ind(FEDGE1) - @property - def e2(self): return self._ind(FEDGE2) - @property - def e3(self): return self._ind(FEDGE3) - @property - def n0(self): return self.e0.n0 - @property - def n1(self): return self.e0.n1 - @property - def n2(self): return self.e1.n0 - @property - def n3(self): return self.e1.n1 - @property - def nodes(self): - return [self.n0, self.n1, self.n2, self.n3] - @property - def center(self): - return (self.n0.vec + self.n1.vec + self.n2.vec + self.n3.vec)/4.0 - @property - def area(self): - - n0 = self.n0.vec # 2------3 3------2 - n1 = self.n1.vec # | | ---> | | - n2 = self.n3.vec # | | | | - n3 = self.n2.vec # 0------1 0------1 - - a = np.sum((n1 - n0)**2,axis=1)**0.5 - b = np.sum((n2 - n1)**2,axis=1)**0.5 - c = np.sum((n3 - n2)**2,axis=1)**0.5 - d = np.sum((n0 - n3)**2,axis=1)**0.5 - p = np.sum((n2 - n0)**2,axis=1)**0.5 - q = np.sum((n3 - n1)**2,axis=1)**0.5 - - # Area of an arbitrary quadrilateral (in a plane) - V = 0.25 * (4.0*(p**2)*(q**2) - (a**2 + c**2 - b**2 - d**2)**2)**0.5 - return V - - @property - def children(self): - if self.isleaf: return None - ind = int(self.index) # can not get children of a fancy slice at the moment. - subInds = np.argwhere(self.F[:,PARENT] == ind).flatten() - return TreeFace(self.M, subInds) - - - def refine(self, function, level): - - int(self.index) # should only be able to refine one at a time. - - toLevel = function(self) - - if toLevel < level+1: - return - - inds, rows = self.M.refineFace(self.index) - for i in inds: - TreeFace(self.M, i).refine(function, level + 1) - - -class TreeCell(TreeIndexer): - _SubTree = TreeFace - _pointer = '_cells' - - @property - def num(self):return self.C[self.index, NUM] - @property - def isleaf(self):return self.C[self.index, ACTIVE] == 1 - - @property - def fXm(self): return self._ind(CFACE0) - @property - def fXp(self): return self._ind(CFACE1) - @property - def fYm(self): return self._ind(CFACE2) - @property - def fYp(self): return self._ind(CFACE3) - @property - def fZm(self): return self._ind(CFACE4) - @property - def fZp(self): return self._ind(CFACE5) - - # fZp - # | - # 6 ------eX3------ 7 - # /| | / | - # /eZ2 . / eZ3 - # eY2 | fYp eY3 | - # / | / fXp| - # 4 ------eX2----- 5 | - # |fXm 2 -----eX1--|---- 3 z - # eZ0 / | eY1 ^ y - # | eY0 . fYm eZ1 / | / - # | / | | / | / - # 0 ------eX0------1 o----> x - # | - # fZm - # - # - # fX fY fZ - # 2___________3 2___________3 2___________3 - # | e1 | | e1 | | e1 | - # | | | | | | - # e2 | x | e3 z e2 | x | e3 z e2 | x | e3 y - # | | ^ | | ^ | | ^ - # |___________| |___> y |___________| |___> x |___________| |___> x - # 0 e0 1 0 e0 1 0 e0 1 - # - # Mapping Nodes: numOnFace > numOnCell - # - # fXm 0>0, 1>2, 2>4, 3>6 fYm 0>0, 1>1, 2>4, 3>5 fZm 0>0, 1>1, 2>2, 3>3 - # fXp 0>1, 1>3, 2>5, 3>7 fYp 0>2, 1>3, 2>6, 3>7 fZp 0>4, 1>5, 2>6, 3>7 - - @property - def eX0(self): return self.fZm.e0 - @property - def eX1(self): return self.fZm.e1 - @property - def eX2(self): return self.fZp.e0 - @property - def eX3(self): return self.fZp.e1 - - @property - def eY0(self): return self.fZm.e2 - @property - def eY1(self): return self.fZm.e3 - @property - def eY2(self): return self.fZp.e2 - @property - def eY3(self): return self.fZp.e3 - - @property - def eZ0(self): return self.fXm.e2 - @property - def eZ1(self): return self.fXp.e2 - @property - def eZ2(self): return self.fXm.e3 - @property - def eZ3(self): return self.fXp.e3 - - @property - def n0(self): return self.fZm.n0 - @property - def n1(self): return self.fZm.n1 - @property - def n2(self): return self.fZm.n2 - @property - def n3(self): return self.fZm.n3 - @property - def n4(self): return self.fZp.n0 - @property - def n5(self): return self.fZp.n1 - @property - def n6(self): return self.fZp.n2 - @property - def n7(self): return self.fZp.n3 - @property - def nodes(self): - return [self.n0, self.n1, self.n2, self.n3, self.n4, self.n5, self.n6, self.n7] - @property - def center(self): - return (self.n0.vec + self.n1.vec + self.n2.vec + self.n3.vec + - self.n4.vec + self.n5.vec + self.n6.vec + self.n7.vec)/8.0 - - @property - def vol(self): - # - # 6 --------------- 7 - # /| / | - # / | / | - # / | / | - # / | / | - # 4 -------------- 5 | - # | 2 ----------|---- 3 z - # | / | / ^ y - # | / | / | / - # | / | / | / - # 0 ---------------1 o----> x - - - # __ Look at the 4 (I mixed up the Z axis, sorry) - # / - n0, n1, n2, n3, n4, n5, n6, n7 = (self.n4.index, self.n5.index, self.n6.index, self.n7.index, - self.n0.index, self.n1.index, self.n2.index, self.n3.index) - - vol1 = (volTetra(self.M._nodes[:,NX:], n4, n5, n0, n6) + # cut edge top - volTetra(self.M._nodes[:,NX:], n5, n6, n7, n3) + # cut edge top - volTetra(self.M._nodes[:,NX:], n5, n0, n6, n3) + # middle - volTetra(self.M._nodes[:,NX:], n5, n1, n0, n3) + # cut edge bottom - volTetra(self.M._nodes[:,NX:], n0, n6, n3, n2)) # cut edge bottom - - vol2 = (volTetra(self.M._nodes[:,NX:], n4, n7, n5, n1) + # cut edge top - volTetra(self.M._nodes[:,NX:], n4, n6, n7, n2) + # cut edge top - volTetra(self.M._nodes[:,NX:], n4, n2, n7, n1) + # middle - volTetra(self.M._nodes[:,NX:], n1, n2, n0, n4) + # cut edge bottom - volTetra(self.M._nodes[:,NX:], n1, n3, n2, n7)) # cut edge bottom - - return (vol1 + vol2)/2.0 - - @property - def children(self): - if self.isleaf: return None - ind = int(self.index) # can not get children of a fancy slice at the moment. - subInds = np.argwhere(self.C[:,PARENT] == ind).flatten() - return TreeCell(self.M, subInds) - - def refine(self, function, level): - - int(self.index) # should only be able to refine one at a time. - - toLevel = function(self) - - if toLevel < level+1: - return - - inds, rows = self.M.refineCell(self.index) - for i in inds: - TreeCell(self.M, i).refine(function, level + 1) - - -class TreeMesh(InnerProducts, BaseMesh): - - _meshType = 'TREEMESH' - _unitDimensions = [1, 1, 1] - - def __init__(self, h_in, x0=None): - assert type(h_in) in [list, tuple], 'h_in must be a list' - assert len(h_in) > 1, "len(h_in) must be greater than 1" - - h = range(len(h_in)) - for i, h_i in enumerate(h_in): - if Utils.isScalar(h_i) and type(h_i) is not np.ndarray: - # This gives you something over the unit cube. - h_i = self._unitDimensions[i] * np.ones(int(h_i))/int(h_i) - elif type(h_i) is list: - h_i = Utils.meshTensor(h_i) - assert isinstance(h_i, np.ndarray), ("h[%i] is not a numpy array." % i) - assert len(h_i.shape) == 1, ("h[%i] must be a 1D numpy array." % i) - h[i] = h_i[:] # make a copy. - self.h = h - - if x0 is None: - x0 = np.zeros(len(h)) - else: - assert type(x0) in [list, tuple, np.ndarray], 'x0 must be an array' - x0 = np.array(x0, dtype=float) - assert len(x0) == self.dim, 'x0 must have the same dimensions as the mesh' - - BaseMesh.__init__(self, np.array([x.size for x in h]), x0) - if self.dim == 2: - self._init2D() - else: - self._init3D() - - self.isNumbered = False - - def _init2D(self): - XY = ndgrid(*[np.r_[0, h.cumsum()] for h in self.h]) - - nCx, nCy = [len(h) for h in self.h] - - vnC = [nCx , nCy ] - vnN = [nCx+1, nCy+1] - - vnEx = [nCx , nCy+1] - vnEy = [nCx+1, nCy ] - - vnFx = [nCx+1, nCy ] - vnFy = [nCx , nCy+1] - - nC = np.prod(vnC) - nN = np.prod(vnN) - nFx = np.prod(vnFx) - nFy = np.prod(vnFy) - nF = nFx + nFy - nEx = np.prod(vnEx) - nEy = np.prod(vnEy) - nE = nEx + nEy - - N = np.c_[np.arange(nN), np.ones(nN), XY] - - iN = np.arange(nN, dtype=int).reshape(vnN, order='F') - - # Pointers to the nodes for the edges - pnEx = np.c_[mkvc(iN[:-1,:]), mkvc(iN[1:,:])] - pnEy = np.c_[mkvc(iN[:,:-1]), mkvc(iN[:,1:])] - - iEx = np.arange(nEx, dtype=int).reshape(*vnEx, order='F') - iEy = np.arange(nEy, dtype=int).reshape(*vnEy, order='F') + nEx - - zEx = np.zeros(nEx, dtype=int) - zEy = np.zeros(nEy, dtype=int) - - Ex = np.c_[mkvc(iEx), zEx+1, zEx-1, zEx+0, pnEx] - Ey = np.c_[mkvc(iEy), zEy+1, zEy-1, zEy+1, pnEy] - - # Pointers to the edges for the faces - vFz = np.c_[mkvc(iEx[:,:-1]), mkvc(iEx[:,1:]), mkvc(iEy[:-1,:]), mkvc(iEy[1:,:])] - - iC = np.arange(nC, dtype=int) - - zC = np.zeros(nC, dtype=int) - - C = np.c_[iC, zC+1, zC-1, zC+2, vFz] - - self._nodes = N - self._edges = np.r_[Ex, Ey] - self._faces = C - - - def _init3D(self): - XYZ = ndgrid(*[np.r_[0, h.cumsum()] for h in self.h]) - - nCx, nCy, nCz = [len(h) for h in self.h] - - vnC = [nCx , nCy , nCz ] - vnN = [nCx+1, nCy+1, nCz+1] - - vnEx = [nCx , nCy+1, nCz+1] - vnEy = [nCx+1, nCy , nCz+1] - vnEz = [nCx+1, nCy+1, nCz ] - - vnFx = [nCx+1, nCy , nCz ] - vnFy = [nCx , nCy+1, nCz ] - vnFz = [nCx , nCy , nCz+1] - - nC = np.prod(vnC) - nN = np.prod(vnN) - nFx = np.prod(vnFx) - nFy = np.prod(vnFy) - nFz = np.prod(vnFz) - nF = nFx + nFy + nFz - nEx = np.prod(vnEx) - nEy = np.prod(vnEy) - nEz = np.prod(vnEz) - nE = nEx + nEy + nEz - - N = np.c_[np.arange(XYZ.shape[0]), np.ones(XYZ.shape[0]), XYZ] - - iN = np.arange(nN, dtype=int).reshape(vnN, order='F') - - # Pointers to the nodes for the edges - pnEx = np.c_[mkvc(iN[:-1,:,:]), mkvc(iN[1:,:,:])] - pnEy = np.c_[mkvc(iN[:,:-1,:]), mkvc(iN[:,1:,:])] - pnEz = np.c_[mkvc(iN[:,:,:-1]), mkvc(iN[:,:,1:])] - - iEx = np.arange(nEx, dtype=int).reshape(*vnEx, order='F') - iEy = np.arange(nEy, dtype=int).reshape(*vnEy, order='F') + nEx - iEz = np.arange(nEz, dtype=int).reshape(*vnEz, order='F') + nEx + nEy - - zEx = np.zeros(nEx, dtype=int) - zEy = np.zeros(nEy, dtype=int) - zEz = np.zeros(nEz, dtype=int) - - Ex = np.c_[mkvc(iEx), zEx+1, zEx-1, zEx+0, pnEx] - Ey = np.c_[mkvc(iEy), zEy+1, zEy-1, zEy+1, pnEy] - Ez = np.c_[mkvc(iEz), zEz+1, zEz-1, zEz+2, pnEz] - - # Pointers to the edges for the faces - peFx = np.c_[ mkvc(iEy[:,:,:-1]), mkvc(iEy[:,:,1:]), mkvc(iEz[:,:-1,:]), mkvc(iEz[:,1:,:])] - peFy = np.c_[mkvc(iEx[:,:,:-1]), mkvc(iEx[:,:,1:]), mkvc(iEz[:-1,:,:]), mkvc(iEz[1:,:,:])] - peFz = np.c_[mkvc(iEx[:,:-1,:]), mkvc(iEx[:,1:,:]), mkvc(iEy[:-1,:,:]), mkvc(iEy[1:,:,:]) ] - - iFx = np.arange(nFx, dtype=int).reshape(*vnFx, order='F') - iFy = np.arange(nFy, dtype=int).reshape(*vnFy, order='F') + nFx - iFz = np.arange(nFz, dtype=int).reshape(*vnFz, order='F') + nFx + nFy - - zFx = np.zeros(nFx, dtype=int) - zFy = np.zeros(nFy, dtype=int) - zFz = np.zeros(nFz, dtype=int) - - Fx = np.c_[mkvc(iFx), zFx+1, zFx-1, zFx+0, peFx] - Fy = np.c_[mkvc(iFy), zFy+1, zFy-1, zFy+1, peFy] - Fz = np.c_[mkvc(iFz), zFz+1, zFz-1, zFz+2, peFz] - - # Pointers to the faces for the cells - pfCx = np.c_[mkvc(iFx[:-1,:,:]), mkvc(iFx[1:,:,:])] - pfCy = np.c_[mkvc(iFy[:,:-1,:]), mkvc(iFy[:,1:,:])] - pfCz = np.c_[mkvc(iFz[:,:,:-1]), mkvc(iFz[:,:,1:])] - - iC = np.arange(nC, dtype=int) - - zC = np.zeros(nC, dtype=int) - - C = np.c_[iC, zC+1, zC-1, pfCx, pfCy, pfCz] - - self._nodes = N - self._edges = np.r_[Ex, Ey, Ez] - self._faces = np.r_[Fx, Fy, Fz] - self._cells = C - - @property - def isNumbered(self): - return self._numbered - @isNumbered.setter - def isNumbered(self, value): - assert value is False, 'Can only set to False.' - self._numbered = False - for name in ['vol', 'area', 'edge', 'gridCC', 'gridN', 'gridEx', 'gridEy', 'gridEz', 'gridFx', 'gridFy', 'gridFz']: - if hasattr(self, '_'+name): - delattr(self, '_'+name) - - def number(self): - if self._numbered: - return - - dtypeN = [('x',float),('y',float)] - if self.dim == 3: - dtypeN += [('z',float)] - dtypeV = [('v', int)] - - N = TreeNode(self, 'active') - E = TreeEdge(self, 'active') - F = TreeFace(self, 'active') - self._nodes[:,NUM] = -1 - self._edges[:,NUM] = -1 - self._faces[:,NUM] = -1 - if self.dim == 3: - C = TreeCell(self, 'active') - self._cells[:,NUM] = -1 - - - def doNumbering(indexer, nodes, dtype): - grid = np.zeros(np.sum(indexer.index), dtype=dtype) - grid['x'][:] = nodes.x - grid['y'][:] = nodes.y - if self.dim == 3: - grid['z'][:] = nodes.z - if 'v' in [d[0] for d in dtype]: - grid['v'][:] = indexer.dir - P = np.argsort(grid, order=[d[0] for d in reversed(dtype)]) - cnt = np.zeros(P.size, dtype=int) - cnt[P] = np.arange(P.size) - return cnt - - self._nodes[N.index, NUM] = doNumbering(N, N, dtypeN) - - self._edges[E.index, NUM] = doNumbering(E, E.n0, dtypeN + dtypeV) - - dtype = dtypeN if self.dim == 2 else (dtypeN + dtypeV) - self._faces[F.index, NUM] = doNumbering(F, F.n0, dtype) - - if self.dim == 3: - self._cells[C.index, NUM] = doNumbering(C, C.n0, dtypeN) - - self._numbered = True - - @property - def nC(self): - if self.dim == 2: - return np.sum(self._faces[:,ACTIVE] == 1) - return np.sum(self._cells[:,ACTIVE] == 1) - - @property - def nN(self): - return np.sum(self._nodes[:,ACTIVE] == 1) - - @property - def nE(self): - if self.dim == 2: - return self.nEx + self.nEy - return self.nEx + self.nEy + self.nEz - - @property - def nF(self): - if self.dim == 2: - return self.nFx + self.nFy - return self.nFx + self.nFy + self.nFz - - @property - def nEx(self): - return np.sum((self._edges[:,ACTIVE] == 1) & (self._edges[:,EDIR] == 0)) - - @property - def nEy(self): - return np.sum((self._edges[:,ACTIVE] == 1) & (self._edges[:,EDIR] == 1)) - - @property - def nEz(self): - if self.dim == 2: return None - return np.sum((self._edges[:,ACTIVE] == 1) & (self._edges[:,EDIR] == 2)) - - @property - def nFx(self): - if self.dim == 2: return self.nEy - return np.sum((self._faces[:,ACTIVE] == 1) & (self._faces[:,FDIR] == 0)) - - @property - def nFy(self): - if self.dim == 2: return self.nEx - return np.sum((self._faces[:,ACTIVE] == 1) & (self._faces[:,FDIR] == 1)) - - @property - def nFz(self): - if self.dim == 2: return None - return np.sum((self._faces[:,ACTIVE] == 1) & (self._faces[:,FDIR] == 2)) - - @property - def edge(self): - if getattr(self, '_edge', None) is None: - E = TreeEdge(self, 'active') - self._edge = E.sort(E.length) - return self._edge - - @property - def area(self): - if getattr(self, '_area', None) is None: - if self.dim == 2: - self._area = np.r_[self.edge[self.nEx:], self.edge[:self.nEx]] - elif self.dim == 3: - F = TreeFace(self, 'active') - self._area = F.sort(F.area) - return self._area - - @property - def vol(self): - if getattr(self, '_vol', None) is None: - if self.dim == 2: - F = TreeFace(self, 'active') - self._vol = F.sort(F.area) - elif self.dim == 3: - C = TreeCell(self, 'active') - self._vol = C.sort(C.vol) - return self._vol - - @property - def gridN(self): - N = TreeNode(self, 'active') - return N.sort(N.vec) - - @property - def gridCC(self): - if self.dim == 2: - F = TreeFace(self, 'active') - return F.sort(F.center) - C = TreeCell(self, 'active') - return C.sort(C.center) - - @property - def gridEx(self): - E = TreeEdge(self, (self._edges[:,ACTIVE] == 1) & (self._edges[:,EDIR] == 0)) - return E.sort(E.center) - - @property - def gridEy(self): - E = TreeEdge(self, (self._edges[:,ACTIVE] == 1) & (self._edges[:,EDIR] == 1)) - return E.sort(E.center) - - @property - def gridEz(self): - if self.dim == 2: return None - E = TreeEdge(self, (self._edges[:,ACTIVE] == 1) & (self._edges[:,EDIR] == 2)) - return E.sort(E.center) - - @property - def gridFx(self): - if self.dim == 2: - return self.gridEy - else: - F = TreeFace(self, (self._faces[:,ACTIVE] == 1) & (self._faces[:,FDIR] == 0)) - return F.sort(F.center) - - @property - def gridFy(self): - if self.dim == 2: - return self.gridEx - else: - F = TreeFace(self, (self._faces[:,ACTIVE] == 1) & (self._faces[:,FDIR] == 1)) - return F.sort(F.center) - - @property - def gridFz(self): - if self.dim == 2: return None - F = TreeFace(self, (self._faces[:,ACTIVE] == 1) & (self._faces[:,FDIR] == 2)) - return F.sort(F.center) - - def _push(self, attr, rows): - self.isNumbered = False - rows = np.atleast_2d(rows) - X = getattr(self, attr) - offset = X.shape[0] - rowNumer = np.arange(rows.shape[0], dtype=int) + offset - rows[:,0] = rowNumer*0-1 - setattr(self, attr, np.vstack((X, rows)).astype(X.dtype)) - if rows.shape[0] == 1: - return offset, rows.flatten() - return rowNumer, rows - - def addNode(self, between): - """Add a node between the node in list between""" - between = np.array(between).flatten() - nodes = self._nodes[between.astype(int), :] - newNode = np.mean(nodes, axis=0) - newNode[ACTIVE] = 1 - return self._push('_nodes', newNode) - - def refineEdge(self, index): - e = self._edges[index,:] - if e[ACTIVE] == 0: - # search for the children up to one level deep - subInds = np.argwhere(self._edges[:,PARENT] == index).flatten() - return subInds, self._edges[subInds,:] - - self._edges[index, ACTIVE] = 0 - - newNode, node = self.addNode(e[[ENODE0, ENODE1]]) - - Es = np.zeros((2, 6)) - Es[:, ACTIVE] = 1 - Es[:, PARENT] = index - Es[:, EDIR] = e[EDIR] - Es[0, ENODE0] = e[ENODE0] - Es[0, ENODE1] = newNode - Es[1, ENODE0] = newNode - Es[1, ENODE1] = e[ENODE1] - return self._push('_edges', Es) - - def refineFace(self, index): - f = self._faces[index,:] - if f[ACTIVE] == 0: - # search for the children up to one level deep - subInds = np.argwhere(self._faces[:,PARENT] == index).flatten() - return subInds, self._faces[subInds,:] - - self._faces[index, ACTIVE] = 0 - - # Refine the outer edges - E0i, E0 = self.refineEdge(f[FEDGE0]) - E1i, E1 = self.refineEdge(f[FEDGE1]) - E2i, E2 = self.refineEdge(f[FEDGE2]) - E3i, E3 = self.refineEdge(f[FEDGE3]) - - nodeNums = [n.index for n in TreeFace(self, index).nodes] - newNode, node = self.addNode(nodeNums) - - # Refine the inner edges - # new faces and edges - # 2_______________3 _______________ - # | e1--> | | | | - # ^ | | ^ | 2 3 3 | y z z - # | | | | | | | ^ ^ ^ - # | | + | | ---> |---0---+---1---| | | | - # e2 | | e3 | | | | | | - # | | | 0 2 1 | z-----> x y-----> x x-----> y - # |_______________| |_______|_______| - # 0 e0--> 1 - - nE = np.zeros((4,6)) - nE[:, ACTIVE] = 1 - nE[:, PARENT] = -1 - nE[:, EDIR] = [0,0,1,1] if f[FDIR] == 2 else [0,0,2,2] if f[FDIR] == 1 else [1,1,2,2] - nE[0, ENODE0] = E2[0, ENODE1] - nE[0, ENODE1] = newNode - nE[1, ENODE0] = newNode - nE[1, ENODE1] = E3[0, ENODE1] - nE[2, ENODE0] = E0[0, ENODE1] - nE[2, ENODE1] = newNode - nE[3, ENODE0] = newNode - nE[3, ENODE1] = E1[0, ENODE1] - nEi, nE = self._push('_edges', nE) - - # Add four new faces - nF = np.zeros((4,8)) - nF[:, ACTIVE] = 1 - nF[:, PARENT] = index - nF[:, FDIR] = f[FDIR] - - feInds = [FEDGE0,FEDGE1,FEDGE2,FEDGE3] - nF[0, feInds] = [E0i[0], nEi[0], E2i[0], nEi[2]] - nF[1, feInds] = [E0i[1], nEi[1], nEi[2], E3i[0]] - nF[2, feInds] = [nEi[0], E1i[0], E2i[1], nEi[3]] - nF[3, feInds] = [nEi[1], E1i[1], nEi[3], E3i[1]] - - return self._push('_faces', nF) - - - def refineCell(self, index): - c = self._cells[index,:] - if c[ACTIVE] == 0: - # search for the children up to one level deep - subInds = np.argwhere(self._cells[:,PARENT] == index).flatten() - return subInds, self._cells[subInds,:] - - self._cells[index, ACTIVE] = 0 - - # Refine the outer faces - fXm, rfXm = self.refineFace(c[CFACE0]) - fXp, rfXp = self.refineFace(c[CFACE1]) - fYm, rfYm = self.refineFace(c[CFACE2]) - fYp, rfYp = self.refineFace(c[CFACE3]) - fZm, rfZm = self.refineFace(c[CFACE4]) - fZp, rfZp = self.refineFace(c[CFACE5]) - - nodes = TreeCell(self, index).fXm.nodes + TreeCell(self, index).fXp.nodes - nodeNums = [n.index for n in nodes] - newNode, node = self.addNode(nodeNums) - - # .----------------.----------------. - # /| /| /| - # / | / | / | - # / | 6 / | 7 / | - # / | / | / | - # .----------------.----+-----------. | - # /| . ---------/|----.----------/|----. - # fZp / | /| / | /| / | /| - # | / | / | 4 / | / | 5 / | / | - # 6 ------eX3------ 7 / | / | / | / | / | / | - # /| | / | . -------------- .----------------. |/ | - # /eZ2 . / eZ3 | . ---+------|----.----+------|----. | - # eY2 | fYp eY3 | | /| .______|___/|____.______|___/|____. - # / | / fXp| | / | / 2 | / | / 3 | / | / - # 4 ------eX2----- 5 | | / | / | / | / | / | / - # |fXm 2 -----eX1--|---- 3 z . ---+---------- . ---+---------- . | / - # eZ0 / | eY1 ^ y | |/ | |/ | |/ - # | eY0 . fYm eZ1 / | / | . ----------|----.-----------|----. - # | / | | / | / | / 0 | / 1 | / - # 0 ------eX0------1 o----> x | / | / | / - # | | / | / | / - # fZm . -------------- . -------------- . - # - # - # fX fY fZ - # 2___________3 2___________3 2___________3 - # | e1 | | e1 | | e1 | - # | | | | | | - # e2 | x | e3 z e2 | x | e3 z e2 | x | e3 y - # | | ^ | | ^ | | ^ - # |___________| |___> y |___________| |___> x |___________| |___> x - # 0 e0 1 0 e0 1 0 e0 1 - - nE = np.zeros((6,6)) - nE[:, ACTIVE] = 1 - nE[:, PARENT] = -1 - nE[:, EDIR] = [0, 0, 1, 1, 2, 2] - - nE[0, ENODE0] = TreeFace(self, fXm[0]).n3.index - nE[0, ENODE1] = newNode - nE[1, ENODE0] = newNode - nE[1, ENODE1] = TreeFace(self, fXp[0]).n3.index - - nE[2, ENODE0] = TreeFace(self, fYm[0]).n3.index - nE[2, ENODE1] = newNode - nE[3, ENODE0] = newNode - nE[3, ENODE1] = TreeFace(self, fYp[0]).n3.index - - nE[4, ENODE0] = TreeFace(self, fZm[0]).n3.index - nE[4, ENODE1] = newNode - nE[5, ENODE0] = newNode - nE[5, ENODE1] = TreeFace(self, fZp[0]).n3.index - - nEi, nE = self._push('_edges', nE) - - nF = np.zeros((12,8)) - nF[:, ACTIVE] = 1 - nF[:, PARENT] = -1 - nF[:, FDIR] = [0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2] - - feInds = [FEDGE0,FEDGE1,FEDGE2,FEDGE3] - nF[0, feInds] = [rfZm[0, FEDGE3], nEi[2], rfYm[0, FEDGE3], nEi[4]] - nF[1, feInds] = [rfZm[2, FEDGE3], nEi[3], nEi[4], rfYp[0, FEDGE3]] - nF[2, feInds] = [nEi[2], rfZp[0, FEDGE3], rfYm[2, FEDGE3], nEi[5]] - nF[3, feInds] = [nEi[3], rfZp[2, FEDGE3], nEi[5], rfYp[2, FEDGE3]] - - nF[4, feInds] = [rfZm[0, FEDGE1], nEi[0], rfXm[0, FEDGE3], nEi[4]] - nF[5, feInds] = [rfZm[1, FEDGE1], nEi[1], nEi[4], rfXp[0, FEDGE3]] - nF[6, feInds] = [nEi[0], rfZp[0, FEDGE1], rfXm[2, FEDGE3], nEi[5]] - nF[7, feInds] = [nEi[1], rfZp[1, FEDGE1], nEi[5], rfXp[2, FEDGE3]] - - nF[8, feInds] = [rfYm[0, FEDGE1], nEi[0], rfXm[0, FEDGE1], nEi[2]] - nF[9, feInds] = [rfYm[1, FEDGE1], nEi[1], nEi[2], rfXp[0, FEDGE1]] - nF[10,feInds] = [nEi[0], rfYp[0, FEDGE1], rfXm[1, FEDGE1], nEi[3]] - nF[11,feInds] = [nEi[1], rfYp[1, FEDGE1], nEi[3], rfXp[1, FEDGE1]] - - nFi, nF = self._push('_faces', nF) - - nC = np.zeros((8,9)) - nC[:, ACTIVE] = 1 - nC[:, PARENT] = index - - cfInds = [CFACE0,CFACE1,CFACE2,CFACE3,CFACE4,CFACE5] - nC[0, cfInds] = [fXm[0], nFi[0], fYm[0], nFi[4], fZm[ 0], nFi[ 8]] - nC[1, cfInds] = [nFi[0], fXp[0], fYm[1], nFi[5], fZm[ 1], nFi[ 9]] - nC[2, cfInds] = [fXm[1], nFi[1], nFi[4], fYp[0], fZm[ 2], nFi[10]] - nC[3, cfInds] = [nFi[1], fXp[1], nFi[5], fYp[1], fZm[ 3], nFi[11]] - nC[4, cfInds] = [fXm[2], nFi[2], fYm[2], nFi[6], nFi[ 8], fZp[ 0]] - nC[5, cfInds] = [nFi[2], fXp[2], fYm[3], nFi[7], nFi[ 9], fZp[ 1]] - nC[6, cfInds] = [fXm[3], nFi[3], nFi[6], fYp[2], nFi[10], fZp[ 2]] - nC[7, cfInds] = [nFi[3], fXp[3], nFi[7], fYp[3], nFi[11], fZp[ 3]] - - return self._push('_cells', nC) - - def _index(self, attr, index): - index = [index] if np.isscalar(index) else list(index) - C = getattr(self, attr) - cSub = [] - iSub = [] - for I in index: - if C[I, ACTIVE] == 1: - iSub += [I] - cSub += [C[I, :]] - else: - subInds = np.argwhere(C[:,PARENT] == I).flatten() - i, c = self._index(attr, subInds) - iSub += i - cSub += [c] - return iSub, np.vstack(cSub) - - @property - def faceDiv(self): - if getattr(self, '_faceDiv', None) is None: - self.number() - - if self.dim == 2: - offset = np.r_[self.nFx, -self.nEx] # this switches from edge to face numbering - C = self._faces - sign_face = zip([-1,1,-1,1],[FEDGE0, FEDGE1, FEDGE2, FEDGE3]) - faceStr = '_edges' - elif self.dim == 3: - C = self._cells - sign_face = zip([-1,1,-1,1,-1,1],[CFACE0, CFACE1, CFACE2, CFACE3, CFACE4, CFACE5]) - faceStr = '_faces' - - # TODO: Preallocate! - I, J, V = [], [], [] - activeCells = C[:,ACTIVE] == 1 - for cell in C[activeCells]: - for sign, face in sign_face: - ij, jrow = self._index(faceStr, cell[face]) - I += [cell[NUM]]*len(ij) - if self.dim == 2: - J += list(jrow[:,0] + offset[jrow[:,EDIR]]) - elif self.dim == 3: - J += list(jrow[:,0]) - V += [sign]*len(ij) - VOL = self.vol - D = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.nF)) - S = self.area - self._faceDiv = sdiag(1/VOL)*D*sdiag(S) - return self._faceDiv - - @property - def edgeCurl(self): - """Construct the 3D curl operator.""" - assert self.dim > 2, "Edge Curl only programed for 3D." - - if getattr(self, '_edgeCurl', None) is None: - self.number() - # TODO: Preallocate! - I, J, V = [], [], [] - F = self._faces - sign_edge = zip([-1,1,-1,1],[FEDGE0, FEDGE1, FEDGE2, FEDGE3]) - activeFaces = F[:,ACTIVE] == 1 - for face in F[activeFaces]: - for sign, edge in sign_edge: - ij, jrow = self._index('_edges', face[edge]) - I += [face[NUM]]*len(ij) - J += list(jrow[:,0]) - V += [sign]*len(ij) - C = sp.csr_matrix((V,(I,J)), shape=(self.nF, self.nE)) - S = self.area - L = self.edge - self._edgeCurl = sdiag(1.0/S)*C*sdiag(L) - return self._edgeCurl - - @property - def nodalGrad(self): - if getattr(self, '_nodalGrad', None) is None: - self.number() - # TODO: Preallocate! - I, J, V = [], [], [] - E = self._edges - N = self._nodes - activeEdges = E[:,ACTIVE] == 1 - for edge in E[activeEdges]: - I += [edge[NUM], edge[NUM]] - J += [N[edge[ENODE0], NUM], N[edge[ENODE1], NUM]] - V += [-1, 1] - G = sp.csr_matrix((V,(I,J)), shape=(self.nE, self.nN)) - L = self.edge - self._nodalGrad = sdiag(1.0/L)*G - return self._nodalGrad - - - def _getFaceP(self, face0, face1, face2): - if self.dim == 2: - raise NotImplementedError() - - I, J, V = [], [], [] - - Cs = self._cells - activeCells = Cs[:,ACTIVE] == 1 - for cellInd in np.argwhere(activeCells): - - C = TreeCell(self, cellInd) - - face = getattr(C, face0) - if face.isleaf: - j = [int(face.num)] - elif self.dim == 2: - raise NotImplementedError() - j = face.children[0 if 'm' in face1 else 1].index - elif self.dim == 3: - raise NotImplementedError() - j = face.children[0 if 'm' in face1 else 1, - 0 if 'm' in face2 else 1].index - lenj = len(j) - I += [int(C.num)]*lenj - J += j - V += [1./lenj]*lenj - return sp.csr_matrix((V,(I,J)), shape=(self.nC, self.nF)) - - def _getEdgeP(self, edge0, edge1, edge2): - - if self.dim == 2: - raise NotImplementedError() - - I, J, V = [], [], [] - - - Cs = self._cells - activeCells = Cs[:,ACTIVE] == 1 - for cellInd in np.argwhere(activeCells): - - C = TreeCell(self, cellInd) - - if self.dim == 2: - raise NotImplementedError() - e2f = lambda e: ('f' + {'X':'Y','Y':'X'}[e[1]] - + {'0':'m','1':'p'}[e[2]]) - face = cell.faceDict[e2f(edge0)] - if face.isleaf: - j = face.index - else: - j = face.children[0 if 'm' in e2f(edge1) else 1].index - # Need to flip the numbering for edges - if 'X' in edge0: - j = [jj - self.nFx for jj in j] - elif 'Y' in edge0: - j = [jj + self.nFy for jj in j] - elif self.dim == 3: - edge = getattr(C, edge0) - if edge.isleaf: - j = [int(edge.num)] - else: - raise NotImplementedError() - mSide = lambda e: {'0':True,'1':True,'2':False,'3':False}[e[2]] - j = edge.children[0 if mSide(edge1) else 1, - 0 if mSide(edge2) else 1].index - lenj = len(j) - I += [int(C.num)]*lenj - J += j - V += [1./lenj]*lenj - return sp.csr_matrix((V,(I,J)), shape=(self.nC, self.nE)) - - def _getFacePxx(self): - def Pxx(xFace, yFace): - self.number() - xP = self._getFaceP(xFace, yFace, None) - yP = self._getFaceP(yFace, xFace, None) - return sp.vstack((xP, yP)) - return Pxx - - def _getEdgePxx(self): - def Pxx(xEdge, yEdge): - self.number() - xP = self._getEdgeP(xEdge, yEdge, None) - yP = self._getEdgeP(yEdge, xEdge, None) - return sp.vstack((xP, yP)) - return Pxx - - def _getFacePxxx(self): - def Pxxx(xFace, yFace, zFace): - self.number() - xP = self._getFaceP(xFace, yFace, zFace) - yP = self._getFaceP(yFace, xFace, zFace) - zP = self._getFaceP(zFace, xFace, yFace) - return sp.vstack((xP, yP, zP)) - return Pxxx - - def _getEdgePxxx(self): - def Pxxx(xEdge, yEdge, zEdge): - self.number() - xP = self._getEdgeP(xEdge, yEdge, zEdge) - yP = self._getEdgeP(yEdge, xEdge, zEdge) - zP = self._getEdgeP(zEdge, xEdge, yEdge) - return sp.vstack((xP, yP, zP)) - return Pxxx - - def refine(self, function): - if self.dim == 3: - TreeCell(self, 0).refine(function, 0) - elif self.dim == 2: - TreeFace(self, 0).refine(function, 0) - - def plotGrid(self, ax=None, text=True, showIt=False, figsize=(10,8)): - import matplotlib.pyplot as plt - - - - - if self.dim == 3: - axOpts = {'projection':'3d'} - if ax is None: ax = plt.subplot(111, **axOpts) - C = TreeCell(self, 'active') - - - # fZp - # | - # 6 ------eX3------ 7 - # /| | / | - # /eZ2 . / eZ3 - # eY2 | fYp eY3 | - # / | / fXp| - # 4 ------eX2----- 5 | - # |fXm 2 -----eX1--|---- 3 z - # eZ0 / | eY1 ^ y - # | eY0 . fYm eZ1 / | / - # | / | | / | / - # 0 ------eX0------1 o----> x - # | - # fZm - # - - - - Es = TreeEdge(self, 'active') - ax.plot(np.c_[Es.n0.x, Es.n1.x, Es.n1.x+np.nan].flatten(), np.c_[Es.n0.y, Es.n1.y, Es.n1.y+np.nan].flatten(), 'b-', zs=np.c_[Es.n0.z, Es.n1.z, Es.n1.z+np.nan].flatten()) - # n1, n2, n3, n4, n5 = 0, 1, 3, 2, 0 - # eX = np.c_[C.nodes[n1].x, C.nodes[n2].x, C.nodes[n3].x, C.nodes[n4].x, C.nodes[n5].x, [np.nan]*self.nC] - # eY = np.c_[C.nodes[n1].y, C.nodes[n2].y, C.nodes[n3].y, C.nodes[n4].y, C.nodes[n5].y, [np.nan]*self.nC] - # eZ = np.c_[C.nodes[n1].z, C.nodes[n2].z, C.nodes[n3].z, C.nodes[n4].z, C.nodes[n5].z, [np.nan]*self.nC] - # ax.plot(eX.flatten(), eY.flatten(), 'b-', zs=eZ.flatten()) - - # n1, n2, n3, n4, n5 = 4, 5, 7, 6, 4 - # eX = np.c_[C.nodes[n1].x, C.nodes[n2].x, C.nodes[n3].x, C.nodes[n4].x, C.nodes[n5].x, [np.nan]*self.nC] - # eY = np.c_[C.nodes[n1].y, C.nodes[n2].y, C.nodes[n3].y, C.nodes[n4].y, C.nodes[n5].y, [np.nan]*self.nC] - # eZ = np.c_[C.nodes[n1].z, C.nodes[n2].z, C.nodes[n3].z, C.nodes[n4].z, C.nodes[n5].z, [np.nan]*self.nC] - # ax.plot(eX.flatten(), eY.flatten(), 'r-', zs=eZ.flatten()) - - ax.plot(self.gridN[:,0], self.gridN[:,1], 'bs', zs=self.gridN[:,2]) - ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'ro', zs=self.gridCC[:,2]) - - ax.set_xlabel('x') - ax.set_ylabel('y') - ax.set_zlabel('z') - if showIt: plt.show() - return ax - - N = self._nodes - E = self._edges - C = self._faces - - if ax is None:f, ax = plt.subplots(1,1,figsize=figsize) - - Es = TreeEdge(self, 'active') - ax.plot(np.c_[Es.n0.x, Es.n1.x, Es.n1.x+np.nan].flatten(), np.c_[Es.n0.y, Es.n1.y, Es.n1.y+np.nan].flatten(), 'b-') - Ns = TreeNode(self, 'active') - ax.plot(Ns.x, Ns.y, 'k.') - - gridCC = self.gridCC - if text: - [ax.text(cc[0], cc[1],i) for i, cc in enumerate(gridCC)] - ax.plot(gridCC[:,0], gridCC[:,1], 'r.') - gridFx = self.gridFx - gridFy = self.gridFy - if text: - [ax.text(cc[0], cc[1],i) for i, cc in enumerate(np.vstack((gridFx,gridFy)))] - gridEx = self.gridEx - gridEy = self.gridEy - # if text: - # [ax.text(cc[0], cc[1],i) for i, cc in enumerate(np.vstack((gridEx,gridEy)))] - - # for E in self._edges: - # if E[ACTIVE] == 0: continue - # ex = N[E[[ENODE0,ENODE1]],NX] - # ey = N[E[[ENODE0,ENODE1]],NY] - # ax.plot(ex, ey, 'b-') - # ax.text(ex.mean(), ey.mean(), E[NUM]) - - if showIt: - plt.show() - - - - -if __name__ == '__main__': - from SimPEG import Mesh, Utils - import matplotlib.pyplot as plt - - # tM = TreeMesh([np.ones(3),np.ones(2)]) - tM = TreeMesh([np.ones(2),1,1]) - - # tM.refine(lambda c:2) - tM.refineCell(0) - tM.refineCell(2) - # tM.refineCell(7) - - # M = Mesh.TensorMesh([4,4,4]) - # print tM.gridN - M.gridN - tM.plotGrid() - - # plt.show() - - - - # tM.refineFace(0) - # tM.refineFace(1) - # tM.refineFace(3) - # tM.refineFace(9) - - # print tM._nodes[:,NUM] - # tM.number() - # print tM._nodes[:,NUM] - # print tM._edges[:,NUM] - - # print TreeFace(tM,'active').e3.n1.index - - # Mr = TreeMesh([2,1,1]) - # Mr.refineCell(0) - - # print Mr.vol - - # M = TreeMesh([2,2,2]) - # M.number() - # M.refineCell(0) - # M.refineCell(3) - # assert M.isNumbered is False - # C = TreeCell(M, 'active') - # M.getEdgeInnerProduct() - - # tM = TreeMesh([100,100,100]) - # print tM.vol - - - # print tM._faces - # print tM._edges[0,:] - # print tM.vol - - - # tM.number() - # print tM._index('_edges',3)[1] - - - # print tM._edges[:,[0,1,3, 4,5 ]] - - # plt.subplot(211) - # plt.spy(tM.faceDiv) - # tM.plotGrid(ax=plt.subplot(212)) - - # plt.figure(2) - # plt.plot(SortByX0(tM.gridCC),'b.') - # plt.show() - - - M = TreeMesh([[(1,3)],[(1,3)],[(1,3)]]) - - def refFunc(cell): - n = 5 - np.sum((cell.center.flatten() - np.r_[1.5, 1.5, 1.5])**2)**0.5 * 2 - print n, cell.center - return n - return 1 - M.refine(refFunc) - print M.nC - - M.plotGrid(text=False) - plt.show() - diff --git a/SimPEG/Mesh/PointerTree.py b/SimPEG/Mesh/PointerTree.py deleted file mode 100644 index a5ed562b..00000000 --- a/SimPEG/Mesh/PointerTree.py +++ /dev/null @@ -1,1669 +0,0 @@ -# ___ ___ ___ ___ ___ -# /\ \ ___ /\__\ /\ \ /\ \ /\ \ -# /::\ \ /\ \ /::| | /::\ \ /::\ \ /::\ \ -# /:/\ \ \ \:\ \ /:|:| | /:/\:\ \ /:/\:\ \ /:/\:\ \ -# _\:\~\ \ \ /::\__\ /:/|:|__|__ /::\~\:\ \ /::\~\:\ \ /:/ \:\ \ -# /\ \:\ \ \__\ __/:/\/__//:/ |::::\__\/:/\:\ \:\__\/:/\:\ \:\__\/:/__/_\:\__\ -# \:\ \:\ \/__//\/:/ / \/__/~~/:/ /\/__\:\/:/ /\:\~\:\ \/__/\:\ /\ \/__/ -# \:\ \:\__\ \::/__/ /:/ / \::/ / \:\ \:\__\ \:\ \:\__\ -# \:\/:/ / \:\__\ /:/ / \/__/ \:\ \/__/ \:\/:/ / -# \::/ / \/__/ /:/ / \:\__\ \::/ / -# \/__/ \/__/ \/__/ \/__/ -# ___ ___ ___ ___ ___ ___ -# /\ \ /\ \ /\ \ /\ \ /\ \ /\ \ -# /::\ \ /::\ \ \:\ \ /::\ \ /::\ \ /::\ \ -# /:/\:\ \ /:/\:\ \ \:\ \ /:/\:\ \ /:/\:\ \ /:/\:\ \ -# /:/ \:\ \ /:/ \:\ \ /::\ \ /::\~\:\ \ /::\~\:\ \ /::\~\:\ \ -# /:/__/ \:\__\/:/__/ \:\__\ /:/\:\__\/:/\:\ \:\__\/:/\:\ \:\__\/:/\:\ \:\__\ -# \:\ \ /:/ /\:\ \ \/__//:/ \/__/\/_|::\/:/ /\:\~\:\ \/__/\:\~\:\ \/__/ -# \:\ /:/ / \:\ \ /:/ / |:|::/ / \:\ \:\__\ \:\ \:\__\ -# \:\/:/ / \:\ \ \/__/ |:|\/__/ \:\ \/__/ \:\ \/__/ -# \::/ / \:\__\ |:| | \:\__\ \:\__\ -# \/__/ \/__/ \|__| \/__/ \/__/ -# -# -# @rowanc1, Nov. 10, 2015 -# -# .----------------.----------------. -# /| /| /| -# / | / | / | -# / | 011 / | 111 / | -# / | / | / | -# .----------------.----+-----------. | -# /| . ---------/|----.----------/|----. -# / | /| / | /| / | /| -# / | / | 001 / | / | 101 / | / | -# / | / | / | / | / | / | -# . -------------- .----------------. |/ | -# | . ---+------|----.----+------|----. | -# | /| .______|___/|____.______|___/|____. -# | / | / 010 | / | / 110| / | / -# | / | / | / | / | / | / -# . ---+---------- . ---+---------- . | / -# | |/ | |/ | |/ z -# | . ----------|----.-----------|----. ^ y -# | / 000 | / 100 | / | / -# | / | / | / | / -# | / | / | / o----> x -# . -------------- . -------------- . -# -# -# Face Refinement: -# -# 2_______________3 _______________ -# | | | | | -# ^ | | | (0,1) | (1,1) | -# | | | | | | -# | | x | ---> |-------+-------| -# t1 | | | | | -# | | | (0,0) | (1,0) | -# |_______________| |_______|_______| -# 0 t0--> 1 -# -# -# Face and Edge naming conventions: -# -# fZp -# | -# 6 ------eX3------ 7 -# /| | / | -# /eZ2 . / eZ3 -# eY2 | fYp eY3 | -# / | / fXp| -# 4 ------eX2----- 5 | -# |fXm 2 -----eX1--|---- 3 z -# eZ0 / | eY1 ^ y -# | eY0 . fYm eZ1 / | / -# | / | | / | / -# 0 ------eX0------1 o----> x -# | -# fZm -# -# -# fX fY fZ -# 2___________3 2___________3 2___________3 -# | e1 | | e1 | | e1 | -# | | | | | | -# e2 | x | e3 z e2 | x | e3 z e2 | x | e3 y -# | | ^ | | ^ | | ^ -# |___________| |___> y |___________| |___> x |___________| |___> x -# 0 e0 1 0 e0 1 0 e0 1 -# - -from SimPEG import np, sp, Utils, Solver, Mesh -import matplotlib.pyplot as plt -import matplotlib -from mpl_toolkits.mplot3d import Axes3D -import matplotlib.colors as colors -import matplotlib.cm as cmx - -import TreeUtils -from SimPEG.Mesh.InnerProducts import InnerProducts -from SimPEG.Mesh.BaseMesh import BaseMesh -import time - -MAX_BITS = 20 - -class Tree(BaseMesh, InnerProducts): - def __init__(self, h_in, x0_in=None, levels=3): - assert type(h_in) is list, 'h_in must be a list' - assert len(h_in) > 1, "len(h_in) must be greater than 1" - - h = range(len(h_in)) - for i, h_i in enumerate(h_in): - if type(h_i) in [int, long, float]: - # This gives you something over the unit cube. - h_i = np.ones(int(h_i))/int(h_i) - elif type(h_i) is list: - h_i = Utils.meshTensor(h_i) - assert isinstance(h_i, np.ndarray), ("h[%i] is not a numpy array." % i) - assert len(h_i.shape) == 1, ("h[%i] must be a 1D numpy array." % i) - assert len(h_i) == 2**levels, "must make h and levels match" - h[i] = h_i[:] # make a copy. - self.h = h - - x0 = np.zeros(len(h)) - if x0_in is not None: - assert len(h) == len(x0_in), "Dimension mismatch. x0 != len(h)" - for i in range(len(h)): - x_i, h_i = x0_in[i], h[i] - if Utils.isScalar(x_i): - x0[i] = x_i - elif x_i == '0': - x0[i] = 0.0 - elif x_i == 'C': - x0[i] = -h_i.sum()*0.5 - elif x_i == 'N': - x0[i] = -h_i.sum() - else: - raise Exception("x0[%i] must be a scalar or '0' to be zero, 'C' to center, or 'N' to be negative." % i) - - BaseMesh.__init__(self, [len(_) for _ in h], x0) - - self._levels = levels - self._levelBits = int(np.ceil(np.sqrt(levels)))+1 - - self.__dirty__ = True #: The numbering is dirty! - - self._cells = set() - self._cells.add(0) - - @property - def __dirty__(self): - return self.__dirtyFaces__ or self.__dirtyEdges__ or self.__dirtyNodes__ or self.__dirtyHanging__ - - @__dirty__.setter - def __dirty__(self, val): - assert val is True - self.__dirtyFaces__ = True - self.__dirtyEdges__ = True - self.__dirtyNodes__ = True - self.__dirtyHanging__ = True - - deleteThese = [ - '__sortedCells', - '_gridCC', '_gridN', '_gridFx', '_gridFy', '_gridFz', '_gridEx', '_gridEy', '_gridEz', - '_area', '_edge', '_vol', - '_faceDiv', '_edgeCurl', '_nodalGrad' - ] - for p in deleteThese: - if hasattr(self, p): delattr(self, p) - - @property - def levels(self): return self._levels - - @property - def dim(self): return len(self.h) - - @property - def nC(self): return len(self._cells) - - @property - def nN(self): - self.number() - return len(self._nodes) - len(self._hangingN) - - @property - def nF(self): - return self.nFx + self.nFy + (0 if self.dim == 2 else self.nFz) - - @property - def nFx(self): - self.number() - return len(self._facesX) - len(self._hangingFx) - - @property - def nFy(self): - self.number() - return len(self._facesY) - len(self._hangingFy) - - @property - def nFz(self): - if self.dim == 2: return None - self.number() - return len(self._facesZ) - len(self._hangingFz) - - @property - def nE(self): - return self.nEx + self.nEy + (0 if self.dim == 2 else self.nEz) - - @property - def nEx(self): - if self.dim == 2:return self.nFy - self.number() - return len(self._edgesX) - len(self._hangingEx) - - @property - def nEy(self): - if self.dim == 2:return self.nFx - self.number() - return len(self._edgesY) - len(self._hangingEy) - - @property - def nEz(self): - if self.dim == 2: return None - self.number() - return len(self._edgesZ) - len(self._hangingEz) - - @property - def nhN(self): - self.number() - return len(self._hangingN) - - @property - def nhF(self): - return self.nhFx + self.nhFy + (0 if self.dim == 2 else self.nhFz) - - @property - def nhFx(self): - self.number() - return len(self._hangingFx) - - @property - def nhFy(self): - self.number() - return len(self._hangingFy) - - @property - def nhFz(self): - if self.dim == 2: return None - self.number() - return len(self._hangingFz) - - @property - def nhE(self): - return self.nhEx + self.nhEy + (0 if self.dim == 2 else self.nhEz) - - @property - def nhEx(self): - if self.dim == 2:return self.nhFy - self.number() - return len(self._hangingEx) - - @property - def nhEy(self): - if self.dim == 2:return self.nhFx - self.number() - return len(self._hangingEy) - - @property - def nhEz(self): - if self.dim == 2: return None - self.number() - return len(self._hangingEz) - - - @property - def ntN(self): - self.number() - return len(self._nodes) - - @property - def ntF(self): - return self.ntFx + self.ntFy + (0 if self.dim == 2 else self.ntFz) - - @property - def ntFx(self): - self.number() - return len(self._facesX) - - @property - def ntFy(self): - self.number() - return len(self._facesY) - - @property - def ntFz(self): - if self.dim == 2: return None - self.number() - return len(self._facesZ) - - @property - def ntE(self): - return self.ntEx + self.ntEy + (0 if self.dim == 2 else self.ntEz) - - @property - def ntEx(self): - if self.dim == 2:return self.ntFy - self.number() - return len(self._edgesX) - - @property - def ntEy(self): - if self.dim == 2:return self.ntFx - self.number() - return len(self._edgesY) - - @property - def ntEz(self): - if self.dim == 2: return None - self.number() - return len(self._edgesZ) - - @property - def _sortedCells(self): - if getattr(self, '__sortedCells', None) is None: - self.__sortedCells = sorted(self._cells) - return self.__sortedCells - - @property - def permuteCC(self): - #TODO: cache these? - P = SortGrid(self.gridCC) - return sp.identity(self.nC).tocsr()[P,:] - - @property - def permuteF(self): - #TODO: cache these? - P = SortGrid(self.gridFx) - P += SortGrid(self.gridFy, offset=self.nFx) - if self.dim == 3: - P += SortGrid(self.gridFz, offset=self.nFx+self.nFy) - return sp.identity(self.nF).tocsr()[P,:] - - @property - def permuteE(self): - #TODO: cache these? - if self.dim == 2: - P = SortGrid(self.gridFy) - P += SortGrid(self.gridFx, offset=self.nEx) - return sp.identity(self.nE).tocsr()[P,:] - if self.dim == 3: - P = SortGrid(self.gridEx) - P += SortGrid(self.gridEy, offset=self.nEx) - P += SortGrid(self.gridEz, offset=self.nEx+self.nEy) - return sp.identity(self.nE).tocsr()[P,:] - - def _index(self, pointer): - assert len(pointer) is self.dim+1 - assert pointer[-1] <= self.levels - return TreeUtils.index(self.dim, MAX_BITS, self._levelBits, pointer[:-1], pointer[-1]) - - def _pointer(self, index): - assert type(index) in [int, long] - return TreeUtils.point(self.dim, MAX_BITS, self._levelBits, index) - - def __contains__(self, v): - return self._asIndex(v) in self._cells - - def refine(self, function=None, recursive=True, cells=None, balance=True, verbose=False, _inRecursion=False): - - if not _inRecursion: - self.__dirty__ = True - if verbose: print 'Refining Mesh' - - cells = cells if cells is not None else sorted(self._cells) - recurse = [] - tic = time.time() - for cell in cells: - p = self._pointer(cell) - do = function(self._cellC(cell)) > p[-1] - if do: - recurse += self._refineCell(cell) - - if verbose: print ' ', time.time() - tic - - if recursive and len(recurse) > 0: - recurse += self.refine(function=function, recursive=True, cells=recurse, balance=balance, _inRecursion=True) - - if balance and not _inRecursion: - self.balance() - return recurse - - def _refineCell(self, pointer): - pointer = self._asPointer(pointer) - ind = self._asIndex(pointer) - assert ind in self - h = self._levelWidth(pointer[-1])/2 # halfWidth - nL = pointer[-1] + 1 # new level - add = lambda p:p[0]+p[1] - added = [] - def addCell(p): - i = self._index(p+[nL]) - self._cells.add(i) - added.append(i) - - addCell(map(add, zip(pointer[:-1], [0,0,0][:self.dim]))) - addCell(map(add, zip(pointer[:-1], [h,0,0][:self.dim]))) - addCell(map(add, zip(pointer[:-1], [0,h,0][:self.dim]))) - addCell(map(add, zip(pointer[:-1], [h,h,0][:self.dim]))) - if self.dim == 3: - addCell(map(add, zip(pointer[:-1], [0,0,h]))) - addCell(map(add, zip(pointer[:-1], [h,0,h]))) - addCell(map(add, zip(pointer[:-1], [0,h,h]))) - addCell(map(add, zip(pointer[:-1], [h,h,h]))) - self._cells.remove(ind) - return added - - def corsen(self, function=None): - self.__dirty__ = True - raise Exception('Not yet implemented') - - - def _corsenCell(self, pointer): - raise Exception('Not yet implemented') - - # something like this: ?? - pointer = self._asPointer(pointer) - ind = self._asIndex(pointer) - assert ind in self - - parent = self._parentPointer(ind) - children = _childPointers(parent) - for child in children: - self._cells.remove(self._asIndex(child)) - - parentInd = self._asIndex(parent) - self._cells.add(parentInd) - return parentInd - - def _asPointer(self, ind): - if type(ind) in [int, long]: - return self._pointer(ind) - if type(ind) is list: - assert len(ind) == (self.dim + 1), str(ind) +' is not valid pointer' - assert ind[-1] <= self.levels, str(ind) +' is not valid pointer' - return ind - if isinstance(ind, np.ndarray): - return ind.tolist() - raise Exception - - def _asIndex(self, pointer): - if type(pointer) in [int, long]: - return pointer - if type(pointer) is list: - return self._index(pointer) - raise Exception - - - def _childPointers(self, pointer, direction=0, positive=True, returnAll=False): - l = self._levelWidth(pointer[-1] + 1) - - if self.dim == 2: - - children = [ - [pointer[0] , pointer[1] , pointer[-1] + 1], - [pointer[0] + l, pointer[1] , pointer[-1] + 1], - [pointer[0] , pointer[1] + l, pointer[-1] + 1], - [pointer[0] + l, pointer[1] + l, pointer[-1] + 1] - ] - - elif self.dim == 3: - - children = [ - [pointer[0] , pointer[1] , pointer[2] , pointer[-1] + 1], - [pointer[0] + l, pointer[1] , pointer[2] , pointer[-1] + 1], - [pointer[0] , pointer[1] + l, pointer[2] , pointer[-1] + 1], - [pointer[0] + l, pointer[1] + l, pointer[2] , pointer[-1] + 1], - [pointer[0] , pointer[1] , pointer[2] + l, pointer[-1] + 1], - [pointer[0] + l, pointer[1] , pointer[2] + l, pointer[-1] + 1], - [pointer[0] , pointer[1] + l, pointer[2] + l, pointer[-1] + 1], - [pointer[0] + l, pointer[1] + l, pointer[2] + l, pointer[-1] + 1] - ] - if direction == 0: ind = [0,2,4,6] if not positive else [1,3,5,7] - if direction == 1: ind = [0,1,4,5] if not positive else [2,3,6,7] - if direction == 2: ind = [0,1,2,3] if not positive else [4,5,6,7] - - if returnAll: - return children - return [children[_] for _ in ind[:(self.dim-1)*2]] - - - def _parentPointer(self, pointer): - mod = self._levelWidth(pointer[-1] - 1) - return [p - (p % mod) for p in pointer[:-1]] + [pointer[-1]-1] - - def _cellN(self, p): - p = self._asPointer(p) - return [hi[:p[ii]].sum() for ii, hi in enumerate(self.h)] - - def _cellH(self, p): - p = self._asPointer(p) - w = self._levelWidth(p[-1]) - return [hi[p[ii]:p[ii]+w].sum() for ii, hi in enumerate(self.h)] - - def _cellC(self, p): - return (np.array(self._cellH(p))/2.0 + self._cellN(p)).tolist() - - def _levelWidth(self, level): - return 2**(self.levels - level) - - def _isInsideMesh(self, pointer): - inside = True - for p in pointer[:-1]: - inside = inside and p >= 0 and p < 2**self.levels - return inside - - def _getNextCell(self, ind, direction=0, positive=True, _lookUp=True): - """ - Returns a None, int, list, or nested list - The int is the cell number. - - """ - if direction >= self.dim: return None - pointer = self._asPointer(ind) - if pointer[-1] > self.levels: return None - - step = (1 if positive else -1) * self._levelWidth(pointer[-1]) - nextCell = [p if ii is not direction else p + step for ii, p in enumerate(pointer)] - # raise Exception(pointer, nextCell) - if not self._isInsideMesh(nextCell): return None - - # it might be the same size as me? - if nextCell in self: return self._index(nextCell) - - if nextCell[-1] + 1 <= self.levels: # if I am not the smallest. - children = self._childPointers(pointer, direction=direction, positive=positive) - nextCells = [self._getNextCell(child, direction=direction, positive=positive, _lookUp=False) for child in children] - if nextCells[0] is not None: - return nextCells - - if not _lookUp: return None - - # it might be bigger than me? - return self._getNextCell(self._parentPointer(pointer), - direction=direction, positive=positive) - - def balance(self, recursive=True, cells=None, verbose=False, _inRecursion=False): - - tic = time.time() - if not _inRecursion: - self.__dirty__ = True - if verbose: print 'Balancing Mesh:' - - cells = cells if cells is not None else sorted(self._cells) - - # calcDepth = lambda i: lambda A: i if type(A) is not list else max(map(calcDepth(i+1), A)) - # flatten = lambda A: A if calcDepth(0)(A) == 1 else flatten([_ for __ in A for _ in (__ if type(__) is list else [__])]) - - recurse = set() - - for cell in cells: - p = self._asPointer(cell) - if p[-1] == self.levels: continue - - cs = range(6) - cs[0] = self._getNextCell(cell, direction=0, positive=False) - cs[1] = self._getNextCell(cell, direction=0, positive=True) - cs[2] = self._getNextCell(cell, direction=1, positive=False) - cs[3] = self._getNextCell(cell, direction=1, positive=True) - cs[4] = self._getNextCell(cell, direction=2, positive=False) # this will be None if in 2D - cs[5] = self._getNextCell(cell, direction=2, positive=True) # this will be None if in 2D - - do = np.any([ - type(c) is list and np.any([type(_) is list for _ in c]) - for c in cs - if c is not None - ]) - # depth = calcDepth(0)(cs) - # print depth, depth > 2, do, [jj for jj in flatten(cs) if jj is not None] - # recurse += [jj for jj in flatten(cs) if jj is not None] - - if do and cell in self: - newCells = self._refineCell(cell) - recurse.update([_ for _ in cs if type(_) in [int, long]]) # only add the bigger ones! - recurse.update(newCells) - - if verbose: print ' ', len(cells), time.time() - tic - if recursive and len(recurse) > 0: - self.balance(cells=sorted(recurse), _inRecursion=True) - - @property - def gridCC(self): - if getattr(self, '_gridCC', None) is None: - self._gridCC = np.zeros((len(self._cells),self.dim)) - for ii, ind in enumerate(self._sortedCells): - p = self._asPointer(ind) - self._gridCC[ii, :] = self._cellC(p) - return self._gridCC - - @property - def gridN(self): - self.number() - R = self._deflationMatrix('N', withHanging=False) - return R.T * self._gridN - - @property - def gridFx(self): - self.number() - R = self._deflationMatrix('Fx', withHanging=False) - return R.T * self._gridFx - - @property - def gridFy(self): - self.number() - R = self._deflationMatrix('Fy', withHanging=False) - return R.T * self._gridFy - - @property - def gridFz(self): - if self.dim < 3: return None - self.number() - R = self._deflationMatrix('Fz', withHanging=False) - return R.T * self._gridFz - - @property - def gridEx(self): - if self.dim == 2: return self.gridFy - self.number() - R = self._deflationMatrix('Ex', withHanging=False) - return R.T * self._gridEx - - @property - def gridEy(self): - if self.dim == 2: return self.gridFx - self.number() - R = self._deflationMatrix('Ey', withHanging=False) - return R.T * self._gridEy - - @property - def gridEz(self): - if self.dim < 3: return None - self.number() - R = self._deflationMatrix('Ez', withHanging=False) - return R.T * self._gridEz - - @property - def vol(self): - if getattr(self, '_vol', None) is None: - self._vol = np.zeros(len(self._cells)) - for ii, ind in enumerate(self._sortedCells): - p = self._asPointer(ind) - self._vol[ii] = np.prod(self._cellH(p)) - return self._vol - - @property - def area(self): - self.number() - if getattr(self, '_area', None) is None: - Rf = self._deflationMatrix('F', withHanging=False) - self._area = Rf.T * ( - np.r_[self._areaFxFull, self._areaFyFull] if self.dim == 2 else - np.r_[self._areaFxFull, self._areaFyFull, self._areaFzFull] - ) - return self._area - - @property - def edge(self): - self.number() - if self.dim == 2: - return np.r_[self.area[self.nFx:], self.area[:self.nFx]] - if getattr(self, '_edge', None) is None: - Re = self._deflationMatrix('E', withHanging=False) - self._edge = Re.T * np.r_[self._edgeExFull, self._edgeEyFull, self._edgeEzFull] - - return self._edge - - def _onSameLevel(self, i0, i1): - p0 = self._asPointer(i0) - p1 = self._asPointer(i1) - return p0[-1] == p1[-1] - - def _numberNodes(self, force=False): - if not self.__dirtyNodes__ and not force: return - - self._nodes = set() - - for ind in self._cells: - p = self._asPointer(ind) - w = self._levelWidth(p[-1]) - if self.dim == 2: - self._nodes.add(self._index([p[0] , p[1] , p[2]])) - self._nodes.add(self._index([p[0] + w, p[1] , p[2]])) - self._nodes.add(self._index([p[0] , p[1] + w, p[2]])) - self._nodes.add(self._index([p[0] + w, p[1] + w, p[2]])) - elif self.dim == 3: - self._nodes.add(self._index([p[0] , p[1] , p[2] , p[3]])) - self._nodes.add(self._index([p[0] + w, p[1] , p[2] , p[3]])) - self._nodes.add(self._index([p[0] , p[1] + w, p[2] , p[3]])) - self._nodes.add(self._index([p[0] + w, p[1] + w, p[2] , p[3]])) - self._nodes.add(self._index([p[0] , p[1] , p[2] + w, p[3]])) - self._nodes.add(self._index([p[0] + w, p[1] , p[2] + w, p[3]])) - self._nodes.add(self._index([p[0] , p[1] + w, p[2] + w, p[3]])) - self._nodes.add(self._index([p[0] + w, p[1] + w, p[2] + w, p[3]])) - gridN = [] - self._n2i = dict() - for ii, n in enumerate(sorted(self._nodes)): - self._n2i[n] = ii - gridN.append( self._cellN( self._pointer(n) ) ) - self._gridN = np.array(gridN) - - self.__dirtyNodes__ = False - - def _numberFaces(self, force=False): - if not self.__dirtyFaces__ and not force: return - - self._facesX = set() - self._facesY = set() - if self.dim == 3: - self._facesZ = set() - - for ind in self._cells: - p = self._asPointer(ind) - w = self._levelWidth(p[-1]) - - if self.dim == 2: - self._facesX.add(self._index([p[0] , p[1] , p[2]])) - self._facesX.add(self._index([p[0] + w, p[1] , p[2]])) - self._facesY.add(self._index([p[0] , p[1] , p[2]])) - self._facesY.add(self._index([p[0] , p[1] + w, p[2]])) - elif self.dim == 3: - self._facesX.add(self._index([p[0] , p[1] , p[2] , p[3]])) - self._facesX.add(self._index([p[0] + w, p[1] , p[2] , p[3]])) - self._facesY.add(self._index([p[0] , p[1] , p[2] , p[3]])) - self._facesY.add(self._index([p[0] , p[1] + w, p[2] , p[3]])) - self._facesZ.add(self._index([p[0] , p[1] , p[2] , p[3]])) - self._facesZ.add(self._index([p[0] , p[1] , p[2] + w, p[3]])) - - gridFx = [] - areaFx = [] - self._fx2i = dict() - for ii, fx in enumerate(sorted(self._facesX)): - self._fx2i[fx] = ii - p = self._pointer(fx) - n, h = self._cellN(p), self._cellH(p) - if self.dim == 2: - gridFx.append( [n[0], n[1] + h[1]/2.0] ) - areaFx.append( h[1] ) - elif self.dim == 3: - gridFx.append( [n[0], n[1] + h[1]/2.0, n[2] + h[2]/2.0] ) - areaFx.append( h[1]*h[2] ) - self._gridFx = np.array(gridFx) - self._areaFxFull = np.array(areaFx) - - gridFy = [] - areaFy = [] - self._fy2i = dict() - for ii, fy in enumerate(sorted(self._facesY)): - self._fy2i[fy] = ii - p = self._pointer(fy) - n, h = self._cellN(p), self._cellH(p) - if self.dim == 2: - gridFy.append( [n[0] + h[0]/2.0, n[1]] ) - areaFy.append( h[0] ) - elif self.dim == 3: - gridFy.append( [n[0] + h[0]/2.0, n[1], n[2] + h[2]/2.0] ) - areaFy.append( h[0]*h[2] ) - self._gridFy = np.array(gridFy) - self._areaFyFull = np.array(areaFy) - - if self.dim == 2: - self.__dirtyFaces__ = False - return - - gridFz = [] - areaFz = [] - self._fz2i = dict() - for ii, fz in enumerate(sorted(self._facesZ)): - self._fz2i[fz] = ii - p = self._pointer(fz) - n, h = self._cellN(p), self._cellH(p) - gridFz.append( [n[0] + h[0]/2.0, n[1] + h[1]/2.0, n[2]] ) - areaFz.append(h[0]*h[1]) - self._gridFz = np.array(gridFz) - self._areaFzFull = np.array(areaFz) - - self.__dirtyFaces__ = False - - def _numberEdges(self, force=False): - if self.dim == 2: - self.__dirtyEdges__ = False - return - if not self.__dirtyEdges__ and not force: return - - self._edgesX = set() - self._edgesY = set() - self._edgesZ = set() - - for ind in self._cells: - p = self._asPointer(ind) - w = self._levelWidth(p[-1]) - self._edgesX.add(self._index([p[0] , p[1] , p[2] , p[3]])) - self._edgesX.add(self._index([p[0] , p[1] + w, p[2] , p[3]])) - self._edgesX.add(self._index([p[0] , p[1] , p[2] + w, p[3]])) - self._edgesX.add(self._index([p[0] , p[1] + w, p[2] + w, p[3]])) - - self._edgesY.add(self._index([p[0] , p[1] , p[2] , p[3]])) - self._edgesY.add(self._index([p[0] + w, p[1] , p[2] , p[3]])) - self._edgesY.add(self._index([p[0] , p[1] , p[2] + w, p[3]])) - self._edgesY.add(self._index([p[0] + w, p[1] , p[2] + w, p[3]])) - - self._edgesZ.add(self._index([p[0] , p[1] , p[2] , p[3]])) - self._edgesZ.add(self._index([p[0] + w, p[1] , p[2] , p[3]])) - self._edgesZ.add(self._index([p[0] , p[1] + w, p[2] , p[3]])) - self._edgesZ.add(self._index([p[0] + w, p[1] + w, p[2] , p[3]])) - - gridEx = [] - edgeEx = [] - self._ex2i = dict() - for ii, ex in enumerate(sorted(self._edgesX)): - self._ex2i[ex] = ii - p = self._pointer(ex) - n, h = self._cellN(p), self._cellH(p) - gridEx.append( [n[0] + h[0]/2.0, n[1], n[2]] ) - edgeEx.append( h[0] ) - self._gridEx = np.array(gridEx) - self._edgeExFull = np.array(edgeEx) - - gridEy = [] - edgeEy = [] - self._ey2i = dict() - for ii, ey in enumerate(sorted(self._edgesY)): - self._ey2i[ey] = ii - p = self._pointer(ey) - n, h = self._cellN(p), self._cellH(p) - gridEy.append( [n[0], n[1] + h[1]/2.0, n[2]] ) - edgeEy.append( h[1] ) - self._gridEy = np.array(gridEy) - self._edgeEyFull = np.array(edgeEy) - - gridEz = [] - edgeEz = [] - self._ez2i = dict() - for ii, ez in enumerate(sorted(self._edgesZ)): - self._ez2i[ez] = ii - p = self._pointer(ez) - n, h = self._cellN(p), self._cellH(p) - gridEz.append( [n[0], n[1], n[2] + h[2]/2.0] ) - edgeEz.append( h[2] ) - self._gridEz = np.array(gridEz) - self._edgeEzFull = np.array(edgeEz) - - self.__dirtyEdges__ = False - - def _hanging(self, force=False): - if not self.__dirtyHanging__ and not force: return - - self._numberNodes(force=force) - self._numberFaces(force=force) - self._numberEdges(force=force) - - self._hangingN = dict() - self._hangingFx = dict() - self._hangingFy = dict() - if self.dim == 3: - self._hangingFz = dict() - self._hangingEx = dict() - self._hangingEy = dict() - self._hangingEz = dict() - - # Compute from x faces - for fx in self._facesX: - p = self._pointer(fx) - if p[-1] + 1 > self.levels: continue - sl = p[-1] + 1 #: small level - test = self._index(p[:-1] + [sl]) - if test not in self._facesX: - # Return early without checking the other faces - continue - w = self._levelWidth(sl) - - if self.dim == 2: - chy0 = self._cellH([p[0] , p[1] , sl])[1] - chy1 = self._cellH([p[0] , p[1] + w, sl])[1] - A = (chy0 + chy1) - - self._hangingFx[self._fx2i[test ]] = ([self._fx2i[fx], chy0 / A], ) - self._hangingFx[self._fx2i[self._index([p[0] , p[1] + w, sl])]] = ([self._fx2i[fx], chy1 / A], ) - - n0, n1 = fx, self._index([p[0], p[1] + 2*w, p[-1]]) - self._hangingN[self._n2i[test ]] = ([self._n2i[n0], 1.0], ) - self._hangingN[self._n2i[self._index([p[0] , p[1] + w, sl])]] = ([self._n2i[n0], 1.0 - chy0 / A], [self._n2i[n1], 1.0 - chy1 / A]) - self._hangingN[self._n2i[self._index([p[0] , p[1] + 2*w, sl])]] = ([self._n2i[n1], 1.0], ) - - elif self.dim == 3: - - chy0 = self._cellH([p[0] , p[1] , p[2] , sl])[1] - chy1 = self._cellH([p[0] , p[1] + w, p[2] , sl])[1] - chz0 = self._cellH([p[0] , p[1] , p[2] , sl])[2] - chz1 = self._cellH([p[0] , p[1] , p[2] + w, sl])[2] - lenY = chy0 + chy1 - lenZ = chz0 + chz1 - A = lenY * lenZ - - ey0 = fx - ey1 = self._index([p[0], p[1] , p[2] + 2*w, p[-1]]) - ez0 = fx - ez1 = self._index([p[0], p[1] + 2*w, p[2] , p[-1]]) - - n0 = fx - n1 = self._index([p[0], p[1] + 2*w, p[2] , p[-1]]) - n2 = self._index([p[0], p[1] , p[2] + 2*w, p[-1]]) - n3 = self._index([p[0], p[1] + 2*w, p[2] + 2*w, p[-1]]) - - self._hangingFx[self._fx2i[test ]] = ([self._fx2i[fx], chy0*chz0 / A ], ) - self._hangingFx[self._fx2i[self._index([p[0], p[1] + w, p[2] , sl])]] = ([self._fx2i[fx], chy1*chz0 / A ], ) - self._hangingFx[self._fx2i[self._index([p[0], p[1] , p[2] + w, sl])]] = ([self._fx2i[fx], chy0*chz1 / A ], ) - self._hangingFx[self._fx2i[self._index([p[0], p[1] + w, p[2] + w, sl])]] = ([self._fx2i[fx], chy1*chz1 / A ], ) - - self._hangingEy[self._ey2i[test ]] = ([self._ey2i[ey0], 1.0], ) - self._hangingEy[self._ey2i[self._index([p[0], p[1] + w, p[2] , sl])]] = ([self._ey2i[ey0], 1.0], ) - self._hangingEy[self._ey2i[self._index([p[0], p[1] , p[2] + w, sl])]] = ([self._ey2i[ey0], 0.5], [self._ey2i[ey1], 0.5]) - self._hangingEy[self._ey2i[self._index([p[0], p[1] + w, p[2] + w, sl])]] = ([self._ey2i[ey0], 0.5], [self._ey2i[ey1], 0.5]) - self._hangingEy[self._ey2i[self._index([p[0], p[1] , p[2] + 2*w, sl])]] = ([self._ey2i[ey1], 1.0], ) - self._hangingEy[self._ey2i[self._index([p[0], p[1] + w, p[2] + 2*w, sl])]] = ([self._ey2i[ey1], 1.0], ) - - self._hangingEz[self._ez2i[test ]] = ([self._ez2i[ez0], 1.0], ) - self._hangingEz[self._ez2i[self._index([p[0], p[1] , p[2] + w, sl])]] = ([self._ez2i[ez0], 1.0], ) - self._hangingEz[self._ez2i[self._index([p[0], p[1] + w, p[2] , sl])]] = ([self._ez2i[ez0], 0.5], [self._ez2i[ez1], 0.5]) - self._hangingEz[self._ez2i[self._index([p[0], p[1] + w, p[2] + w, sl])]] = ([self._ez2i[ez0], 0.5], [self._ez2i[ez1], 0.5]) - self._hangingEz[self._ez2i[self._index([p[0], p[1] + 2*w, p[2] , sl])]] = ([self._ez2i[ez1], 1.0], ) - self._hangingEz[self._ez2i[self._index([p[0], p[1] + 2*w, p[2] + w, sl])]] = ([self._ez2i[ez1], 1.0], ) - - # self._hangingEy[self._ey2i[test ]] = ([self._ey2i[ey0], chy0 / lenY], ) - # self._hangingEy[self._ey2i[self._index([p[0], p[1] + w, p[2] , sl])]] = ([self._ey2i[ey0], chy1 / lenY], ) - # self._hangingEy[self._ey2i[self._index([p[0], p[1] , p[2] + w, sl])]] = ([self._ey2i[ey0], chy0 / lenY / 2.0], [self._ey2i[ey1], chy0 / lenY / 2.0]) - # self._hangingEy[self._ey2i[self._index([p[0], p[1] + w, p[2] + w, sl])]] = ([self._ey2i[ey0], chy1 / lenY / 2.0], [self._ey2i[ey1], chy1 / lenY / 2.0]) - # self._hangingEy[self._ey2i[self._index([p[0], p[1] , p[2] + 2*w, sl])]] = ([self._ey2i[ey1], chy0 / lenY], ) - # self._hangingEy[self._ey2i[self._index([p[0], p[1] + w, p[2] + 2*w, sl])]] = ([self._ey2i[ey1], chy1 / lenY], ) - - # self._hangingEz[self._ez2i[test ]] = ([self._ez2i[ez0], chz0 / lenZ], ) - # self._hangingEz[self._ez2i[self._index([p[0], p[1] , p[2] + w, sl])]] = ([self._ez2i[ez0], chz1 / lenZ], ) - # self._hangingEz[self._ez2i[self._index([p[0], p[1] + w, p[2] , sl])]] = ([self._ez2i[ez0], chz0 / lenZ / 2.0], [self._ez2i[ez1], chz0 / lenZ / 2.0]) - # self._hangingEz[self._ez2i[self._index([p[0], p[1] + w, p[2] + w, sl])]] = ([self._ez2i[ez0], chz1 / lenZ / 2.0], [self._ez2i[ez1], chz1 / lenZ / 2.0]) - # self._hangingEz[self._ez2i[self._index([p[0], p[1] + 2*w, p[2] , sl])]] = ([self._ez2i[ez1], chz0 / lenZ], ) - # self._hangingEz[self._ez2i[self._index([p[0], p[1] + 2*w, p[2] + w, sl])]] = ([self._ez2i[ez1], chz1 / lenZ], ) - - self._hangingN[ self._n2i[ test ]] = ([self._n2i[n0], 1.0], ) - self._hangingN[ self._n2i[ self._index([p[0], p[1] + w, p[2] , sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n1], 0.5]) - self._hangingN[ self._n2i[ self._index([p[0], p[1] + 2*w, p[2] , sl])]] = ([self._n2i[n1], 1.0], ) - self._hangingN[ self._n2i[ self._index([p[0], p[1] , p[2] + w, sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n2], 0.5]) - self._hangingN[ self._n2i[ self._index([p[0], p[1] + w, p[2] + w, sl])]] = ([self._n2i[n0], 0.25], [self._n2i[n1], 0.25], [self._n2i[n2], 0.25], [self._n2i[n3], 0.25]) - self._hangingN[ self._n2i[ self._index([p[0], p[1] + 2*w, p[2] + w, sl])]] = ([self._n2i[n1], 0.5], [self._n2i[n3], 0.5]) - self._hangingN[ self._n2i[ self._index([p[0], p[1] , p[2] + 2*w, sl])]] = ([self._n2i[n2], 1.0], ) - self._hangingN[ self._n2i[ self._index([p[0], p[1] + w, p[2] + 2*w, sl])]] = ([self._n2i[n2], 0.5], [self._n2i[n3], 0.5]) - self._hangingN[ self._n2i[ self._index([p[0], p[1] + 2*w, p[2] + 2*w, sl])]] = ([self._n2i[n3], 1.0], ) - - # Compute from y faces - for fy in self._facesY: - p = self._pointer(fy) - if p[-1] + 1 > self.levels: continue - sl = p[-1] + 1 #: small level - test = self._index(p[:-1] + [sl]) - if test not in self._facesY: - # Return early without checking the other faces - continue - w = self._levelWidth(sl) - - if self.dim == 2: - chx0 = self._cellH([p[0] , p[1] , sl])[0] - chx1 = self._cellH([p[0] + w, p[1] , sl])[0] - - self._hangingFy[self._fy2i[test ]] = ([self._fy2i[fy], chx0 / (chx0 + chx1)], ) - self._hangingFy[self._fy2i[self._index([p[0] + w, p[1] , sl])]] = ([self._fy2i[fy], chx1 / (chx0 + chx1)], ) - - n0, n1 = fy, self._index([p[0] + 2*w, p[1], p[-1]]) - self._hangingN[self._n2i[test ]] = ([self._n2i[n0], 1.0], ) - self._hangingN[self._n2i[self._index([p[0] + w, p[1] , sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n1], 0.5]) - self._hangingN[self._n2i[self._index([p[0] + 2*w, p[1] , sl])]] = ([self._n2i[n1], 1.0], ) - - elif self.dim == 3: - - chx0 = self._cellH([p[0] , p[1] , p[2] , sl])[0] - chx1 = self._cellH([p[0] + w, p[1] , p[2] , sl])[0] - chz0 = self._cellH([p[0] , p[1] , p[2] , sl])[2] - chz1 = self._cellH([p[0] , p[1] , p[2] + w, sl])[2] - lenX = chx0 + chx1 - lenZ = chz0 + chz1 - A = lenX * lenZ - - ex0 = fy - ex1 = self._index([p[0] , p[1], p[2] + 2*w, p[-1]]) - ez0 = fy - ez1 = self._index([p[0] + 2*w, p[1], p[2] , p[-1]]) - - n0 = fy - n1 = self._index([p[0] + 2*w, p[1], p[2] , p[-1]]) - n2 = self._index([p[0] , p[1], p[2] + 2*w, p[-1]]) - n3 = self._index([p[0] + 2*w, p[1], p[2] + 2*w, p[-1]]) - - self._hangingFy[self._fy2i[test ]] = ([self._fy2i[fy], chx0*chz0 / A ], ) - self._hangingFy[self._fy2i[self._index([p[0] + w, p[1], p[2] , sl])]] = ([self._fy2i[fy], chx1*chz0 / A ], ) - self._hangingFy[self._fy2i[self._index([p[0] , p[1], p[2] + w, sl])]] = ([self._fy2i[fy], chx0*chz1 / A ], ) - self._hangingFy[self._fy2i[self._index([p[0] + w, p[1], p[2] + w, sl])]] = ([self._fy2i[fy], chx1*chz1 / A ], ) - - self._hangingEx[self._ex2i[test ]] = ([self._ex2i[ex0], 1.0], ) - self._hangingEx[self._ex2i[self._index([p[0] + w, p[1], p[2] , sl])]] = ([self._ex2i[ex0], 1.0], ) - self._hangingEx[self._ex2i[self._index([p[0] , p[1], p[2] + w, sl])]] = ([self._ex2i[ex0], 0.5], [self._ex2i[ex1], 0.5]) - self._hangingEx[self._ex2i[self._index([p[0] + w, p[1], p[2] + w, sl])]] = ([self._ex2i[ex0], 0.5], [self._ex2i[ex1], 0.5]) - self._hangingEx[self._ex2i[self._index([p[0] , p[1], p[2] + 2*w, sl])]] = ([self._ex2i[ex1], 1.0], ) - self._hangingEx[self._ex2i[self._index([p[0] + w, p[1], p[2] + 2*w, sl])]] = ([self._ex2i[ex1], 1.0], ) - - self._hangingEz[self._ez2i[test ]] = ([self._ez2i[ez0], 1.0], ) - self._hangingEz[self._ez2i[self._index([p[0] , p[1], p[2] + w, sl])]] = ([self._ez2i[ez0], 1.0], ) - self._hangingEz[self._ez2i[self._index([p[0] + w, p[1], p[2] , sl])]] = ([self._ez2i[ez0], 0.5], [self._ez2i[ez1], 0.5]) - self._hangingEz[self._ez2i[self._index([p[0] + w, p[1], p[2] + w, sl])]] = ([self._ez2i[ez0], 0.5], [self._ez2i[ez1], 0.5]) - self._hangingEz[self._ez2i[self._index([p[0] + 2*w, p[1], p[2] , sl])]] = ([self._ez2i[ez1], 1.0], ) - self._hangingEz[self._ez2i[self._index([p[0] + 2*w, p[1], p[2] + w, sl])]] = ([self._ez2i[ez1], 1.0], ) - - # self._hangingEx[self._ex2i[test ]] = ([self._ex2i[ex0], chx0 / lenX], ) - # self._hangingEx[self._ex2i[self._index([p[0] + w, p[1], p[2] , sl])]] = ([self._ex2i[ex0], chx1 / lenX], ) - # self._hangingEx[self._ex2i[self._index([p[0] , p[1], p[2] + w, sl])]] = ([self._ex2i[ex0], chx0 / lenX / 2.0], [self._ex2i[ex1], chx0 / lenX / 2.0]) - # self._hangingEx[self._ex2i[self._index([p[0] + w, p[1], p[2] + w, sl])]] = ([self._ex2i[ex0], chx1 / lenX / 2.0], [self._ex2i[ex1], chx1 / lenX / 2.0]) - # self._hangingEx[self._ex2i[self._index([p[0] , p[1], p[2] + 2*w, sl])]] = ([self._ex2i[ex1], chx0 / lenX], ) - # self._hangingEx[self._ex2i[self._index([p[0] + w, p[1], p[2] + 2*w, sl])]] = ([self._ex2i[ex1], chx1 / lenX], ) - - # self._hangingEz[self._ez2i[test ]] = ([self._ez2i[ez0], chz0 / lenZ], ) - # self._hangingEz[self._ez2i[self._index([p[0] , p[1], p[2] + w, sl])]] = ([self._ez2i[ez0], chz1 / lenZ], ) - # self._hangingEz[self._ez2i[self._index([p[0] + w, p[1], p[2] , sl])]] = ([self._ez2i[ez0], chz0 / lenZ / 2.0], [self._ez2i[ez1], chz0 / lenZ / 2.0]) - # self._hangingEz[self._ez2i[self._index([p[0] + w, p[1], p[2] + w, sl])]] = ([self._ez2i[ez0], chz1 / lenZ / 2.0], [self._ez2i[ez1], chz1 / lenZ / 2.0]) - # self._hangingEz[self._ez2i[self._index([p[0] + 2*w, p[1], p[2] , sl])]] = ([self._ez2i[ez1], chz0 / lenZ], ) - # self._hangingEz[self._ez2i[self._index([p[0] + 2*w, p[1], p[2] + w, sl])]] = ([self._ez2i[ez1], chz1 / lenZ], ) - - self._hangingN[ self._n2i[ test ]] = ([self._n2i[n0], 1.0], ) - self._hangingN[ self._n2i[ self._index([p[0] + w, p[1], p[2] , sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n1], 0.5]) - self._hangingN[ self._n2i[ self._index([p[0] + 2*w, p[1], p[2] , sl])]] = ([self._n2i[n1], 1.0], ) - self._hangingN[ self._n2i[ self._index([p[0] , p[1], p[2] + w, sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n2], 0.5]) - self._hangingN[ self._n2i[ self._index([p[0] + w, p[1], p[2] + w, sl])]] = ([self._n2i[n0], 0.25], [self._n2i[n1], 0.25], [self._n2i[n2], 0.25], [self._n2i[n3], 0.25]) - self._hangingN[ self._n2i[ self._index([p[0] + 2*w, p[1], p[2] + w, sl])]] = ([self._n2i[n1], 0.5], [self._n2i[n3], 0.5]) - self._hangingN[ self._n2i[ self._index([p[0] , p[1], p[2] + 2*w, sl])]] = ([self._n2i[n2], 1.0], ) - self._hangingN[ self._n2i[ self._index([p[0] + w, p[1], p[2] + 2*w, sl])]] = ([self._n2i[n2], 0.5], [self._n2i[n3], 0.5]) - self._hangingN[ self._n2i[ self._index([p[0] + 2*w, p[1], p[2] + 2*w, sl])]] = ([self._n2i[n3], 1.0], ) - - if self.dim == 2: - self.__dirtyHanging__ = False - return - - # Compute from z faces - for fz in self._facesZ: - p = self._pointer(fz) - if p[-1] + 1 > self.levels: continue - sl = p[-1] + 1 #: small level - test = self._index(p[:-1] + [sl]) - if test not in self._facesZ: - # Return early without checking the other faces - continue - w = self._levelWidth(sl) - - chx0 = self._cellH([p[0] , p[1] , p[2] , sl])[0] - chx1 = self._cellH([p[0] + w, p[1] , p[2] , sl])[0] - chy0 = self._cellH([p[0] , p[1] , p[2] , sl])[1] - chy1 = self._cellH([p[0] , p[1] + w, p[2] , sl])[1] - lenX = chx0 + chx1 - lenY = chy0 + chy1 - A = lenX * lenY - - ex0 = fz - ex1 = self._index([p[0] , p[1] + 2*w, p[2], p[-1]]) - ey0 = fz - ey1 = self._index([p[0] + 2*w, p[1] , p[2], p[-1]]) - - n0 = fz - n1 = self._index([p[0] + 2*w, p[1] , p[2], p[-1]]) - n2 = self._index([p[0] , p[1] + 2*w, p[2], p[-1]]) - n3 = self._index([p[0] + 2*w, p[1] + 2*w, p[2], p[-1]]) - - self._hangingFz[self._fz2i[test ]] = ([self._fz2i[fz], chx0*chy0 / A ], ) - self._hangingFz[self._fz2i[self._index([p[0] + w, p[1] , p[2], sl])]] = ([self._fz2i[fz], chx1*chy0 / A ], ) - self._hangingFz[self._fz2i[self._index([p[0] , p[1] + w, p[2], sl])]] = ([self._fz2i[fz], chx0*chy1 / A ], ) - self._hangingFz[self._fz2i[self._index([p[0] + w, p[1] + w, p[2], sl])]] = ([self._fz2i[fz], chx1*chy1 / A ], ) - - self._hangingEx[self._ex2i[test ]] = ([self._ex2i[ex0], 1.0], ) - self._hangingEx[self._ex2i[self._index([p[0] + w, p[1] , p[2], sl])]] = ([self._ex2i[ex0], 1.0], ) - self._hangingEx[self._ex2i[self._index([p[0] , p[1] + w, p[2], sl])]] = ([self._ex2i[ex0], 0.5], [self._ex2i[ex1], 0.5]) - self._hangingEx[self._ex2i[self._index([p[0] + w, p[1] + w, p[2], sl])]] = ([self._ex2i[ex0], 0.5], [self._ex2i[ex1], 0.5]) - self._hangingEx[self._ex2i[self._index([p[0] , p[1] + 2*w, p[2], sl])]] = ([self._ex2i[ex1], 1.0], ) - self._hangingEx[self._ex2i[self._index([p[0] + w, p[1] + 2*w, p[2], sl])]] = ([self._ex2i[ex1], 1.0], ) - - self._hangingEy[self._ey2i[test ]] = ([self._ey2i[ey0], 1.0], ) - self._hangingEy[self._ey2i[self._index([p[0] , p[1] + w, p[2], sl])]] = ([self._ey2i[ey0], 1.0], ) - self._hangingEy[self._ey2i[self._index([p[0] + w, p[1] , p[2], sl])]] = ([self._ey2i[ey0], 0.5], [self._ey2i[ey1], 0.5]) - self._hangingEy[self._ey2i[self._index([p[0] + w, p[1] + w, p[2], sl])]] = ([self._ey2i[ey0], 0.5], [self._ey2i[ey1], 0.5]) - self._hangingEy[self._ey2i[self._index([p[0] + 2*w, p[1] , p[2], sl])]] = ([self._ey2i[ey1], 1.0], ) - self._hangingEy[self._ey2i[self._index([p[0] + 2*w, p[1] + w, p[2], sl])]] = ([self._ey2i[ey1], 1.0], ) - - # self._hangingEx[self._ex2i[test ]] = ([self._ex2i[ex0], chx0 / lenX], ) - # self._hangingEx[self._ex2i[self._index([p[0] + w, p[1] , p[2], sl])]] = ([self._ex2i[ex0], chx1 / lenX], ) - # self._hangingEx[self._ex2i[self._index([p[0] , p[1] + w, p[2], sl])]] = ([self._ex2i[ex0], chx0 / lenX / 2.0], [self._ex2i[ex1], chx0 / lenX / 2.0]) - # self._hangingEx[self._ex2i[self._index([p[0] + w, p[1] + w, p[2], sl])]] = ([self._ex2i[ex0], chx1 / lenX / 2.0], [self._ex2i[ex1], chx1 / lenX / 2.0]) - # self._hangingEx[self._ex2i[self._index([p[0] , p[1] + 2*w, p[2], sl])]] = ([self._ex2i[ex1], chx0 / lenX], ) - # self._hangingEx[self._ex2i[self._index([p[0] + w, p[1] + 2*w, p[2], sl])]] = ([self._ex2i[ex1], chx1 / lenX], ) - - # self._hangingEy[self._ey2i[test ]] = ([self._ey2i[ey0], chy0 / lenY], ) - # self._hangingEy[self._ey2i[self._index([p[0] , p[1] + w, p[2], sl])]] = ([self._ey2i[ey0], chy1 / lenY], ) - # self._hangingEy[self._ey2i[self._index([p[0] + w, p[1] , p[2], sl])]] = ([self._ey2i[ey0], chy0 / lenY / 2.0], [self._ey2i[ey1], chy0 / lenY / 2.0]) - # self._hangingEy[self._ey2i[self._index([p[0] + w, p[1] + w, p[2], sl])]] = ([self._ey2i[ey0], chy1 / lenY / 2.0], [self._ey2i[ey1], chy1 / lenY / 2.0]) - # self._hangingEy[self._ey2i[self._index([p[0] + 2*w, p[1] , p[2], sl])]] = ([self._ey2i[ey1], chy0 / lenY], ) - # self._hangingEy[self._ey2i[self._index([p[0] + 2*w, p[1] + w, p[2], sl])]] = ([self._ey2i[ey1], chy1 / lenY], ) - - self._hangingN[ self._n2i[ test ]] = ([self._n2i[n0], 1.0], ) - self._hangingN[ self._n2i[ self._index([p[0] + w, p[1] , p[2], sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n1], 0.5]) - self._hangingN[ self._n2i[ self._index([p[0] + 2*w, p[1] , p[2], sl])]] = ([self._n2i[n1], 1.0], ) - self._hangingN[ self._n2i[ self._index([p[0] , p[1] + w, p[2], sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n2], 0.5]) - self._hangingN[ self._n2i[ self._index([p[0] + w, p[1] + w, p[2], sl])]] = ([self._n2i[n0], 0.25], [self._n2i[n1], 0.25], [self._n2i[n2], 0.25], [self._n2i[n3], 0.25]) - self._hangingN[ self._n2i[ self._index([p[0] + 2*w, p[1] + w, p[2], sl])]] = ([self._n2i[n1], 0.5], [self._n2i[n3], 0.5]) - self._hangingN[ self._n2i[ self._index([p[0] , p[1] + 2*w, p[2], sl])]] = ([self._n2i[n2], 1.0], ) - self._hangingN[ self._n2i[ self._index([p[0] + w, p[1] + 2*w, p[2], sl])]] = ([self._n2i[n2], 0.5], [self._n2i[n3], 0.5]) - self._hangingN[ self._n2i[ self._index([p[0] + 2*w, p[1] + 2*w, p[2], sl])]] = ([self._n2i[n3], 1.0], ) - - self.__dirtyHanging__ = False - - def number(self, balance=True, force=False): - if not self.__dirty__ and not force: return - if balance: self.balance() - self._hanging(force=force) - - def _deflationMatrix(self, location, withHanging=True, asOnes=False): - assert location in ['N','F','Fx','Fy'] + (['Fz','E','Ex','Ey','Ez'] if self.dim == 3 else []) - - args = dict() - args['N'] = (self._nodes, self._hangingN, self._n2i ) - args['Fx'] = (self._facesX, self._hangingFx, self._fx2i) - args['Fy'] = (self._facesY, self._hangingFy, self._fy2i) - if self.dim == 3: - args['Fz'] = (self._facesZ, self._hangingFz, self._fz2i) - args['Ex'] = (self._edgesX, self._hangingEx, self._ex2i) - args['Ey'] = (self._edgesY, self._hangingEy, self._ey2i) - args['Ez'] = (self._edgesZ, self._hangingEz, self._ez2i) - if location in ['F', 'E']: - Rlist = [self._deflationMatrix(location + subLoc, withHanging=withHanging, asOnes=asOnes) for subLoc in ['x','y','z'][:self.dim]] - return sp.block_diag(Rlist) - return self.__deflationMatrix(*args[location], withHanging=withHanging, asOnes=asOnes) - - def __deflationMatrix(self, theSet, theHang, theIndex, withHanging=True, asOnes=False): - reducedInd = dict() # final reduced index - ii = 0 - I,J,V = [],[],[] - for fx in sorted(theSet): - if theIndex[fx] not in theHang: - reducedInd[theIndex[fx]] = ii - I += [theIndex[fx]] - J += [ii] - V += [1.0] - ii += 1 - if withHanging: - for hfkey in theHang.keys(): - hf = theHang[hfkey] - I += [hfkey]*len(hf) - J += [reducedInd[_[0]] for _ in hf] - if asOnes: - V += [1.0]*len(hf) - else: - V += [_[1] for _ in hf] - return sp.csr_matrix((V,(I,J)), shape=(len(theSet), len(reducedInd))) - - @property - def faceDiv(self): - if getattr(self, '_faceDiv', None) is None: - self.number() - - # TODO: Preallocate! - I, J, V = [], [], [] - PM = [-1,1]*self.dim # plus / minus - - # TODO total number of faces? - offset = [0]*2 + [self.ntFx]*2 + [self.ntFx+self.ntFy]*2 - - for ii, ind in enumerate(self._sortedCells): - - p = self._pointer(ind) - w = self._levelWidth(p[-1]) - - if self.dim == 2: - faces = [ - self._fx2i[self._index([ p[0] , p[1] , p[2]])], - self._fx2i[self._index([ p[0] + w, p[1] , p[2]])], - self._fy2i[self._index([ p[0] , p[1] , p[2]])], - self._fy2i[self._index([ p[0] , p[1] + w, p[2]])] - ] - elif self.dim == 3: - faces = [ - self._fx2i[self._index([ p[0] , p[1] , p[2] , p[3]])], - self._fx2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], - self._fy2i[self._index([ p[0] , p[1] , p[2] , p[3]])], - self._fy2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], - self._fz2i[self._index([ p[0] , p[1] , p[2] , p[3]])], - self._fz2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])] - ] - - for off, pm, face in zip(offset,PM,faces): - I += [ii] - J += [face + off] - V += [pm] - - D = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.ntF)) - R = self._deflationMatrix('F',asOnes=True) - VOL = self.vol - if self.dim == 2: - S = np.r_[self._areaFxFull, self._areaFyFull] - elif self.dim == 3: - S = np.r_[self._areaFxFull, self._areaFyFull, self._areaFzFull] - self._faceDiv = Utils.sdiag(1.0/VOL)*D*Utils.sdiag(S)*R - return self._faceDiv - - @property - def edgeCurl(self): - """Construct the 3D curl operator.""" - assert self.dim > 2, "Edge Curl only programed for 3D." - - if getattr(self, '_edgeCurl', None) is None: - self.number() - # TODO: Preallocate! - I, J, V = [], [], [] - faceOffset = 0 - offset = [self.ntEx]*2 + [self.ntEx+self.ntEy]*2 - PM = [1, -1, -1, 1] - for ii, fx in enumerate(sorted(self._facesX)): - - p = self._pointer(fx) - w = self._levelWidth(p[-1]) - - edges = [ - self._ey2i[self._index([ p[0] , p[1] , p[2] , p[3]])], - self._ey2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])], - self._ez2i[self._index([ p[0] , p[1] , p[2] , p[3]])], - self._ez2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], - ] - - for off, pm, edge in zip(offset,PM,edges): - I += [ii + faceOffset] - J += [edge + off] - V += [pm] - - faceOffset = self.ntFx - offset = [0]*2 + [self.ntEx+self.ntEy]*2 - PM = [-1, 1, 1, -1] - for ii, fy in enumerate(sorted(self._facesY)): - - p = self._pointer(fy) - w = self._levelWidth(p[-1]) - - edges = [ - self._ex2i[self._index([ p[0] , p[1] , p[2] , p[3]])], - self._ex2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])], - self._ez2i[self._index([ p[0] , p[1] , p[2] , p[3]])], - self._ez2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], - ] - - for off, pm, edge in zip(offset,PM,edges): - I += [ii + faceOffset] - J += [edge + off] - V += [pm] - - faceOffset = self.ntFx + self.ntFy - offset = [0]*2 + [self.ntEx]*2 - PM = [1, -1, -1, 1] - for ii, fz in enumerate(sorted(self._facesZ)): - - p = self._pointer(fz) - w = self._levelWidth(p[-1]) - - edges = [ - self._ex2i[self._index([ p[0] , p[1] , p[2] , p[3]])], - self._ex2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], - self._ey2i[self._index([ p[0] , p[1] , p[2] , p[3]])], - self._ey2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], - ] - - for off, pm, edge in zip(offset,PM,edges): - I += [ii + faceOffset] - J += [edge + off] - V += [pm] - - Rf = self._deflationMatrix('F', withHanging=True, asOnes=False) - Re = self._deflationMatrix('E') - - Rf_ave = Utils.sdiag(1./Rf.sum(axis=0)) * Rf.T - - C = sp.csr_matrix((V,(I,J)), shape=(self.ntF, self.ntE)) - S = np.r_[self._areaFxFull, self._areaFyFull, self._areaFzFull] - L = np.r_[self._edgeExFull, self._edgeEyFull, self._edgeEzFull] - self._edgeCurl = Rf_ave*Utils.sdiag(1.0/S)*C*Utils.sdiag(L)*Re - return self._edgeCurl - - - @property - def nodalGrad(self): - raise Exception('Not yet implemented!') - # if getattr(self, '_nodalGrad', None) is None: - # self.number() - # # TODO: Preallocate! - # I, J, V = [], [], [] - # # kinda a hack for the 2D gradient - # # because edges are not stored - # edges = self.faces if self.dim == 2 else self.edges - # for edge in edges: - # if self.dim == 3: - # I += [edge.num, edge.num] - # elif self.dim == 2 and edge.faceType == 'x': - # I += [edge.num + self.nFy, edge.num + self.nFy] - # elif self.dim == 2 and edge.faceType == 'y': - # I += [edge.num - self.nFx, edge.num - self.nFx] - # J += [edge.node0.num, edge.node1.num] - # V += [-1, 1] - # G = sp.csr_matrix((V,(I,J)), shape=(self.nE, self.nN)) - # L = self.edge - # self._nodalGrad = Utils.sdiag(1/L)*G - # return self._nodalGrad - - def _getFaceP(self, xFace, yFace, zFace): - ind1, ind2, ind3 = [], [], [] - for ind in self._sortedCells: - p = self._pointer(ind) - w = self._levelWidth(p[-1]) - - posX = 0 if xFace == 'fXm' else w - posY = 0 if yFace == 'fYm' else w - if self.dim == 3: - posZ = 0 if zFace == 'fZm' else w - - ind1.append( self._fx2i[self._index([ p[0] + posX, p[1]] + p[2:])] ) - ind2.append( self._fy2i[self._index([ p[0], p[1] + posY] + p[2:])] + self.ntFx ) - if self.dim == 3: - ind3.append( self._fz2i[self._index([ p[0], p[1], p[2] + posZ, p[3]])] + self.ntFx + self.ntFy ) - - if self.dim == 2: - IND = np.r_[ind1, ind2] - if self.dim == 3: - IND = np.r_[ind1, ind2, ind3] - - PXXX = sp.coo_matrix((np.ones(self.dim*self.nC), (range(self.dim*self.nC), IND)), shape=(self.dim*self.nC, self.ntF)).tocsr() - - Rf = self._deflationMatrix('F', withHanging=True, asOnes=True) - - return PXXX * Rf - - def _getFacePxx(self): - self.number() - def Pxx(xFace, yFace): - return self._getFaceP(xFace, yFace, None) - return Pxx - - def _getFacePxxx(self): - self.number() - def Pxxx(xFace, yFace, zFace): - return self._getFaceP(xFace, yFace, zFace) - return Pxxx - - def _getEdgeP(self, xEdge, yEdge, zEdge): - if self.dim == 2: raise Exception('Not implemented') # this should be a reordering of the face inner product? - - ind1, ind2, ind3 = [], [], [] - for ind in self._sortedCells: - p = self._pointer(ind) - w = self._levelWidth(p[-1]) - - posX = [0,0] if xEdge == 'eX0' else [w, 0] if xEdge == 'eX1' else [0,w] if xEdge == 'eX2' else [w,w] - posY = [0,0] if yEdge == 'eY0' else [w, 0] if yEdge == 'eY1' else [0,w] if yEdge == 'eY2' else [w,w] - posZ = [0,0] if zEdge == 'eZ0' else [w, 0] if zEdge == 'eZ1' else [0,w] if zEdge == 'eZ2' else [w,w] - - ind1.append( self._ex2i[self._index([ p[0] , p[1] + posX[0], p[2] + posX[1], p[3]])] ) - ind2.append( self._ey2i[self._index([ p[0] + posY[0], p[1] , p[2] + posY[1], p[3]])] + self.ntEx ) - ind3.append( self._ez2i[self._index([ p[0] + posZ[0], p[1] + posZ[1], p[2] , p[3]])] + self.ntEx + self.ntEy ) - - IND = np.r_[ind1, ind2, ind3] - - PXXX = sp.coo_matrix((np.ones(self.dim*self.nC), (range(self.dim*self.nC), IND)), shape=(self.dim*self.nC, self.ntE)).tocsr() - - Re = self._deflationMatrix('E') - - return PXXX * Re - - def _getEdgePxx(self): - raise Exception('Not implemented') # this should be a reordering of the face inner product? - def _getEdgePxxx(self): - self.number() - def Pxxx(xEdge, yEdge, zEdge): - return self._getEdgeP(xEdge, yEdge, zEdge) - return Pxxx - - - def plotGrid(self, ax=None, showIt=False, - grid=True, - cells=True, cellLine=False, - nodes=False, - facesX=False, facesY=False, facesZ=False, - edgesX=False, edgesY=False, edgesZ=False): - - # self.number() - - axOpts = {'projection':'3d'} if self.dim == 3 else {} - if ax is None: - ax = plt.subplot(111, **axOpts) - else: - assert isinstance(ax,matplotlib.axes.Axes), "ax must be an Axes!" - fig = ax.figure - - if grid: - for ind in self._sortedCells: - p = self._asPointer(ind) - n = self._cellN(p) - h = self._cellH(p) - x = [n[0] , n[0] + h[0], n[0] + h[0], n[0] , n[0]] - y = [n[1] , n[1] , n[1] + h[1], n[1] + h[1], n[1]] - if self.dim == 2: - ax.plot(x,y, 'b-') - elif self.dim == 3: - ax.plot(x,y, 'b-', zs=[n[2]]*5) - z = [n[2] + h[2], n[2] + h[2], n[2] + h[2], n[2] + h[2], n[2] + h[2]] - ax.plot(x,y, 'b-', zs=z) - sides = [0,0], [h[0],0], [0,h[1]], [h[0],h[1]] - for s in sides: - x = [n[0] + s[0], n[0] + s[0]] - y = [n[1] + s[1], n[1] + s[1]] - z = [n[2] , n[2] + h[2]] - ax.plot(x,y, 'b-', zs=z) - - if self.dim == 2: - if cells: - ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'r.') - if cellLine: - ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'r:') - ax.plot(self.gridCC[[0,-1],0], self.gridCC[[0,-1],1], 'ro') - if nodes: - ax.plot(self._gridN[:,0], self._gridN[:,1], 'ms') - ax.plot(self._gridN[self._hangingN.keys(),0], self._gridN[self._hangingN.keys(),1], 'ms', ms=10, mfc='none', mec='m') - if facesX: - ax.plot(self._gridFx[self._hangingFx.keys(),0], self._gridFx[self._hangingFx.keys(),1], 'gs', ms=10, mfc='none', mec='g') - ax.plot(self._gridFx[:,0], self._gridFx[:,1], 'g>') - if facesY: - ax.plot(self._gridFy[self._hangingFy.keys(),0], self._gridFy[self._hangingFy.keys(),1], 'gs', ms=10, mfc='none', mec='g') - ax.plot(self._gridFy[:,0], self._gridFy[:,1], 'g^') - elif self.dim == 3: - if cells: - ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'r.', zs=self.gridCC[:,2]) - if cellLine: - ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'r:', zs=self.gridCC[:,2]) - ax.plot(self.gridCC[[0,-1],0], self.gridCC[[0,-1],1], 'ro', zs=self.gridCC[[0,-1],2]) - - if nodes: - ax.plot(self._gridN[:,0], self._gridN[:,1], 'ms', zs=self._gridN[:,2]) - ax.plot(self._gridN[self._hangingN.keys(),0], self._gridN[self._hangingN.keys(),1], 'ms', ms=10, mfc='none', mec='m', zs=self._gridN[self._hangingN.keys(),2]) - for key in self._hangingN.keys(): - for hf in self._hangingN[key]: - ind = [key, hf[0]] - ax.plot(self._gridN[ind,0], self._gridN[ind,1], 'm:', zs=self._gridN[ind,2]) - - if facesX: - ax.plot(self._gridFx[:,0], self._gridFx[:,1], 'g>', zs=self._gridFx[:,2]) - ax.plot(self._gridFx[self._hangingFx.keys(),0], self._gridFx[self._hangingFx.keys(),1], 'gs', ms=10, mfc='none', mec='g', zs=self._gridFx[self._hangingFx.keys(),2]) - for key in self._hangingFx.keys(): - for hf in self._hangingFx[key]: - ind = [key, hf[0]] - ax.plot(self._gridFx[ind,0], self._gridFx[ind,1], 'g:', zs=self._gridFx[ind,2]) - - if facesY: - ax.plot(self._gridFy[:,0], self._gridFy[:,1], 'g^', zs=self._gridFy[:,2]) - ax.plot(self._gridFy[self._hangingFy.keys(),0], self._gridFy[self._hangingFy.keys(),1], 'gs', ms=10, mfc='none', mec='g', zs=self._gridFy[self._hangingFy.keys(),2]) - for key in self._hangingFy.keys(): - for hf in self._hangingFy[key]: - ind = [key, hf[0]] - ax.plot(self._gridFy[ind,0], self._gridFy[ind,1], 'g:', zs=self._gridFy[ind,2]) - - if facesZ: - ax.plot(self._gridFz[:,0], self._gridFz[:,1], 'g^', zs=self._gridFz[:,2]) - ax.plot(self._gridFz[self._hangingFz.keys(),0], self._gridFz[self._hangingFz.keys(),1], 'gs', ms=10, mfc='none', mec='g', zs=self._gridFz[self._hangingFz.keys(),2]) - for key in self._hangingFz.keys(): - for hf in self._hangingFz[key]: - ind = [key, hf[0]] - ax.plot(self._gridFz[ind,0], self._gridFz[ind,1], 'g:', zs=self._gridFz[ind,2]) - - if edgesX: - ax.plot(self._gridEx[:,0], self._gridEx[:,1], 'k>', zs=self._gridEx[:,2]) - ax.plot(self._gridEx[self._hangingEx.keys(),0], self._gridEx[self._hangingEx.keys(),1], 'ks', ms=10, mfc='none', mec='k', zs=self._gridEx[self._hangingEx.keys(),2]) - for key in self._hangingEx.keys(): - for hf in self._hangingEx[key]: - ind = [key, hf[0]] - ax.plot(self._gridEx[ind,0], self._gridEx[ind,1], 'k:', zs=self._gridEx[ind,2]) - - - if edgesY: - ax.plot(self._gridEy[:,0], self._gridEy[:,1], 'k<', zs=self._gridEy[:,2]) - ax.plot(self._gridEy[self._hangingEy.keys(),0], self._gridEy[self._hangingEy.keys(),1], 'ks', ms=10, mfc='none', mec='k', zs=self._gridEy[self._hangingEy.keys(),2]) - for key in self._hangingEy.keys(): - for hf in self._hangingEy[key]: - ind = [key, hf[0]] - ax.plot(self._gridEy[ind,0], self._gridEy[ind,1], 'k:', zs=self._gridEy[ind,2]) - - if edgesZ: - ax.plot(self._gridEz[:,0], self._gridEz[:,1], 'k^', zs=self._gridEz[:,2]) - ax.plot(self._gridEz[self._hangingEz.keys(),0], self._gridEz[self._hangingEz.keys(),1], 'ks', ms=10, mfc='none', mec='k', zs=self._gridEz[self._hangingEz.keys(),2]) - for key in self._hangingEz.keys(): - for hf in self._hangingEz[key]: - ind = [key, hf[0]] - ax.plot(self._gridEz[ind,0], self._gridEz[ind,1], 'k:', zs=self._gridEz[ind,2]) - - if showIt:plt.show() - - - def plotImage(self, I, ax=None, showIt=True): - if self.dim == 3: raise Exception() - - if ax is None: ax = plt.subplot(111) - jet = cm = plt.get_cmap('jet') - cNorm = colors.Normalize(vmin=I.min(), vmax=I.max()) - scalarMap = cmx.ScalarMappable(norm=cNorm, cmap=jet) - ax.set_xlim((self.x0[0], self.h[0].sum())) - ax.set_ylim((self.x0[1], self.h[1].sum())) - for ii, node in enumerate(self._sortedCells): - x0, sz = self._cellN(node), self._cellH(node) - ax.add_patch(plt.Rectangle((x0[0], x0[1]), sz[0], sz[1], facecolor=scalarMap.to_rgba(I[ii]), edgecolor='k')) - # if text: ax.text(self.center[0],self.center[1],self.num) - scalarMap._A = [] # http://stackoverflow.com/questions/8342549/matplotlib-add-colorbar-to-a-sequence-of-line-plots - plt.colorbar(scalarMap) - if showIt: plt.show() - - -def SortGrid(grid, offset=0): - """ - Sorts a grid by the x0 location. - """ - - eps = 1e-7 - def mycmp(c1,c2): - c1 = grid[c1-offset] - c2 = grid[c2-offset] - if c1.size == 2: - if np.abs(c1[1] - c2[1]) < eps: - return c1[0] - c2[0] - return c1[1] - c2[1] - elif c1.size == 3: - if np.abs(c1[2] - c2[2]) < eps: - if np.abs(c1[1] - c2[1]) < eps: - return c1[0] - c2[0] - return c1[1] - c2[1] - return c1[2] - c2[2] - - class K(object): - def __init__(self, obj, *args): - self.obj = obj - def __lt__(self, other): - return mycmp(self.obj, other.obj) < 0 - def __gt__(self, other): - return mycmp(self.obj, other.obj) > 0 - def __eq__(self, other): - return mycmp(self.obj, other.obj) == 0 - def __le__(self, other): - return mycmp(self.obj, other.obj) <= 0 - def __ge__(self, other): - return mycmp(self.obj, other.obj) >= 0 - def __ne__(self, other): - return mycmp(self.obj, other.obj) != 0 - - return sorted(range(offset,grid.shape[0]+offset), key=K) - - -class NotBalancedException(Exception): - pass - -if __name__ == '__main__': - - - def function(xc): - r = xc - np.array([0.5*128]*len(xc)) - dist = np.sqrt(r.dot(r)) - # if dist < 0.05: - # return 5 - if dist < 0.1*128: - return 4 - if dist < 0.3*128: - return 3 - if dist < 1.0*128: - return 2 - else: - return 0 - - # T = Tree([[(1,128)],[(1,128)],[(1,128)]],levels=7) - # T = Tree([128,128,128],levels=7) - T = Tree([[(1,16)],[(1,16)]],levels=4) - # T = Tree([[(1,128)],[(1,128)]],levels=7) - # T.refine(lambda xc:1, balance=False) - # T._index([0,0,0]) - # T._pointer(0) - - - tic = time.time() - T.refine(function)#, balance=False) - print time.time() - tic - print T.nC - - T.plotImage(np.random.rand(T.nC),showIt=True) - - print T.getFaceInnerProduct() - # print T.gridFz - - - # T._refineCell([8,0,1]) - # T._refineCell([8,0,2]) - # T._refineCell([12,0,2]) - # T._refineCell([8,4,2]) - # T._refineCell([6,0,3]) - # T._refineCell([8,8,1]) - # T._refineCell([0,0,0,1]) - # T.__dirty__ = True - - - print T.gridFx.shape[0], T.nFx - - - - ax = plt.subplot(211) - ax.spy(T.edgeCurl) - - # print Mesh.TensorMesh([2,2,2]).edgeCurl.todense() - # print T.edgeCurl.todense() - # print Mesh.TensorMesh([2,2,2]).edgeCurl.todense() - T.edgeCurl.todense() - # print T.gridEy - Mesh.TensorMesh([2,2,2]).gridEy - - # print T.edge - # T.plotGrid(ax=ax) - - # R = deflationMatrix(T._facesX, T._hangingFx, T._fx2i) - # print R - - ax = plt.subplot(212)#, projection='3d') - ax.spy(Mesh.TensorMesh([2,2,2]).edgeCurl) - - # ax = plt.subplot(313) - # ax.spy(T.faceDiv[:,:T.nFx] * R) - - - # T.balance() - # T.plotGrid(ax=ax) - - # cx = T._getNextCell([0,0,1],direction=0,positive=True) - # print cx - # # print [T._asPointer(_) for _ in cx] - # cx = T._getNextCell([8,0,3],direction=0,positive=False) - # print T._asPointer(cx) - # cx = T._getNextCell([8,8,1],direction=1,positive=False) - # print cx, #[T._asPointer(_) for _ in cx] - # cm = T._getNextCell([64,80,4],direction=0,positive=False) - # cy = T._getNextCell([64,80,4],direction=1,positive=True) - # cp = T._getNextCell([64,80,4],direction=1,positive=False) - - # ax.plot( T._cellN([4,0,1])[0],T._cellN([4,0,1])[1], 'yd') - # ax.plot( T._cellN(cx)[0],T._cellN(cx)[1], 'ys') - # ax.plot( T._cellN(cm)[0],T._cellN(cm)[1], 'ys') - # ax.plot( T._cellN(cy)[0],T._cellN(cy)[1], 'ys') - # ax.plot( T._cellN(cp[0])[0],T._cellN(cp[0])[1], 'ys') - # ax.plot( T._cellN(cp[1])[0],T._cellN(cp[1])[1], 'ys') - - - - - - # print T.nN - - plt.show() - diff --git a/SimPEG/Mesh/TreeMesh.py b/SimPEG/Mesh/TreeMesh.py index d2d18972..aa697ec1 100644 --- a/SimPEG/Mesh/TreeMesh.py +++ b/SimPEG/Mesh/TreeMesh.py @@ -1,26 +1,1548 @@ +# ___ ___ ___ ___ ___ +# /\ \ ___ /\__\ /\ \ /\ \ /\ \ +# /::\ \ /\ \ /::| | /::\ \ /::\ \ /::\ \ +# /:/\ \ \ \:\ \ /:|:| | /:/\:\ \ /:/\:\ \ /:/\:\ \ +# _\:\~\ \ \ /::\__\ /:/|:|__|__ /::\~\:\ \ /::\~\:\ \ /:/ \:\ \ +# /\ \:\ \ \__\ __/:/\/__//:/ |::::\__\/:/\:\ \:\__\/:/\:\ \:\__\/:/__/_\:\__\ +# \:\ \:\ \/__//\/:/ / \/__/~~/:/ /\/__\:\/:/ /\:\~\:\ \/__/\:\ /\ \/__/ +# \:\ \:\__\ \::/__/ /:/ / \::/ / \:\ \:\__\ \:\ \:\__\ +# \:\/:/ / \:\__\ /:/ / \/__/ \:\ \/__/ \:\/:/ / +# \::/ / \/__/ /:/ / \:\__\ \::/ / +# \/__/ \/__/ \/__/ \/__/ +# ___ ___ ___ ___ ___ ___ +# /\ \ /\ \ /\ \ /\ \ /\ \ /\ \ +# /::\ \ /::\ \ \:\ \ /::\ \ /::\ \ /::\ \ +# /:/\:\ \ /:/\:\ \ \:\ \ /:/\:\ \ /:/\:\ \ /:/\:\ \ +# /:/ \:\ \ /:/ \:\ \ /::\ \ /::\~\:\ \ /::\~\:\ \ /::\~\:\ \ +# /:/__/ \:\__\/:/__/ \:\__\ /:/\:\__\/:/\:\ \:\__\/:/\:\ \:\__\/:/\:\ \:\__\ +# \:\ \ /:/ /\:\ \ \/__//:/ \/__/\/_|::\/:/ /\:\~\:\ \/__/\:\~\:\ \/__/ +# \:\ /:/ / \:\ \ /:/ / |:|::/ / \:\ \:\__\ \:\ \:\__\ +# \:\/:/ / \:\ \ \/__/ |:|\/__/ \:\ \/__/ \:\ \/__/ +# \::/ / \:\__\ |:| | \:\__\ \:\__\ +# \/__/ \/__/ \|__| \/__/ \/__/ +# +# +# @rowanc1, Nov. 10, 2015 +# +# .----------------.----------------. +# /| /| /| +# / | / | / | +# / | 011 / | 111 / | +# / | / | / | +# .----------------.----+-----------. | +# /| . ---------/|----.----------/|----. +# / | /| / | /| / | /| +# / | / | 001 / | / | 101 / | / | +# / | / | / | / | / | / | +# . -------------- .----------------. |/ | +# | . ---+------|----.----+------|----. | +# | /| .______|___/|____.______|___/|____. +# | / | / 010 | / | / 110| / | / +# | / | / | / | / | / | / +# . ---+---------- . ---+---------- . | / +# | |/ | |/ | |/ z +# | . ----------|----.-----------|----. ^ y +# | / 000 | / 100 | / | / +# | / | / | / | / +# | / | / | / o----> x +# . -------------- . -------------- . +# +# +# Face Refinement: +# +# 2_______________3 _______________ +# | | | | | +# ^ | | | (0,1) | (1,1) | +# | | | | | | +# | | x | ---> |-------+-------| +# t1 | | | | | +# | | | (0,0) | (1,0) | +# |_______________| |_______|_______| +# 0 t0--> 1 +# +# +# Face and Edge naming conventions: +# +# fZp +# | +# 6 ------eX3------ 7 +# /| | / | +# /eZ2 . / eZ3 +# eY2 | fYp eY3 | +# / | / fXp| +# 4 ------eX2----- 5 | +# |fXm 2 -----eX1--|---- 3 z +# eZ0 / | eY1 ^ y +# | eY0 . fYm eZ1 / | / +# | / | | / | / +# 0 ------eX0------1 o----> x +# | +# fZm +# +# +# fX fY fZ +# 2___________3 2___________3 2___________3 +# | e1 | | e1 | | e1 | +# | | | | | | +# e2 | x | e3 z e2 | x | e3 z e2 | x | e3 y +# | | ^ | | ^ | | ^ +# |___________| |___> y |___________| |___> x |___________| |___> x +# 0 e0 1 0 e0 1 0 e0 1 +# + from SimPEG import np, sp, Utils, Solver -from BaseMesh import BaseMesh -from InnerProducts import InnerProducts import matplotlib.pyplot as plt +import matplotlib from mpl_toolkits.mplot3d import Axes3D import matplotlib.colors as colors import matplotlib.cm as cmx +import TreeUtils +from InnerProducts import InnerProducts +from BaseMesh import BaseMesh +import time + +MAX_BITS = 20 + +class TreeMesh(BaseMesh, InnerProducts): + def __init__(self, h_in, x0_in=None, levels=3): + assert type(h_in) is list, 'h_in must be a list' + assert len(h_in) > 1, "len(h_in) must be greater than 1" + + h = range(len(h_in)) + for i, h_i in enumerate(h_in): + if type(h_i) in [int, long, float]: + # This gives you something over the unit cube. + h_i = np.ones(int(h_i))/int(h_i) + elif type(h_i) is list: + h_i = Utils.meshTensor(h_i) + assert isinstance(h_i, np.ndarray), ("h[%i] is not a numpy array." % i) + assert len(h_i.shape) == 1, ("h[%i] must be a 1D numpy array." % i) + assert len(h_i) == 2**levels, "must make h and levels match" + h[i] = h_i[:] # make a copy. + self.h = h + + x0 = np.zeros(len(h)) + if x0_in is not None: + assert len(h) == len(x0_in), "Dimension mismatch. x0 != len(h)" + for i in range(len(h)): + x_i, h_i = x0_in[i], h[i] + if Utils.isScalar(x_i): + x0[i] = x_i + elif x_i == '0': + x0[i] = 0.0 + elif x_i == 'C': + x0[i] = -h_i.sum()*0.5 + elif x_i == 'N': + x0[i] = -h_i.sum() + else: + raise Exception("x0[%i] must be a scalar or '0' to be zero, 'C' to center, or 'N' to be negative." % i) + + BaseMesh.__init__(self, [len(_) for _ in h], x0) + + self._levels = levels + self._levelBits = int(np.ceil(np.sqrt(levels)))+1 + + self.__dirty__ = True #: The numbering is dirty! + + self._cells = set() + self._cells.add(0) + + @property + def __dirty__(self): + return self.__dirtyFaces__ or self.__dirtyEdges__ or self.__dirtyNodes__ or self.__dirtyHanging__ + + @__dirty__.setter + def __dirty__(self, val): + assert val is True + self.__dirtyFaces__ = True + self.__dirtyEdges__ = True + self.__dirtyNodes__ = True + self.__dirtyHanging__ = True + + deleteThese = [ + '__sortedCells', + '_gridCC', '_gridN', '_gridFx', '_gridFy', '_gridFz', '_gridEx', '_gridEy', '_gridEz', + '_area', '_edge', '_vol', + '_faceDiv', '_edgeCurl', '_nodalGrad' + ] + for p in deleteThese: + if hasattr(self, p): delattr(self, p) + + @property + def levels(self): return self._levels + + @property + def dim(self): return len(self.h) + + @property + def nC(self): return len(self._cells) + + @property + def nN(self): + self.number() + return len(self._nodes) - len(self._hangingN) + + @property + def nF(self): + return self.nFx + self.nFy + (0 if self.dim == 2 else self.nFz) + + @property + def nFx(self): + self.number() + return len(self._facesX) - len(self._hangingFx) + + @property + def nFy(self): + self.number() + return len(self._facesY) - len(self._hangingFy) + + @property + def nFz(self): + if self.dim == 2: return None + self.number() + return len(self._facesZ) - len(self._hangingFz) + + @property + def nE(self): + return self.nEx + self.nEy + (0 if self.dim == 2 else self.nEz) + + @property + def nEx(self): + if self.dim == 2:return self.nFy + self.number() + return len(self._edgesX) - len(self._hangingEx) + + @property + def nEy(self): + if self.dim == 2:return self.nFx + self.number() + return len(self._edgesY) - len(self._hangingEy) + + @property + def nEz(self): + if self.dim == 2: return None + self.number() + return len(self._edgesZ) - len(self._hangingEz) + + @property + def nhN(self): + self.number() + return len(self._hangingN) + + @property + def nhF(self): + return self.nhFx + self.nhFy + (0 if self.dim == 2 else self.nhFz) + + @property + def nhFx(self): + self.number() + return len(self._hangingFx) + + @property + def nhFy(self): + self.number() + return len(self._hangingFy) + + @property + def nhFz(self): + if self.dim == 2: return None + self.number() + return len(self._hangingFz) + + @property + def nhE(self): + return self.nhEx + self.nhEy + (0 if self.dim == 2 else self.nhEz) + + @property + def nhEx(self): + if self.dim == 2:return self.nhFy + self.number() + return len(self._hangingEx) + + @property + def nhEy(self): + if self.dim == 2:return self.nhFx + self.number() + return len(self._hangingEy) + + @property + def nhEz(self): + if self.dim == 2: return None + self.number() + return len(self._hangingEz) -def SortByX0(): + @property + def ntN(self): + self.number() + return len(self._nodes) + + @property + def ntF(self): + return self.ntFx + self.ntFy + (0 if self.dim == 2 else self.ntFz) + + @property + def ntFx(self): + self.number() + return len(self._facesX) + + @property + def ntFy(self): + self.number() + return len(self._facesY) + + @property + def ntFz(self): + if self.dim == 2: return None + self.number() + return len(self._facesZ) + + @property + def ntE(self): + return self.ntEx + self.ntEy + (0 if self.dim == 2 else self.ntEz) + + @property + def ntEx(self): + if self.dim == 2:return self.ntFy + self.number() + return len(self._edgesX) + + @property + def ntEy(self): + if self.dim == 2:return self.ntFx + self.number() + return len(self._edgesY) + + @property + def ntEz(self): + if self.dim == 2: return None + self.number() + return len(self._edgesZ) + + @property + def _sortedCells(self): + if getattr(self, '__sortedCells', None) is None: + self.__sortedCells = sorted(self._cells) + return self.__sortedCells + + @property + def permuteCC(self): + #TODO: cache these? + P = SortGrid(self.gridCC) + return sp.identity(self.nC).tocsr()[P,:] + + @property + def permuteF(self): + #TODO: cache these? + P = SortGrid(self.gridFx) + P += SortGrid(self.gridFy, offset=self.nFx) + if self.dim == 3: + P += SortGrid(self.gridFz, offset=self.nFx+self.nFy) + return sp.identity(self.nF).tocsr()[P,:] + + @property + def permuteE(self): + #TODO: cache these? + if self.dim == 2: + P = SortGrid(self.gridFy) + P += SortGrid(self.gridFx, offset=self.nEx) + return sp.identity(self.nE).tocsr()[P,:] + if self.dim == 3: + P = SortGrid(self.gridEx) + P += SortGrid(self.gridEy, offset=self.nEx) + P += SortGrid(self.gridEz, offset=self.nEx+self.nEy) + return sp.identity(self.nE).tocsr()[P,:] + + def _index(self, pointer): + assert len(pointer) is self.dim+1 + assert pointer[-1] <= self.levels + return TreeUtils.index(self.dim, MAX_BITS, self._levelBits, pointer[:-1], pointer[-1]) + + def _pointer(self, index): + assert type(index) in [int, long] + return TreeUtils.point(self.dim, MAX_BITS, self._levelBits, index) + + def __contains__(self, v): + return self._asIndex(v) in self._cells + + def refine(self, function=None, recursive=True, cells=None, balance=True, verbose=False, _inRecursion=False): + + if not _inRecursion: + self.__dirty__ = True + if verbose: print 'Refining Mesh' + + cells = cells if cells is not None else sorted(self._cells) + recurse = [] + tic = time.time() + for cell in cells: + p = self._pointer(cell) + do = function(self._cellC(cell)) > p[-1] + if do: + recurse += self._refineCell(cell) + + if verbose: print ' ', time.time() - tic + + if recursive and len(recurse) > 0: + recurse += self.refine(function=function, recursive=True, cells=recurse, balance=balance, _inRecursion=True) + + if balance and not _inRecursion: + self.balance() + return recurse + + def _refineCell(self, pointer): + pointer = self._asPointer(pointer) + ind = self._asIndex(pointer) + assert ind in self + h = self._levelWidth(pointer[-1])/2 # halfWidth + nL = pointer[-1] + 1 # new level + add = lambda p:p[0]+p[1] + added = [] + def addCell(p): + i = self._index(p+[nL]) + self._cells.add(i) + added.append(i) + + addCell(map(add, zip(pointer[:-1], [0,0,0][:self.dim]))) + addCell(map(add, zip(pointer[:-1], [h,0,0][:self.dim]))) + addCell(map(add, zip(pointer[:-1], [0,h,0][:self.dim]))) + addCell(map(add, zip(pointer[:-1], [h,h,0][:self.dim]))) + if self.dim == 3: + addCell(map(add, zip(pointer[:-1], [0,0,h]))) + addCell(map(add, zip(pointer[:-1], [h,0,h]))) + addCell(map(add, zip(pointer[:-1], [0,h,h]))) + addCell(map(add, zip(pointer[:-1], [h,h,h]))) + self._cells.remove(ind) + return added + + def corsen(self, function=None): + self.__dirty__ = True + raise Exception('Not yet implemented') + + + def _corsenCell(self, pointer): + raise Exception('Not yet implemented') + + # something like this: ?? + pointer = self._asPointer(pointer) + ind = self._asIndex(pointer) + assert ind in self + + parent = self._parentPointer(ind) + children = _childPointers(parent) + for child in children: + self._cells.remove(self._asIndex(child)) + + parentInd = self._asIndex(parent) + self._cells.add(parentInd) + return parentInd + + def _asPointer(self, ind): + if type(ind) in [int, long]: + return self._pointer(ind) + if type(ind) is list: + assert len(ind) == (self.dim + 1), str(ind) +' is not valid pointer' + assert ind[-1] <= self.levels, str(ind) +' is not valid pointer' + return ind + if isinstance(ind, np.ndarray): + return ind.tolist() + raise Exception + + def _asIndex(self, pointer): + if type(pointer) in [int, long]: + return pointer + if type(pointer) is list: + return self._index(pointer) + raise Exception + + + def _childPointers(self, pointer, direction=0, positive=True, returnAll=False): + l = self._levelWidth(pointer[-1] + 1) + + if self.dim == 2: + + children = [ + [pointer[0] , pointer[1] , pointer[-1] + 1], + [pointer[0] + l, pointer[1] , pointer[-1] + 1], + [pointer[0] , pointer[1] + l, pointer[-1] + 1], + [pointer[0] + l, pointer[1] + l, pointer[-1] + 1] + ] + + elif self.dim == 3: + + children = [ + [pointer[0] , pointer[1] , pointer[2] , pointer[-1] + 1], + [pointer[0] + l, pointer[1] , pointer[2] , pointer[-1] + 1], + [pointer[0] , pointer[1] + l, pointer[2] , pointer[-1] + 1], + [pointer[0] + l, pointer[1] + l, pointer[2] , pointer[-1] + 1], + [pointer[0] , pointer[1] , pointer[2] + l, pointer[-1] + 1], + [pointer[0] + l, pointer[1] , pointer[2] + l, pointer[-1] + 1], + [pointer[0] , pointer[1] + l, pointer[2] + l, pointer[-1] + 1], + [pointer[0] + l, pointer[1] + l, pointer[2] + l, pointer[-1] + 1] + ] + if direction == 0: ind = [0,2,4,6] if not positive else [1,3,5,7] + if direction == 1: ind = [0,1,4,5] if not positive else [2,3,6,7] + if direction == 2: ind = [0,1,2,3] if not positive else [4,5,6,7] + + if returnAll: + return children + return [children[_] for _ in ind[:(self.dim-1)*2]] + + + def _parentPointer(self, pointer): + mod = self._levelWidth(pointer[-1] - 1) + return [p - (p % mod) for p in pointer[:-1]] + [pointer[-1]-1] + + def _cellN(self, p): + p = self._asPointer(p) + return [hi[:p[ii]].sum() for ii, hi in enumerate(self.h)] + + def _cellH(self, p): + p = self._asPointer(p) + w = self._levelWidth(p[-1]) + return [hi[p[ii]:p[ii]+w].sum() for ii, hi in enumerate(self.h)] + + def _cellC(self, p): + return (np.array(self._cellH(p))/2.0 + self._cellN(p)).tolist() + + def _levelWidth(self, level): + return 2**(self.levels - level) + + def _isInsideMesh(self, pointer): + inside = True + for p in pointer[:-1]: + inside = inside and p >= 0 and p < 2**self.levels + return inside + + def _getNextCell(self, ind, direction=0, positive=True, _lookUp=True): + """ + Returns a None, int, list, or nested list + The int is the cell number. + + """ + if direction >= self.dim: return None + pointer = self._asPointer(ind) + if pointer[-1] > self.levels: return None + + step = (1 if positive else -1) * self._levelWidth(pointer[-1]) + nextCell = [p if ii is not direction else p + step for ii, p in enumerate(pointer)] + # raise Exception(pointer, nextCell) + if not self._isInsideMesh(nextCell): return None + + # it might be the same size as me? + if nextCell in self: return self._index(nextCell) + + if nextCell[-1] + 1 <= self.levels: # if I am not the smallest. + children = self._childPointers(pointer, direction=direction, positive=positive) + nextCells = [self._getNextCell(child, direction=direction, positive=positive, _lookUp=False) for child in children] + if nextCells[0] is not None: + return nextCells + + if not _lookUp: return None + + # it might be bigger than me? + return self._getNextCell(self._parentPointer(pointer), + direction=direction, positive=positive) + + def balance(self, recursive=True, cells=None, verbose=False, _inRecursion=False): + + tic = time.time() + if not _inRecursion: + self.__dirty__ = True + if verbose: print 'Balancing Mesh:' + + cells = cells if cells is not None else sorted(self._cells) + + # calcDepth = lambda i: lambda A: i if type(A) is not list else max(map(calcDepth(i+1), A)) + # flatten = lambda A: A if calcDepth(0)(A) == 1 else flatten([_ for __ in A for _ in (__ if type(__) is list else [__])]) + + recurse = set() + + for cell in cells: + p = self._asPointer(cell) + if p[-1] == self.levels: continue + + cs = range(6) + cs[0] = self._getNextCell(cell, direction=0, positive=False) + cs[1] = self._getNextCell(cell, direction=0, positive=True) + cs[2] = self._getNextCell(cell, direction=1, positive=False) + cs[3] = self._getNextCell(cell, direction=1, positive=True) + cs[4] = self._getNextCell(cell, direction=2, positive=False) # this will be None if in 2D + cs[5] = self._getNextCell(cell, direction=2, positive=True) # this will be None if in 2D + + do = np.any([ + type(c) is list and np.any([type(_) is list for _ in c]) + for c in cs + if c is not None + ]) + # depth = calcDepth(0)(cs) + # print depth, depth > 2, do, [jj for jj in flatten(cs) if jj is not None] + # recurse += [jj for jj in flatten(cs) if jj is not None] + + if do and cell in self: + newCells = self._refineCell(cell) + recurse.update([_ for _ in cs if type(_) in [int, long]]) # only add the bigger ones! + recurse.update(newCells) + + if verbose: print ' ', len(cells), time.time() - tic + if recursive and len(recurse) > 0: + self.balance(cells=sorted(recurse), _inRecursion=True) + + @property + def gridCC(self): + if getattr(self, '_gridCC', None) is None: + self._gridCC = np.zeros((len(self._cells),self.dim)) + for ii, ind in enumerate(self._sortedCells): + p = self._asPointer(ind) + self._gridCC[ii, :] = self._cellC(p) + return self._gridCC + + @property + def gridN(self): + self.number() + R = self._deflationMatrix('N', withHanging=False) + return R.T * self._gridN + + @property + def gridFx(self): + self.number() + R = self._deflationMatrix('Fx', withHanging=False) + return R.T * self._gridFx + + @property + def gridFy(self): + self.number() + R = self._deflationMatrix('Fy', withHanging=False) + return R.T * self._gridFy + + @property + def gridFz(self): + if self.dim < 3: return None + self.number() + R = self._deflationMatrix('Fz', withHanging=False) + return R.T * self._gridFz + + @property + def gridEx(self): + if self.dim == 2: return self.gridFy + self.number() + R = self._deflationMatrix('Ex', withHanging=False) + return R.T * self._gridEx + + @property + def gridEy(self): + if self.dim == 2: return self.gridFx + self.number() + R = self._deflationMatrix('Ey', withHanging=False) + return R.T * self._gridEy + + @property + def gridEz(self): + if self.dim < 3: return None + self.number() + R = self._deflationMatrix('Ez', withHanging=False) + return R.T * self._gridEz + + @property + def vol(self): + if getattr(self, '_vol', None) is None: + self._vol = np.zeros(len(self._cells)) + for ii, ind in enumerate(self._sortedCells): + p = self._asPointer(ind) + self._vol[ii] = np.prod(self._cellH(p)) + return self._vol + + @property + def area(self): + self.number() + if getattr(self, '_area', None) is None: + Rf = self._deflationMatrix('F', withHanging=False) + self._area = Rf.T * ( + np.r_[self._areaFxFull, self._areaFyFull] if self.dim == 2 else + np.r_[self._areaFxFull, self._areaFyFull, self._areaFzFull] + ) + return self._area + + @property + def edge(self): + self.number() + if self.dim == 2: + return np.r_[self.area[self.nFx:], self.area[:self.nFx]] + if getattr(self, '_edge', None) is None: + Re = self._deflationMatrix('E', withHanging=False) + self._edge = Re.T * np.r_[self._edgeExFull, self._edgeEyFull, self._edgeEzFull] + + return self._edge + + def _onSameLevel(self, i0, i1): + p0 = self._asPointer(i0) + p1 = self._asPointer(i1) + return p0[-1] == p1[-1] + + def _numberNodes(self, force=False): + if not self.__dirtyNodes__ and not force: return + + self._nodes = set() + + for ind in self._cells: + p = self._asPointer(ind) + w = self._levelWidth(p[-1]) + if self.dim == 2: + self._nodes.add(self._index([p[0] , p[1] , p[2]])) + self._nodes.add(self._index([p[0] + w, p[1] , p[2]])) + self._nodes.add(self._index([p[0] , p[1] + w, p[2]])) + self._nodes.add(self._index([p[0] + w, p[1] + w, p[2]])) + elif self.dim == 3: + self._nodes.add(self._index([p[0] , p[1] , p[2] , p[3]])) + self._nodes.add(self._index([p[0] + w, p[1] , p[2] , p[3]])) + self._nodes.add(self._index([p[0] , p[1] + w, p[2] , p[3]])) + self._nodes.add(self._index([p[0] + w, p[1] + w, p[2] , p[3]])) + self._nodes.add(self._index([p[0] , p[1] , p[2] + w, p[3]])) + self._nodes.add(self._index([p[0] + w, p[1] , p[2] + w, p[3]])) + self._nodes.add(self._index([p[0] , p[1] + w, p[2] + w, p[3]])) + self._nodes.add(self._index([p[0] + w, p[1] + w, p[2] + w, p[3]])) + gridN = [] + self._n2i = dict() + for ii, n in enumerate(sorted(self._nodes)): + self._n2i[n] = ii + gridN.append( self._cellN( self._pointer(n) ) ) + self._gridN = np.array(gridN) + + self.__dirtyNodes__ = False + + def _numberFaces(self, force=False): + if not self.__dirtyFaces__ and not force: return + + self._facesX = set() + self._facesY = set() + if self.dim == 3: + self._facesZ = set() + + for ind in self._cells: + p = self._asPointer(ind) + w = self._levelWidth(p[-1]) + + if self.dim == 2: + self._facesX.add(self._index([p[0] , p[1] , p[2]])) + self._facesX.add(self._index([p[0] + w, p[1] , p[2]])) + self._facesY.add(self._index([p[0] , p[1] , p[2]])) + self._facesY.add(self._index([p[0] , p[1] + w, p[2]])) + elif self.dim == 3: + self._facesX.add(self._index([p[0] , p[1] , p[2] , p[3]])) + self._facesX.add(self._index([p[0] + w, p[1] , p[2] , p[3]])) + self._facesY.add(self._index([p[0] , p[1] , p[2] , p[3]])) + self._facesY.add(self._index([p[0] , p[1] + w, p[2] , p[3]])) + self._facesZ.add(self._index([p[0] , p[1] , p[2] , p[3]])) + self._facesZ.add(self._index([p[0] , p[1] , p[2] + w, p[3]])) + + gridFx = [] + areaFx = [] + self._fx2i = dict() + for ii, fx in enumerate(sorted(self._facesX)): + self._fx2i[fx] = ii + p = self._pointer(fx) + n, h = self._cellN(p), self._cellH(p) + if self.dim == 2: + gridFx.append( [n[0], n[1] + h[1]/2.0] ) + areaFx.append( h[1] ) + elif self.dim == 3: + gridFx.append( [n[0], n[1] + h[1]/2.0, n[2] + h[2]/2.0] ) + areaFx.append( h[1]*h[2] ) + self._gridFx = np.array(gridFx) + self._areaFxFull = np.array(areaFx) + + gridFy = [] + areaFy = [] + self._fy2i = dict() + for ii, fy in enumerate(sorted(self._facesY)): + self._fy2i[fy] = ii + p = self._pointer(fy) + n, h = self._cellN(p), self._cellH(p) + if self.dim == 2: + gridFy.append( [n[0] + h[0]/2.0, n[1]] ) + areaFy.append( h[0] ) + elif self.dim == 3: + gridFy.append( [n[0] + h[0]/2.0, n[1], n[2] + h[2]/2.0] ) + areaFy.append( h[0]*h[2] ) + self._gridFy = np.array(gridFy) + self._areaFyFull = np.array(areaFy) + + if self.dim == 2: + self.__dirtyFaces__ = False + return + + gridFz = [] + areaFz = [] + self._fz2i = dict() + for ii, fz in enumerate(sorted(self._facesZ)): + self._fz2i[fz] = ii + p = self._pointer(fz) + n, h = self._cellN(p), self._cellH(p) + gridFz.append( [n[0] + h[0]/2.0, n[1] + h[1]/2.0, n[2]] ) + areaFz.append(h[0]*h[1]) + self._gridFz = np.array(gridFz) + self._areaFzFull = np.array(areaFz) + + self.__dirtyFaces__ = False + + def _numberEdges(self, force=False): + if self.dim == 2: + self.__dirtyEdges__ = False + return + if not self.__dirtyEdges__ and not force: return + + self._edgesX = set() + self._edgesY = set() + self._edgesZ = set() + + for ind in self._cells: + p = self._asPointer(ind) + w = self._levelWidth(p[-1]) + self._edgesX.add(self._index([p[0] , p[1] , p[2] , p[3]])) + self._edgesX.add(self._index([p[0] , p[1] + w, p[2] , p[3]])) + self._edgesX.add(self._index([p[0] , p[1] , p[2] + w, p[3]])) + self._edgesX.add(self._index([p[0] , p[1] + w, p[2] + w, p[3]])) + + self._edgesY.add(self._index([p[0] , p[1] , p[2] , p[3]])) + self._edgesY.add(self._index([p[0] + w, p[1] , p[2] , p[3]])) + self._edgesY.add(self._index([p[0] , p[1] , p[2] + w, p[3]])) + self._edgesY.add(self._index([p[0] + w, p[1] , p[2] + w, p[3]])) + + self._edgesZ.add(self._index([p[0] , p[1] , p[2] , p[3]])) + self._edgesZ.add(self._index([p[0] + w, p[1] , p[2] , p[3]])) + self._edgesZ.add(self._index([p[0] , p[1] + w, p[2] , p[3]])) + self._edgesZ.add(self._index([p[0] + w, p[1] + w, p[2] , p[3]])) + + gridEx = [] + edgeEx = [] + self._ex2i = dict() + for ii, ex in enumerate(sorted(self._edgesX)): + self._ex2i[ex] = ii + p = self._pointer(ex) + n, h = self._cellN(p), self._cellH(p) + gridEx.append( [n[0] + h[0]/2.0, n[1], n[2]] ) + edgeEx.append( h[0] ) + self._gridEx = np.array(gridEx) + self._edgeExFull = np.array(edgeEx) + + gridEy = [] + edgeEy = [] + self._ey2i = dict() + for ii, ey in enumerate(sorted(self._edgesY)): + self._ey2i[ey] = ii + p = self._pointer(ey) + n, h = self._cellN(p), self._cellH(p) + gridEy.append( [n[0], n[1] + h[1]/2.0, n[2]] ) + edgeEy.append( h[1] ) + self._gridEy = np.array(gridEy) + self._edgeEyFull = np.array(edgeEy) + + gridEz = [] + edgeEz = [] + self._ez2i = dict() + for ii, ez in enumerate(sorted(self._edgesZ)): + self._ez2i[ez] = ii + p = self._pointer(ez) + n, h = self._cellN(p), self._cellH(p) + gridEz.append( [n[0], n[1], n[2] + h[2]/2.0] ) + edgeEz.append( h[2] ) + self._gridEz = np.array(gridEz) + self._edgeEzFull = np.array(edgeEz) + + self.__dirtyEdges__ = False + + def _hanging(self, force=False): + if not self.__dirtyHanging__ and not force: return + + self._numberNodes(force=force) + self._numberFaces(force=force) + self._numberEdges(force=force) + + self._hangingN = dict() + self._hangingFx = dict() + self._hangingFy = dict() + if self.dim == 3: + self._hangingFz = dict() + self._hangingEx = dict() + self._hangingEy = dict() + self._hangingEz = dict() + + # Compute from x faces + for fx in self._facesX: + p = self._pointer(fx) + if p[-1] + 1 > self.levels: continue + sl = p[-1] + 1 #: small level + test = self._index(p[:-1] + [sl]) + if test not in self._facesX: + # Return early without checking the other faces + continue + w = self._levelWidth(sl) + + if self.dim == 2: + chy0 = self._cellH([p[0] , p[1] , sl])[1] + chy1 = self._cellH([p[0] , p[1] + w, sl])[1] + A = (chy0 + chy1) + + self._hangingFx[self._fx2i[test ]] = ([self._fx2i[fx], chy0 / A], ) + self._hangingFx[self._fx2i[self._index([p[0] , p[1] + w, sl])]] = ([self._fx2i[fx], chy1 / A], ) + + n0, n1 = fx, self._index([p[0], p[1] + 2*w, p[-1]]) + self._hangingN[self._n2i[test ]] = ([self._n2i[n0], 1.0], ) + self._hangingN[self._n2i[self._index([p[0] , p[1] + w, sl])]] = ([self._n2i[n0], 1.0 - chy0 / A], [self._n2i[n1], 1.0 - chy1 / A]) + self._hangingN[self._n2i[self._index([p[0] , p[1] + 2*w, sl])]] = ([self._n2i[n1], 1.0], ) + + elif self.dim == 3: + + chy0 = self._cellH([p[0] , p[1] , p[2] , sl])[1] + chy1 = self._cellH([p[0] , p[1] + w, p[2] , sl])[1] + chz0 = self._cellH([p[0] , p[1] , p[2] , sl])[2] + chz1 = self._cellH([p[0] , p[1] , p[2] + w, sl])[2] + lenY = chy0 + chy1 + lenZ = chz0 + chz1 + A = lenY * lenZ + + ey0 = fx + ey1 = self._index([p[0], p[1] , p[2] + 2*w, p[-1]]) + ez0 = fx + ez1 = self._index([p[0], p[1] + 2*w, p[2] , p[-1]]) + + n0 = fx + n1 = self._index([p[0], p[1] + 2*w, p[2] , p[-1]]) + n2 = self._index([p[0], p[1] , p[2] + 2*w, p[-1]]) + n3 = self._index([p[0], p[1] + 2*w, p[2] + 2*w, p[-1]]) + + self._hangingFx[self._fx2i[test ]] = ([self._fx2i[fx], chy0*chz0 / A ], ) + self._hangingFx[self._fx2i[self._index([p[0], p[1] + w, p[2] , sl])]] = ([self._fx2i[fx], chy1*chz0 / A ], ) + self._hangingFx[self._fx2i[self._index([p[0], p[1] , p[2] + w, sl])]] = ([self._fx2i[fx], chy0*chz1 / A ], ) + self._hangingFx[self._fx2i[self._index([p[0], p[1] + w, p[2] + w, sl])]] = ([self._fx2i[fx], chy1*chz1 / A ], ) + + self._hangingEy[self._ey2i[test ]] = ([self._ey2i[ey0], 1.0], ) + self._hangingEy[self._ey2i[self._index([p[0], p[1] + w, p[2] , sl])]] = ([self._ey2i[ey0], 1.0], ) + self._hangingEy[self._ey2i[self._index([p[0], p[1] , p[2] + w, sl])]] = ([self._ey2i[ey0], 0.5], [self._ey2i[ey1], 0.5]) + self._hangingEy[self._ey2i[self._index([p[0], p[1] + w, p[2] + w, sl])]] = ([self._ey2i[ey0], 0.5], [self._ey2i[ey1], 0.5]) + self._hangingEy[self._ey2i[self._index([p[0], p[1] , p[2] + 2*w, sl])]] = ([self._ey2i[ey1], 1.0], ) + self._hangingEy[self._ey2i[self._index([p[0], p[1] + w, p[2] + 2*w, sl])]] = ([self._ey2i[ey1], 1.0], ) + + self._hangingEz[self._ez2i[test ]] = ([self._ez2i[ez0], 1.0], ) + self._hangingEz[self._ez2i[self._index([p[0], p[1] , p[2] + w, sl])]] = ([self._ez2i[ez0], 1.0], ) + self._hangingEz[self._ez2i[self._index([p[0], p[1] + w, p[2] , sl])]] = ([self._ez2i[ez0], 0.5], [self._ez2i[ez1], 0.5]) + self._hangingEz[self._ez2i[self._index([p[0], p[1] + w, p[2] + w, sl])]] = ([self._ez2i[ez0], 0.5], [self._ez2i[ez1], 0.5]) + self._hangingEz[self._ez2i[self._index([p[0], p[1] + 2*w, p[2] , sl])]] = ([self._ez2i[ez1], 1.0], ) + self._hangingEz[self._ez2i[self._index([p[0], p[1] + 2*w, p[2] + w, sl])]] = ([self._ez2i[ez1], 1.0], ) + + # self._hangingEy[self._ey2i[test ]] = ([self._ey2i[ey0], chy0 / lenY], ) + # self._hangingEy[self._ey2i[self._index([p[0], p[1] + w, p[2] , sl])]] = ([self._ey2i[ey0], chy1 / lenY], ) + # self._hangingEy[self._ey2i[self._index([p[0], p[1] , p[2] + w, sl])]] = ([self._ey2i[ey0], chy0 / lenY / 2.0], [self._ey2i[ey1], chy0 / lenY / 2.0]) + # self._hangingEy[self._ey2i[self._index([p[0], p[1] + w, p[2] + w, sl])]] = ([self._ey2i[ey0], chy1 / lenY / 2.0], [self._ey2i[ey1], chy1 / lenY / 2.0]) + # self._hangingEy[self._ey2i[self._index([p[0], p[1] , p[2] + 2*w, sl])]] = ([self._ey2i[ey1], chy0 / lenY], ) + # self._hangingEy[self._ey2i[self._index([p[0], p[1] + w, p[2] + 2*w, sl])]] = ([self._ey2i[ey1], chy1 / lenY], ) + + # self._hangingEz[self._ez2i[test ]] = ([self._ez2i[ez0], chz0 / lenZ], ) + # self._hangingEz[self._ez2i[self._index([p[0], p[1] , p[2] + w, sl])]] = ([self._ez2i[ez0], chz1 / lenZ], ) + # self._hangingEz[self._ez2i[self._index([p[0], p[1] + w, p[2] , sl])]] = ([self._ez2i[ez0], chz0 / lenZ / 2.0], [self._ez2i[ez1], chz0 / lenZ / 2.0]) + # self._hangingEz[self._ez2i[self._index([p[0], p[1] + w, p[2] + w, sl])]] = ([self._ez2i[ez0], chz1 / lenZ / 2.0], [self._ez2i[ez1], chz1 / lenZ / 2.0]) + # self._hangingEz[self._ez2i[self._index([p[0], p[1] + 2*w, p[2] , sl])]] = ([self._ez2i[ez1], chz0 / lenZ], ) + # self._hangingEz[self._ez2i[self._index([p[0], p[1] + 2*w, p[2] + w, sl])]] = ([self._ez2i[ez1], chz1 / lenZ], ) + + self._hangingN[ self._n2i[ test ]] = ([self._n2i[n0], 1.0], ) + self._hangingN[ self._n2i[ self._index([p[0], p[1] + w, p[2] , sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n1], 0.5]) + self._hangingN[ self._n2i[ self._index([p[0], p[1] + 2*w, p[2] , sl])]] = ([self._n2i[n1], 1.0], ) + self._hangingN[ self._n2i[ self._index([p[0], p[1] , p[2] + w, sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n2], 0.5]) + self._hangingN[ self._n2i[ self._index([p[0], p[1] + w, p[2] + w, sl])]] = ([self._n2i[n0], 0.25], [self._n2i[n1], 0.25], [self._n2i[n2], 0.25], [self._n2i[n3], 0.25]) + self._hangingN[ self._n2i[ self._index([p[0], p[1] + 2*w, p[2] + w, sl])]] = ([self._n2i[n1], 0.5], [self._n2i[n3], 0.5]) + self._hangingN[ self._n2i[ self._index([p[0], p[1] , p[2] + 2*w, sl])]] = ([self._n2i[n2], 1.0], ) + self._hangingN[ self._n2i[ self._index([p[0], p[1] + w, p[2] + 2*w, sl])]] = ([self._n2i[n2], 0.5], [self._n2i[n3], 0.5]) + self._hangingN[ self._n2i[ self._index([p[0], p[1] + 2*w, p[2] + 2*w, sl])]] = ([self._n2i[n3], 1.0], ) + + # Compute from y faces + for fy in self._facesY: + p = self._pointer(fy) + if p[-1] + 1 > self.levels: continue + sl = p[-1] + 1 #: small level + test = self._index(p[:-1] + [sl]) + if test not in self._facesY: + # Return early without checking the other faces + continue + w = self._levelWidth(sl) + + if self.dim == 2: + chx0 = self._cellH([p[0] , p[1] , sl])[0] + chx1 = self._cellH([p[0] + w, p[1] , sl])[0] + + self._hangingFy[self._fy2i[test ]] = ([self._fy2i[fy], chx0 / (chx0 + chx1)], ) + self._hangingFy[self._fy2i[self._index([p[0] + w, p[1] , sl])]] = ([self._fy2i[fy], chx1 / (chx0 + chx1)], ) + + n0, n1 = fy, self._index([p[0] + 2*w, p[1], p[-1]]) + self._hangingN[self._n2i[test ]] = ([self._n2i[n0], 1.0], ) + self._hangingN[self._n2i[self._index([p[0] + w, p[1] , sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n1], 0.5]) + self._hangingN[self._n2i[self._index([p[0] + 2*w, p[1] , sl])]] = ([self._n2i[n1], 1.0], ) + + elif self.dim == 3: + + chx0 = self._cellH([p[0] , p[1] , p[2] , sl])[0] + chx1 = self._cellH([p[0] + w, p[1] , p[2] , sl])[0] + chz0 = self._cellH([p[0] , p[1] , p[2] , sl])[2] + chz1 = self._cellH([p[0] , p[1] , p[2] + w, sl])[2] + lenX = chx0 + chx1 + lenZ = chz0 + chz1 + A = lenX * lenZ + + ex0 = fy + ex1 = self._index([p[0] , p[1], p[2] + 2*w, p[-1]]) + ez0 = fy + ez1 = self._index([p[0] + 2*w, p[1], p[2] , p[-1]]) + + n0 = fy + n1 = self._index([p[0] + 2*w, p[1], p[2] , p[-1]]) + n2 = self._index([p[0] , p[1], p[2] + 2*w, p[-1]]) + n3 = self._index([p[0] + 2*w, p[1], p[2] + 2*w, p[-1]]) + + self._hangingFy[self._fy2i[test ]] = ([self._fy2i[fy], chx0*chz0 / A ], ) + self._hangingFy[self._fy2i[self._index([p[0] + w, p[1], p[2] , sl])]] = ([self._fy2i[fy], chx1*chz0 / A ], ) + self._hangingFy[self._fy2i[self._index([p[0] , p[1], p[2] + w, sl])]] = ([self._fy2i[fy], chx0*chz1 / A ], ) + self._hangingFy[self._fy2i[self._index([p[0] + w, p[1], p[2] + w, sl])]] = ([self._fy2i[fy], chx1*chz1 / A ], ) + + self._hangingEx[self._ex2i[test ]] = ([self._ex2i[ex0], 1.0], ) + self._hangingEx[self._ex2i[self._index([p[0] + w, p[1], p[2] , sl])]] = ([self._ex2i[ex0], 1.0], ) + self._hangingEx[self._ex2i[self._index([p[0] , p[1], p[2] + w, sl])]] = ([self._ex2i[ex0], 0.5], [self._ex2i[ex1], 0.5]) + self._hangingEx[self._ex2i[self._index([p[0] + w, p[1], p[2] + w, sl])]] = ([self._ex2i[ex0], 0.5], [self._ex2i[ex1], 0.5]) + self._hangingEx[self._ex2i[self._index([p[0] , p[1], p[2] + 2*w, sl])]] = ([self._ex2i[ex1], 1.0], ) + self._hangingEx[self._ex2i[self._index([p[0] + w, p[1], p[2] + 2*w, sl])]] = ([self._ex2i[ex1], 1.0], ) + + self._hangingEz[self._ez2i[test ]] = ([self._ez2i[ez0], 1.0], ) + self._hangingEz[self._ez2i[self._index([p[0] , p[1], p[2] + w, sl])]] = ([self._ez2i[ez0], 1.0], ) + self._hangingEz[self._ez2i[self._index([p[0] + w, p[1], p[2] , sl])]] = ([self._ez2i[ez0], 0.5], [self._ez2i[ez1], 0.5]) + self._hangingEz[self._ez2i[self._index([p[0] + w, p[1], p[2] + w, sl])]] = ([self._ez2i[ez0], 0.5], [self._ez2i[ez1], 0.5]) + self._hangingEz[self._ez2i[self._index([p[0] + 2*w, p[1], p[2] , sl])]] = ([self._ez2i[ez1], 1.0], ) + self._hangingEz[self._ez2i[self._index([p[0] + 2*w, p[1], p[2] + w, sl])]] = ([self._ez2i[ez1], 1.0], ) + + # self._hangingEx[self._ex2i[test ]] = ([self._ex2i[ex0], chx0 / lenX], ) + # self._hangingEx[self._ex2i[self._index([p[0] + w, p[1], p[2] , sl])]] = ([self._ex2i[ex0], chx1 / lenX], ) + # self._hangingEx[self._ex2i[self._index([p[0] , p[1], p[2] + w, sl])]] = ([self._ex2i[ex0], chx0 / lenX / 2.0], [self._ex2i[ex1], chx0 / lenX / 2.0]) + # self._hangingEx[self._ex2i[self._index([p[0] + w, p[1], p[2] + w, sl])]] = ([self._ex2i[ex0], chx1 / lenX / 2.0], [self._ex2i[ex1], chx1 / lenX / 2.0]) + # self._hangingEx[self._ex2i[self._index([p[0] , p[1], p[2] + 2*w, sl])]] = ([self._ex2i[ex1], chx0 / lenX], ) + # self._hangingEx[self._ex2i[self._index([p[0] + w, p[1], p[2] + 2*w, sl])]] = ([self._ex2i[ex1], chx1 / lenX], ) + + # self._hangingEz[self._ez2i[test ]] = ([self._ez2i[ez0], chz0 / lenZ], ) + # self._hangingEz[self._ez2i[self._index([p[0] , p[1], p[2] + w, sl])]] = ([self._ez2i[ez0], chz1 / lenZ], ) + # self._hangingEz[self._ez2i[self._index([p[0] + w, p[1], p[2] , sl])]] = ([self._ez2i[ez0], chz0 / lenZ / 2.0], [self._ez2i[ez1], chz0 / lenZ / 2.0]) + # self._hangingEz[self._ez2i[self._index([p[0] + w, p[1], p[2] + w, sl])]] = ([self._ez2i[ez0], chz1 / lenZ / 2.0], [self._ez2i[ez1], chz1 / lenZ / 2.0]) + # self._hangingEz[self._ez2i[self._index([p[0] + 2*w, p[1], p[2] , sl])]] = ([self._ez2i[ez1], chz0 / lenZ], ) + # self._hangingEz[self._ez2i[self._index([p[0] + 2*w, p[1], p[2] + w, sl])]] = ([self._ez2i[ez1], chz1 / lenZ], ) + + self._hangingN[ self._n2i[ test ]] = ([self._n2i[n0], 1.0], ) + self._hangingN[ self._n2i[ self._index([p[0] + w, p[1], p[2] , sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n1], 0.5]) + self._hangingN[ self._n2i[ self._index([p[0] + 2*w, p[1], p[2] , sl])]] = ([self._n2i[n1], 1.0], ) + self._hangingN[ self._n2i[ self._index([p[0] , p[1], p[2] + w, sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n2], 0.5]) + self._hangingN[ self._n2i[ self._index([p[0] + w, p[1], p[2] + w, sl])]] = ([self._n2i[n0], 0.25], [self._n2i[n1], 0.25], [self._n2i[n2], 0.25], [self._n2i[n3], 0.25]) + self._hangingN[ self._n2i[ self._index([p[0] + 2*w, p[1], p[2] + w, sl])]] = ([self._n2i[n1], 0.5], [self._n2i[n3], 0.5]) + self._hangingN[ self._n2i[ self._index([p[0] , p[1], p[2] + 2*w, sl])]] = ([self._n2i[n2], 1.0], ) + self._hangingN[ self._n2i[ self._index([p[0] + w, p[1], p[2] + 2*w, sl])]] = ([self._n2i[n2], 0.5], [self._n2i[n3], 0.5]) + self._hangingN[ self._n2i[ self._index([p[0] + 2*w, p[1], p[2] + 2*w, sl])]] = ([self._n2i[n3], 1.0], ) + + if self.dim == 2: + self.__dirtyHanging__ = False + return + + # Compute from z faces + for fz in self._facesZ: + p = self._pointer(fz) + if p[-1] + 1 > self.levels: continue + sl = p[-1] + 1 #: small level + test = self._index(p[:-1] + [sl]) + if test not in self._facesZ: + # Return early without checking the other faces + continue + w = self._levelWidth(sl) + + chx0 = self._cellH([p[0] , p[1] , p[2] , sl])[0] + chx1 = self._cellH([p[0] + w, p[1] , p[2] , sl])[0] + chy0 = self._cellH([p[0] , p[1] , p[2] , sl])[1] + chy1 = self._cellH([p[0] , p[1] + w, p[2] , sl])[1] + lenX = chx0 + chx1 + lenY = chy0 + chy1 + A = lenX * lenY + + ex0 = fz + ex1 = self._index([p[0] , p[1] + 2*w, p[2], p[-1]]) + ey0 = fz + ey1 = self._index([p[0] + 2*w, p[1] , p[2], p[-1]]) + + n0 = fz + n1 = self._index([p[0] + 2*w, p[1] , p[2], p[-1]]) + n2 = self._index([p[0] , p[1] + 2*w, p[2], p[-1]]) + n3 = self._index([p[0] + 2*w, p[1] + 2*w, p[2], p[-1]]) + + self._hangingFz[self._fz2i[test ]] = ([self._fz2i[fz], chx0*chy0 / A ], ) + self._hangingFz[self._fz2i[self._index([p[0] + w, p[1] , p[2], sl])]] = ([self._fz2i[fz], chx1*chy0 / A ], ) + self._hangingFz[self._fz2i[self._index([p[0] , p[1] + w, p[2], sl])]] = ([self._fz2i[fz], chx0*chy1 / A ], ) + self._hangingFz[self._fz2i[self._index([p[0] + w, p[1] + w, p[2], sl])]] = ([self._fz2i[fz], chx1*chy1 / A ], ) + + self._hangingEx[self._ex2i[test ]] = ([self._ex2i[ex0], 1.0], ) + self._hangingEx[self._ex2i[self._index([p[0] + w, p[1] , p[2], sl])]] = ([self._ex2i[ex0], 1.0], ) + self._hangingEx[self._ex2i[self._index([p[0] , p[1] + w, p[2], sl])]] = ([self._ex2i[ex0], 0.5], [self._ex2i[ex1], 0.5]) + self._hangingEx[self._ex2i[self._index([p[0] + w, p[1] + w, p[2], sl])]] = ([self._ex2i[ex0], 0.5], [self._ex2i[ex1], 0.5]) + self._hangingEx[self._ex2i[self._index([p[0] , p[1] + 2*w, p[2], sl])]] = ([self._ex2i[ex1], 1.0], ) + self._hangingEx[self._ex2i[self._index([p[0] + w, p[1] + 2*w, p[2], sl])]] = ([self._ex2i[ex1], 1.0], ) + + self._hangingEy[self._ey2i[test ]] = ([self._ey2i[ey0], 1.0], ) + self._hangingEy[self._ey2i[self._index([p[0] , p[1] + w, p[2], sl])]] = ([self._ey2i[ey0], 1.0], ) + self._hangingEy[self._ey2i[self._index([p[0] + w, p[1] , p[2], sl])]] = ([self._ey2i[ey0], 0.5], [self._ey2i[ey1], 0.5]) + self._hangingEy[self._ey2i[self._index([p[0] + w, p[1] + w, p[2], sl])]] = ([self._ey2i[ey0], 0.5], [self._ey2i[ey1], 0.5]) + self._hangingEy[self._ey2i[self._index([p[0] + 2*w, p[1] , p[2], sl])]] = ([self._ey2i[ey1], 1.0], ) + self._hangingEy[self._ey2i[self._index([p[0] + 2*w, p[1] + w, p[2], sl])]] = ([self._ey2i[ey1], 1.0], ) + + # self._hangingEx[self._ex2i[test ]] = ([self._ex2i[ex0], chx0 / lenX], ) + # self._hangingEx[self._ex2i[self._index([p[0] + w, p[1] , p[2], sl])]] = ([self._ex2i[ex0], chx1 / lenX], ) + # self._hangingEx[self._ex2i[self._index([p[0] , p[1] + w, p[2], sl])]] = ([self._ex2i[ex0], chx0 / lenX / 2.0], [self._ex2i[ex1], chx0 / lenX / 2.0]) + # self._hangingEx[self._ex2i[self._index([p[0] + w, p[1] + w, p[2], sl])]] = ([self._ex2i[ex0], chx1 / lenX / 2.0], [self._ex2i[ex1], chx1 / lenX / 2.0]) + # self._hangingEx[self._ex2i[self._index([p[0] , p[1] + 2*w, p[2], sl])]] = ([self._ex2i[ex1], chx0 / lenX], ) + # self._hangingEx[self._ex2i[self._index([p[0] + w, p[1] + 2*w, p[2], sl])]] = ([self._ex2i[ex1], chx1 / lenX], ) + + # self._hangingEy[self._ey2i[test ]] = ([self._ey2i[ey0], chy0 / lenY], ) + # self._hangingEy[self._ey2i[self._index([p[0] , p[1] + w, p[2], sl])]] = ([self._ey2i[ey0], chy1 / lenY], ) + # self._hangingEy[self._ey2i[self._index([p[0] + w, p[1] , p[2], sl])]] = ([self._ey2i[ey0], chy0 / lenY / 2.0], [self._ey2i[ey1], chy0 / lenY / 2.0]) + # self._hangingEy[self._ey2i[self._index([p[0] + w, p[1] + w, p[2], sl])]] = ([self._ey2i[ey0], chy1 / lenY / 2.0], [self._ey2i[ey1], chy1 / lenY / 2.0]) + # self._hangingEy[self._ey2i[self._index([p[0] + 2*w, p[1] , p[2], sl])]] = ([self._ey2i[ey1], chy0 / lenY], ) + # self._hangingEy[self._ey2i[self._index([p[0] + 2*w, p[1] + w, p[2], sl])]] = ([self._ey2i[ey1], chy1 / lenY], ) + + self._hangingN[ self._n2i[ test ]] = ([self._n2i[n0], 1.0], ) + self._hangingN[ self._n2i[ self._index([p[0] + w, p[1] , p[2], sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n1], 0.5]) + self._hangingN[ self._n2i[ self._index([p[0] + 2*w, p[1] , p[2], sl])]] = ([self._n2i[n1], 1.0], ) + self._hangingN[ self._n2i[ self._index([p[0] , p[1] + w, p[2], sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n2], 0.5]) + self._hangingN[ self._n2i[ self._index([p[0] + w, p[1] + w, p[2], sl])]] = ([self._n2i[n0], 0.25], [self._n2i[n1], 0.25], [self._n2i[n2], 0.25], [self._n2i[n3], 0.25]) + self._hangingN[ self._n2i[ self._index([p[0] + 2*w, p[1] + w, p[2], sl])]] = ([self._n2i[n1], 0.5], [self._n2i[n3], 0.5]) + self._hangingN[ self._n2i[ self._index([p[0] , p[1] + 2*w, p[2], sl])]] = ([self._n2i[n2], 1.0], ) + self._hangingN[ self._n2i[ self._index([p[0] + w, p[1] + 2*w, p[2], sl])]] = ([self._n2i[n2], 0.5], [self._n2i[n3], 0.5]) + self._hangingN[ self._n2i[ self._index([p[0] + 2*w, p[1] + 2*w, p[2], sl])]] = ([self._n2i[n3], 1.0], ) + + self.__dirtyHanging__ = False + + def number(self, balance=True, force=False): + if not self.__dirty__ and not force: return + if balance: self.balance() + self._hanging(force=force) + + def _deflationMatrix(self, location, withHanging=True, asOnes=False): + assert location in ['N','F','Fx','Fy'] + (['Fz','E','Ex','Ey','Ez'] if self.dim == 3 else []) + + args = dict() + args['N'] = (self._nodes, self._hangingN, self._n2i ) + args['Fx'] = (self._facesX, self._hangingFx, self._fx2i) + args['Fy'] = (self._facesY, self._hangingFy, self._fy2i) + if self.dim == 3: + args['Fz'] = (self._facesZ, self._hangingFz, self._fz2i) + args['Ex'] = (self._edgesX, self._hangingEx, self._ex2i) + args['Ey'] = (self._edgesY, self._hangingEy, self._ey2i) + args['Ez'] = (self._edgesZ, self._hangingEz, self._ez2i) + if location in ['F', 'E']: + Rlist = [self._deflationMatrix(location + subLoc, withHanging=withHanging, asOnes=asOnes) for subLoc in ['x','y','z'][:self.dim]] + return sp.block_diag(Rlist) + return self.__deflationMatrix(*args[location], withHanging=withHanging, asOnes=asOnes) + + def __deflationMatrix(self, theSet, theHang, theIndex, withHanging=True, asOnes=False): + reducedInd = dict() # final reduced index + ii = 0 + I,J,V = [],[],[] + for fx in sorted(theSet): + if theIndex[fx] not in theHang: + reducedInd[theIndex[fx]] = ii + I += [theIndex[fx]] + J += [ii] + V += [1.0] + ii += 1 + if withHanging: + for hfkey in theHang.keys(): + hf = theHang[hfkey] + I += [hfkey]*len(hf) + J += [reducedInd[_[0]] for _ in hf] + if asOnes: + V += [1.0]*len(hf) + else: + V += [_[1] for _ in hf] + return sp.csr_matrix((V,(I,J)), shape=(len(theSet), len(reducedInd))) + + @property + def faceDiv(self): + if getattr(self, '_faceDiv', None) is None: + self.number() + + # TODO: Preallocate! + I, J, V = [], [], [] + PM = [-1,1]*self.dim # plus / minus + + # TODO total number of faces? + offset = [0]*2 + [self.ntFx]*2 + [self.ntFx+self.ntFy]*2 + + for ii, ind in enumerate(self._sortedCells): + + p = self._pointer(ind) + w = self._levelWidth(p[-1]) + + if self.dim == 2: + faces = [ + self._fx2i[self._index([ p[0] , p[1] , p[2]])], + self._fx2i[self._index([ p[0] + w, p[1] , p[2]])], + self._fy2i[self._index([ p[0] , p[1] , p[2]])], + self._fy2i[self._index([ p[0] , p[1] + w, p[2]])] + ] + elif self.dim == 3: + faces = [ + self._fx2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._fx2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], + self._fy2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._fy2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], + self._fz2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._fz2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])] + ] + + for off, pm, face in zip(offset,PM,faces): + I += [ii] + J += [face + off] + V += [pm] + + D = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.ntF)) + R = self._deflationMatrix('F',asOnes=True) + VOL = self.vol + if self.dim == 2: + S = np.r_[self._areaFxFull, self._areaFyFull] + elif self.dim == 3: + S = np.r_[self._areaFxFull, self._areaFyFull, self._areaFzFull] + self._faceDiv = Utils.sdiag(1.0/VOL)*D*Utils.sdiag(S)*R + return self._faceDiv + + @property + def edgeCurl(self): + """Construct the 3D curl operator.""" + assert self.dim > 2, "Edge Curl only programed for 3D." + + if getattr(self, '_edgeCurl', None) is None: + self.number() + # TODO: Preallocate! + I, J, V = [], [], [] + faceOffset = 0 + offset = [self.ntEx]*2 + [self.ntEx+self.ntEy]*2 + PM = [1, -1, -1, 1] + for ii, fx in enumerate(sorted(self._facesX)): + + p = self._pointer(fx) + w = self._levelWidth(p[-1]) + + edges = [ + self._ey2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._ey2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])], + self._ez2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._ez2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], + ] + + for off, pm, edge in zip(offset,PM,edges): + I += [ii + faceOffset] + J += [edge + off] + V += [pm] + + faceOffset = self.ntFx + offset = [0]*2 + [self.ntEx+self.ntEy]*2 + PM = [-1, 1, 1, -1] + for ii, fy in enumerate(sorted(self._facesY)): + + p = self._pointer(fy) + w = self._levelWidth(p[-1]) + + edges = [ + self._ex2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._ex2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])], + self._ez2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._ez2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], + ] + + for off, pm, edge in zip(offset,PM,edges): + I += [ii + faceOffset] + J += [edge + off] + V += [pm] + + faceOffset = self.ntFx + self.ntFy + offset = [0]*2 + [self.ntEx]*2 + PM = [1, -1, -1, 1] + for ii, fz in enumerate(sorted(self._facesZ)): + + p = self._pointer(fz) + w = self._levelWidth(p[-1]) + + edges = [ + self._ex2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._ex2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], + self._ey2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._ey2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], + ] + + for off, pm, edge in zip(offset,PM,edges): + I += [ii + faceOffset] + J += [edge + off] + V += [pm] + + Rf = self._deflationMatrix('F', withHanging=True, asOnes=False) + Re = self._deflationMatrix('E') + + Rf_ave = Utils.sdiag(1./Rf.sum(axis=0)) * Rf.T + + C = sp.csr_matrix((V,(I,J)), shape=(self.ntF, self.ntE)) + S = np.r_[self._areaFxFull, self._areaFyFull, self._areaFzFull] + L = np.r_[self._edgeExFull, self._edgeEyFull, self._edgeEzFull] + self._edgeCurl = Rf_ave*Utils.sdiag(1.0/S)*C*Utils.sdiag(L)*Re + return self._edgeCurl + + + @property + def nodalGrad(self): + raise Exception('Not yet implemented!') + # if getattr(self, '_nodalGrad', None) is None: + # self.number() + # # TODO: Preallocate! + # I, J, V = [], [], [] + # # kinda a hack for the 2D gradient + # # because edges are not stored + # edges = self.faces if self.dim == 2 else self.edges + # for edge in edges: + # if self.dim == 3: + # I += [edge.num, edge.num] + # elif self.dim == 2 and edge.faceType == 'x': + # I += [edge.num + self.nFy, edge.num + self.nFy] + # elif self.dim == 2 and edge.faceType == 'y': + # I += [edge.num - self.nFx, edge.num - self.nFx] + # J += [edge.node0.num, edge.node1.num] + # V += [-1, 1] + # G = sp.csr_matrix((V,(I,J)), shape=(self.nE, self.nN)) + # L = self.edge + # self._nodalGrad = Utils.sdiag(1/L)*G + # return self._nodalGrad + + def _getFaceP(self, xFace, yFace, zFace): + ind1, ind2, ind3 = [], [], [] + for ind in self._sortedCells: + p = self._pointer(ind) + w = self._levelWidth(p[-1]) + + posX = 0 if xFace == 'fXm' else w + posY = 0 if yFace == 'fYm' else w + if self.dim == 3: + posZ = 0 if zFace == 'fZm' else w + + ind1.append( self._fx2i[self._index([ p[0] + posX, p[1]] + p[2:])] ) + ind2.append( self._fy2i[self._index([ p[0], p[1] + posY] + p[2:])] + self.ntFx ) + if self.dim == 3: + ind3.append( self._fz2i[self._index([ p[0], p[1], p[2] + posZ, p[3]])] + self.ntFx + self.ntFy ) + + if self.dim == 2: + IND = np.r_[ind1, ind2] + if self.dim == 3: + IND = np.r_[ind1, ind2, ind3] + + PXXX = sp.coo_matrix((np.ones(self.dim*self.nC), (range(self.dim*self.nC), IND)), shape=(self.dim*self.nC, self.ntF)).tocsr() + + Rf = self._deflationMatrix('F', withHanging=True, asOnes=True) + + return PXXX * Rf + + def _getFacePxx(self): + self.number() + def Pxx(xFace, yFace): + return self._getFaceP(xFace, yFace, None) + return Pxx + + def _getFacePxxx(self): + self.number() + def Pxxx(xFace, yFace, zFace): + return self._getFaceP(xFace, yFace, zFace) + return Pxxx + + def _getEdgeP(self, xEdge, yEdge, zEdge): + if self.dim == 2: raise Exception('Not implemented') # this should be a reordering of the face inner product? + + ind1, ind2, ind3 = [], [], [] + for ind in self._sortedCells: + p = self._pointer(ind) + w = self._levelWidth(p[-1]) + + posX = [0,0] if xEdge == 'eX0' else [w, 0] if xEdge == 'eX1' else [0,w] if xEdge == 'eX2' else [w,w] + posY = [0,0] if yEdge == 'eY0' else [w, 0] if yEdge == 'eY1' else [0,w] if yEdge == 'eY2' else [w,w] + posZ = [0,0] if zEdge == 'eZ0' else [w, 0] if zEdge == 'eZ1' else [0,w] if zEdge == 'eZ2' else [w,w] + + ind1.append( self._ex2i[self._index([ p[0] , p[1] + posX[0], p[2] + posX[1], p[3]])] ) + ind2.append( self._ey2i[self._index([ p[0] + posY[0], p[1] , p[2] + posY[1], p[3]])] + self.ntEx ) + ind3.append( self._ez2i[self._index([ p[0] + posZ[0], p[1] + posZ[1], p[2] , p[3]])] + self.ntEx + self.ntEy ) + + IND = np.r_[ind1, ind2, ind3] + + PXXX = sp.coo_matrix((np.ones(self.dim*self.nC), (range(self.dim*self.nC), IND)), shape=(self.dim*self.nC, self.ntE)).tocsr() + + Re = self._deflationMatrix('E') + + return PXXX * Re + + def _getEdgePxx(self): + raise Exception('Not implemented') # this should be a reordering of the face inner product? + def _getEdgePxxx(self): + self.number() + def Pxxx(xEdge, yEdge, zEdge): + return self._getEdgeP(xEdge, yEdge, zEdge) + return Pxxx + + + def plotGrid(self, ax=None, showIt=False, + grid=True, + cells=True, cellLine=False, + nodes=False, + facesX=False, facesY=False, facesZ=False, + edgesX=False, edgesY=False, edgesZ=False): + + # self.number() + + axOpts = {'projection':'3d'} if self.dim == 3 else {} + if ax is None: + ax = plt.subplot(111, **axOpts) + else: + assert isinstance(ax,matplotlib.axes.Axes), "ax must be an Axes!" + fig = ax.figure + + if grid: + for ind in self._sortedCells: + p = self._asPointer(ind) + n = self._cellN(p) + h = self._cellH(p) + x = [n[0] , n[0] + h[0], n[0] + h[0], n[0] , n[0]] + y = [n[1] , n[1] , n[1] + h[1], n[1] + h[1], n[1]] + if self.dim == 2: + ax.plot(x,y, 'b-') + elif self.dim == 3: + ax.plot(x,y, 'b-', zs=[n[2]]*5) + z = [n[2] + h[2], n[2] + h[2], n[2] + h[2], n[2] + h[2], n[2] + h[2]] + ax.plot(x,y, 'b-', zs=z) + sides = [0,0], [h[0],0], [0,h[1]], [h[0],h[1]] + for s in sides: + x = [n[0] + s[0], n[0] + s[0]] + y = [n[1] + s[1], n[1] + s[1]] + z = [n[2] , n[2] + h[2]] + ax.plot(x,y, 'b-', zs=z) + + if self.dim == 2: + if cells: + ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'r.') + if cellLine: + ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'r:') + ax.plot(self.gridCC[[0,-1],0], self.gridCC[[0,-1],1], 'ro') + if nodes: + ax.plot(self._gridN[:,0], self._gridN[:,1], 'ms') + ax.plot(self._gridN[self._hangingN.keys(),0], self._gridN[self._hangingN.keys(),1], 'ms', ms=10, mfc='none', mec='m') + if facesX: + ax.plot(self._gridFx[self._hangingFx.keys(),0], self._gridFx[self._hangingFx.keys(),1], 'gs', ms=10, mfc='none', mec='g') + ax.plot(self._gridFx[:,0], self._gridFx[:,1], 'g>') + if facesY: + ax.plot(self._gridFy[self._hangingFy.keys(),0], self._gridFy[self._hangingFy.keys(),1], 'gs', ms=10, mfc='none', mec='g') + ax.plot(self._gridFy[:,0], self._gridFy[:,1], 'g^') + elif self.dim == 3: + if cells: + ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'r.', zs=self.gridCC[:,2]) + if cellLine: + ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'r:', zs=self.gridCC[:,2]) + ax.plot(self.gridCC[[0,-1],0], self.gridCC[[0,-1],1], 'ro', zs=self.gridCC[[0,-1],2]) + + if nodes: + ax.plot(self._gridN[:,0], self._gridN[:,1], 'ms', zs=self._gridN[:,2]) + ax.plot(self._gridN[self._hangingN.keys(),0], self._gridN[self._hangingN.keys(),1], 'ms', ms=10, mfc='none', mec='m', zs=self._gridN[self._hangingN.keys(),2]) + for key in self._hangingN.keys(): + for hf in self._hangingN[key]: + ind = [key, hf[0]] + ax.plot(self._gridN[ind,0], self._gridN[ind,1], 'm:', zs=self._gridN[ind,2]) + + if facesX: + ax.plot(self._gridFx[:,0], self._gridFx[:,1], 'g>', zs=self._gridFx[:,2]) + ax.plot(self._gridFx[self._hangingFx.keys(),0], self._gridFx[self._hangingFx.keys(),1], 'gs', ms=10, mfc='none', mec='g', zs=self._gridFx[self._hangingFx.keys(),2]) + for key in self._hangingFx.keys(): + for hf in self._hangingFx[key]: + ind = [key, hf[0]] + ax.plot(self._gridFx[ind,0], self._gridFx[ind,1], 'g:', zs=self._gridFx[ind,2]) + + if facesY: + ax.plot(self._gridFy[:,0], self._gridFy[:,1], 'g^', zs=self._gridFy[:,2]) + ax.plot(self._gridFy[self._hangingFy.keys(),0], self._gridFy[self._hangingFy.keys(),1], 'gs', ms=10, mfc='none', mec='g', zs=self._gridFy[self._hangingFy.keys(),2]) + for key in self._hangingFy.keys(): + for hf in self._hangingFy[key]: + ind = [key, hf[0]] + ax.plot(self._gridFy[ind,0], self._gridFy[ind,1], 'g:', zs=self._gridFy[ind,2]) + + if facesZ: + ax.plot(self._gridFz[:,0], self._gridFz[:,1], 'g^', zs=self._gridFz[:,2]) + ax.plot(self._gridFz[self._hangingFz.keys(),0], self._gridFz[self._hangingFz.keys(),1], 'gs', ms=10, mfc='none', mec='g', zs=self._gridFz[self._hangingFz.keys(),2]) + for key in self._hangingFz.keys(): + for hf in self._hangingFz[key]: + ind = [key, hf[0]] + ax.plot(self._gridFz[ind,0], self._gridFz[ind,1], 'g:', zs=self._gridFz[ind,2]) + + if edgesX: + ax.plot(self._gridEx[:,0], self._gridEx[:,1], 'k>', zs=self._gridEx[:,2]) + ax.plot(self._gridEx[self._hangingEx.keys(),0], self._gridEx[self._hangingEx.keys(),1], 'ks', ms=10, mfc='none', mec='k', zs=self._gridEx[self._hangingEx.keys(),2]) + for key in self._hangingEx.keys(): + for hf in self._hangingEx[key]: + ind = [key, hf[0]] + ax.plot(self._gridEx[ind,0], self._gridEx[ind,1], 'k:', zs=self._gridEx[ind,2]) + + + if edgesY: + ax.plot(self._gridEy[:,0], self._gridEy[:,1], 'k<', zs=self._gridEy[:,2]) + ax.plot(self._gridEy[self._hangingEy.keys(),0], self._gridEy[self._hangingEy.keys(),1], 'ks', ms=10, mfc='none', mec='k', zs=self._gridEy[self._hangingEy.keys(),2]) + for key in self._hangingEy.keys(): + for hf in self._hangingEy[key]: + ind = [key, hf[0]] + ax.plot(self._gridEy[ind,0], self._gridEy[ind,1], 'k:', zs=self._gridEy[ind,2]) + + if edgesZ: + ax.plot(self._gridEz[:,0], self._gridEz[:,1], 'k^', zs=self._gridEz[:,2]) + ax.plot(self._gridEz[self._hangingEz.keys(),0], self._gridEz[self._hangingEz.keys(),1], 'ks', ms=10, mfc='none', mec='k', zs=self._gridEz[self._hangingEz.keys(),2]) + for key in self._hangingEz.keys(): + for hf in self._hangingEz[key]: + ind = [key, hf[0]] + ax.plot(self._gridEz[ind,0], self._gridEz[ind,1], 'k:', zs=self._gridEz[ind,2]) + + if showIt:plt.show() + + + def plotImage(self, I, ax=None, showIt=True): + if self.dim == 3: raise Exception() + + if ax is None: ax = plt.subplot(111) + jet = cm = plt.get_cmap('jet') + cNorm = colors.Normalize(vmin=I.min(), vmax=I.max()) + scalarMap = cmx.ScalarMappable(norm=cNorm, cmap=jet) + ax.set_xlim((self.x0[0], self.h[0].sum())) + ax.set_ylim((self.x0[1], self.h[1].sum())) + for ii, node in enumerate(self._sortedCells): + x0, sz = self._cellN(node), self._cellH(node) + ax.add_patch(plt.Rectangle((x0[0], x0[1]), sz[0], sz[1], facecolor=scalarMap.to_rgba(I[ii]), edgecolor='k')) + # if text: ax.text(self.center[0],self.center[1],self.num) + scalarMap._A = [] # http://stackoverflow.com/questions/8342549/matplotlib-add-colorbar-to-a-sequence-of-line-plots + plt.colorbar(scalarMap) + if showIt: plt.show() + + +def SortGrid(grid, offset=0): + """ + Sorts a grid by the x0 location. + """ + eps = 1e-7 def mycmp(c1,c2): - if c1.x0.size == 2: - if np.abs(c1.x0[1] - c2.x0[1]) < eps: - return c1.x0[0] - c2.x0[0] - return c1.x0[1] - c2.x0[1] - elif c1.x0.size == 3: - if np.abs(c1.x0[2] - c2.x0[2]) < eps: - if np.abs(c1.x0[1] - c2.x0[1]) < eps: - return c1.x0[0] - c2.x0[0] - return c1.x0[1] - c2.x0[1] - return c1.x0[2] - c2.x0[2] + c1 = grid[c1-offset] + c2 = grid[c2-offset] + if c1.size == 2: + if np.abs(c1[1] - c2[1]) < eps: + return c1[0] - c2[0] + return c1[1] - c2[1] + elif c1.size == 3: + if np.abs(c1[2] - c2[2]) < eps: + if np.abs(c1[1] - c2[1]) < eps: + return c1[0] - c2[0] + return c1[1] - c2[1] + return c1[2] - c2[2] class K(object): def __init__(self, obj, *args): @@ -37,1107 +1559,111 @@ def SortByX0(): return mycmp(self.obj, other.obj) >= 0 def __ne__(self, other): return mycmp(self.obj, other.obj) != 0 - return K - -class TreeNode(object): - """docstring for TreeNode""" - - __slots__ = ['x0', 'num'] - - def __init__(self, mesh, x0=[0,0]): - self.x0 = np.array(x0, dtype=float) - mesh.nodes.add(self) - - @property - def center(self): return self.x0 - -class TreeEdge(object): - """docstring for TreeEdge""" - - __slots__ = ['mesh', 'children', 'depth', 'x0', 'num', 'edgeType', 'sz', 'node0', 'node1'] - - def __init__(self, mesh, x0=[0,0], edgeType=None, sz=[1,], depth=0, - node0=None, node1=None): - self.mesh = mesh - self.depth = depth - - self.x0 = x0 - self.sz = sz - self.edgeType = edgeType - - mesh.edges.add(self) - if edgeType is 'x': mesh.edgesX.add(self) - elif edgeType is 'y': mesh.edgesY.add(self) - elif edgeType is 'z': mesh.edgesZ.add(self) - - self.node0 = node0 if isinstance(node0,TreeNode) else TreeNode(mesh, x0=self.x0) - self.node1 = node1 if isinstance(node1,TreeNode) else TreeNode(mesh, x0=self.x0 + self.tangent*self.sz[0]) - - @property - def isleaf(self): return getattr(self, 'children', None) is None - - def refine(self): - if not self.isleaf: return - self.mesh.isNumbered = False - - self.children = np.empty(2,dtype=TreeFace) - # Create refined x0's - x0r_0 = self.x0 - x0r_1 = self.x0+0.5*self.tangent*self.sz - self.children[0] = TreeEdge(self.mesh, x0=x0r_0, edgeType=self.edgeType, sz=0.5*self.sz, depth=self.depth+1, node0=self.node0) - self.children[1] = TreeEdge(self.mesh, x0=x0r_1, edgeType=self.edgeType, sz=0.5*self.sz, depth=self.depth+1, node0=self.children[0].node1, node1=self.node1) - self.mesh.edges.remove(self) - if self.edgeType is 'x': - self.mesh.edgesX.remove(self) - elif self.edgeType is 'y': - self.mesh.edgesY.remove(self) - elif self.edgeType is 'z': - self.mesh.edgesZ.remove(self) - - @property - def tangent(self): - if self.edgeType is 'x': return np.r_[1.,0,0] - elif self.edgeType is 'y': return np.r_[0,1.,0] - elif self.edgeType is 'z': return np.r_[0,0,1.] - - def plotGrid(self, ax, text=False, lineOpts={'color':'r', 'ls': '-'}): - line = np.c_[self.node0.x0, self.node1.x0].T - ax.plot(line[:,0], line[:,1], zs=line[:,2], **lineOpts) - - @property - def center(self): - return 0.5*(self.node0.x0 + self.node1.x0) - - @property - def length(self): - return np.sqrt(((self.node1.x0 - self.node0.x0)**2).sum()) - - @property - def index(self): - if self.isleaf: return [self.num] - l = [edge.index for edge in self.children.flatten(order='F')] - # Flatten the list - # e.g. - # [[1,3],[4]] --> [1, 3, 4] - return [item for sublist in l for item in sublist] - -class TreeFace(object): - """docstring for TreeFace""" - - __slots__ = ['mesh', 'children', 'depth', 'num', 'faceType', 'sz', 'node0', 'node1', 'node2', 'node3', 'edge0', 'edge1', 'edge2', 'edge3', '_tangent0', '_tangent1'] - - def __init__(self, mesh, x0=[0,0], faceType=None, sz=[1,], depth=0, - node0=None, node1=None, - edge0=None, edge1=None, edge2=None, edge3=None): - - self.mesh = mesh - self.depth = depth - - self.faceType = faceType - self.sz = sz - - mesh.faces.add(self) - if faceType is 'x': mesh.facesX.add(self) - elif faceType is 'y': mesh.facesY.add(self) - elif faceType is 'z': mesh.facesZ.add(self) - if self.dim == 2: - # Add the nodes: - self.node0 = node0 if isinstance(node0,TreeNode) else TreeNode(mesh, x0=x0) - self.node1 = node1 if isinstance(node1,TreeNode) else TreeNode(mesh, x0=x0 + self.tangent0*self.sz[0]) - if self.dim == 3: - #TODO: Change this to edges - - # - # 2___________3 - # | e1 | - # | | - # e2| x |e3 t1 - # | | ^ - # |___________| |___> t0 - # 0 e0 1 - # - - N = {} - n0 = getattr(edge0, 'node0', None) or getattr(edge2, 'node0', None) - n1 = getattr(edge0, 'node1', None) or getattr(edge3, 'node0', None) - n2 = getattr(edge1, 'node0', None) or getattr(edge2, 'node1', None) - n3 = getattr(edge1, 'node1', None) or getattr(edge3, 'node1', None) - - eType = ['x', 'y'] if self.faceType == 'z' else ['x', 'z'] if self.faceType == 'y' else ['y', 'z'] - - e0 = edge0 if isinstance(edge0,TreeEdge) else TreeEdge(mesh, x0=x0, edgeType=eType[0], sz=np.r_[sz[0]], depth=depth, node0=n0, node1=n1) - n0, n1 = e0.node0, e0.node1 - - e1 = edge1 if isinstance(edge1,TreeEdge) else TreeEdge(mesh, x0=x0 + self.tangent1*self.sz[1], edgeType=eType[0], sz=np.r_[sz[0]], depth=depth, node0=n2, node1=n3) - n2, n3 = e1.node0, e1.node1 - - e2 = edge2 if isinstance(edge2,TreeEdge) else TreeEdge(mesh, x0=x0, edgeType=eType[1], sz=np.r_[sz[1]], depth=depth, node0=n0, node1=n2) - n0, n2 = e2.node0, e2.node1 - - e3 = edge3 if isinstance(edge3,TreeEdge) else TreeEdge(mesh, x0=x0 + self.tangent0*self.sz[0], edgeType=eType[1], sz=np.r_[sz[1]], depth=depth, node0=n1, node1=n3) - n1, n3 = e3.node0, e3.node1 - - # self.nodes = N - self.node0, self.node1, self.node2, self.node3 = n0, n1, n2, n3 - self.edge0, self.edge1, self.edge2, self.edge3 = e0, e1, e2, e3 - # self.edges = {'e0':e0, 'e1':e1, 'e2':e2, 'e3':e3} - - @property - def dim(self): return self.mesh.dim - - @property - def x0(self): return self.node0.x0 - - @property - def isleaf(self): return getattr(self, 'children', None) is None - - @property - def branchdepth(self): - if self.isleaf: - return self.depth - else: - return np.max([node.branchdepth for node in self.children.flatten('F')]) - - @property - def tangent0(self): - if getattr(self,'_tangent0',None) is None: - if self.faceType is 'x': t = np.r_[0,1.,0] - elif self.faceType is 'y': t = np.r_[1.,0,0] - elif self.faceType is 'z': t = np.r_[1.,0,0] - self._tangent0 = t[:self.dim] - return self._tangent0 - - @property - def tangent1(self): - if self.dim == 2: return - if getattr(self,'_tangent1',None) is None: - if self.faceType is 'x': t = np.r_[0,0,1.] - elif self.faceType is 'y': t = np.r_[0,0,1.] - elif self.faceType is 'z': t = np.r_[0,1.,0] - self._tangent1 = t - return self._tangent1 - - @property - def normal(self): - if self.faceType is 'x': n = np.r_[1.,0,0] - elif self.faceType is 'y': n = np.r_[0,1.,0] - elif self.faceType is 'z': n = np.r_[0,0,1.] - return n[:self.dim] - - @property - def index(self): - if self.isleaf: return [self.num] - l = [face.index for face in self.children.flatten(order='F')] - # Flatten the list - # e.g. - # [[1,3],[4]] --> [1, 3, 4] - return [item for sublist in l for item in sublist] - - @property - def area(self): - """area of the face""" - return self.sz.prod() - - @property - def length(self): - if self.dim == 3: raise Exception('face.length is not defined for 2D face') - return np.sqrt(((self.node1.x0 - self.node0.x0)**2).sum()) - - def refine(self): - if not self.isleaf: return - self.mesh.isNumbered = False - if self.dim == 2: - self._refine2D() - elif self.dim == 3: - self._refine3D() - - def _refine2D(self): - self.children = np.empty(2,dtype=TreeFace) - # Create refined x0's - x0r_0 = self.x0 - x0r_1 = self.x0+0.5*self.tangent0*self.sz - self.children[0] = TreeFace(self.mesh, x0=x0r_0, faceType=self.faceType, sz=0.5*self.sz, depth=self.depth+1, node0=self.node0) - self.children[1] = TreeFace(self.mesh, x0=x0r_1, faceType=self.faceType, sz=0.5*self.sz, depth=self.depth+1, node0=self.children[0].node1, node1=self.node1) - self.mesh.faces.remove(self) - if self.faceType is 'x': - self.mesh.facesX.remove(self) - elif self.faceType is 'y': - self.mesh.facesY.remove(self) - - def _refine3D(self): - # - # 2_______________3 _______________ - # | e1--> | | | | - # ^ | | ^ | (0,1) | (1,1) | - # | | | | | | | - # | | x | | ---> |-------+-------| - # e2 | | e3 | | | - # | | | (0,0) | (1,0) | - # |_______________| |_______|_______| - # 0 e0--> 1 - - - order = [{'c':[0,0], - 'e0': ('p', 'e0', [0]), 'e1': 'new' , - 'e2': ('p', 'e2', [0]), 'e3': 'new' }, - {'c':[1,0], - 'e0': ('p', 'e0', [1]), 'e1': 'new' , - 'e2': ('c', 'e3', [0,0]), 'e3': ('p', 'e3', [0])}, - {'c':[0,1], - 'e0': ('c', 'e1', [0,0]), 'e1': ('p', 'e1', [0]), - 'e2': ('p', 'e2', [1]), 'e3': 'new' }, - {'c':[1,1], - 'e0': ('c', 'e1', [1,0]), 'e1': ('p', 'e1', [1]), - 'e2': ('c', 'e3', [0,1]), 'e3': ('p', 'e3', [1])}] - - def getEdge(pointer): - if pointer is 'new': return - if pointer[0] == 'p': - return getattr(self, 'edg' + pointer[1]).children[pointer[2][0]] - if pointer[0] == 'c': - f = self.children[pointer[2][0],pointer[2][1]] - return getattr(f, 'edg' + pointer[1]) - - self.children = np.empty((2,2), dtype=TreeFace) - - for edge in [self.edge0, self.edge1, self.edge2, self.edge3]: - edge.refine() - - for O in order: - i, j = O['c'] - x0r = self.x0 + 0.5*i*self.tangent0*self.sz[0] + 0.5*j*self.tangent1*self.sz[1] - e0, e1, e2, e3 = getEdge(O['e0']), getEdge(O['e1']), getEdge(O['e2']), getEdge(O['e3']) - self.children[i,j] = TreeFace(self.mesh, x0=x0r, faceType=self.faceType, depth=self.depth+1, sz=0.5*self.sz, edge0=e0, edge1=e1, edge2=e2, edge3=e3) - - self.mesh.faces.remove(self) - if self.faceType is 'x': - self.mesh.facesX.remove(self) - elif self.faceType is 'y': - self.mesh.facesY.remove(self) - elif self.faceType is 'z': - self.mesh.facesZ.remove(self) - - def plotGrid(self, ax, text=True): - if not self.isleaf: return - if self.dim == 2: - line = np.c_[self.node0.x0, self.node1.x0].T - ax.plot(line[:,0], line[:,1],'b-') - if text: ax.text(self.center[0], self.center[1],self.num) - elif self.dim == 3: - if text: ax.text(self.center[0], self.center[1], self.center[2], self.num) - - @property - def center(self): - if self.dim == 2: - return self.x0 + 0.5*self.tangent0*self.sz[0] - elif self.dim == 3: - return self.x0 + 0.5*self.tangent0*self.sz[0] + 0.5*self.tangent1*self.sz[1] - - -class TreeCell(object): - - __slots__ = ['mesh', 'children', 'depth', 'num', 'sz', - 'node0', 'node1', 'node2', 'node3', - 'node4', 'node5', 'node6', 'node7', - 'fXm', 'fXp', 'fYm', 'fYp', 'fZm', 'fZp', - 'eX0','eX1','eX2','eX3', - 'eY0','eY1','eY2','eY3', - 'eZ0','eZ1','eZ2','eZ3'] - - def __init__(self, mesh, x0=[0,0], depth=0, sz=[1,1], - fXm=None, fXp=None, - fYm=None, fYp=None, - fZm=None, fZp=None): - - self.mesh = mesh - self.depth = depth - - self.sz = np.array(sz, dtype=float) - if self.dim == 2: - # - # 2___________3 - # | fYp | - # | | - # fXm| x |fXp y - # | | ^ - # |___________| |___> x - # 0 fYm 1 - # - n0 = getattr(fXm, 'node0', None) or getattr(fYm, 'node0', None) - n1 = getattr(fXp, 'node0', None) or getattr(fYm, 'node1', None) - n2 = getattr(fXm, 'node1', None) or getattr(fYp, 'node0', None) - n3 = getattr(fXp, 'node1', None) or getattr(fYp, 'node1', None) - - self.fXm = fXm if isinstance(fXm, TreeFace) else TreeFace(mesh, x0=np.r_[x0[0] , x0[1] ], faceType='x', sz=np.r_[sz[1]], depth=depth, node0=n0, node1=n2) - n0, n2 = self.fXm.node0, self.fXm.node1 - - self.fXp = fXp if isinstance(fXp, TreeFace) else TreeFace(mesh, x0=np.r_[x0[0]+sz[0], x0[1] ], faceType='x', sz=np.r_[sz[1]], depth=depth, node0=n1, node1=n3) - n1, n3 = self.fXp.node0, self.fXp.node1 - - self.fYm = fYm if isinstance(fYm, TreeFace) else TreeFace(mesh, x0=np.r_[x0[0] , x0[1] ], faceType='y', sz=np.r_[sz[0]], depth=depth, node0=n0, node1=n1) - n0, n1 = self.fYm.node0, self.fYm.node1 - - self.fYp = fYp if isinstance(fYp, TreeFace) else TreeFace(mesh, x0=np.r_[x0[0] , x0[1]+sz[1]], faceType='y', sz=np.r_[sz[0]], depth=depth, node0=n2, node1=n3) - n2, n3 = self.fYp.node0, self.fYp.node1 - - self.node0, self.node1, self.node2, self.node3 = n0, n1, n2, n3 - - elif self.dim == 3: - # fZp - # | - # 6 ------eX3------ 7 - # /| | / | - # /eZ2 . / eZ3 - # eY2 | fYp eY3 | - # / | / fXp| - # 4 ------eX2----- 5 | - # |fXm 2 -----eX1--|---- 3 z - # eZ0 / | eY1 ^ y - # | eY0 . fYm eZ1 / | / - # | / | | / | / - # 0 ------eX0------1 o----> x - # | - # fZm - # - # - # fX fY fZ - # 2___________3 2___________3 2___________3 - # | e1 | | e1 | | e1 | - # | | | | | | - # e2 | x | e3 z e2 | x | e3 z e2 | x | e3 y - # | | ^ | | ^ | | ^ - # |___________| |___> y |___________| |___> x |___________| |___> x - # 0 e0 1 0 e0 1 0 e0 1 - # - # Mapping Nodes: numOnFace > numOnCell - # - # fXm 0>0, 1>2, 2>4, 3>6 fYm 0>0, 1>1, 2>4, 3>5 fZm 0>0, 1>1, 2>2, 3>3 - # fXp 0>1, 1>3, 2>5, 3>7 fYp 0>2, 1>3, 2>6, 3>7 fZp 0>4, 1>5, 2>6, 3>7 - - def getEdge(face, key): - if face is None: return - return getattr(face, key) - - E = {} - eX0 = getEdge(fYm, 'edge0') or getEdge(fZm, 'edge0') - eX1 = getEdge(fYp, 'edge0') or getEdge(fZm, 'edge1') - eX2 = getEdge(fYm, 'edge1') or getEdge(fZp, 'edge0') - eX3 = getEdge(fYp, 'edge1') or getEdge(fZp, 'edge1') - - eY0 = getEdge(fXm, 'edge0') or getEdge(fZm, 'edge2') - eY1 = getEdge(fXp, 'edge0') or getEdge(fZm, 'edge3') - eY2 = getEdge(fXm, 'edge1') or getEdge(fZp, 'edge2') - eY3 = getEdge(fXp, 'edge1') or getEdge(fZp, 'edge3') - - eZ0 = getEdge(fXm, 'edge2') or getEdge(fYm, 'edge2') - eZ1 = getEdge(fXp, 'edge2') or getEdge(fYm, 'edge3') - eZ2 = getEdge(fXm, 'edge3') or getEdge(fYp, 'edge2') - eZ3 = getEdge(fXp, 'edge3') or getEdge(fYp, 'edge3') - - - self.fXm = fXm if isinstance(fXm, TreeFace) else TreeFace(mesh, x0=np.r_[x0[0] , x0[1] , x0[2] ], faceType='x', sz=np.r_[sz[1], sz[2]], depth=depth, edge0=eY0, edge1=eY2, edge2=eZ0, edge3=eZ2) - eY0, eY2, eZ0, eZ2 = self.fXm.edge0, self.fXm.edge1, self.fXm.edge2, self.fXm.edge3 - - self.fXp = fXp if isinstance(fXp, TreeFace) else TreeFace(mesh, x0=np.r_[x0[0]+sz[0], x0[1] , x0[2] ], faceType='x', sz=np.r_[sz[1], sz[2]], depth=depth, edge0=eY1, edge1=eY3, edge2=eZ1, edge3=eZ3) - eY1, eY3, eZ1, eZ3 = self.fXp.edge0, self.fXp.edge1, self.fXp.edge2, self.fXp.edge3 - - self.fYm = fYm if isinstance(fYm, TreeFace) else TreeFace(mesh, x0=np.r_[x0[0] , x0[1] , x0[2] ], faceType='y', sz=np.r_[sz[0], sz[2]], depth=depth, edge0=eX0, edge1=eX2, edge2=eZ0, edge3=eZ1) - eX0, eX2, eZ0, eZ1 = self.fYm.edge0, self.fYm.edge1, self.fYm.edge2, self.fYm.edge3 - - self.fYp = fYp if isinstance(fYp, TreeFace) else TreeFace(mesh, x0=np.r_[x0[0] , x0[1]+sz[1], x0[2] ], faceType='y', sz=np.r_[sz[0], sz[2]], depth=depth, edge0=eX1, edge1=eX3, edge2=eZ2, edge3=eZ3) - eX1, eX3, eZ2, eZ3 = self.fYp.edge0, self.fYp.edge1, self.fYp.edge2, self.fYp.edge3 - - self.fZm = fZm if isinstance(fZm, TreeFace) else TreeFace(mesh, x0=np.r_[x0[0] , x0[1] , x0[2] ], faceType='z', sz=np.r_[sz[0], sz[1]], depth=depth, edge0=eX0, edge1=eX1, edge2=eY0, edge3=eY1) - eX0, eX1, eY0, eY1 = self.fZm.edge0, self.fZm.edge1, self.fZm.edge2, self.fZm.edge3 - - self.fZp = fZp if isinstance(fZp, TreeFace) else TreeFace(mesh, x0=np.r_[x0[0] , x0[1] , x0[2]+sz[2]], faceType='z', sz=np.r_[sz[0], sz[1]], depth=depth, edge0=eX2, edge1=eX3, edge2=eY2, edge3=eY3) - eX2, eX3, eY2, eY3 = self.fZp.edge0, self.fZp.edge1, self.fZp.edge2, self.fZp.edge3 - - self.eX0, self.eX1, self.eX2, self.eX3, self.eY0, self.eY1, self.eY2, self.eY3, self.eZ0, self.eZ1, self.eZ2, self.eZ3 = eX0, eX1, eX2, eX3, eY0, eY1, eY2, eY3, eZ0, eZ1, eZ2, eZ3 - self.node0, self.node1, self.node2, self.node3, self.node4, self.node5, self.node6, self.node7 = self.fZm.node0, self.fZm.node1, self.fZm.node2, self.fZm.node3, self.fZp.node0, self.fZp.node1, self.fZp.node2, self.fZp.node3 - - mesh.cells.add(self) - - @property - def x0(self): return self.node0.x0 - - @property - def center(self): return self.x0 + 0.5*self.sz - - @property - def dim(self): return self.mesh.dim - - @property - def faceDict(self): - d = {"fXm":self.fXm, "fXp":self.fXp, "fYm":self.fYm, "fYp":self.fYp} - if self.dim == 3: - d["fZm"] = self.fZm - d["fZp"] = self.fZp - return d - - @property - def edgeDict(self): - if self.dim == 2: return None - return {'eX0': self.eX0, 'eX1': self.eX1, 'eX2': self.eX2, 'eX3': self.eX3, 'eY0': self.eY0, 'eY1': self.eY1, 'eY2': self.eY2, 'eY3': self.eY3, 'eZ0': self.eZ0, 'eZ1': self.eZ1, 'eZ2': self.eZ2, 'eZ3': self.eZ3} - - @property - def faceList(self): - l = [self.fXm, self.fXp, self.fYm, self.fYp] - if self.dim == 3: - l += [self.fZm, self.fZp] - return l - - @property - def edgeList(self): - if self.dim == 2: return None - return [self.eX0, self.eX1, self.eX2, self.eX3, self.eY0, self.eY1, self.eY2, self.eY3, self.eZ0, self.eZ1, self.eZ2, self.eZ3] - - @property - def isleaf(self): return getattr(self, 'children', None) is None - - def refine(self, function=None): - if not self.isleaf and function is None: return - - if function is not None: - do = function(self.center) > self.depth - if not do: return - - if self.dim == 2: - self._refine2D() - elif self.dim == 3: - self._refine3D() - - # pass the refine function to the children - if function is not None: - for child in self.children.flatten(): - child.refine(function) - - def _refine2D(self): - - self.mesh.isNumbered = False - - self.children = np.empty((2,2), dtype=TreeCell) - x0, sz = self.x0, self.sz - - for face in self.faceList: - face.refine() - - order = [{'c':[0,0], - 'fXm': ('p', 'fXm', [0]), 'fXp': 'new' , - 'fYm': ('p', 'fYm', [0]), 'fYp': 'new' }, - {'c':[1,0], - 'fXm': ('c', 'fXp', [0,0]), 'fXp': ('p', 'fXp', [0]), - 'fYm': ('p', 'fYm', [1]), 'fYp': 'new' }, - {'c':[0,1], - 'fXm': ('p', 'fXm', [1]), 'fXp': 'new' , - 'fYm': ('c', 'fYp', [0,0]), 'fYp': ('p', 'fYp', [0])}, - {'c':[1,1], - 'fXm': ('c', 'fXp', [0,1]), 'fXp': ('p', 'fXp', [1]), - 'fYm': ('c', 'fYp', [1,0]), 'fYp': ('p', 'fYp', [1])}] - - def getFace(pointer): - if pointer is 'new': return None - if pointer[0] == 'p': - return self.faceDict[pointer[1]].children[pointer[2][0],] - if pointer[0] == 'c': - return self.children[pointer[2][0],pointer[2][1]].faceDict[pointer[1]] - - for O in order: - i, j = O['c'] - x0r = np.r_[x0[0] + 0.5*i*sz[0], x0[1] + 0.5*j*sz[1]] - fXm, fXp, fYm, fYp = getFace(O['fXm']), getFace(O['fXp']), getFace(O['fYm']), getFace(O['fYp']) - self.children[i,j] = TreeCell(self.mesh, x0=x0r, depth=self.depth+1, sz=0.5*sz, fXm=fXm, fXp=fXp, fYm=fYm, fYp=fYp) - - self.mesh.cells.remove(self) - - - def _refine3D(self): - # .----------------.----------------. - # /| /| /| - # / | / | / | - # / | 011 / | 111 / | - # / | / | / | - # .----------------.----+-----------. | - # /| . ---------/|----.----------/|----. - # / | /| / | /| / | /| - # / | / | 001 / | / | 101 / | / | - # / | / | / | / | / | / | - # . -------------- .----------------. |/ | - # | . ---+------|----.----+------|----. | - # | /| .______|___/|____.______|___/|____. - # | / | / 010 | / | / 110| / | / - # | / | / | / | / | / | / - # . ---+---------- . ---+---------- . | / - # | |/ | |/ | |/ z - # | . ----------|----.-----------|----. ^ y - # | / 000 | / 100 | / | / - # | / | / | / | / - # | / | / | / o----> x - # . -------------- . -------------- . - # - # - # Face Refinement: - # - # 2_______________3 _______________ - # | | | | | - # ^ | | | (0,1) | (1,1) | - # | | | | | | - # | | x | ---> |-------+-------| - # t1 | | | | | - # | | | (0,0) | (1,0) | - # |_______________| |_______|_______| - # 0 t0--> 1 - - - order = [{'c':[0,0,0], - 'fXm': ('p', 'fXm', [0,0]), 'fXp': 'new' , - 'fYm': ('p', 'fYm', [0,0]), 'fYp': 'new' , - 'fZm': ('p', 'fZm', [0,0]), 'fZp': 'new' ,}, - {'c':[1,0,0], - 'fXm': ('c', 'fXp', [0,0,0]), 'fXp': ('p', 'fXp', [0,0]), - 'fYm': ('p', 'fYm', [1,0]), 'fYp': 'new' , - 'fZm': ('p', 'fZm', [1,0]), 'fZp': 'new' }, - {'c':[0,1,0], - 'fXm': ('p', 'fXm', [1,0]), 'fXp': 'new' , - 'fYm': ('c', 'fYp', [0,0,0]), 'fYp': ('p', 'fYp', [0,0]), - 'fZm': ('p', 'fZm', [0,1]), 'fZp': 'new' }, - {'c':[1,1,0], - 'fXm': ('c', 'fXp', [0,1,0]), 'fXp': ('p', 'fXp', [1,0]), - 'fYm': ('c', 'fYp', [1,0,0]), 'fYp': ('p', 'fYp', [1,0]), - 'fZm': ('p', 'fZm', [1,1]), 'fZp': 'new' }, - {'c':[0,0,1], - 'fXm': ('p', 'fXm', [0,1]), 'fXp': 'new' , - 'fYm': ('p', 'fYm', [0,1]), 'fYp': 'new' , - 'fZm': ('c', 'fZp', [0,0,0]), 'fZp': ('p', 'fZp', [0,0])}, - {'c':[1,0,1], - 'fXm': ('c', 'fXp', [0,0,1]), 'fXp': ('p', 'fXp', [0,1]), - 'fYm': ('p', 'fYm', [1,1]), 'fYp': 'new' , - 'fZm': ('c', 'fZp', [1,0,0]), 'fZp': ('p', 'fZp', [1,0])}, - {'c':[0,1,1], - 'fXm': ('p', 'fXm', [1,1]), 'fXp': 'new' , - 'fYm': ('c', 'fYp', [0,0,1]), 'fYp': ('p', 'fYp', [0,1]), - 'fZm': ('c', 'fZp', [0,1,0]), 'fZp': ('p', 'fZp', [0,1])}, - {'c':[1,1,1], - 'fXm': ('c', 'fXp', [0,1,1]), 'fXp': ('p', 'fXp', [1,1]), - 'fYm': ('c', 'fYp', [1,0,1]), 'fYp': ('p', 'fYp', [1,1]), - 'fZm': ('c', 'fZp', [1,1,0]), 'fZp': ('p', 'fZp', [1,1])}] - - self.mesh.isNumbered = False - - self.children = np.empty((2,2,2), dtype=TreeCell) - x0, sz = self.x0, self.sz - - for face in self.faceList: - face.refine() - - def getFace(pointer): - if pointer is 'new': return None - if pointer[0] == 'p': - return self.faceDict[pointer[1]].children[pointer[2][0],pointer[2][1]] - if pointer[0] == 'c': - return self.children[pointer[2][0],pointer[2][1],pointer[2][2]].faceDict[pointer[1]] - - for O in order: - i, j, k = O['c'] - x0r = np.r_[x0[0] + 0.5*i*sz[0], x0[1] + 0.5*j*sz[1], x0[2] + 0.5*k*sz[2]] - fXm, fXp, fYm, fYp, fZm, fZp = getFace(O['fXm']), getFace(O['fXp']), getFace(O['fYm']), getFace(O['fYp']), getFace(O['fZm']), getFace(O['fZp']) - self.children[i,j,k] = TreeCell(self.mesh, x0=x0r, depth=self.depth+1, sz=0.5*sz, fXm=fXm, fXp=fXp, fYm=fYm, fYp=fYp, fZm=fZm, fZp=fZp) - - self.mesh.cells.remove(self) - - @property - def faceIndex(self): - F = {} - for face in self.faces: - F[face] = self.faces[face].index - return F - - @property - def vol(self): return self.sz.prod() - - def viz(self, ax, color='none', text=False): - if not self.isleaf: return - x0, sz = self.x0, self.sz - ax.add_patch(plt.Rectangle((x0[0], x0[1]), sz[0], sz[1], facecolor=color, edgecolor='k')) - if text: ax.text(self.center[0],self.center[1],self.num) - - def plotGrid(self, ax, text=False): - if not self.isleaf: return - if self.dim == 2: - ax.plot(self.center[0],self.center[1],'ro') - if text: ax.text(self.center[0],self.center[1],self.num) - elif self.dim == 3: - ax.plot([self.center[0]],[self.center[1]],'ro', zs=[self.center[2]]) - if text: ax.text(self.center[0], self.center[1], self.center[2], self.num) - - -class TreeMesh(InnerProducts, BaseMesh): - """TreeMesh""" - - _meshType = 'TREE' - - def __init__(self, h_in, x0=None): - assert type(h_in) is list, 'h_in must be a list' - assert len(h_in) > 1, "len(h_in) must be greater than 1" - - h = range(len(h_in)) - for i, h_i in enumerate(h_in): - if type(h_i) in [int, long, float]: - # This gives you something over the unit cube. - h_i = np.ones(int(h_i))/int(h_i) - assert isinstance(h_i, np.ndarray), ("h[%i] is not a numpy array." % i) - assert len(h_i.shape) == 1, ("h[%i] must be a 1D numpy array." % i) - h[i] = h_i[:] # make a copy. - self.h = h - - if x0 is None: - x0 = np.zeros(self.dim) - else: - assert type(x0) in [list, np.ndarray], 'x0 must be a numpy array or a list' - x0 = np.array(x0, dtype=float) - assert len(x0) == self.dim, 'x0 must have the same dimensions as the mesh' - - # TODO: this has a lot of stuff which doesn't work for this style of mesh... - BaseMesh.__init__(self, np.array([x.size for x in h]), x0) - - # set the sets for holding the cells, nodes, faces, and edges - self.cells = set() - self.nodes = set() - self.faces = set() - self.facesX = set() - self.facesY = set() - if self.dim == 3: - self.facesZ = set() - self.edges = set() - self.edgesX = set() - self.edgesY = set() - self.edgesZ = set() - - self.children = np.empty([hi.size for hi in h],dtype=TreeCell) - - if self.dim == 2: - for i in range(h[0].size): - for j in range(h[1].size): - fXm = None if i is 0 else self.children[i-1][j].fXp - fYm = None if j is 0 else self.children[i][j-1].fYp - x0i = (np.r_[x0[0], h[0][:i]]).sum() - x0j = (np.r_[x0[1], h[1][:j]]).sum() - self.children[i][j] = TreeCell(self, x0=[x0i, x0j], depth=0, sz=[h[0][i], h[1][j]], fXm=fXm, fYm=fYm) - - elif self.dim == 3: - for i in range(h[0].size): - for j in range(h[1].size): - for k in range(h[2].size): - fXm = None if i is 0 else self.children[i-1][j][k].fXp - fYm = None if j is 0 else self.children[i][j-1][k].fYp - fZm = None if k is 0 else self.children[i][j][k-1].fZp - x0i = (np.r_[x0[0], h[0][:i]]).sum() - x0j = (np.r_[x0[1], h[1][:j]]).sum() - x0k = (np.r_[x0[2], h[2][:k]]).sum() - self.children[i][j][k] = TreeCell(self, x0=[x0i, x0j, x0k], depth=0, sz=[h[0][i], h[1][j], h[2][k]], fXm=fXm, fYm=fYm, fZm=fZm) - - isNumbered = Utils.dependentProperty('_isNumbered', False, ['_faceDiv'], 'Setting this to False will delete all operators.') - - @property - def branchdepth(self): - return np.max([node.branchdepth for node in self.children.flatten('F')]) - - def refine(self, function): - for cell in self.children.flatten(): - cell.refine(function) - - def number(self): - if self.isNumbered: return - - self.sortedCells = sorted(self.cells,key=SortByX0()) - for i, sC in enumerate(self.sortedCells): sC.num = i - - self.sortedNodes = sorted(self.nodes,key=SortByX0()) - for i, sN in enumerate(self.sortedNodes): sN.num = i - - self.sortedFaceX = sorted(self.facesX,key=SortByX0()) - for i, sFx in enumerate(self.sortedFaceX): sFx.num = i - - self.sortedFaceY = sorted(self.facesY,key=SortByX0()) - for i, sFy in enumerate(self.sortedFaceY): sFy.num = i + self.nFx - - if self.dim == 3: - self.sortedFaceZ = sorted(self.facesZ,key=SortByX0()) - for i, sFz in enumerate(self.sortedFaceZ): sFz.num = i + self.nFx + self.nFy - - self.sortedEdgeX = sorted(self.edgesX,key=SortByX0()) - for i, sEx in enumerate(self.sortedEdgeX): sEx.num = i - - self.sortedEdgeY = sorted(self.edgesY,key=SortByX0()) - for i, sEy in enumerate(self.sortedEdgeY): sEy.num = i + self.nEx - - self.sortedEdgeZ = sorted(self.edgesZ,key=SortByX0()) - for i, sEz in enumerate(self.sortedEdgeZ): sEz.num = i + self.nEx + self.nEy - - self.isNumbered = True - - @property - def dim(self): return len(self.h) - - @property - def nC(self): return len(self.cells) - - @property - def nN(self): return len(self.nodes) - - @property - def nF(self): return len(self.faces) - - @property - def nFx(self): return len(self.facesX) - - @property - def nFy(self): return len(self.facesY) - - @property - def nFz(self): return None if self.dim < 3 else len(self.facesZ) - - @property - def nE(self): - if self.dim == 2: - return len(self.faces) - elif self.dim == 3: - return len(self.edges) - - @property - def nEx(self): - if self.dim == 2: - return len(self.facesY) - elif self.dim == 3: - return len(self.edgesX) - - @property - def nEy(self): - if self.dim == 2: - return len(self.facesX) - elif self.dim == 3: - return len(self.edgesY) - - @property - def nEz(self): return None if self.dim < 3 else len(self.edgesZ) - - def _grid(self, key): - self.number() - sObjs = {'CC':self.sortedCells, - 'N':self.sortedNodes, - 'Fx': self.sortedFaceX, - 'Fy': self.sortedFaceY, - 'Fz': getattr(self,'sortedFaceZ', None), - 'Ex': getattr(self,'sortedEdgeX', self.sortedFaceY), - 'Ey': getattr(self,'sortedEdgeY', self.sortedFaceX), - 'Ez': getattr(self,'sortedEdgeZ', None)}[key] - G = np.empty((len(sObjs),self.dim)) - for ii, obj in enumerate(sObjs): - G[ii,:] = obj.center - return G - - @property - def gridCC(self): - if getattr(self, '_gridCC', None) is None: - self._gridCC = self._grid('CC') - return self._gridCC - - @property - def gridN(self): - if getattr(self, '_gridN', None) is None: - self._gridN = self._grid('N') - return self._gridN - - @property - def gridFx(self): - if getattr(self, '_gridFx', None) is None: - self._gridFx = self._grid('Fx') - return self._gridFx - - @property - def gridFy(self): - if getattr(self, '_gridFy', None) is None: - self._gridFy = self._grid('Fy') - return self._gridFy - - @property - def gridFz(self): - if self.dim == 2: return None - if getattr(self, '_gridFz', None) is None: - self._gridFz = self._grid('Fz') - return self._gridFz - - @property - def gridEx(self): - if self.dim == 2: return self.gridFy - if getattr(self, '_gridEx', None) is None: - self._gridEx = self._grid('Ex') - return self._gridEx - - @property - def gridEy(self): - if self.dim == 2: return self.gridFx - if getattr(self, '_gridEy', None) is None: - self._gridEy = self._grid('Ey') - return self._gridEy - - @property - def gridEz(self): - if self.dim == 2: return None - if getattr(self, '_gridEz', None) is None: - self._gridEz = self._grid('Ez') - return self._gridEz - - @property - def vol(self): - self.number() - return np.array([cell.vol for cell in self.sortedCells]) - - @property - def area(self): - self.number() - faces = self.sortedFaceX + self.sortedFaceY - if self.dim == 3: - faces += self.sortedFaceZ - return np.array([face.area for face in faces], dtype=float) - - @property - def edge(self): - self.number() - if self.dim == 2: - edges = self.sortedFaceY + self.sortedFaceX - elif self.dim == 3: - edges = self.sortedEdgeX + self.sortedEdgeY + self.sortedEdgeZ - return np.array([e.length for e in edges], dtype=float) - - @property - def faceDiv(self): - if getattr(self, '_faceDiv', None) is None: - self.number() - # TODO: Preallocate! - I, J, V = [], [], [] - for cell in self.sortedCells: - faces = cell.faceDict - for face in faces: - j = faces[face].index - I += [cell.num]*len(j) - J += j - V += [-1 if 'm' in face else 1]*len(j) - VOL = self.vol - D = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.nF)) - S = self.area - self._faceDiv = Utils.sdiag(1/VOL)*D*Utils.sdiag(S) - return self._faceDiv - - @property - def edgeCurl(self): - """Construct the 3D curl operator.""" - assert self.dim > 2, "Edge Curl only programed for 3D." - - if getattr(self, '_edgeCurl', None) is None: - self.number() - # TODO: Preallocate! - I, J, V = [], [], [] - for face in self.faces: - for ii, edge in enumerate([face.edge0, face.edge1, face.edge2, face.edge3]): - j = edge.index - I += [face.num]*len(j) - J += j - isNeg = [True, False, True, False] - V += [-1 if isNeg[ii] else 1]*len(j) - C = sp.csr_matrix((V,(I,J)), shape=(self.nF, self.nE)) - S = self.area - L = self.edge - self._edgeCurl = Utils.sdiag(1/S)*C*Utils.sdiag(L) - return self._edgeCurl - - @property - def nodalGrad(self): - if getattr(self, '_nodalGrad', None) is None: - self.number() - # TODO: Preallocate! - I, J, V = [], [], [] - # kinda a hack for the 2D gradient - # because edges are not stored - edges = self.faces if self.dim == 2 else self.edges - for edge in edges: - if self.dim == 3: - I += [edge.num, edge.num] - elif self.dim == 2 and edge.faceType == 'x': - I += [edge.num + self.nFy, edge.num + self.nFy] - elif self.dim == 2 and edge.faceType == 'y': - I += [edge.num - self.nFx, edge.num - self.nFx] - J += [edge.node0.num, edge.node1.num] - V += [-1, 1] - G = sp.csr_matrix((V,(I,J)), shape=(self.nE, self.nN)) - L = self.edge - self._nodalGrad = Utils.sdiag(1/L)*G - return self._nodalGrad - - def _getFaceP(self, face0, face1, face2): - I, J, V = [], [], [] - for cell in self.sortedCells: - face = cell.faceDict[face0] - if face.isleaf: - j = face.index - elif self.dim == 2: - j = face.children[0 if 'm' in face1 else 1].index - elif self.dim == 3: - j = face.children[0 if 'm' in face1 else 1, - 0 if 'm' in face2 else 1].index - lenj = len(j) - I += [cell.num]*lenj - J += j - V += [1./lenj]*lenj - return sp.csr_matrix((V,(I,J)), shape=(self.nC, self.nF)) - - def _getEdgeP(self, edge0, edge1, edge2): - I, J, V = [], [], [] - for cell in self.sortedCells: - if self.dim == 2: - e2f = lambda e: ('f' + {'X':'Y','Y':'X'}[e[1]] - + {'0':'m','1':'p'}[e[2]]) - face = cell.faceDict[e2f(edge0)] - if face.isleaf: - j = face.index - else: - j = face.children[0 if 'm' in e2f(edge1) else 1].index - # Need to flip the numbering for edges - if 'X' in edge0: - j = [jj - self.nFx for jj in j] - elif 'Y' in edge0: - j = [jj + self.nFy for jj in j] - elif self.dim == 3: - edge = cell.edgeDict[edge0] - if edge.isleaf: - j = edge.index - else: - mSide = lambda e: {'0':True,'1':True,'2':False,'3':False}[e[2]] - j = edge.children[0 if mSide(edge1) else 1, - 0 if mSide(edge2) else 1].index - lenj = len(j) - I += [cell.num]*lenj - J += j - V += [1./lenj]*lenj - return sp.csr_matrix((V,(I,J)), shape=(self.nC, self.nE)) - - def _getFacePxx(self): - def Pxx(xFace, yFace): - self.number() - xP = self._getFaceP(xFace, yFace, None) - yP = self._getFaceP(yFace, xFace, None) - return sp.vstack((xP, yP)) - return Pxx - - def _getEdgePxx(self): - def Pxx(xEdge, yEdge): - self.number() - xP = self._getEdgeP(xEdge, yEdge, None) - yP = self._getEdgeP(yEdge, xEdge, None) - return sp.vstack((xP, yP)) - return Pxx - - def _getFacePxxx(self): - def Pxxx(xFace, yFace, zFace): - self.number() - xP = self._getFaceP(xFace, yFace, zFace) - yP = self._getFaceP(yFace, xFace, zFace) - zP = self._getFaceP(zFace, xFace, yFace) - return sp.vstack((xP, yP, zP)) - return Pxxx - - def _getEdgePxxx(self): - def Pxxx(xEdge, yEdge, zEdge): - self.number() - xP = self._getEdgeP(xEdge, yEdge, zEdge) - yP = self._getEdgeP(yEdge, xEdge, zEdge) - zP = self._getEdgeP(zEdge, xEdge, yEdge) - return sp.vstack((xP, yP, zP)) - return Pxxx - - def plotGrid(self, ax=None, text=False, centers=False, faces=False, edges=False, lines=True, nodes=False, showIt=False): - self.number() - - axOpts = {'projection':'3d'} if self.dim == 3 else {} - if ax is None: ax = plt.subplot(111, **axOpts) - - if lines: - [f.plotGrid(ax, text=text) for f in self.faces] - if centers: - [c.plotGrid(ax, text=text) for c in self.cells] - if faces: - fX = np.array([f.center for f in self.sortedFaceX]) - ax.plot(fX[:,0],fX[:,1],'g>') - fY = np.array([f.center for f in self.sortedFaceY]) - ax.plot(fY[:,0],fY[:,1],'g^') - if edges: - eX = np.array([e.center for e in self.sortedFaceY]) - ax.plot(eX[:,0],eX[:,1],'c>') - eY = np.array([e.center for e in self.sortedFaceX]) - ax.plot(eY[:,0],eY[:,1],'c^') - if nodes: - ns = np.array([n.x0 for n in self.sortedNodes]) - ax.plot(ns[:,0],ns[:,1],'bs') - - ax.set_xlim((self.x0[0], self.h[0].sum())) - ax.set_ylim((self.x0[1], self.h[1].sum())) - if self.dim == 3: - ax.set_zlim((self.x0[2], self.h[2].sum())) - ax.grid(True) - ax.hold(False) - ax.set_xlabel('x1') - ax.set_ylabel('x2') - if showIt: plt.show() - - def plotImage(self, I, ax=None, showIt=True): - if self.dim == 2: - self._plotImage2D(I, ax=ax, showIt=showIt) - elif self.dim == 3: - raise NotImplementedError('3D visualization is not yet implemented.') - - def _plotImage2D(self, I, ax=None, showIt=True): - if ax is None: ax = plt.subplot(111) - jet = cm = plt.get_cmap('jet') - cNorm = colors.Normalize(vmin=I.min(), vmax=I.max()) - scalarMap = cmx.ScalarMappable(norm=cNorm, cmap=jet) - ax.set_xlim((self.x0[0], self.h[0].sum())) - ax.set_ylim((self.x0[1], self.h[1].sum())) - for ii, node in enumerate(self.sortedCells): - node.viz(ax=ax, color=scalarMap.to_rgba(I[ii])) - scalarMap._A = [] # http://stackoverflow.com/questions/8342549/matplotlib-add-colorbar-to-a-sequence-of-line-plots - plt.colorbar(scalarMap) - if showIt: plt.show() + return sorted(range(offset,grid.shape[0]+offset), key=K) +class NotBalancedException(Exception): + pass if __name__ == '__main__': - M = TreeMesh([np.ones(x) for x in [4,10]]) + def function(xc): - r = xc - np.r_[2.,6.] + r = xc - np.array([0.5*128]*len(xc)) dist = np.sqrt(r.dot(r)) - if dist < 1.0: + # if dist < 0.05: + # return 5 + if dist < 0.1*128: + return 4 + if dist < 0.3*128: return 3 - if dist < 1.5: + if dist < 1.0*128: return 2 else: - return 1 + return 0 - M.refine(function) + # T = Tree([[(1,128)],[(1,128)],[(1,128)]],levels=7) + # T = Tree([128,128,128],levels=7) + T = Tree([[(1,16)],[(1,16)]],levels=4) + # T = Tree([[(1,128)],[(1,128)]],levels=7) + # T.refine(lambda xc:1, balance=False) + # T._index([0,0,0]) + # T._pointer(0) - DIV = M.faceDiv - Mf = M.getFaceInnerProduct() - # plt.subplot(211) - # plt.spy(DIV) - M.plotGrid(ax=plt.subplot(111),text=True,showIt=True) - q = np.zeros(M.nC) - q[208] = -1.0 - q[291] = 1.0 - b = Solver(-DIV*Mf*DIV.T) * (q) - plt.figure() - M.plotImage(b) - # plt.gca().invert_yaxis() - print M.vol + tic = time.time() + T.refine(function)#, balance=False) + print time.time() - tic + print T.nC + + T.plotImage(np.random.rand(T.nC),showIt=True) + + print T.getFaceInnerProduct() + # print T.gridFz + + + # T._refineCell([8,0,1]) + # T._refineCell([8,0,2]) + # T._refineCell([12,0,2]) + # T._refineCell([8,4,2]) + # T._refineCell([6,0,3]) + # T._refineCell([8,8,1]) + # T._refineCell([0,0,0,1]) + # T.__dirty__ = True + + + print T.gridFx.shape[0], T.nFx + + + + ax = plt.subplot(211) + ax.spy(T.edgeCurl) + + # print Mesh.TensorMesh([2,2,2]).edgeCurl.todense() + # print T.edgeCurl.todense() + # print Mesh.TensorMesh([2,2,2]).edgeCurl.todense() - T.edgeCurl.todense() + # print T.gridEy - Mesh.TensorMesh([2,2,2]).gridEy + + # print T.edge + # T.plotGrid(ax=ax) + + # R = deflationMatrix(T._facesX, T._hangingFx, T._fx2i) + # print R + + ax = plt.subplot(212)#, projection='3d') + ax.spy(Mesh.TensorMesh([2,2,2]).edgeCurl) + + # ax = plt.subplot(313) + # ax.spy(T.faceDiv[:,:T.nFx] * R) + + + # T.balance() + # T.plotGrid(ax=ax) + + # cx = T._getNextCell([0,0,1],direction=0,positive=True) + # print cx + # # print [T._asPointer(_) for _ in cx] + # cx = T._getNextCell([8,0,3],direction=0,positive=False) + # print T._asPointer(cx) + # cx = T._getNextCell([8,8,1],direction=1,positive=False) + # print cx, #[T._asPointer(_) for _ in cx] + # cm = T._getNextCell([64,80,4],direction=0,positive=False) + # cy = T._getNextCell([64,80,4],direction=1,positive=True) + # cp = T._getNextCell([64,80,4],direction=1,positive=False) + + # ax.plot( T._cellN([4,0,1])[0],T._cellN([4,0,1])[1], 'yd') + # ax.plot( T._cellN(cx)[0],T._cellN(cx)[1], 'ys') + # ax.plot( T._cellN(cm)[0],T._cellN(cm)[1], 'ys') + # ax.plot( T._cellN(cy)[0],T._cellN(cy)[1], 'ys') + # ax.plot( T._cellN(cp[0])[0],T._cellN(cp[0])[1], 'ys') + # ax.plot( T._cellN(cp[1])[0],T._cellN(cp[1])[1], 'ys') + + + + + + # print T.nN + plt.show() + diff --git a/tests/mesh/test_NewTreeMesh.py b/tests/mesh/test_NewTreeMesh.py deleted file mode 100644 index 6dcffb86..00000000 --- a/tests/mesh/test_NewTreeMesh.py +++ /dev/null @@ -1,367 +0,0 @@ -from SimPEG.Mesh import TensorMesh -from SimPEG.Mesh.NewTreeMesh import TreeMesh, TreeCell -import numpy as np -import unittest -import matplotlib.pyplot as plt - -TOL = 1e-10 - -class TestQuadTreeMesh(unittest.TestCase): - - def setUp(self): - M = TreeMesh([np.ones(x) for x in [3,2]]) - M.refineFace(0) - self.M = M - M.number() - # M.plotGrid(showIt=True) - - def test_numbering(self): - M = TreeMesh([2,2,2]) - M.number() - M.refineCell(0) - M.refineCell(3) - assert M.isNumbered is False - - def test_MeshSizes(self): - self.assertTrue(self.M.nC==9) - self.assertTrue(self.M.nF==25) - self.assertTrue(self.M.nFx==12) - self.assertTrue(self.M.nFy==13) - self.assertTrue(self.M.nE==25) - self.assertTrue(self.M.nEx==13) - self.assertTrue(self.M.nEy==12) - - def test_gridCC(self): - x = np.r_[0.25,0.75,1.5,2.5,0.25,0.75,0.5,1.5,2.5] - y = np.r_[0.25,0.25,0.5,0.5,0.75,0.75,1.5,1.5,1.5] - self.assertTrue(np.linalg.norm((np.c_[x,y]-self.M.gridCC).flatten()) == 0) - - def test_gridN(self): - x = np.r_[0,0.5,1,2,3,0,0.5,1,0,0.5,1,2,3,0,1,2,3] - y = np.r_[0,0,0,0,0,.5,.5,.5,1,1,1,1,1,2,2,2,2] - self.assertTrue(np.linalg.norm((np.c_[x,y]-self.M.gridN).flatten()) == 0) - - def test_gridFx(self): - x = np.r_[0.0,0.5,1.0,2.0,3.0,0.0,0.5,1.0,0.0,1.0,2.0,3.0] - y = np.r_[0.25,0.25,0.25,0.5,0.5,0.75,0.75,0.75,1.5,1.5,1.5,1.5] - self.assertTrue(np.linalg.norm((np.c_[x,y]-self.M.gridFx).flatten()) == 0) - - def test_gridFy(self): - x = np.r_[0.25,0.75,1.5,2.5,0.25,0.75,0.25,0.75,1.5,2.5,0.5,1.5,2.5] - y = np.r_[0,0,0,0,0.5,0.5,1,1,1,1,2,2,2] - self.assertTrue(np.linalg.norm((np.c_[x,y]-self.M.gridFy).flatten()) == 0) - - def test_gridEx(self): - x = np.r_[0.25,0.75,1.5,2.5,0.25,0.75,0.25,0.75,1.5,2.5,0.5,1.5,2.5] - y = np.r_[0,0,0,0,0.5,0.5,1,1,1,1,2,2,2] - self.assertTrue(np.linalg.norm((np.c_[x,y]-self.M.gridEx).flatten()) == 0) - - def test_gridEy(self): - x = np.r_[0.0,0.5,1.0,2.0,3.0,0.0,0.5,1.0,0.0,1.0,2.0,3.0] - y = np.r_[0.25,0.25,0.25,0.5,0.5,0.75,0.75,0.75,1.5,1.5,1.5,1.5] - self.assertTrue(np.linalg.norm((np.c_[x,y]-self.M.gridEy).flatten()) == 0) - - def test_vol(self): - v = np.r_[0.25,0.25,1,1,0.25,0.25,1,1,1] - self.assertTrue(np.linalg.norm((v-self.M.vol)) < TOL) - - def test_edge(self): - ex = np.r_[0.5,0.5,1,1,0.5,0.5,0.5,0.5,1,1,1,1,1] - ey = np.r_[0.5,0.5,0.5,1,1,0.5,0.5,0.5,1,1,1,1] - self.assertTrue(np.linalg.norm((np.r_[ex,ey]-self.M.edge)) < TOL) - - def test_area(self): - ax = np.r_[0.5,0.5,0.5,1,1,0.5,0.5,0.5,1,1,1,1] - ay = np.r_[0.5,0.5,1,1,0.5,0.5,0.5,0.5,1,1,1,1,1] - self.assertTrue(np.linalg.norm((np.r_[ax,ay]-self.M.area)) < TOL) - -class TestOcTreeConnectivity(unittest.TestCase): - - def setUp(self): - self.oM = TreeMesh([1,1,1]) - self.oM.refine(lambda c: 1) - - def test_setup(self): - C = TreeCell(self.oM, 0) - children = C.children - assert not C.isleaf - assert len(children.index) == 8 - # assert not TreeCell(self.oM, 0).isleaf - c0, c1, c2, c3, c4, c5, c6, c7 = [TreeCell(self.oM, i) for i in range(1,9)] - - - # .----------------.----------------. - # /| /| /| - # / | / | / | - # / | c6 / | c7 / | - # / | / | / | - # .----------------.----+-----------. | - # /| . ---------/|----.----------/|----. - # fZp / | /| / | /| / | /| - # | / | / | c4 / | / | c5 / | X | - # 6 ------eX3------ 7 / | / | / | / | / | / | - # /| | / | . -------------- .----------------. |/ | - # /eZ2 . / eZ3 | . ---+------|----.----+------|----. | - # eY2 | fYp eY3 | | /| .______|___/|____.______|___/|____. - # / | / fXp| | / | / c2 | / | / c3 | / | / - # 4 ------eX2----- 5 | | / | / | / | / | / | / - # |fXm 2 -----eX1--|---- 3 z . ---+---------- . ---+---------- . | / - # eZ0 / | eY1 ^ y | |/ | |/ | |/ - # | eY0 . fYm eZ1 / | / | . ----------|----.-----------|----. - # | / | | / | / | / c0 | / c1 | / - # 0 ------eX0------1 o----> x | / | / | / - # | | / | / | / - # fZm . -------------- . -------------- . - # - # - # fX fY fZ - # 2___________3 2___________3 2___________3 - # | e1 | | e1 | | e1 | - # | | | | | | - # e2 | x | e3 z e2 | x | e3 z e2 | x | e3 y - # | | ^ | | ^ | | ^ - # |___________| |___> y |___________| |___> x |___________| |___> x - # 0 e0 1 0 e0 1 0 e0 1 - # - - - # there are two faces for each edge - for ii, c in enumerate([c0, c1, c2, c3, c4, c5, c6, c7]): - assert c.fZm.e0.index == c.fYm.e0.index, "Cell %d: fZm.e0 and fYm.e0"%ii - assert c.fZm.e1.index == c.fYp.e0.index, "Cell %d: fZm.e1 and fYp.e0"%ii - assert c.fZp.e0.index == c.fYm.e1.index, "Cell %d: fZp.e0 and fYm.e1"%ii - assert c.fZp.e1.index == c.fYp.e1.index, "Cell %d: fZp.e1 and fYp.e1"%ii - assert c.fZm.e2.index == c.fXm.e0.index, "Cell %d: fZm.e2 and fXm.e0"%ii - assert c.fZm.e3.index == c.fXp.e0.index, "Cell %d: fZm.e3 and fXp.e0"%ii - assert c.fZp.e2.index == c.fXm.e1.index, "Cell %d: fZp.e2 and fXm.e1"%ii - assert c.fZp.e3.index == c.fXp.e1.index, "Cell %d: fZp.e3 and fXp.e1"%ii - assert c.fYm.e2.index == c.fXm.e2.index, "Cell %d: fYm.e2 and fXm.e2"%ii - assert c.fYm.e3.index == c.fXp.e2.index, "Cell %d: fYm.e3 and fXp.e2"%ii - assert c.fYp.e2.index == c.fXm.e3.index, "Cell %d: fYp.e2 and fXm.e3"%ii - assert c.fYp.e3.index == c.fXp.e3.index, "Cell %d: fYp.e3 and fXp.e3"%ii - - assert c0.eZ1.index == c1.eZ0.index - assert c0.eZ3.index == c1.eZ2.index - assert c2.eZ1.index == c3.eZ0.index - assert c2.eZ3.index == c3.eZ2.index - - assert c4.eZ1.index == c5.eZ0.index - assert c4.eZ3.index == c5.eZ2.index - assert c6.eZ1.index == c7.eZ0.index - assert c6.eZ3.index == c7.eZ2.index - - assert c0.n7.index == c7.n0.index - - - - - -class SimpleOctreeOperatorTests(unittest.TestCase): - - def setUp(self): - h1 = np.random.rand(5) - h2 = np.random.rand(7) - h3 = np.random.rand(3) - self.tM = TensorMesh([h1,h2,h3]) - self.oM = TreeMesh([h1,h2,h3]) - self.tM2 = TensorMesh([h1,h2]) - self.oM2 = TreeMesh([h1,h2]) - # self.oM2.plotGrid(showIt=True) - - def test_faceDiv(self): - self.assertAlmostEqual((self.tM.faceDiv - self.oM.faceDiv).toarray().sum(), 0) - self.assertAlmostEqual((self.tM2.faceDiv - self.oM2.faceDiv).toarray().sum(), 0) - - def test_nodalGrad(self): - self.assertAlmostEqual((self.tM.nodalGrad - self.oM.nodalGrad).toarray().sum(), 0) - self.assertAlmostEqual((self.tM2.nodalGrad - self.oM2.nodalGrad).toarray().sum(), 0) - - def test_edgeCurl(self): - self.assertAlmostEqual((self.tM.edgeCurl - self.oM.edgeCurl).toarray().sum(), 0) - # self.assertAlmostEqual((self.tM2.edgeCurl - self.oM2.edgeCurl).toarray().sum(), 0) - - def test_InnerProducts(self): - self.assertAlmostEqual((self.tM.getFaceInnerProduct() - self.oM.getFaceInnerProduct()).toarray().sum(), 0) - self.assertAlmostEqual((self.tM.getEdgeInnerProduct() - self.oM.getEdgeInnerProduct()).toarray().sum(), 0) - # self.assertAlmostEqual((self.tM2.getFaceInnerProduct() - self.oM2.getFaceInnerProduct()).toarray().sum(), 0) - # self.assertAlmostEqual((self.tM2.getEdgeInnerProduct() - self.oM2.getEdgeInnerProduct()).toarray().sum(), 0) - - -class SimpleOctreeOperatorTestsRefined(unittest.TestCase): - def setUp(self): - self.tM = TreeMesh([1,1,1]) - self.tM.refine(lambda c:2) - self.M = TensorMesh([4,4,4]) - - self.tM2 = TreeMesh([1,1]) - self.tM2.refine(lambda c:2) - self.M2 = TensorMesh([4,4]) - - def test_grids(self): - self.assertAlmostEqual((self.tM2.gridN - self.M2.gridN).sum(), 0) - self.assertAlmostEqual((self.tM2.gridCC - self.M2.gridCC).sum(), 0) - self.assertAlmostEqual((self.tM2.gridFx - self.M2.gridFx).sum(), 0) - self.assertAlmostEqual((self.tM2.gridFy - self.M2.gridFy).sum(), 0) - self.assertAlmostEqual((self.tM2.gridEx - self.M2.gridEx).sum(), 0) - self.assertAlmostEqual((self.tM2.gridEy - self.M2.gridEy).sum(), 0) - - self.assertAlmostEqual((self.tM.gridN - self.M.gridN).sum(), 0) - self.assertAlmostEqual((self.tM.gridCC - self.M.gridCC).sum(), 0) - self.assertAlmostEqual((self.tM.gridFx - self.M.gridFx).sum(), 0) - self.assertAlmostEqual((self.tM.gridFy - self.M.gridFy).sum(), 0) - self.assertAlmostEqual((self.tM.gridFz - self.M.gridFz).sum(), 0) - self.assertAlmostEqual((self.tM.gridEx - self.M.gridEx).sum(), 0) - self.assertAlmostEqual((self.tM.gridEy - self.M.gridEy).sum(), 0) - self.assertAlmostEqual((self.tM.gridEz - self.M.gridEz).sum(), 0) - - def test_InnerProducts(self): - self.assertAlmostEqual((self.tM.getFaceInnerProduct() - self.M.getFaceInnerProduct()).toarray().sum(), 0) - self.assertAlmostEqual((self.tM.getEdgeInnerProduct() - self.M.getEdgeInnerProduct()).toarray().sum(), 0) - - # self.assertAlmostEqual((self.tM2.getFaceInnerProduct() - self.M2.getFaceInnerProduct()).toarray().sum(), 0) - # self.assertAlmostEqual((self.tM2.getEdgeInnerProduct() - self.M2.getEdgeInnerProduct()).toarray().sum(), 0) - - def test_faceDiv(self): - self.assertAlmostEqual((self.tM2.faceDiv - self.M2.faceDiv).toarray().sum(), 0) - self.assertAlmostEqual((self.tM.faceDiv - self.M.faceDiv).toarray().sum(), 0) - - def test_nodalGrad(self): - self.assertAlmostEqual((self.tM2.nodalGrad - self.M2.nodalGrad).toarray().sum(), 0) - self.assertAlmostEqual((self.tM.nodalGrad - self.M.nodalGrad).toarray().sum(), 0) - - def test_edgeCurl(self): - self.assertAlmostEqual((self.tM.edgeCurl - self.M.edgeCurl).toarray().sum(), 0) - # self.assertAlmostEqual((self.tM2.edgeCurl - self.M2.edgeCurl).toarray().sum(), 0) - - def test_InnerProducts(self): - self.assertAlmostEqual((self.tM.getFaceInnerProduct() - self.M.getFaceInnerProduct()).toarray().sum(), 0) - self.assertAlmostEqual((self.tM.getEdgeInnerProduct() - self.M.getEdgeInnerProduct()).toarray().sum(), 0) - # self.assertAlmostEqual((self.tM2.getFaceInnerProduct() - self.M2.getFaceInnerProduct()).toarray().sum(), 0) - # self.assertAlmostEqual((self.tM2.getEdgeInnerProduct() - self.M2.getEdgeInnerProduct()).toarray().sum(), 0) - - -class TestOcTreeObjects(unittest.TestCase): - - def setUp(self): - self.M = TreeMesh([2,1,1]) - self.M.number() - - self.Mr = TreeMesh([2,1,1]) - self.Mr.refineCell(0) - self.Mr.number() - - def test_counts(self): - self.assertTrue(self.M.nC == 2) - self.assertTrue(self.M.nFx == 3) - self.assertTrue(self.M.nFy == 4) - self.assertTrue(self.M.nFz == 4) - self.assertTrue(self.M.nF == 11) - self.assertTrue(self.M.nEx == 8) - self.assertTrue(self.M.nEy == 6) - self.assertTrue(self.M.nEz == 6) - self.assertTrue(self.M.nE == 20) - self.assertTrue(self.M.nN == 12) - - self.assertTrue(self.Mr.nC == 9) - self.assertTrue(self.Mr.nFx == 13) - self.assertTrue(self.Mr.nFy == 14) - self.assertTrue(self.Mr.nFz == 14) - self.assertTrue(self.Mr.nF == 41) - - self.assertTrue(self.Mr.nN == 31) - self.assertTrue(self.Mr.nEx == 22) - self.assertTrue(self.Mr.nEy == 20) - self.assertTrue(self.Mr.nEz == 20) - - - def test_gridCC(self): - x = np.r_[0.25,0.75] - y = np.r_[0.5,0.5] - z = np.r_[0.5,0.5] - self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.M.gridCC).flatten()) == 0) - - x = np.r_[0.125,0.375,0.75,0.125,0.375,0.125,0.375,0.125,0.375] - y = np.r_[0.25,0.25,0.5,0.75,0.75,0.25,0.25,0.75,0.75] - z = np.r_[0.25,0.25,0.5,0.25,0.25,0.75,0.75,0.75,0.75] - self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.Mr.gridCC).flatten()) == 0) - - def test_gridN(self): - x = np.r_[0,0.5,1,0,0.5,1,0,0.5,1,0,0.5,1] - y = np.r_[0,0,0,1,1,1,0,0,0,1,1,1.] - z = np.r_[0,0,0,0,0,0,1,1,1,1,1,1.] - self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.M.gridN).flatten()) == 0) - - x = np.r_[0,0.25,0.5,1,0,0.25,0.5,0,0.25,0.5,1,0,0.25,0.5,0,0.25,0.5,0,0.25,0.5,0,0.25,0.5,1,0,0.25,0.5,0,0.25,0.5,1] - y = np.r_[0,0,0,0,0.5,0.5,0.5,1,1,1,1,0,0,0,0.5,0.5,0.5,1,1,1,0,0,0,0,0.5,0.5,0.5,1,1,1,1] - z = np.r_[0,0,0,0,0,0,0,0,0,0,0,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,1,1,1,1,1,1,1,1,1,1,1] - self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.Mr.gridN).flatten()) == 0) - - def test_gridFx(self): - x = np.r_[0.0,0.5,1.0] - y = np.r_[0.5,0.5,0.5] - z = np.r_[0.5,0.5,0.5] - self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.M.gridFx).flatten()) == 0) - - x = np.r_[0.0,0.25,0.5,1.0,0.0,0.25,0.5,0.0,0.25,0.5,0.0,0.25,0.5] - y = np.r_[0.25,0.25,0.25,0.5,0.75,0.75,0.75,0.25,0.25,0.25,0.75,0.75,0.75] - z = np.r_[0.25,0.25,0.25,0.5,0.25,0.25,0.25,0.75,0.75,0.75,0.75,0.75,0.75] - self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.Mr.gridFx).flatten()) == 0) - - def test_gridFy(self): - x = np.r_[0.25,0.75,0.25,0.75] - y = np.r_[0,0,1.,1.] - z = np.r_[0.5,0.5,0.5,0.5] - self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.M.gridFy).flatten()) == 0) - - x = np.r_[0.125,0.375,0.75,0.125,0.375,0.125,0.375,0.75,0.125,0.375,0.125,0.375,0.125,0.375] - y = np.r_[0,0,0,0.5,0.5,1,1,1,0,0,0.5,0.5,1,1] - z = np.r_[0.25,0.25,0.5,0.25,0.25,0.25,0.25,0.5,0.75,0.75,0.75,0.75,0.75,0.75] - self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.Mr.gridFy).flatten()) == 0) - - def test_gridFz(self): - x = np.r_[0.25,0.75,0.25,0.75] - y = np.r_[0.5,0.5,0.5,0.5] - z = np.r_[0,0,1.,1.] - self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.M.gridFz).flatten()) == 0) - - x = np.r_[0.125,0.375,0.75,0.125,0.375,0.125,0.375,0.125,0.375,0.125,0.375,0.75,0.125,0.375] - y = np.r_[0.25,0.25,0.5,0.75,0.75,0.25,0.25,0.75,0.75,0.25,0.25,0.5,0.75,0.75] - z = np.r_[0,0,0,0,0,0.5,0.5,0.5,0.5,1,1,1,1,1] - self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.Mr.gridFz).flatten()) == 0) - - - def test_gridEx(self): - x = np.r_[0.25,0.75,0.25,0.75,0.25,0.75,0.25,0.75] - y = np.r_[0,0,1.,1.,0,0,1.,1.] - z = np.r_[0,0,0,0,1.,1.,1.,1.] - self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.M.gridEx).flatten()) == 0) - - x = np.r_[0.125,0.375,0.75,0.125,0.375,0.125,0.375,0.75,0.125,0.375,0.125,0.375,0.125,0.375,0.125,0.375,0.75,0.125,0.375,0.125,0.375,0.75] - y = np.r_[0,0,0,0.5,0.5,1,1,1,0,0,0.5,0.5,1,1,0,0,0,0.5,0.5,1,1,1] - z = np.r_[0,0,0,0,0,0,0,0,0.5,0.5,0.5,0.5,0.5,0.5,1,1,1,1,1,1,1,1] - self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.Mr.gridEx).flatten()) == 0) - - def test_gridEy(self): - x = np.r_[0,0.5,1,0,0.5,1] - y = np.r_[0.5,0.5,0.5,0.5,0.5,0.5] - z = np.r_[0,0,0,1.,1.,1.] - self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.M.gridEy).flatten()) == 0) - - x = np.r_[0,0.25,0.5,1,0,0.25,0.5,0,0.25,0.5,0,0.25,0.5,0,0.25,0.5,1,0,0.25,0.5] - y = np.r_[0.25,0.25,0.25,0.5,0.75,0.75,0.75,0.25,0.25,0.25,0.75,0.75,0.75,0.25,0.25,0.25,0.5,0.75,0.75,0.75] - z = np.r_[0,0,0,0,0,0,0,0.5,0.5,0.5,0.5,0.5,0.5,1,1,1,1,1,1,1] - self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.Mr.gridEy).flatten()) == 0) - - def test_gridEz(self): - x = np.r_[0,0.5,1,0,0.5,1] - y = np.r_[0,0,0,1.,1.,1.] - z = np.r_[0.5,0.5,0.5,0.5,0.5,0.5] - self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.M.gridEz).flatten()) == 0) - - x = np.r_[0,0.25,0.5,1,0 ,0.25,0.5,0,0.25,0.5,1,0,0.25,0.5,0 ,0.25,0.5,0 ,0.25,0.5] - y = np.r_[0,0 ,0 ,0,0.5,0.5 ,0.5,1,1 ,1 ,1,0,0 ,0 ,0.5,0.5 ,0.5,1 ,1 ,1 ] - z = np.r_[0.25,0.25,0.25,0.5,0.25,0.25,0.25,0.25,0.25,0.25,0.5,0.75,0.75,0.75,0.75,0.75,0.75,0.75,0.75,0.75] - self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.Mr.gridEz).flatten()) == 0) - -if __name__ == '__main__': - unittest.main() diff --git a/tests/mesh/test_TreeMesh.py b/tests/mesh/test_TreeMesh.py index 977392cb..82288f99 100644 --- a/tests/mesh/test_TreeMesh.py +++ b/tests/mesh/test_TreeMesh.py @@ -1,504 +1,158 @@ -from SimPEG.Mesh import TensorMesh -from SimPEG.Mesh.TreeMesh import TreeMesh, TreeFace, TreeCell +from SimPEG import Mesh import numpy as np -import unittest import matplotlib.pyplot as plt +import unittest TOL = 1e-10 -class TestOcTreeObjects(unittest.TestCase): - def setUp(self): - self.M = TreeMesh([2,1,1]) - self.M.number() - self.Mr = TreeMesh([2,1,1]) - self.Mr.children[0,0,0].refine() - self.Mr.number() - - def q(s): - if s[0] == 'M': - m = self.M - s = s[1:] - else: - m = self.Mr - c = m.sortedCells[int(s[1])] - if len(s) == 2: return c - if s[2] == 'f' and len(s) == 5: return c.faceDict[s[2:]] - if s[2] == 'f': return getattr(c.faceDict[s[2:5]], 'edg' +s[5:]) - if s[2] == 'e': return getattr(c,s[2:]) - if s[2] == 'n': return getattr(c,'node'+s[3:]) - - self.q = q +class TestSimpleQuadTree(unittest.TestCase): def test_counts(self): - self.assertTrue(self.M.nC == 2) - self.assertTrue(self.M.nFx == 3) - self.assertTrue(self.M.nFy == 4) - self.assertTrue(self.M.nFz == 4) - self.assertTrue(self.M.nF == 11) - self.assertTrue(self.M.nEx == 8) - self.assertTrue(self.M.nEy == 6) - self.assertTrue(self.M.nEz == 6) - self.assertTrue(self.M.nE == 20) - self.assertTrue(self.M.nN == 12) - - self.assertTrue(self.Mr.nC == 9) - self.assertTrue(self.Mr.nFx == 13) - self.assertTrue(self.Mr.nFy == 14) - self.assertTrue(self.Mr.nFz == 14) - self.assertTrue(self.Mr.nF == 41) - - - for cell in self.Mr.sortedCells: - for e in cell.edgeDict: - self.assertTrue(cell.edgeDict[e].edgeType==e[1].lower()) - - self.assertTrue(self.Mr.nN == 31) - self.assertTrue(self.Mr.nEx == 22) - self.assertTrue(self.Mr.nEy == 20) - self.assertTrue(self.Mr.nEz == 20) - - def test_sizes(self): - q = self.q - - for key in ['Mc0','Mc1']: - self.assertTrue(q(key).vol == 0.5) - self.assertTrue(q(key+'fXm').area == 1.) - self.assertTrue(q(key+'fXp').area == 1.) - self.assertTrue(q(key+'fYm').area == 0.5) - self.assertTrue(q(key+'fYp').area == 0.5) - self.assertTrue(q(key+'fZm').area == 0.5) - self.assertTrue(q(key+'fZp').area == 0.5) - - def test_pointersM(self): - q = self.q - - self.assertTrue(q('Mc0fXp') is q('Mc1fXm')) - self.assertTrue(q('Mc0fXpe0') is q('Mc1fXme0')) - self.assertTrue(q('Mc0fXpe1') is q('Mc1fXme1')) - self.assertTrue(q('Mc0fXpe2') is q('Mc1fXme2')) - self.assertTrue(q('Mc0fXpe3') is q('Mc1fXme3')) - self.assertTrue(q('Mc0fYp') is not q('c1fYm')) - self.assertTrue(q('Mc0fXm') is not q('c1fXm')) - - # Test connectivity of shared edges - self.assertTrue(q('Mc0fZpe3') is not q('c1fZpe0')) - self.assertTrue(q('Mc0fZpe3') is not q('c1fZpe1')) - self.assertTrue(q('Mc0fZpe3') is q('Mc1fZpe2')) - self.assertTrue(q('Mc0fZpe3') is not q('c1fZpe3')) - - self.assertTrue(q('Mc0fZme3') is not q('c1fZme0')) - self.assertTrue(q('Mc0fZme3') is not q('c1fZme1')) - self.assertTrue(q('Mc0fZme3') is q('Mc1fZme2')) - self.assertTrue(q('Mc0fZme3') is not q('c1fZme3')) - - self.assertTrue(q('Mc0fYpe3') is not q('c1fYpe0')) - self.assertTrue(q('Mc0fYpe3') is not q('c1fYpe1')) - self.assertTrue(q('Mc0fYpe3') is q('Mc1fYpe2')) - self.assertTrue(q('Mc0fYpe3') is not q('c1fYpe3')) - - self.assertTrue(q('Mc0fYme3') is not q('c1fYme0')) - self.assertTrue(q('Mc0fYme3') is not q('c1fYme1')) - self.assertTrue(q('Mc0fYme3') is q('Mc1fYme2')) - self.assertTrue(q('Mc0fYme3') is not q('c1fYme3')) - - self.assertTrue(q('Mc0fZme3') is q('Mc1fXme0')) - self.assertTrue(q('Mc0fZpe3') is q('Mc1fXme1')) - self.assertTrue(q('Mc0fYme3') is q('Mc1fXme2')) - self.assertTrue(q('Mc0fYpe3') is q('Mc1fXme3')) - - self.assertTrue(q('Mc0fZme3') is q('Mc0fXpe0')) - self.assertTrue(q('Mc0fZpe3') is q('Mc0fXpe1')) - self.assertTrue(q('Mc0fYme3') is q('Mc0fXpe2')) - self.assertTrue(q('Mc0fYpe3') is q('Mc0fXpe3')) - - self.assertTrue(q('Mc1fZme2') is q('Mc1fXme0')) - self.assertTrue(q('Mc1fZpe2') is q('Mc1fXme1')) - self.assertTrue(q('Mc1fYme2') is q('Mc1fXme2')) - self.assertTrue(q('Mc1fYpe2') is q('Mc1fXme3')) - - self.assertTrue(q('Mc1fZme2') is q('Mc0fXpe0')) - self.assertTrue(q('Mc1fZpe2') is q('Mc0fXpe1')) - self.assertTrue(q('Mc1fYme2') is q('Mc0fXpe2')) - self.assertTrue(q('Mc1fYpe2') is q('Mc0fXpe3')) - - - def test_nodePointers(self): - q = self.q - c0 = self.Mr.sortedCells[0] - c0n0 = c0.node0 - self.assertTrue(c0n0 is q('c0n0')) - self.assertTrue(np.all(q('c0n0').center == np.r_[0,0,0.])) - self.assertTrue(q('c0n0').num == 0) - self.assertTrue(q('c0n1').num == 1) - self.assertTrue(q('c0n2').num == 4) - self.assertTrue(q('c0n3').num == 5) - self.assertTrue(q('c0n4').num == 11) - self.assertTrue(q('c0n5').num == 12) - self.assertTrue(q('c0n6').num == 14) - self.assertTrue(q('c0n7').num == 15) - - def test_pointersMr(self): - q = self.q - - c0 = self.Mr.sortedCells[0] - c0fXm = c0.fXm - c0eX0 = c0.eX0 - c0fYme0 = c0.fYm.edge0 - self.assertTrue(c0 is q('c0')) - self.assertTrue(c0fXm is q('c0fXm')) - self.assertTrue(c0eX0 is q('c0eX0')) - self.assertTrue(c0fYme0 is q('c0fYme0')) - - self.assertTrue(q('c0').depth == 1) - self.assertTrue(q('c1').depth == 1) - self.assertTrue(q('c2').depth == 0) - - # Make sure we know where the center of the cells are. - self.assertTrue(np.all(q('c0').center == np.r_[0.125,0.25,0.25])) - self.assertTrue(np.all(q('c1').center == np.r_[0.375,0.25,0.25])) - self.assertTrue(np.all(q('c2').center == np.r_[0.75,0.5,0.5])) - self.assertTrue(np.all(q('c3').center == np.r_[0.125,0.75,0.25])) - self.assertTrue(np.all(q('c4').center == np.r_[0.375,0.75,0.25])) - self.assertTrue(np.all(q('c5').center == np.r_[0.125,0.25,0.75])) - self.assertTrue(np.all(q('c6').center == np.r_[0.375,0.25,0.75])) - self.assertTrue(np.all(q('c7').center == np.r_[0.125,0.75,0.75])) - self.assertTrue(np.all(q('c8').center == np.r_[0.375,0.75,0.75])) - - # Test X face connectivity and locations and stuff... - self.assertTrue(np.all(q('c0fXm').center == np.r_[0,0.25,0.25])) - self.assertTrue(np.all(q('c0fXp').center == np.r_[0.25,0.25,0.25])) - self.assertTrue(q('c0fXp') is q('c1fXm')) - self.assertTrue(np.all(q('c1fXp').center == np.r_[0.5,0.25,0.25])) - self.assertTrue(np.all(q('c2fXm').center == np.r_[0.5,0.5,0.5])) - self.assertTrue(q('c2fXm').branchdepth == 1) - self.assertTrue(q('c2fXm').children[0,0] is q('c1fXp')) - self.assertTrue(np.all(q('c3fXm').center == np.r_[0,0.75,0.25])) - self.assertTrue(np.all(q('c3fXp').center == np.r_[0.25,0.75,0.25])) - self.assertTrue(q('c4fXm') is q('c3fXp')) - self.assertTrue(q('c2fXm').children[1,0] is q('c4fXp')) - - #Test some internal stuff (edges held by cell should be same as inside) - for key in ['Mc0', 'Mc1'] + ['c%d'%i for i in range(9)]: - self.assertTrue(q(key+'eX0') is q(key+'fZme0')) - self.assertTrue(q(key+'eX1') is q(key+'fZme1')) - self.assertTrue(q(key+'eX2') is q(key+'fZpe0')) - self.assertTrue(q(key+'eX3') is q(key+'fZpe1')) - - self.assertTrue(q(key+'eX0') is q(key+'fYme0')) - self.assertTrue(q(key+'eX1') is q(key+'fYpe0')) - self.assertTrue(q(key+'eX2') is q(key+'fYme1')) - self.assertTrue(q(key+'eX3') is q(key+'fYpe1')) - - self.assertTrue(q(key+'eY0') is q(key+'fXme0')) - self.assertTrue(q(key+'eY1') is q(key+'fXpe0')) - self.assertTrue(q(key+'eY2') is q(key+'fXme1')) - self.assertTrue(q(key+'eY3') is q(key+'fXpe1')) - - self.assertTrue(q(key+'eY0') is q(key+'fZme2')) - self.assertTrue(q(key+'eY1') is q(key+'fZme3')) - self.assertTrue(q(key+'eY2') is q(key+'fZpe2')) - self.assertTrue(q(key+'eY3') is q(key+'fZpe3')) - - self.assertTrue(q(key+'eZ0') is q(key+'fXme2')) - self.assertTrue(q(key+'eZ1') is q(key+'fXpe2')) - self.assertTrue(q(key+'eZ2') is q(key+'fXme3')) - self.assertTrue(q(key+'eZ3') is q(key+'fXpe3')) - - self.assertTrue(q(key+'eZ0') is q(key+'fYme2')) - self.assertTrue(q(key+'eZ1') is q(key+'fYme3')) - self.assertTrue(q(key+'eZ2') is q(key+'fYpe2')) - self.assertTrue(q(key+'eZ3') is q(key+'fYpe3')) - - #Test some edge stuff - self.assertTrue(np.all(q('c0eX0').center == np.r_[0.125,0,0])) - self.assertTrue(np.all(q('c0eX1').center == np.r_[0.125,0.5,0])) - self.assertTrue(np.all(q('c0eX2').center == np.r_[0.125,0,0.5])) - self.assertTrue(np.all(q('c0eX3').center == np.r_[0.125,0.5,0.5])) - - self.assertTrue(np.all(q('c5eX0').center == np.r_[0.125,0,0.5])) - self.assertTrue(np.all(q('c5eX1').center == np.r_[0.125,0.5,0.5])) - self.assertTrue(q('c5eX0') is q('c0eX2')) - self.assertTrue(q('c5eX1') is q('c0eX3')) - - self.assertTrue(np.all(q('c0eY0').center == np.r_[0,0.25,0])) - self.assertTrue(np.all(q('c0eY1').center == np.r_[0.25,0.25,0])) - self.assertTrue(np.all(q('c0eY2').center == np.r_[0,0.25,0.5])) - self.assertTrue(np.all(q('c0eY3').center == np.r_[0.25,0.25,0.5])) - - self.assertTrue(np.all(q('c1eY0').center == np.r_[0.25,0.25,0])) - self.assertTrue(np.all(q('c1eY2').center == np.r_[0.25,0.25,0.5])) - self.assertTrue(q('c1eY0') is q('c0eY1')) - self.assertTrue(q('c1eY2') is q('c0eY3')) - - - self.assertTrue(np.all(q('c0eZ0').center == np.r_[0,0,0.25])) - self.assertTrue(np.all(q('c0eZ1').center == np.r_[0.25,0,0.25])) - self.assertTrue(np.all(q('c0eZ2').center == np.r_[0,0.5,0.25])) - self.assertTrue(np.all(q('c0eZ3').center == np.r_[0.25,0.5,0.25])) - - self.assertTrue(np.all(q('c3eZ0').center == np.r_[0,0.5,0.25])) - self.assertTrue(np.all(q('c3eZ1').center == np.r_[0.25,0.5,0.25])) - self.assertTrue(q('c3eZ0') is q('c0eZ2')) - self.assertTrue(q('c3eZ1') is q('c0eZ3')) - - - self.assertTrue(q('c0fXp') is q('c1fXm')) - self.assertTrue(q('c0fYp') is not q('c1fYm')) - self.assertTrue(q('c0fXm') is not q('c1fXm')) - - self.assertTrue(q('c1fXp') is q('c2fXm').children[0,0]) - - self.assertTrue(q('c1fYp') is q('c4fYm')) - self.assertTrue(q('c1fZp') is q('c6fZm')) - - self.assertTrue(q('c6fXp') is q('c2fXm').children[0,1]) - - self.assertTrue(q('c4fXp') is q('c2fXm').children[1,0]) - - - def test_gridCC(self): - x = np.r_[0.25,0.75] - y = np.r_[0.5,0.5] - z = np.r_[0.5,0.5] - self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.M.gridCC).flatten()) == 0) - - x = np.r_[0.125,0.375,0.75,0.125,0.375,0.125,0.375,0.125,0.375] - y = np.r_[0.25,0.25,0.5,0.75,0.75,0.25,0.25,0.75,0.75] - z = np.r_[0.25,0.25,0.5,0.25,0.25,0.75,0.75,0.75,0.75] - self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.Mr.gridCC).flatten()) == 0) - - def test_gridN(self): - x = np.r_[0,0.5,1,0,0.5,1,0,0.5,1,0,0.5,1] - y = np.r_[0,0,0,1,1,1,0,0,0,1,1,1.] - z = np.r_[0,0,0,0,0,0,1,1,1,1,1,1.] - self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.M.gridN).flatten()) == 0) - - x = np.r_[0,0.25,0.5,1,0,0.25,0.5,0,0.25,0.5,1,0,0.25,0.5,0,0.25,0.5,0,0.25,0.5,0,0.25,0.5,1,0,0.25,0.5,0,0.25,0.5,1] - y = np.r_[0,0,0,0,0.5,0.5,0.5,1,1,1,1,0,0,0,0.5,0.5,0.5,1,1,1,0,0,0,0,0.5,0.5,0.5,1,1,1,1] - z = np.r_[0,0,0,0,0,0,0,0,0,0,0,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,1,1,1,1,1,1,1,1,1,1,1] - self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.Mr.gridN).flatten()) == 0) - - def test_gridFx(self): - x = np.r_[0.0,0.5,1.0] - y = np.r_[0.5,0.5,0.5] - z = np.r_[0.5,0.5,0.5] - self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.M.gridFx).flatten()) == 0) - - x = np.r_[0.0,0.25,0.5,1.0,0.0,0.25,0.5,0.0,0.25,0.5,0.0,0.25,0.5] - y = np.r_[0.25,0.25,0.25,0.5,0.75,0.75,0.75,0.25,0.25,0.25,0.75,0.75,0.75] - z = np.r_[0.25,0.25,0.25,0.5,0.25,0.25,0.25,0.75,0.75,0.75,0.75,0.75,0.75] - self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.Mr.gridFx).flatten()) == 0) - - def test_gridFy(self): - x = np.r_[0.25,0.75,0.25,0.75] - y = np.r_[0,0,1.,1.] - z = np.r_[0.5,0.5,0.5,0.5] - self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.M.gridFy).flatten()) == 0) - - x = np.r_[0.125,0.375,0.75,0.125,0.375,0.125,0.375,0.75,0.125,0.375,0.125,0.375,0.125,0.375] - y = np.r_[0,0,0,0.5,0.5,1,1,1,0,0,0.5,0.5,1,1] - z = np.r_[0.25,0.25,0.5,0.25,0.25,0.25,0.25,0.5,0.75,0.75,0.75,0.75,0.75,0.75] - self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.Mr.gridFy).flatten()) == 0) - - def test_gridFz(self): - x = np.r_[0.25,0.75,0.25,0.75] - y = np.r_[0.5,0.5,0.5,0.5] - z = np.r_[0,0,1.,1.] - self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.M.gridFz).flatten()) == 0) - - x = np.r_[0.125,0.375,0.75,0.125,0.375,0.125,0.375,0.125,0.375,0.125,0.375,0.75,0.125,0.375] - y = np.r_[0.25,0.25,0.5,0.75,0.75,0.25,0.25,0.75,0.75,0.25,0.25,0.5,0.75,0.75] - z = np.r_[0,0,0,0,0,0.5,0.5,0.5,0.5,1,1,1,1,1] - self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.Mr.gridFz).flatten()) == 0) - - - def test_gridEx(self): - x = np.r_[0.25,0.75,0.25,0.75,0.25,0.75,0.25,0.75] - y = np.r_[0,0,1.,1.,0,0,1.,1.] - z = np.r_[0,0,0,0,1.,1.,1.,1.] - self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.M.gridEx).flatten()) == 0) - - x = np.r_[0.125,0.375,0.75,0.125,0.375,0.125,0.375,0.75,0.125,0.375,0.125,0.375,0.125,0.375,0.125,0.375,0.75,0.125,0.375,0.125,0.375,0.75] - y = np.r_[0,0,0,0.5,0.5,1,1,1,0,0,0.5,0.5,1,1,0,0,0,0.5,0.5,1,1,1] - z = np.r_[0,0,0,0,0,0,0,0,0.5,0.5,0.5,0.5,0.5,0.5,1,1,1,1,1,1,1,1] - self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.Mr.gridEx).flatten()) == 0) - - def test_gridEy(self): - x = np.r_[0,0.5,1,0,0.5,1] - y = np.r_[0.5,0.5,0.5,0.5,0.5,0.5] - z = np.r_[0,0,0,1.,1.,1.] - self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.M.gridEy).flatten()) == 0) - - x = np.r_[0,0.25,0.5,1,0,0.25,0.5,0,0.25,0.5,0,0.25,0.5,0,0.25,0.5,1,0,0.25,0.5] - y = np.r_[0.25,0.25,0.25,0.5,0.75,0.75,0.75,0.25,0.25,0.25,0.75,0.75,0.75,0.25,0.25,0.25,0.5,0.75,0.75,0.75] - z = np.r_[0,0,0,0,0,0,0,0.5,0.5,0.5,0.5,0.5,0.5,1,1,1,1,1,1,1] - self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.Mr.gridEy).flatten()) == 0) - - def test_gridEz(self): - x = np.r_[0,0.5,1,0,0.5,1] - y = np.r_[0,0,0,1.,1.,1.] - z = np.r_[0.5,0.5,0.5,0.5,0.5,0.5] - self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.M.gridEz).flatten()) == 0) - - x = np.r_[0,0.25,0.5,1,0 ,0.25,0.5,0,0.25,0.5,1,0,0.25,0.5,0 ,0.25,0.5,0 ,0.25,0.5] - y = np.r_[0,0 ,0 ,0,0.5,0.5 ,0.5,1,1 ,1 ,1,0,0 ,0 ,0.5,0.5 ,0.5,1 ,1 ,1 ] - z = np.r_[0.25,0.25,0.25,0.5,0.25,0.25,0.25,0.25,0.25,0.25,0.5,0.75,0.75,0.75,0.75,0.75,0.75,0.75,0.75,0.75] - self.assertTrue(np.linalg.norm((np.c_[x,y,z]-self.Mr.gridEz).flatten()) == 0) - - -class TestQuadTreeObjects(unittest.TestCase): - - def setUp(self): - self.M = TreeMesh([2,1]) - self.Mr = TreeMesh([2,1]) - self.Mr.children[0,0].refine() - self.Mr.number() - # self.Mr.plotGrid(showIt=True) - - def test_pointersM(self): - c0 = self.M.children[0,0] - c0fXm = c0.fXm - c0fXp = c0.fXp - c0fYm = c0.fYm - c0fYp = c0.fYp - - c1 = self.M.children[1,0] - c1fXm = c1.fXm - c1fXp = c1.fXp - c1fYm = c1.fYm - c1fYp = c1.fYp - - self.assertTrue(c0fXp is c1fXm) - self.assertTrue(c0fYp is not c1fYm) - self.assertTrue(c0fXm is not c1fXm) - - self.assertTrue(c0fXm.area == 1) - self.assertTrue(c0fYm.area == 0.5) - - self.assertTrue(c0.node1 is c1.node0) - self.assertTrue(c0.node3 is c1.node2) - self.assertTrue(self.M.nN == 6) - - - def test_pointersMr(self): - c0 = self.Mr.sortedCells[0] - c0fXm = c0.fXm - c0fXp = c0.fXp - c0fYm = c0.fYm - c0fYp = c0.fYp - - c1 = self.Mr.sortedCells[1] - c1fXm = c1.fXm - c1fXp = c1.fXp - c1fYm = c1.fYm - c1fYp = c1.fYp - - c2 = self.Mr.sortedCells[2] - c2fXm = c2.fXm - c2fXp = c2.fXp - c2fYm = c2.fYm - c2fYp = c2.fYp - - c4 = self.Mr.sortedCells[4] - c4fXm = c4.fXm - c4fXp = c4.fXp - c4fYm = c4.fYm - c4fYp = c4.fYp - - self.assertTrue(c0fXp is c1fXm) - self.assertTrue(c1fXp.node0 is c2fXm.node0) - self.assertTrue(c1fXp.node0 is c2fXm.node0) - self.assertTrue(c4fYm is c1fYp) - self.assertTrue(c4fXp.node1 is c2fXm.node1) - self.assertTrue(c4fXp.node0 is c1fYp.node1) - self.assertTrue(c0fXp.node1 is c4fYm.node0) - - self.assertTrue(self.Mr.nN == 11) - - self.assertTrue(np.all(c1fXp.node0.x0 == np.r_[0.5,0])) - self.assertTrue(np.all(c1fYp.node0.x0 == np.r_[0.25,0.5])) - - -class TestQuadTreeMesh(unittest.TestCase): - - def setUp(self): - M = TreeMesh([np.ones(x) for x in [3,2]]) - for ii in range(1): - M.children[ii,ii].refine() - self.M = M + nc = 8 + h1 = np.random.rand(nc)*nc*0.5 + nc*0.5 + h2 = np.random.rand(nc)*nc*0.5 + nc*0.5 + h = [hi/np.sum(hi) for hi in [h1, h2]] # normalize + M = Mesh.TreeMesh(h) + M._refineCell([0,0,0]) + M._refineCell([0,0,1]) M.number() # M.plotGrid(showIt=True) + assert M.nhFx == 2 + assert M.nFx == 9 - def test_MeshSizes(self): - self.assertTrue(self.M.nC==9) - self.assertTrue(self.M.nF==25) - self.assertTrue(self.M.nFx==12) - self.assertTrue(self.M.nFy==13) - self.assertTrue(self.M.nE==25) - self.assertTrue(self.M.nEx==13) - self.assertTrue(self.M.nEy==12) + assert np.allclose(M.vol.sum(), 1.0) - def test_gridCC(self): - x = np.r_[0.25,0.75,1.5,2.5,0.25,0.75,0.5,1.5,2.5] - y = np.r_[0.25,0.25,0.5,0.5,0.75,0.75,1.5,1.5,1.5] - self.assertTrue(np.linalg.norm((np.c_[x,y]-self.M.gridCC).flatten()) == 0) + assert np.allclose(np.r_[M._areaFxFull, M._areaFyFull], M._deflationMatrix('F') * M.area) - def test_gridN(self): - x = np.r_[0,0.5,1,2,3,0,0.5,1,0,0.5,1,2,3,0,1,2,3] - y = np.r_[0,0,0,0,0,.5,.5,.5,1,1,1,1,1,2,2,2,2] - self.assertTrue(np.linalg.norm((np.c_[x,y]-self.M.gridN).flatten()) == 0) - - def test_gridFx(self): - x = np.r_[0.0,0.5,1.0,2.0,3.0,0.0,0.5,1.0,0.0,1.0,2.0,3.0] - y = np.r_[0.25,0.25,0.25,0.5,0.5,0.75,0.75,0.75,1.5,1.5,1.5,1.5] - self.assertTrue(np.linalg.norm((np.c_[x,y]-self.M.gridFx).flatten()) == 0) - - def test_gridFy(self): - x = np.r_[0.25,0.75,1.5,2.5,0.25,0.75,0.25,0.75,1.5,2.5,0.5,1.5,2.5] - y = np.r_[0,0,0,0,0.5,0.5,1,1,1,1,2,2,2] - self.assertTrue(np.linalg.norm((np.c_[x,y]-self.M.gridFy).flatten()) == 0) - - def test_gridEx(self): - x = np.r_[0.25,0.75,1.5,2.5,0.25,0.75,0.25,0.75,1.5,2.5,0.5,1.5,2.5] - y = np.r_[0,0,0,0,0.5,0.5,1,1,1,1,2,2,2] - self.assertTrue(np.linalg.norm((np.c_[x,y]-self.M.gridEx).flatten()) == 0) - - def test_gridEy(self): - x = np.r_[0.0,0.5,1.0,2.0,3.0,0.0,0.5,1.0,0.0,1.0,2.0,3.0] - y = np.r_[0.25,0.25,0.25,0.5,0.5,0.75,0.75,0.75,1.5,1.5,1.5,1.5] - self.assertTrue(np.linalg.norm((np.c_[x,y]-self.M.gridEy).flatten()) == 0) - - -class SimpleOctreeOperatorTests(unittest.TestCase): - - def setUp(self): - h1 = np.random.rand(5) - h2 = np.random.rand(7) - h3 = np.random.rand(3) - self.tM = TensorMesh([h1,h2,h3]) - self.oM = TreeMesh([h1,h2,h3]) - self.tM2 = TensorMesh([h1,h2]) - self.oM2 = TreeMesh([h1,h2]) def test_faceDiv(self): - self.assertAlmostEqual((self.tM.faceDiv - self.oM.faceDiv).toarray().sum(), 0) - self.assertAlmostEqual((self.tM2.faceDiv - self.oM2.faceDiv).toarray().sum(), 0) - def test_nodalGrad(self): - self.assertAlmostEqual((self.tM.nodalGrad - self.oM.nodalGrad).toarray().sum(), 0) - self.assertAlmostEqual((self.tM2.nodalGrad - self.oM2.nodalGrad).toarray().sum(), 0) + hx, hy = np.r_[1.,2,3,4], np.r_[5.,6,7,8] + T = Mesh.TreeMesh([hx, hy], levels=2) + T.refine(lambda xc:2) + # T.plotGrid(showIt=True) + M = Mesh.TensorMesh([hx, hy]) + assert M.nC == T.nC + assert M.nF == T.nF + assert M.nFx == T.nFx + assert M.nFy == T.nFy + assert M.nE == T.nE + assert M.nEx == T.nEx + assert M.nEy == T.nEy + assert np.allclose(M.area, T.permuteF*T.area) + assert np.allclose(M.edge, T.permuteE*T.edge) + assert np.allclose(M.vol, T.permuteCC*T.vol) + + # plt.subplot(211).spy(M.faceDiv) + # plt.subplot(212).spy(T.permuteCC*T.faceDiv*T.permuteF.T) + # plt.show() + + assert (M.faceDiv - T.permuteCC*T.faceDiv*T.permuteF.T).nnz == 0 + + +class TestOcTree(unittest.TestCase): + + def test_counts(self): + nc = 8 + h1 = np.random.rand(nc)*nc*0.5 + nc*0.5 + h2 = np.random.rand(nc)*nc*0.5 + nc*0.5 + h3 = np.random.rand(nc)*nc*0.5 + nc*0.5 + h = [hi/np.sum(hi) for hi in [h1, h2, h3]] # normalize + M = Mesh.TreeMesh(h, levels=3) + M._refineCell([0,0,0,0]) + M._refineCell([0,0,0,1]) + M.number() + # M.plotGrid(showIt=True) + # assert M.nhFx == 2 + # assert M.nFx == 9 + + assert np.allclose(M.vol.sum(), 1.0) + + # assert np.allclose(M._areaFxFull, (M._deflationMatrix('F') * M.area)[:M.ntFx]) + # assert np.allclose(M._areaFyFull, (M._deflationMatrix('F') * M.area)[M.ntFx:(M.ntFx+M.ntFy)]) + # assert np.allclose(M._areaFzFull, (M._deflationMatrix('F') * M.area)[(M.ntFx+M.ntFy):]) + + # assert np.allclose(M._edgeExFull, (M._deflationMatrix('E') * M.edge)[:M.ntEx]) + # assert np.allclose(M._edgeEyFull, (M._deflationMatrix('E') * M.edge)[M.ntEx:(M.ntEx+M.ntEy)]) + # assert np.allclose(M._edgeEzFull, (M._deflationMatrix('E') * M.edge)[(M.ntEx+M.ntEy):]) + + def test_faceDiv(self): + + hx, hy, hz = np.r_[1.,2,3,4], np.r_[5.,6,7,8], np.r_[9.,10,11,12] + M = Mesh.TreeMesh([hx, hy, hz], levels=2) + M.refine(lambda xc:2) + # M.plotGrid(showIt=True) + Mr = Mesh.TensorMesh([hx, hy, hz]) + assert M.nC == Mr.nC + assert M.nF == Mr.nF + assert M.nFx == Mr.nFx + assert M.nFy == Mr.nFy + assert M.nE == Mr.nE + assert M.nEx == Mr.nEx + assert M.nEy == Mr.nEy + assert np.allclose(Mr.area, M.permuteF*M.area) + assert np.allclose(Mr.edge, M.permuteE*M.edge) + assert np.allclose(Mr.vol, M.permuteCC*M.vol) + + # plt.subplot(211).spy(Mr.faceDiv) + # plt.subplot(212).spy(M.permuteCC*M.faceDiv*M.permuteF.T) + # plt.show() + + assert (Mr.faceDiv - M.permuteCC*M.faceDiv*M.permuteF.T).nnz == 0 + def test_edgeCurl(self): - self.assertAlmostEqual((self.tM.edgeCurl - self.oM.edgeCurl).toarray().sum(), 0) - # self.assertAlmostEqual((self.tM2.edgeCurl - self.oM2.edgeCurl).toarray().sum(), 0) - def test_InnerProducts(self): - self.assertAlmostEqual((self.tM.getFaceInnerProduct() - self.oM.getFaceInnerProduct()).toarray().sum(), 0) - self.assertAlmostEqual((self.tM2.getFaceInnerProduct() - self.oM2.getFaceInnerProduct()).toarray().sum(), 0) - self.assertAlmostEqual((self.tM2.getEdgeInnerProduct() - self.oM2.getEdgeInnerProduct()).toarray().sum(), 0) - self.assertAlmostEqual((self.tM.getEdgeInnerProduct() - self.oM.getEdgeInnerProduct()).toarray().sum(), 0) + hx, hy, hz = np.r_[1.,2,3,4], np.r_[5.,6,7,8], np.r_[9.,10,11,12] + M = Mesh.TreeMesh([hx, hy, hz], levels=2) + M.refine(lambda xc:2) + # M.plotGrid(showIt=True) + Mr = Mesh.TensorMesh([hx, hy, hz]) + + # plt.subplot(211).spy(Mr.faceDiv) + # plt.subplot(212).spy(M.permuteCC.T*M.faceDiv*M.permuteF) + # plt.show() + + assert (Mr.edgeCurl - M.permuteF*M.edgeCurl*M.permuteE.T).nnz == 0 + + def test_faceInnerProduct(self): + + hx, hy, hz = np.r_[1.,2,3,4], np.r_[5.,6,7,8], np.r_[9.,10,11,12] + # hx, hy, hz = [[(1,4)], [(1,4)], [(1,4)]] + + M = Mesh.TreeMesh([hx, hy, hz], levels=2) + M.refine(lambda xc:2) + # M.plotGrid(showIt=True) + Mr = Mesh.TensorMesh([hx, hy, hz]) + + # plt.subplot(211).spy(Mr.getFaceInnerProduct()) + # plt.subplot(212).spy(M.getFaceInnerProduct()) + # plt.show() + + # print M.nC, M.nF, M.getFaceInnerProduct().shape, M.permuteF.shape + + assert np.allclose(Mr.getFaceInnerProduct().todense(), (M.permuteF * M.getFaceInnerProduct() * M.permuteF.T).todense()) + assert np.allclose(Mr.getEdgeInnerProduct().todense(), (M.permuteE * M.getEdgeInnerProduct() * M.permuteE.T).todense()) + + def test_VectorIdenties(self): + hx, hy, hz = [[(1,4)], [(1,4)], [(1,4)]] + + M = Mesh.TreeMesh([hx, hy, hz], levels=2) + Mr = Mesh.TensorMesh([hx, hy, hz]) + + assert (M.faceDiv * M.edgeCurl).nnz == 0 + assert (Mr.faceDiv * Mr.edgeCurl).nnz == 0 + + hx, hy, hz = np.r_[1.,2,3,4], np.r_[5.,6,7,8], np.r_[9.,10,11,12] + + M = Mesh.TreeMesh([hx, hy, hz], levels=2) + Mr = Mesh.TensorMesh([hx, hy, hz]) + + assert np.max(np.abs((M.faceDiv * M.edgeCurl).todense().flatten())) < TOL + assert np.max(np.abs((Mr.faceDiv * Mr.edgeCurl).todense().flatten())) < TOL + if __name__ == '__main__': diff --git a/tests/mesh/test_pointerMesh.py b/tests/mesh/test_pointerMesh.py deleted file mode 100644 index 753873b1..00000000 --- a/tests/mesh/test_pointerMesh.py +++ /dev/null @@ -1,160 +0,0 @@ -from SimPEG import Mesh -from SimPEG.Mesh.PointerTree import Tree -import numpy as np -import matplotlib.pyplot as plt -import unittest - -TOL = 1e-10 - - - -class TestSimpleQuadTree(unittest.TestCase): - - def test_counts(self): - nc = 8 - h1 = np.random.rand(nc)*nc*0.5 + nc*0.5 - h2 = np.random.rand(nc)*nc*0.5 + nc*0.5 - h = [hi/np.sum(hi) for hi in [h1, h2]] # normalize - M = Tree(h) - M._refineCell([0,0,0]) - M._refineCell([0,0,1]) - M.number() - # M.plotGrid(showIt=True) - assert M.nhFx == 2 - assert M.nFx == 9 - - assert np.allclose(M.vol.sum(), 1.0) - - assert np.allclose(np.r_[M._areaFxFull, M._areaFyFull], M._deflationMatrix('F') * M.area) - - - def test_faceDiv(self): - - hx, hy = np.r_[1.,2,3,4], np.r_[5.,6,7,8] - T = Tree([hx, hy], levels=2) - T.refine(lambda xc:2) - # T.plotGrid(showIt=True) - M = Mesh.TensorMesh([hx, hy]) - assert M.nC == T.nC - assert M.nF == T.nF - assert M.nFx == T.nFx - assert M.nFy == T.nFy - assert M.nE == T.nE - assert M.nEx == T.nEx - assert M.nEy == T.nEy - assert np.allclose(M.area, T.permuteF*T.area) - assert np.allclose(M.edge, T.permuteE*T.edge) - assert np.allclose(M.vol, T.permuteCC*T.vol) - - # plt.subplot(211).spy(M.faceDiv) - # plt.subplot(212).spy(T.permuteCC*T.faceDiv*T.permuteF.T) - # plt.show() - - assert (M.faceDiv - T.permuteCC*T.faceDiv*T.permuteF.T).nnz == 0 - - -class TestOcTree(unittest.TestCase): - - def test_counts(self): - nc = 8 - h1 = np.random.rand(nc)*nc*0.5 + nc*0.5 - h2 = np.random.rand(nc)*nc*0.5 + nc*0.5 - h3 = np.random.rand(nc)*nc*0.5 + nc*0.5 - h = [hi/np.sum(hi) for hi in [h1, h2, h3]] # normalize - M = Tree(h, levels=3) - M._refineCell([0,0,0,0]) - M._refineCell([0,0,0,1]) - M.number() - # M.plotGrid(showIt=True) - # assert M.nhFx == 2 - # assert M.nFx == 9 - - assert np.allclose(M.vol.sum(), 1.0) - - # assert np.allclose(M._areaFxFull, (M._deflationMatrix('F') * M.area)[:M.ntFx]) - # assert np.allclose(M._areaFyFull, (M._deflationMatrix('F') * M.area)[M.ntFx:(M.ntFx+M.ntFy)]) - # assert np.allclose(M._areaFzFull, (M._deflationMatrix('F') * M.area)[(M.ntFx+M.ntFy):]) - - # assert np.allclose(M._edgeExFull, (M._deflationMatrix('E') * M.edge)[:M.ntEx]) - # assert np.allclose(M._edgeEyFull, (M._deflationMatrix('E') * M.edge)[M.ntEx:(M.ntEx+M.ntEy)]) - # assert np.allclose(M._edgeEzFull, (M._deflationMatrix('E') * M.edge)[(M.ntEx+M.ntEy):]) - - def test_faceDiv(self): - - hx, hy, hz = np.r_[1.,2,3,4], np.r_[5.,6,7,8], np.r_[9.,10,11,12] - M = Tree([hx, hy, hz], levels=2) - M.refine(lambda xc:2) - # M.plotGrid(showIt=True) - Mr = Mesh.TensorMesh([hx, hy, hz]) - assert M.nC == Mr.nC - assert M.nF == Mr.nF - assert M.nFx == Mr.nFx - assert M.nFy == Mr.nFy - assert M.nE == Mr.nE - assert M.nEx == Mr.nEx - assert M.nEy == Mr.nEy - assert np.allclose(Mr.area, M.permuteF*M.area) - assert np.allclose(Mr.edge, M.permuteE*M.edge) - assert np.allclose(Mr.vol, M.permuteCC*M.vol) - - # plt.subplot(211).spy(Mr.faceDiv) - # plt.subplot(212).spy(M.permuteCC*M.faceDiv*M.permuteF.T) - # plt.show() - - assert (Mr.faceDiv - M.permuteCC*M.faceDiv*M.permuteF.T).nnz == 0 - - - def test_edgeCurl(self): - - hx, hy, hz = np.r_[1.,2,3,4], np.r_[5.,6,7,8], np.r_[9.,10,11,12] - M = Tree([hx, hy, hz], levels=2) - M.refine(lambda xc:2) - # M.plotGrid(showIt=True) - Mr = Mesh.TensorMesh([hx, hy, hz]) - - # plt.subplot(211).spy(Mr.faceDiv) - # plt.subplot(212).spy(M.permuteCC.T*M.faceDiv*M.permuteF) - # plt.show() - - assert (Mr.edgeCurl - M.permuteF*M.edgeCurl*M.permuteE.T).nnz == 0 - - def test_faceInnerProduct(self): - - hx, hy, hz = np.r_[1.,2,3,4], np.r_[5.,6,7,8], np.r_[9.,10,11,12] - # hx, hy, hz = [[(1,4)], [(1,4)], [(1,4)]] - - M = Tree([hx, hy, hz], levels=2) - M.refine(lambda xc:2) - # M.plotGrid(showIt=True) - Mr = Mesh.TensorMesh([hx, hy, hz]) - - # plt.subplot(211).spy(Mr.getFaceInnerProduct()) - # plt.subplot(212).spy(M.getFaceInnerProduct()) - # plt.show() - - # print M.nC, M.nF, M.getFaceInnerProduct().shape, M.permuteF.shape - - assert np.allclose(Mr.getFaceInnerProduct().todense(), (M.permuteF * M.getFaceInnerProduct() * M.permuteF.T).todense()) - assert np.allclose(Mr.getEdgeInnerProduct().todense(), (M.permuteE * M.getEdgeInnerProduct() * M.permuteE.T).todense()) - - def test_VectorIdenties(self): - hx, hy, hz = [[(1,4)], [(1,4)], [(1,4)]] - - M = Tree([hx, hy, hz], levels=2) - Mr = Mesh.TensorMesh([hx, hy, hz]) - - assert (M.faceDiv * M.edgeCurl).nnz == 0 - assert (Mr.faceDiv * Mr.edgeCurl).nnz == 0 - - hx, hy, hz = np.r_[1.,2,3,4], np.r_[5.,6,7,8], np.r_[9.,10,11,12] - - M = Tree([hx, hy, hz], levels=2) - Mr = Mesh.TensorMesh([hx, hy, hz]) - - assert np.max(np.abs((M.faceDiv * M.edgeCurl).todense().flatten())) < TOL - assert np.max(np.abs((Mr.faceDiv * Mr.edgeCurl).todense().flatten())) < TOL - - - -if __name__ == '__main__': - unittest.main() From 601079dab3586be0e817cb36151400de6f0d97e6 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Tue, 10 Nov 2015 17:57:43 -0800 Subject: [PATCH 53/83] Oh Travis. Just build the cython, please?! --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 0705506f..39a3925b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,6 +26,7 @@ install: - pip install nose-cov python-coveralls # - pip install -r requirements.txt - python setup.py install + - python setup.py build_ext --inplace # Run test script: From 29579c35e09cc0ed393e6805a84aae4f3ab2bd0a Mon Sep 17 00:00:00 2001 From: Lindsey Heagy Date: Tue, 10 Nov 2015 18:42:09 -0800 Subject: [PATCH 54/83] place holders for averaging --- SimPEG/Mesh/TreeMesh.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/SimPEG/Mesh/TreeMesh.py b/SimPEG/Mesh/TreeMesh.py index aa697ec1..24522bf3 100644 --- a/SimPEG/Mesh/TreeMesh.py +++ b/SimPEG/Mesh/TreeMesh.py @@ -1316,6 +1316,22 @@ class TreeMesh(BaseMesh, InnerProducts): # self._nodalGrad = Utils.sdiag(1/L)*G # return self._nodalGrad + @property + def aveE2CC(self): + "Construct the averaging operator on cell edges to cell centers." + raise Exception('Not yet implemented!') + + @property + def aveE2CCV(self): + "Construct the averaging operator on cell edges to cell centers." + raise Exception('Not yet implemented!') + + @property + def aveF2CC(self): + "Construct the averaging operator on cell faces to cell centers." + raise Exception('Not yet implemented!') + + def _getFaceP(self, xFace, yFace, zFace): ind1, ind2, ind3 = [], [], [] for ind in self._sortedCells: From d1ef2fc330f35e5d2cf5c9fdcceb163a424c2cff Mon Sep 17 00:00:00 2001 From: Lindsey Heagy Date: Tue, 10 Nov 2015 19:31:58 -0800 Subject: [PATCH 55/83] import TreeMesh instead of PointerTree --- SimPEG/Tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SimPEG/Tests.py b/SimPEG/Tests.py index 3d89b045..4fe7f1b9 100644 --- a/SimPEG/Tests.py +++ b/SimPEG/Tests.py @@ -4,7 +4,7 @@ from numpy.linalg import norm from SimPEG.Utils import mkvc, sdiag, diagEst from SimPEG import Utils from SimPEG.Mesh import TensorMesh, CurvilinearMesh, CylMesh -from SimPEG.Mesh.PointerTree import Tree +from SimPEG.Mesh.TreeMesh import TreeMesh import numpy as np import scipy.sparse as sp import unittest From 7fd07f821304af17e4ff7dad089189a10587f954 Mon Sep 17 00:00:00 2001 From: Lindsey Heagy Date: Tue, 10 Nov 2015 19:36:42 -0800 Subject: [PATCH 56/83] import TreeMesh as Tree --- SimPEG/Tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SimPEG/Tests.py b/SimPEG/Tests.py index 4fe7f1b9..95f37c06 100644 --- a/SimPEG/Tests.py +++ b/SimPEG/Tests.py @@ -4,7 +4,7 @@ from numpy.linalg import norm from SimPEG.Utils import mkvc, sdiag, diagEst from SimPEG import Utils from SimPEG.Mesh import TensorMesh, CurvilinearMesh, CylMesh -from SimPEG.Mesh.TreeMesh import TreeMesh +from SimPEG.Mesh.TreeMesh import TreeMesh as Tree import numpy as np import scipy.sparse as sp import unittest From a53372a8596001c26c3024740cb586f2d4440ce1 Mon Sep 17 00:00:00 2001 From: Lindsey Heagy Date: Wed, 11 Nov 2015 09:32:31 -0800 Subject: [PATCH 57/83] Averaging from faces to cell centres (2nd order on non-refined mesh, 1st order when we refine... which I think is ok) --- SimPEG/Mesh/TreeMesh.py | 56 ++++++++++ tests/mesh/test_TreeOperators.py | 172 +++++++++++++++++++++++++++++++ 2 files changed, 228 insertions(+) diff --git a/SimPEG/Mesh/TreeMesh.py b/SimPEG/Mesh/TreeMesh.py index 24522bf3..d6196052 100644 --- a/SimPEG/Mesh/TreeMesh.py +++ b/SimPEG/Mesh/TreeMesh.py @@ -1328,6 +1328,62 @@ class TreeMesh(BaseMesh, InnerProducts): @property def aveF2CC(self): + "Construct the averaging operator on cell faces to cell centers." + if getattr(self, '_aveF2CC', None) is None: + # TODO: Preallocate! + I, J, V = [], [], [] + PM = [1./(2*self.dim)]*2*self.dim # plus / plus + + # TODO total number of faces? + offset = [0]*2 + [self.ntFx]*2 + [self.ntFx+self.ntFy]*2 + + for ii, ind in enumerate(self._sortedCells): + + p = self._pointer(ind) + w = self._levelWidth(p[-1]) + + if self.dim == 2: + faces = [ + self._fx2i[self._index([ p[0] , p[1] , p[2]])], + self._fx2i[self._index([ p[0] + w, p[1] , p[2]])], + self._fy2i[self._index([ p[0] , p[1] , p[2]])], + self._fy2i[self._index([ p[0] , p[1] + w, p[2]])] + ] + elif self.dim == 3: + faces = [ + self._fx2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._fx2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], + self._fy2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._fy2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], + self._fz2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._fz2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])] + ] + + for off, pm, face in zip(offset,PM,faces): + I += [ii] + J += [face + off] + V += [pm] + + + Av = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.ntF)) + R = self._deflationMatrix('F',asOnes=True,withHanging=True) + + # VOL = self.vol + # if self.dim == 2: + # S = np.r_[self._areaFxFull, self._areaFyFull] + # elif self.dim == 3: + # S = np.r_[self._areaFxFull, self._areaFyFull, self._areaFzFull] + # self._faceDiv = Utils.sdiag(1.0/VOL)*D*Utils.sdiag(S)*R + # return self._faceDiv + + # raise Exception('Not yet implemented!') + self._aveF2CC = Av*R + return self._aveF2CC + + + + @property + def aveF2CCV(self): "Construct the averaging operator on cell faces to cell centers." raise Exception('Not yet implemented!') diff --git a/tests/mesh/test_TreeOperators.py b/tests/mesh/test_TreeOperators.py index f2ff66da..b9bd4043 100644 --- a/tests/mesh/test_TreeOperators.py +++ b/tests/mesh/test_TreeOperators.py @@ -14,6 +14,8 @@ cartF3 = lambda M, fx, fy, fz: np.vstack((cart_row3(M.gridFx, fx, fy, fz), cart_ cartE3 = lambda M, ex, ey, ez: np.vstack((cart_row3(M.gridEx, ex, ey, ez), cart_row3(M.gridEy, ex, ey, ez), cart_row3(M.gridEz, ex, ey, ez))) +plotit = False + class TestFaceDiv2D(Tests.OrderTest): name = "Face Divergence 2D" meshTypes = MESHTYPES @@ -388,6 +390,176 @@ class TestTreeInnerProducts2D(Tests.OrderTest): self.orderTest() +class TestTreeAveraging2D(Tests.OrderTest): + """Integrate an function over a unit cube domain using edgeInnerProducts and faceInnerProducts.""" + meshTypes = ['uniformTree', 'randomTree'] + meshDimension = 2 + meshSizes = [4,8,16,32] + + def getError(self): + if plotit: + plt.spy(self.getAve(self.M)) + plt.show() + + num = self.getAve(self.M) * self.getHere(self.M) + err = np.linalg.norm((self.getThere(self.M)-num), np.inf) + + if plotit: + self.M.plotImage(self.getThere(self.M)-num) + plt.show() + plt.tight_layout + + return err + + # def test_orderN2CC(self): + # self.name = "Averaging 2D: N2CC" + # fun = lambda x, y: (np.cos(x)+np.sin(y)) + # self.getHere = lambda M: call2(fun, M.gridN) + # self.getThere = lambda M: call2(fun, M.gridCC) + # self.getAve = lambda M: M.aveN2CC + # self.orderTest() + + # def test_orderN2F(self): + # self.name = "Averaging 2D: N2F" + # fun = lambda x, y: (np.cos(x)+np.sin(y)) + # self.getHere = lambda M: call2(fun, M.gridN) + # self.getThere = lambda M: np.r_[call2(fun, M.gridFx), call2(fun, M.gridFy)] + # self.getAve = lambda M: M.aveN2F + # self.orderTest() + + # def test_orderN2E(self): + # self.name = "Averaging 2D: N2E" + # fun = lambda x, y: (np.cos(x)+np.sin(y)) + # self.getHere = lambda M: call2(fun, M.gridN) + # self.getThere = lambda M: np.r_[call2(fun, M.gridEx), call2(fun, M.gridEy)] + # self.getAve = lambda M: M.aveN2E + # self.orderTest() + + + def test_orderF2CC(self): + self.name = "Averaging 2D: F2CC" + fun = lambda x, y: (np.cos(x)+np.sin(y)) + self.getHere = lambda M: np.r_[call2(fun, np.r_[M.gridFx, M.gridFy])] + self.getThere = lambda M: call2(fun, M.gridCC) + self.getAve = lambda M: M.aveF2CC + self.orderTest() + + # def test_orderF2CCV(self): + # self.name = "Averaging 2D: F2CCV" + # funX = lambda x, y: (np.cos(x)+np.sin(y)) + # funY = lambda x, y: (np.cos(y)*np.sin(x)) + # self.getHere = lambda M: np.r_[call2(funX, M.gridFx), call2(funY, M.gridFy)] + # self.getThere = lambda M: np.r_[call2(funX, M.gridCC), call2(funY, M.gridCC)] + # self.getAve = lambda M: M.aveF2CCV + # self.orderTest() + + # def test_orderCC2F(self): + # self.name = "Averaging 2D: CC2F" + # fun = lambda x, y: (np.cos(x)+np.sin(y)) + # self.getHere = lambda M: call2(fun, M.gridCC) + # self.getThere = lambda M: np.r_[call2(fun, M.gridFx), call2(fun, M.gridFy)] + # self.getAve = lambda M: M.aveCC2F + # self.expectedOrders = 1 + # self.orderTest() + # self.expectedOrders = 2 + + # def test_orderE2CC(self): + # self.name = "Averaging 2D: E2CC" + # fun = lambda x, y: (np.cos(x)+np.sin(y)) + # self.getHere = lambda M: np.r_[call2(fun, M.gridEx), call2(fun, M.gridEy)] + # self.getThere = lambda M: call2(fun, M.gridCC) + # self.getAve = lambda M: M.aveE2CC + # self.orderTest() + + # def test_orderE2CCV(self): + # self.name = "Averaging 2D: E2CCV" + # funX = lambda x, y: (np.cos(x)+np.sin(y)) + # funY = lambda x, y: (np.cos(y)*np.sin(x)) + # self.getHere = lambda M: np.r_[call2(funX, M.gridEx), call2(funY, M.gridEy)] + # self.getThere = lambda M: np.r_[call2(funX, M.gridCC), call2(funY, M.gridCC)] + # self.getAve = lambda M: M.aveE2CCV + # self.orderTest() + +class TestAveraging3D(Tests.OrderTest): + name = "Averaging 3D" + meshTypes = ['uniformTree', 'randomTree'] + meshDimension = 3 + meshSizes = [8,16] + + def getError(self): + num = self.getAve(self.M) * self.getHere(self.M) + err = np.linalg.norm((self.getThere(self.M)-num), np.inf) + return err + +# def test_orderN2CC(self): +# self.name = "Averaging 3D: N2CC" +# fun = lambda x, y, z: (np.cos(x)+np.sin(y)+np.exp(z)) +# self.getHere = lambda M: call3(fun, M.gridN) +# self.getThere = lambda M: call3(fun, M.gridCC) +# self.getAve = lambda M: M.aveN2CC +# self.orderTest() + +# def test_orderN2F(self): +# self.name = "Averaging 3D: N2F" +# fun = lambda x, y, z: (np.cos(x)+np.sin(y)+np.exp(z)) +# self.getHere = lambda M: call3(fun, M.gridN) +# self.getThere = lambda M: np.r_[call3(fun, M.gridFx), call3(fun, M.gridFy), call3(fun, M.gridFz)] +# self.getAve = lambda M: M.aveN2F +# self.orderTest() + +# def test_orderN2E(self): +# self.name = "Averaging 3D: N2E" +# fun = lambda x, y, z: (np.cos(x)+np.sin(y)+np.exp(z)) +# self.getHere = lambda M: call3(fun, M.gridN) +# self.getThere = lambda M: np.r_[call3(fun, M.gridEx), call3(fun, M.gridEy), call3(fun, M.gridEz)] +# self.getAve = lambda M: M.aveN2E +# self.orderTest() + + def test_orderF2CC(self): + self.name = "Averaging 3D: F2CC" + fun = lambda x, y, z: (np.cos(x)+np.sin(y)+np.exp(z)) + self.getHere = lambda M: np.r_[call3(fun, M.gridFx), call3(fun, M.gridFy), call3(fun, M.gridFz)] + self.getThere = lambda M: call3(fun, M.gridCC) + self.getAve = lambda M: M.aveF2CC + self.orderTest() + +# def test_orderF2CCV(self): +# self.name = "Averaging 3D: F2CCV" +# funX = lambda x, y, z: (np.cos(x)+np.sin(y)+np.exp(z)) +# funY = lambda x, y, z: (np.cos(x)+np.sin(y)*np.exp(z)) +# funZ = lambda x, y, z: (np.cos(x)*np.sin(y)+np.exp(z)) +# self.getHere = lambda M: np.r_[call3(funX, M.gridFx), call3(funY, M.gridFy), call3(funZ, M.gridFz)] +# self.getThere = lambda M: np.r_[call3(funX, M.gridCC), call3(funY, M.gridCC), call3(funZ, M.gridCC)] +# self.getAve = lambda M: M.aveF2CCV +# self.orderTest() + +# def test_orderE2CC(self): +# self.name = "Averaging 3D: E2CC" +# fun = lambda x, y, z: (np.cos(x)+np.sin(y)+np.exp(z)) +# self.getHere = lambda M: np.r_[call3(fun, M.gridEx), call3(fun, M.gridEy), call3(fun, M.gridEz)] +# self.getThere = lambda M: call3(fun, M.gridCC) +# self.getAve = lambda M: M.aveE2CC +# self.orderTest() + +# def test_orderE2CCV(self): +# self.name = "Averaging 3D: E2CCV" +# funX = lambda x, y, z: (np.cos(x)+np.sin(y)+np.exp(z)) +# funY = lambda x, y, z: (np.cos(x)+np.sin(y)*np.exp(z)) +# funZ = lambda x, y, z: (np.cos(x)*np.sin(y)+np.exp(z)) +# self.getHere = lambda M: np.r_[call3(funX, M.gridEx), call3(funY, M.gridEy), call3(funZ, M.gridEz)] +# self.getThere = lambda M: np.r_[call3(funX, M.gridCC), call3(funY, M.gridCC), call3(funZ, M.gridCC)] +# self.getAve = lambda M: M.aveE2CCV +# self.orderTest() + +# def test_orderCC2F(self): +# self.name = "Averaging 3D: CC2F" +# fun = lambda x, y, z: (np.cos(x)+np.sin(y)+np.exp(z)) +# self.getHere = lambda M: call3(fun, M.gridCC) +# self.getThere = lambda M: np.r_[call3(fun, M.gridFx), call3(fun, M.gridFy), call3(fun, M.gridFz)] +# self.getAve = lambda M: M.aveCC2F +# self.expectedOrders = 1 +# self.orderTest() +# self.expectedOrders = 2 if __name__ == '__main__': unittest.main() From fd55aa6d67472fbc78c4a52531b5554d1903794e Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Wed, 11 Nov 2015 13:05:47 -0800 Subject: [PATCH 58/83] Delete things when __dirty__ --- SimPEG/Mesh/TreeMesh.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/SimPEG/Mesh/TreeMesh.py b/SimPEG/Mesh/TreeMesh.py index d6196052..b9bc7c74 100644 --- a/SimPEG/Mesh/TreeMesh.py +++ b/SimPEG/Mesh/TreeMesh.py @@ -22,7 +22,6 @@ # \/__/ \/__/ \|__| \/__/ \/__/ # # -# @rowanc1, Nov. 10, 2015 # # .----------------.----------------. # /| /| /| @@ -164,7 +163,8 @@ class TreeMesh(BaseMesh, InnerProducts): '__sortedCells', '_gridCC', '_gridN', '_gridFx', '_gridFy', '_gridFz', '_gridEx', '_gridEy', '_gridEz', '_area', '_edge', '_vol', - '_faceDiv', '_edgeCurl', '_nodalGrad' + '_faceDiv', '_edgeCurl', '_nodalGrad', + '_aveF2CC', '_aveF2CCV', '_aveE2CC', '_aveE2CCV','_aveN2CC' ] for p in deleteThese: if hasattr(self, p): delattr(self, p) @@ -1379,7 +1379,7 @@ class TreeMesh(BaseMesh, InnerProducts): # raise Exception('Not yet implemented!') self._aveF2CC = Av*R return self._aveF2CC - + @property From 8fc1a86742dcfe9bde66b0d4563a529b506fb486 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Wed, 11 Nov 2015 13:19:48 -0800 Subject: [PATCH 59/83] Updates to order tests. added 'notatreeTree' mesh. --- SimPEG/Tests.py | 6 ++++-- tests/mesh/test_TreeOperators.py | 18 ++++++++++-------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/SimPEG/Tests.py b/SimPEG/Tests.py index 95f37c06..a881b6dc 100644 --- a/SimPEG/Tests.py +++ b/SimPEG/Tests.py @@ -135,7 +135,7 @@ class OrderTest(unittest.TestCase): elif 'Tree' in self._meshType: nc *= 2 - if 'uniform' in self._meshType: + if 'uniform' in self._meshType or 'notatree' in self._meshType: h = [nc, nc, nc] elif 'random' in self._meshType: h1 = np.random.rand(nc)*nc*0.5 + nc*0.5 @@ -148,11 +148,13 @@ class OrderTest(unittest.TestCase): levels = int(np.log(nc)/np.log(2)) self.M = Tree(h[:self.meshDimension], levels=levels) def function(xc): + if 'notatree' in self._meshType: + return levels - 1 r = xc - np.array([0.5]*len(xc)) dist = np.sqrt(r.dot(r)) if dist < 0.2: return levels - return levels-1 + return levels - 1 self.M.refine(function,balance=False) self.M.number(balance=False) # self.M.plotGrid(showIt=True) diff --git a/tests/mesh/test_TreeOperators.py b/tests/mesh/test_TreeOperators.py index b9bd4043..b50b4000 100644 --- a/tests/mesh/test_TreeOperators.py +++ b/tests/mesh/test_TreeOperators.py @@ -14,7 +14,7 @@ cartF3 = lambda M, fx, fy, fz: np.vstack((cart_row3(M.gridFx, fx, fy, fz), cart_ cartE3 = lambda M, ex, ey, ez: np.vstack((cart_row3(M.gridEx, ex, ey, ez), cart_row3(M.gridEy, ex, ey, ez), cart_row3(M.gridEz, ex, ey, ez))) -plotit = False +plotIt = False class TestFaceDiv2D(Tests.OrderTest): name = "Face Divergence 2D" @@ -252,7 +252,7 @@ class TestTreeInnerProducts(Tests.OrderTest): class TestTreeInnerProducts2D(Tests.OrderTest): """Integrate an function over a unit cube domain using edgeInnerProducts and faceInnerProducts.""" - meshTypes = ['uniformTree', 'randomTree'] #['uniformTensorMesh', 'uniformCurv', 'rotateCurv'] + meshTypes = ['uniformTree'] meshDimension = 2 meshSizes = [4, 8] @@ -393,23 +393,24 @@ class TestTreeInnerProducts2D(Tests.OrderTest): class TestTreeAveraging2D(Tests.OrderTest): """Integrate an function over a unit cube domain using edgeInnerProducts and faceInnerProducts.""" - meshTypes = ['uniformTree', 'randomTree'] + meshTypes = ['notatreeTree', 'uniformTree']#, 'randomTree'] meshDimension = 2 meshSizes = [4,8,16,32] + expectedOrders = [2,1] def getError(self): - if plotit: + if plotIt: plt.spy(self.getAve(self.M)) plt.show() num = self.getAve(self.M) * self.getHere(self.M) err = np.linalg.norm((self.getThere(self.M)-num), np.inf) - - if plotit: + + if plotIt: self.M.plotImage(self.getThere(self.M)-num) plt.show() plt.tight_layout - + return err # def test_orderN2CC(self): @@ -483,9 +484,10 @@ class TestTreeAveraging2D(Tests.OrderTest): class TestAveraging3D(Tests.OrderTest): name = "Averaging 3D" - meshTypes = ['uniformTree', 'randomTree'] + meshTypes = ['notatreeTree', 'uniformTree']#, 'randomTree'] meshDimension = 3 meshSizes = [8,16] + expectedOrders = [2,1] def getError(self): num = self.getAve(self.M) * self.getHere(self.M) From 86eb2440118a1658d99f90078702894fdb7e34b6 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Wed, 11 Nov 2015 14:04:36 -0800 Subject: [PATCH 60/83] updates to innerProductDeriv tests for tree mesh --- tests/mesh/test_innerProductDerivs.py | 98 ++++++++++++++------------- 1 file changed, 50 insertions(+), 48 deletions(-) diff --git a/tests/mesh/test_innerProductDerivs.py b/tests/mesh/test_innerProductDerivs.py index f624ba1c..ba074ede 100644 --- a/tests/mesh/test_innerProductDerivs.py +++ b/tests/mesh/test_innerProductDerivs.py @@ -10,7 +10,9 @@ class TestInnerProductsDerivs(unittest.TestCase): hRect = Utils.exampleLrmGrid(h,'rotate') mesh = Mesh.CurvilinearMesh(hRect) elif meshType == 'Tree': - mesh = Mesh.TreeMesh(h) + mesh = Mesh.TreeMesh(h, levels=3) + mesh.refine(lambda xc: 3) + mesh.number(balance=False) elif meshType == 'Tensor': mesh = Mesh.TensorMesh(h) v = np.random.rand(mesh.nF) @@ -27,7 +29,9 @@ class TestInnerProductsDerivs(unittest.TestCase): hRect = Utils.exampleLrmGrid(h,'rotate') mesh = Mesh.CurvilinearMesh(hRect) elif meshType == 'Tree': - mesh = Mesh.TreeMesh(h) + mesh = Mesh.TreeMesh(h, levels=3) + mesh.refine(lambda xc: 3) + mesh.number(balance=False) elif meshType == 'Tensor': mesh = Mesh.TensorMesh(h) v = np.random.rand(mesh.nE) @@ -197,67 +201,65 @@ class TestInnerProductsDerivs(unittest.TestCase): self.assertTrue(self.doTestEdge([10, 4, 5],3, True, 'Curv')) - - def test_FaceIP_2D_float_Tree(self): - self.assertTrue(self.doTestFace([10, 4],0, False, 'Tree')) + self.assertTrue(self.doTestFace([8, 8],0, False, 'Tree')) def test_FaceIP_3D_float_Tree(self): - self.assertTrue(self.doTestFace([10, 4, 5],0, False, 'Tree')) + self.assertTrue(self.doTestFace([8, 8, 8],0, False, 'Tree')) def test_FaceIP_2D_isotropic_Tree(self): - self.assertTrue(self.doTestFace([10, 4],1, False, 'Tree')) + self.assertTrue(self.doTestFace([8, 8],1, False, 'Tree')) def test_FaceIP_3D_isotropic_Tree(self): - self.assertTrue(self.doTestFace([10, 4, 5],1, False, 'Tree')) + self.assertTrue(self.doTestFace([8, 8, 8],1, False, 'Tree')) def test_FaceIP_2D_anisotropic_Tree(self): - self.assertTrue(self.doTestFace([10, 4],2, False, 'Tree')) + self.assertTrue(self.doTestFace([8, 8],2, False, 'Tree')) def test_FaceIP_3D_anisotropic_Tree(self): - self.assertTrue(self.doTestFace([10, 4, 5],3, False, 'Tree')) + self.assertTrue(self.doTestFace([8, 8, 8],3, False, 'Tree')) def test_FaceIP_2D_tensor_Tree(self): - self.assertTrue(self.doTestFace([10, 4],3, False, 'Tree')) + self.assertTrue(self.doTestFace([8, 8],3, False, 'Tree')) def test_FaceIP_3D_tensor_Tree(self): - self.assertTrue(self.doTestFace([10, 4, 5],6, False, 'Tree')) + self.assertTrue(self.doTestFace([8, 8, 8],6, False, 'Tree')) - def test_FaceIP_2D_float_fast_Tree(self): - self.assertTrue(self.doTestFace([10, 4],0, True, 'Tree')) - def test_FaceIP_3D_float_fast_Tree(self): - self.assertTrue(self.doTestFace([10, 4, 5],0, True, 'Tree')) - def test_FaceIP_2D_isotropic_fast_Tree(self): - self.assertTrue(self.doTestFace([10, 4],1, True, 'Tree')) - def test_FaceIP_3D_isotropic_fast_Tree(self): - self.assertTrue(self.doTestFace([10, 4, 5],1, True, 'Tree')) - def test_FaceIP_2D_anisotropic_fast_Tree(self): - self.assertTrue(self.doTestFace([10, 4],2, True, 'Tree')) - def test_FaceIP_3D_anisotropic_fast_Tree(self): - self.assertTrue(self.doTestFace([10, 4, 5],3, True, 'Tree')) + # def test_FaceIP_2D_float_fast_Tree(self): + # self.assertTrue(self.doTestFace([8, 8],0, True, 'Tree')) + # def test_FaceIP_3D_float_fast_Tree(self): + # self.assertTrue(self.doTestFace([8, 8, 8],0, True, 'Tree')) + # def test_FaceIP_2D_isotropic_fast_Tree(self): + # self.assertTrue(self.doTestFace([8, 8],1, True, 'Tree')) + # def test_FaceIP_3D_isotropic_fast_Tree(self): + # self.assertTrue(self.doTestFace([8, 8, 8],1, True, 'Tree')) + # def test_FaceIP_2D_anisotropic_fast_Tree(self): + # self.assertTrue(self.doTestFace([8, 8],2, True, 'Tree')) + # def test_FaceIP_3D_anisotropic_fast_Tree(self): + # self.assertTrue(self.doTestFace([8, 8, 8],3, True, 'Tree')) - def test_EdgeIP_2D_float_Tree(self): - self.assertTrue(self.doTestEdge([10, 4],0, False, 'Tree')) + # def test_EdgeIP_2D_float_Tree(self): + # self.assertTrue(self.doTestEdge([8, 8],0, False, 'Tree')) def test_EdgeIP_3D_float_Tree(self): - self.assertTrue(self.doTestEdge([10, 4, 5],0, False, 'Tree')) - def test_EdgeIP_2D_isotropic_Tree(self): - self.assertTrue(self.doTestEdge([10, 4],1, False, 'Tree')) + self.assertTrue(self.doTestEdge([8, 8, 8],0, False, 'Tree')) + # def test_EdgeIP_2D_isotropic_Tree(self): + # self.assertTrue(self.doTestEdge([8, 8],1, False, 'Tree')) def test_EdgeIP_3D_isotropic_Tree(self): - self.assertTrue(self.doTestEdge([10, 4, 5],1, False, 'Tree')) - def test_EdgeIP_2D_anisotropic_Tree(self): - self.assertTrue(self.doTestEdge([10, 4],2, False, 'Tree')) + self.assertTrue(self.doTestEdge([8, 8, 8],1, False, 'Tree')) + # def test_EdgeIP_2D_anisotropic_Tree(self): + # self.assertTrue(self.doTestEdge([8, 8],2, False, 'Tree')) def test_EdgeIP_3D_anisotropic_Tree(self): - self.assertTrue(self.doTestEdge([10, 4, 5],3, False, 'Tree')) - def test_EdgeIP_2D_tensor_Tree(self): - self.assertTrue(self.doTestEdge([10, 4],3, False, 'Tree')) + self.assertTrue(self.doTestEdge([8, 8, 8],3, False, 'Tree')) + # def test_EdgeIP_2D_tensor_Tree(self): + # self.assertTrue(self.doTestEdge([8, 8],3, False, 'Tree')) def test_EdgeIP_3D_tensor_Tree(self): - self.assertTrue(self.doTestEdge([10, 4, 5],6, False, 'Tree')) + self.assertTrue(self.doTestEdge([8, 8, 8],6, False, 'Tree')) - def test_EdgeIP_2D_float_fast_Tree(self): - self.assertTrue(self.doTestEdge([10, 4],0, True, 'Tree')) - def test_EdgeIP_3D_float_fast_Tree(self): - self.assertTrue(self.doTestEdge([10, 4, 5],0, True, 'Tree')) - def test_EdgeIP_2D_isotropic_fast_Tree(self): - self.assertTrue(self.doTestEdge([10, 4],1, True, 'Tree')) - def test_EdgeIP_3D_isotropic_fast_Tree(self): - self.assertTrue(self.doTestEdge([10, 4, 5],1, True, 'Tree')) - def test_EdgeIP_2D_anisotropic_fast_Tree(self): - self.assertTrue(self.doTestEdge([10, 4],2, True, 'Tree')) - def test_EdgeIP_3D_anisotropic_fast_Tree(self): - self.assertTrue(self.doTestEdge([10, 4, 5],3, True, 'Tree')) + # def test_EdgeIP_2D_float_fast_Tree(self): + # self.assertTrue(self.doTestEdge([8, 8],0, True, 'Tree')) + # def test_EdgeIP_3D_float_fast_Tree(self): + # self.assertTrue(self.doTestEdge([8, 8, 8],0, True, 'Tree')) + # def test_EdgeIP_2D_isotropic_fast_Tree(self): + # self.assertTrue(self.doTestEdge([8, 8],1, True, 'Tree')) + # def test_EdgeIP_3D_isotropic_fast_Tree(self): + # self.assertTrue(self.doTestEdge([8, 8, 8],1, True, 'Tree')) + # def test_EdgeIP_2D_anisotropic_fast_Tree(self): + # self.assertTrue(self.doTestEdge([8, 8],2, True, 'Tree')) + # def test_EdgeIP_3D_anisotropic_fast_Tree(self): + # self.assertTrue(self.doTestEdge([8, 8, 8],3, True, 'Tree')) if __name__ == '__main__': unittest.main() From 821932ed821184a93acdc0c4dcada94458edbbbc Mon Sep 17 00:00:00 2001 From: Lindsey Heagy Date: Thu, 12 Nov 2015 08:19:15 -0800 Subject: [PATCH 61/83] aveF2CCV in 2 and 3D --- SimPEG/Mesh/TreeMesh.py | 96 +++++++++++++++++++++++++++----- tests/mesh/test_TreeOperators.py | 73 ++++++++++++------------ 2 files changed, 120 insertions(+), 49 deletions(-) diff --git a/SimPEG/Mesh/TreeMesh.py b/SimPEG/Mesh/TreeMesh.py index b9bc7c74..057c0f59 100644 --- a/SimPEG/Mesh/TreeMesh.py +++ b/SimPEG/Mesh/TreeMesh.py @@ -1319,7 +1319,10 @@ class TreeMesh(BaseMesh, InnerProducts): @property def aveE2CC(self): "Construct the averaging operator on cell edges to cell centers." - raise Exception('Not yet implemented!') + if getattr(self, '_aveE2CC', None) is None: + if self.dim == 2: + self._aveE2CC = self.aveF2CC + return self._aveE2CC @property def aveE2CCV(self): @@ -1366,26 +1369,91 @@ class TreeMesh(BaseMesh, InnerProducts): Av = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.ntF)) - R = self._deflationMatrix('F',asOnes=True,withHanging=True) + Rf = self._deflationMatrix('F',asOnes=True,withHanging=True) - # VOL = self.vol - # if self.dim == 2: - # S = np.r_[self._areaFxFull, self._areaFyFull] - # elif self.dim == 3: - # S = np.r_[self._areaFxFull, self._areaFyFull, self._areaFzFull] - # self._faceDiv = Utils.sdiag(1.0/VOL)*D*Utils.sdiag(S)*R - # return self._faceDiv - - # raise Exception('Not yet implemented!') - self._aveF2CC = Av*R + self._aveF2CC = Av*Rf return self._aveF2CC - @property def aveF2CCV(self): "Construct the averaging operator on cell faces to cell centers." - raise Exception('Not yet implemented!') + if getattr(self, '_aveF2CCV', None) is None: + # TODO: Preallocate! + I, J, V = [], [], [] + PM = [1./2.]*2 # 0.5, 0.5 + + offsetx = [0]*2 + offsety = [self.ntFx]*2 + + if self.dim == 2: + for ii, ind in enumerate(self._sortedCells): + p = self._pointer(ind) + w = self._levelWidth(p[-1]) + + facesx = [ + self._fx2i[self._index([ p[0] , p[1] , p[2]])], + self._fx2i[self._index([ p[0] + w, p[1] , p[2]])], + ] + + facesy = [ + self._fy2i[self._index([ p[0] , p[1] , p[2]])], + self._fy2i[self._index([ p[0] , p[1] + w, p[2]])], + ] + + for off, pm, face in zip(offsetx,PM,facesx): + I += [ii] + J += [face + off] + V += [pm] + + for off, pm, face in zip(offsety,PM,facesy): + I += [ii + self.nC] + J += [face + off] + V += [pm] + + + + if self.dim == 3: + offsetz = [self.ntFx + self.ntFy]*2 + + for ii, ind in enumerate(self._sortedCells): + p = self._pointer(ind) + w = self._levelWidth(p[-1]) + + facesx = [ + self._fx2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._fx2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], + ] + + facesy = [ + self._fy2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._fy2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], + ] + facesz = [ + self._fz2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._fz2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])] + ] + + for off, pm, face in zip(offsetx,PM,facesx): + I += [ii] + J += [face + off] + V += [pm] + + for off, pm, face in zip(offsety,PM,facesy): + I += [ii + self.nC] + J += [face + off] + V += [pm] + + for off, pm, face in zip(offsetz,PM,facesz): + I += [ii + self.nC*2] + J += [face + off] + V += [pm] + + Av = sp.csr_matrix((V,(I,J)), shape=(self.nC*self.dim, self.ntF)) + Rf = self._deflationMatrix('F',asOnes=True,withHanging=True) + + self._aveF2CCV = Av*Rf + return self._aveF2CCV def _getFaceP(self, xFace, yFace, zFace): diff --git a/tests/mesh/test_TreeOperators.py b/tests/mesh/test_TreeOperators.py index b50b4000..2f0e066a 100644 --- a/tests/mesh/test_TreeOperators.py +++ b/tests/mesh/test_TreeOperators.py @@ -395,7 +395,7 @@ class TestTreeAveraging2D(Tests.OrderTest): meshTypes = ['notatreeTree', 'uniformTree']#, 'randomTree'] meshDimension = 2 - meshSizes = [4,8,16,32] + meshSizes = [4,8,16] expectedOrders = [2,1] def getError(self): @@ -437,24 +437,23 @@ class TestTreeAveraging2D(Tests.OrderTest): # self.getAve = lambda M: M.aveN2E # self.orderTest() - - def test_orderF2CC(self): - self.name = "Averaging 2D: F2CC" - fun = lambda x, y: (np.cos(x)+np.sin(y)) - self.getHere = lambda M: np.r_[call2(fun, np.r_[M.gridFx, M.gridFy])] - self.getThere = lambda M: call2(fun, M.gridCC) - self.getAve = lambda M: M.aveF2CC - self.orderTest() - - # def test_orderF2CCV(self): - # self.name = "Averaging 2D: F2CCV" - # funX = lambda x, y: (np.cos(x)+np.sin(y)) - # funY = lambda x, y: (np.cos(y)*np.sin(x)) - # self.getHere = lambda M: np.r_[call2(funX, M.gridFx), call2(funY, M.gridFy)] - # self.getThere = lambda M: np.r_[call2(funX, M.gridCC), call2(funY, M.gridCC)] - # self.getAve = lambda M: M.aveF2CCV + # def test_orderF2CC(self): + # self.name = "Averaging 2D: F2CC" + # fun = lambda x, y: (np.cos(x)+np.sin(y)) + # self.getHere = lambda M: np.r_[call2(fun, np.r_[M.gridFx, M.gridFy])] + # self.getThere = lambda M: call2(fun, M.gridCC) + # self.getAve = lambda M: M.aveF2CC # self.orderTest() + def test_orderF2CCV(self): + self.name = "Averaging 2D: F2CCV" + funX = lambda x, y: (np.cos(x)+np.sin(y)) + funY = lambda x, y: (np.cos(y)*np.sin(x)) + self.getHere = lambda M: np.r_[call2(funX, M.gridFx), call2(funY, M.gridFy)] + self.getThere = lambda M: np.r_[call2(funX, M.gridCC), call2(funY, M.gridCC)] + self.getAve = lambda M: M.aveF2CCV + self.orderTest() + # def test_orderCC2F(self): # self.name = "Averaging 2D: CC2F" # fun = lambda x, y: (np.cos(x)+np.sin(y)) @@ -468,7 +467,7 @@ class TestTreeAveraging2D(Tests.OrderTest): # def test_orderE2CC(self): # self.name = "Averaging 2D: E2CC" # fun = lambda x, y: (np.cos(x)+np.sin(y)) - # self.getHere = lambda M: np.r_[call2(fun, M.gridEx), call2(fun, M.gridEy)] + # self.getHere = lambda M: np.r_[call2(fun, np.r_[M.gridEx, M.gridEy])] # self.getThere = lambda M: call2(fun, M.gridCC) # self.getAve = lambda M: M.aveE2CC # self.orderTest() @@ -486,10 +485,14 @@ class TestAveraging3D(Tests.OrderTest): name = "Averaging 3D" meshTypes = ['notatreeTree', 'uniformTree']#, 'randomTree'] meshDimension = 3 - meshSizes = [8,16] + meshSizes = [4,8,16] expectedOrders = [2,1] def getError(self): + if plotIt: + plt.spy(self.getAve(self.M)) + plt.show() + num = self.getAve(self.M) * self.getHere(self.M) err = np.linalg.norm((self.getThere(self.M)-num), np.inf) return err @@ -518,23 +521,23 @@ class TestAveraging3D(Tests.OrderTest): # self.getAve = lambda M: M.aveN2E # self.orderTest() - def test_orderF2CC(self): - self.name = "Averaging 3D: F2CC" - fun = lambda x, y, z: (np.cos(x)+np.sin(y)+np.exp(z)) - self.getHere = lambda M: np.r_[call3(fun, M.gridFx), call3(fun, M.gridFy), call3(fun, M.gridFz)] - self.getThere = lambda M: call3(fun, M.gridCC) - self.getAve = lambda M: M.aveF2CC - self.orderTest() + # def test_orderF2CC(self): + # self.name = "Averaging 3D: F2CC" + # fun = lambda x, y, z: (np.cos(x)+np.sin(y)+np.exp(z)) + # self.getHere = lambda M: np.r_[call3(fun, M.gridFx), call3(fun, M.gridFy), call3(fun, M.gridFz)] + # self.getThere = lambda M: call3(fun, M.gridCC) + # self.getAve = lambda M: M.aveF2CC + # self.orderTest() -# def test_orderF2CCV(self): -# self.name = "Averaging 3D: F2CCV" -# funX = lambda x, y, z: (np.cos(x)+np.sin(y)+np.exp(z)) -# funY = lambda x, y, z: (np.cos(x)+np.sin(y)*np.exp(z)) -# funZ = lambda x, y, z: (np.cos(x)*np.sin(y)+np.exp(z)) -# self.getHere = lambda M: np.r_[call3(funX, M.gridFx), call3(funY, M.gridFy), call3(funZ, M.gridFz)] -# self.getThere = lambda M: np.r_[call3(funX, M.gridCC), call3(funY, M.gridCC), call3(funZ, M.gridCC)] -# self.getAve = lambda M: M.aveF2CCV -# self.orderTest() + def test_orderF2CCV(self): + self.name = "Averaging 3D: F2CCV" + funX = lambda x, y, z: (np.cos(x)+np.sin(y)+np.exp(z)) + funY = lambda x, y, z: (np.cos(x)+np.sin(y)*np.exp(z)) + funZ = lambda x, y, z: (np.cos(x)*np.sin(y)+np.exp(z)) + self.getHere = lambda M: np.r_[call3(funX, M.gridFx), call3(funY, M.gridFy), call3(funZ, M.gridFz)] + self.getThere = lambda M: np.r_[call3(funX, M.gridCC), call3(funY, M.gridCC), call3(funZ, M.gridCC)] + self.getAve = lambda M: M.aveF2CCV + self.orderTest() # def test_orderE2CC(self): # self.name = "Averaging 3D: E2CC" From 6a30ea1d83cb646aa70ef16c2331fba28b7351a8 Mon Sep 17 00:00:00 2001 From: Lindsey Heagy Date: Thu, 12 Nov 2015 08:20:44 -0800 Subject: [PATCH 62/83] better mesh sizes for testing --- tests/mesh/test_TreeOperators.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/mesh/test_TreeOperators.py b/tests/mesh/test_TreeOperators.py index 2f0e066a..75b393b7 100644 --- a/tests/mesh/test_TreeOperators.py +++ b/tests/mesh/test_TreeOperators.py @@ -485,7 +485,7 @@ class TestAveraging3D(Tests.OrderTest): name = "Averaging 3D" meshTypes = ['notatreeTree', 'uniformTree']#, 'randomTree'] meshDimension = 3 - meshSizes = [4,8,16] + meshSizes = [8,16,32] expectedOrders = [2,1] def getError(self): From d130b50f7f72f5d737ad76f1a02361d4b555f762 Mon Sep 17 00:00:00 2001 From: Lindsey Heagy Date: Thu, 12 Nov 2015 09:11:39 -0800 Subject: [PATCH 63/83] aveE2CC for 3D --- SimPEG/Mesh/TreeMesh.py | 71 ++++++++++++++++++++++++++++++-- tests/mesh/test_TreeOperators.py | 42 +++++++++---------- 2 files changed, 89 insertions(+), 24 deletions(-) diff --git a/SimPEG/Mesh/TreeMesh.py b/SimPEG/Mesh/TreeMesh.py index 057c0f59..02a1e19a 100644 --- a/SimPEG/Mesh/TreeMesh.py +++ b/SimPEG/Mesh/TreeMesh.py @@ -1320,8 +1320,73 @@ class TreeMesh(BaseMesh, InnerProducts): def aveE2CC(self): "Construct the averaging operator on cell edges to cell centers." if getattr(self, '_aveE2CC', None) is None: + + # TODO: preallocate + I, J, V = [], [], [] + if self.dim == 2: - self._aveE2CC = self.aveF2CC + raise NotImplementedError('aveE2CC not implemented yet') + # PM = [1./(2.*self.dim)]*self.dim # plus / plus + # offset = [0]*2 + [self.ntEx]*2 + + # for ii, ind in enumerate(self._sortedCells): + # p = self._pointer(ind) + # w = self._levelWidth(p[-1]) + + # edges = [ + # self._ex2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + # self._ex2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], + # self._ex2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])], + # self._ex2i[self._index([ p[0] , p[1] + w, p[2] + w, p[3]])], + # self._ey2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + # self._ey2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], + # self._ey2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])], + # self._ey2i[self._index([ p[0] + w, p[1] , p[2] + w, p[3]])], + # self._ez2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + # self._ez2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], + # self._ez2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], + # self._ez2i[self._index([ p[0] + w, p[1] + w, p[2] , p[3]])] + # ] + + # for off, pm, edge in zip(offset,PM,edges): + # I += [ii] + # J += [edge + off] + # V += [pm] + + if self.dim == 3: + PM = [1./(4.*self.dim)]*4*self.dim # plus / plus + offset = [0]*4 + [self.ntEx]*4 + [self.ntEx+self.ntEy]*4 + + for ii, ind in enumerate(self._sortedCells): + p = self._pointer(ind) + w = self._levelWidth(p[-1]) + + edges = [ + self._ex2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._ex2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], + self._ex2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])], + self._ex2i[self._index([ p[0] , p[1] + w, p[2] + w, p[3]])], + self._ey2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._ey2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], + self._ey2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])], + self._ey2i[self._index([ p[0] + w, p[1] , p[2] + w, p[3]])], + self._ez2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._ez2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], + self._ez2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], + self._ez2i[self._index([ p[0] + w, p[1] + w, p[2] , p[3]])] + ] + + for off, pm, edge in zip(offset,PM,edges): + I += [ii] + J += [edge + off] + V += [pm] + + + Av = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.ntE)) + Re = self._deflationMatrix('E',asOnes=False,withHanging=True) + + self._aveE2CC = Av*Re + return self._aveE2CC @property @@ -1335,7 +1400,7 @@ class TreeMesh(BaseMesh, InnerProducts): if getattr(self, '_aveF2CC', None) is None: # TODO: Preallocate! I, J, V = [], [], [] - PM = [1./(2*self.dim)]*2*self.dim # plus / plus + PM = [1./(2.*self.dim)]*2*self.dim # plus / plus # TODO total number of faces? offset = [0]*2 + [self.ntFx]*2 + [self.ntFx+self.ntFy]*2 @@ -1451,7 +1516,7 @@ class TreeMesh(BaseMesh, InnerProducts): Av = sp.csr_matrix((V,(I,J)), shape=(self.nC*self.dim, self.ntF)) Rf = self._deflationMatrix('F',asOnes=True,withHanging=True) - + self._aveF2CCV = Av*Rf return self._aveF2CCV diff --git a/tests/mesh/test_TreeOperators.py b/tests/mesh/test_TreeOperators.py index 75b393b7..6be03d33 100644 --- a/tests/mesh/test_TreeOperators.py +++ b/tests/mesh/test_TreeOperators.py @@ -437,13 +437,13 @@ class TestTreeAveraging2D(Tests.OrderTest): # self.getAve = lambda M: M.aveN2E # self.orderTest() - # def test_orderF2CC(self): - # self.name = "Averaging 2D: F2CC" - # fun = lambda x, y: (np.cos(x)+np.sin(y)) - # self.getHere = lambda M: np.r_[call2(fun, np.r_[M.gridFx, M.gridFy])] - # self.getThere = lambda M: call2(fun, M.gridCC) - # self.getAve = lambda M: M.aveF2CC - # self.orderTest() + def test_orderF2CC(self): + self.name = "Averaging 2D: F2CC" + fun = lambda x, y: (np.cos(x)+np.sin(y)) + self.getHere = lambda M: np.r_[call2(fun, np.r_[M.gridFx, M.gridFy])] + self.getThere = lambda M: call2(fun, M.gridCC) + self.getAve = lambda M: M.aveF2CC + self.orderTest() def test_orderF2CCV(self): self.name = "Averaging 2D: F2CCV" @@ -521,13 +521,13 @@ class TestAveraging3D(Tests.OrderTest): # self.getAve = lambda M: M.aveN2E # self.orderTest() - # def test_orderF2CC(self): - # self.name = "Averaging 3D: F2CC" - # fun = lambda x, y, z: (np.cos(x)+np.sin(y)+np.exp(z)) - # self.getHere = lambda M: np.r_[call3(fun, M.gridFx), call3(fun, M.gridFy), call3(fun, M.gridFz)] - # self.getThere = lambda M: call3(fun, M.gridCC) - # self.getAve = lambda M: M.aveF2CC - # self.orderTest() + def test_orderF2CC(self): + self.name = "Averaging 3D: F2CC" + fun = lambda x, y, z: (np.cos(x)+np.sin(y)+np.exp(z)) + self.getHere = lambda M: np.r_[call3(fun, M.gridFx), call3(fun, M.gridFy), call3(fun, M.gridFz)] + self.getThere = lambda M: call3(fun, M.gridCC) + self.getAve = lambda M: M.aveF2CC + self.orderTest() def test_orderF2CCV(self): self.name = "Averaging 3D: F2CCV" @@ -539,13 +539,13 @@ class TestAveraging3D(Tests.OrderTest): self.getAve = lambda M: M.aveF2CCV self.orderTest() -# def test_orderE2CC(self): -# self.name = "Averaging 3D: E2CC" -# fun = lambda x, y, z: (np.cos(x)+np.sin(y)+np.exp(z)) -# self.getHere = lambda M: np.r_[call3(fun, M.gridEx), call3(fun, M.gridEy), call3(fun, M.gridEz)] -# self.getThere = lambda M: call3(fun, M.gridCC) -# self.getAve = lambda M: M.aveE2CC -# self.orderTest() + def test_orderE2CC(self): + self.name = "Averaging 3D: E2CC" + fun = lambda x, y, z: (np.cos(x)+np.sin(y)+np.exp(z)) + self.getHere = lambda M: np.r_[call3(fun, M.gridEx), call3(fun, M.gridEy), call3(fun, M.gridEz)] + self.getThere = lambda M: call3(fun, M.gridCC) + self.getAve = lambda M: M.aveE2CC + self.orderTest() # def test_orderE2CCV(self): # self.name = "Averaging 3D: E2CCV" From 4fe9475ffcd9270cf795f7e28864d54ba5ee6093 Mon Sep 17 00:00:00 2001 From: Lindsey Heagy Date: Fri, 13 Nov 2015 08:32:01 -0800 Subject: [PATCH 64/83] aveE2CCV for 3D --- SimPEG/Mesh/TreeMesh.py | 84 +++++++++++++++++++++----------- tests/mesh/test_TreeOperators.py | 18 +++---- 2 files changed, 65 insertions(+), 37 deletions(-) diff --git a/SimPEG/Mesh/TreeMesh.py b/SimPEG/Mesh/TreeMesh.py index 02a1e19a..8030a20e 100644 --- a/SimPEG/Mesh/TreeMesh.py +++ b/SimPEG/Mesh/TreeMesh.py @@ -1326,33 +1326,7 @@ class TreeMesh(BaseMesh, InnerProducts): if self.dim == 2: raise NotImplementedError('aveE2CC not implemented yet') - # PM = [1./(2.*self.dim)]*self.dim # plus / plus - # offset = [0]*2 + [self.ntEx]*2 - # for ii, ind in enumerate(self._sortedCells): - # p = self._pointer(ind) - # w = self._levelWidth(p[-1]) - - # edges = [ - # self._ex2i[self._index([ p[0] , p[1] , p[2] , p[3]])], - # self._ex2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], - # self._ex2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])], - # self._ex2i[self._index([ p[0] , p[1] + w, p[2] + w, p[3]])], - # self._ey2i[self._index([ p[0] , p[1] , p[2] , p[3]])], - # self._ey2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], - # self._ey2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])], - # self._ey2i[self._index([ p[0] + w, p[1] , p[2] + w, p[3]])], - # self._ez2i[self._index([ p[0] , p[1] , p[2] , p[3]])], - # self._ez2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], - # self._ez2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], - # self._ez2i[self._index([ p[0] + w, p[1] + w, p[2] , p[3]])] - # ] - - # for off, pm, edge in zip(offset,PM,edges): - # I += [ii] - # J += [edge + off] - # V += [pm] - if self.dim == 3: PM = [1./(4.*self.dim)]*4*self.dim # plus / plus offset = [0]*4 + [self.ntEx]*4 + [self.ntEx+self.ntEy]*4 @@ -1392,7 +1366,61 @@ class TreeMesh(BaseMesh, InnerProducts): @property def aveE2CCV(self): "Construct the averaging operator on cell edges to cell centers." - raise Exception('Not yet implemented!') + # raise Exception('Not yet implemented!') + + I, J, V = [], [], [] + + if self.dim == 2: + raise NotImplementedError('aveE2CC not implemented yet') + + if self.dim == 3: + PM = [1./4.]*4 # plus / plus + offsetx,offsety,offsetz = [0]*4, [self.ntEx]*4 , [self.ntEx+self.ntEy]*4 + + for ii, ind in enumerate(self._sortedCells): + p = self._pointer(ind) + w = self._levelWidth(p[-1]) + + edgesx = [ + self._ex2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._ex2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], + self._ex2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])], + self._ex2i[self._index([ p[0] , p[1] + w, p[2] + w, p[3]])], + ] + edgesy = [ + self._ey2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._ey2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], + self._ey2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])], + self._ey2i[self._index([ p[0] + w, p[1] , p[2] + w, p[3]])], + ] + edgesz = [ + self._ez2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._ez2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], + self._ez2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], + self._ez2i[self._index([ p[0] + w, p[1] + w, p[2] , p[3]])] + ] + + for off, pm, edge in zip(offsetx,PM,edgesx): + I += [ii] + J += [edge + off] + V += [pm] + + for off, pm, edge in zip(offsety,PM,edgesy): + I += [ii + self.nC] + J += [edge + off] + V += [pm] + + for off, pm, edge in zip(offsetz,PM,edgesz): + I += [ii + self.nC*2.] + J += [edge + off] + V += [pm] + + + Av = sp.csr_matrix((V,(I,J)), shape=(self.nC*self.dim, self.ntE)) + Re = self._deflationMatrix('E',asOnes=False,withHanging=True) + + self._aveE2CCV = Av*Re + return self._aveE2CCV @property def aveF2CC(self): @@ -1433,7 +1461,7 @@ class TreeMesh(BaseMesh, InnerProducts): V += [pm] - Av = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.ntF)) + Av = sp.csr_matrix((V,(I,J)), shape=(self.nC*self.dim, self.ntF)) Rf = self._deflationMatrix('F',asOnes=True,withHanging=True) self._aveF2CC = Av*Rf diff --git a/tests/mesh/test_TreeOperators.py b/tests/mesh/test_TreeOperators.py index 6be03d33..7e36b15c 100644 --- a/tests/mesh/test_TreeOperators.py +++ b/tests/mesh/test_TreeOperators.py @@ -547,15 +547,15 @@ class TestAveraging3D(Tests.OrderTest): self.getAve = lambda M: M.aveE2CC self.orderTest() -# def test_orderE2CCV(self): -# self.name = "Averaging 3D: E2CCV" -# funX = lambda x, y, z: (np.cos(x)+np.sin(y)+np.exp(z)) -# funY = lambda x, y, z: (np.cos(x)+np.sin(y)*np.exp(z)) -# funZ = lambda x, y, z: (np.cos(x)*np.sin(y)+np.exp(z)) -# self.getHere = lambda M: np.r_[call3(funX, M.gridEx), call3(funY, M.gridEy), call3(funZ, M.gridEz)] -# self.getThere = lambda M: np.r_[call3(funX, M.gridCC), call3(funY, M.gridCC), call3(funZ, M.gridCC)] -# self.getAve = lambda M: M.aveE2CCV -# self.orderTest() + def test_orderE2CCV(self): + self.name = "Averaging 3D: E2CCV" + funX = lambda x, y, z: (np.cos(x)+np.sin(y)+np.exp(z)) + funY = lambda x, y, z: (np.cos(x)+np.sin(y)*np.exp(z)) + funZ = lambda x, y, z: (np.cos(x)*np.sin(y)+np.exp(z)) + self.getHere = lambda M: np.r_[call3(funX, M.gridEx), call3(funY, M.gridEy), call3(funZ, M.gridEz)] + self.getThere = lambda M: np.r_[call3(funX, M.gridCC), call3(funY, M.gridCC), call3(funZ, M.gridCC)] + self.getAve = lambda M: M.aveE2CCV + self.orderTest() # def test_orderCC2F(self): # self.name = "Averaging 3D: CC2F" From d7bcc0c0748590c312ba2f787d7031bef6652d0a Mon Sep 17 00:00:00 2001 From: Lindsey Heagy Date: Sun, 15 Nov 2015 00:08:26 -0800 Subject: [PATCH 65/83] broke up averaging so that we have averaging for components as well --- SimPEG/Mesh/TreeMesh.py | 399 +++++++++++++++++-------------- tests/mesh/test_TreeOperators.py | 83 +++++-- 2 files changed, 291 insertions(+), 191 deletions(-) diff --git a/SimPEG/Mesh/TreeMesh.py b/SimPEG/Mesh/TreeMesh.py index 8030a20e..59adaa3a 100644 --- a/SimPEG/Mesh/TreeMesh.py +++ b/SimPEG/Mesh/TreeMesh.py @@ -1316,236 +1316,289 @@ class TreeMesh(BaseMesh, InnerProducts): # self._nodalGrad = Utils.sdiag(1/L)*G # return self._nodalGrad - @property - def aveE2CC(self): - "Construct the averaging operator on cell edges to cell centers." - if getattr(self, '_aveE2CC', None) is None: + # @property + # def aveE2CC(self): + # "Construct the averaging operator on cell edges to cell centers." + # if getattr(self, '_aveE2CC', None) is None: - # TODO: preallocate + # # TODO: preallocate + # I, J, V = [], [], [] + + # if self.dim == 2: + # raise NotImplementedError('aveE2CC not implemented yet') + + # if self.dim == 3: + # PM = [1./(4.*self.dim)]*4*self.dim # plus / plus + # offset = [0]*4 + [self.ntEx]*4 + [self.ntEx+self.ntEy]*4 + + # for ii, ind in enumerate(self._sortedCells): + # p = self._pointer(ind) + # w = self._levelWidth(p[-1]) + + # edges = [ + # self._ex2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + # self._ex2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], + # self._ex2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])], + # self._ex2i[self._index([ p[0] , p[1] + w, p[2] + w, p[3]])], + # self._ey2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + # self._ey2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], + # self._ey2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])], + # self._ey2i[self._index([ p[0] + w, p[1] , p[2] + w, p[3]])], + # self._ez2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + # self._ez2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], + # self._ez2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], + # self._ez2i[self._index([ p[0] + w, p[1] + w, p[2] , p[3]])] + # ] + + # for off, pm, edge in zip(offset,PM,edges): + # I += [ii] + # J += [edge + off] + # V += [pm] + + + # Av = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.ntE)) + # Re = self._deflationMatrix('E',asOnes=False,withHanging=True) + + # self._aveE2CC = Av*Re + + # return self._aveE2CC + + @property + def aveEx2CC(self): + if getattr(self, '_aveEx2CC', None) is None: I, J, V = [], [], [] if self.dim == 2: - raise NotImplementedError('aveE2CC not implemented yet') + raise Exception('aveEx2CC not implemented in 2D') if self.dim == 3: - PM = [1./(4.*self.dim)]*4*self.dim # plus / plus - offset = [0]*4 + [self.ntEx]*4 + [self.ntEx+self.ntEy]*4 + PM = [1./4.]*4 for ii, ind in enumerate(self._sortedCells): p = self._pointer(ind) w = self._levelWidth(p[-1]) - edges = [ + edgesx = [ self._ex2i[self._index([ p[0] , p[1] , p[2] , p[3]])], self._ex2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], self._ex2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])], self._ex2i[self._index([ p[0] , p[1] + w, p[2] + w, p[3]])], + ] + + for pm, edge in zip(PM,edgesx): + I += [ii] + J += [edge] + V += [pm] + + Av = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.ntEx)) + Re = self._deflationMatrix('Ex',asOnes=False,withHanging=True) + + self._aveEx2CC = Av*Re + return self._aveEx2CC + + @property + def aveEy2CC(self): + "Construct the averaging operator on cell edges to cell centers." + if getattr(self, '_aveEy2CC', None) is None: + I, J, V = [], [], [] + + if self.dim == 2: + raise NotImplementedError('aveEy2CC not implemented in 2D') + + if self.dim == 3: + PM = [1./4.]*4 # plus / plus + + for ii, ind in enumerate(self._sortedCells): + p = self._pointer(ind) + w = self._levelWidth(p[-1]) + + edgesy = [ self._ey2i[self._index([ p[0] , p[1] , p[2] , p[3]])], self._ey2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], self._ey2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])], self._ey2i[self._index([ p[0] + w, p[1] , p[2] + w, p[3]])], + ] + + for pm, edge in zip(PM,edgesy): + I += [ii] + J += [edge] + V += [pm] + + Av = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.ntEy)) + Re = self._deflationMatrix('Ey',asOnes=False,withHanging=True) + + self._aveEy2CC = Av*Re + return self._aveEy2CC + + @property + def aveEz2CC(self): + "Construct the averaging operator on cell edges to cell centers." + # raise Exception('Not yet implemented!') + if getattr(self, '_aveEz2CC', None) is None: + I, J, V = [], [], [] + + if self.dim == 2: + raise Exception('There are no z edges in 2D') + + if self.dim == 3: + PM = [1./4.]*4 # plus / plus + + for ii, ind in enumerate(self._sortedCells): + p = self._pointer(ind) + w = self._levelWidth(p[-1]) + + edgesz = [ self._ez2i[self._index([ p[0] , p[1] , p[2] , p[3]])], self._ez2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], self._ez2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], - self._ez2i[self._index([ p[0] + w, p[1] + w, p[2] , p[3]])] + self._ez2i[self._index([ p[0] + w, p[1] + w, p[2] , p[3]])], ] - for off, pm, edge in zip(offset,PM,edges): + for pm, edge in zip(PM,edgesz): I += [ii] - J += [edge + off] + J += [edge] V += [pm] - Av = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.ntE)) - Re = self._deflationMatrix('E',asOnes=False,withHanging=True) + Av = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.ntEz)) + Re = self._deflationMatrix('Ez',asOnes=False,withHanging=True) - self._aveE2CC = Av*Re + self._aveEz2CC = Av*Re + return self._aveEz2CC + + @property + def aveE2CC(self): + "Construct the averaging operator on cell edges to cell centers." + if getattr(self, '_aveE2CC', None) is None: + if self.dim == 2: + raise Exception('aveE2CC not implemented in 2D') + elif self.dim == 3: + self._aveE2CC = 1./self.dim*sp.hstack([self.aveEx2CC, self.aveEy2CC, self.aveEz2CC]) return self._aveE2CC @property def aveE2CCV(self): "Construct the averaging operator on cell edges to cell centers." # raise Exception('Not yet implemented!') + if getattr(self, '_aveE2CCV', None) is None: + if self.dim == 2: + raise Exception('aveE2CC not implemented in 2D') + elif self.dim == 3: + self._aveE2CCV = sp.block_diag([self.aveEx2CC, self.aveEy2CC, self.aveEz2CC]) + return self._aveE2CCV - I, J, V = [], [], [] - - if self.dim == 2: - raise NotImplementedError('aveE2CC not implemented yet') + @property + def aveFx2CC(self): + if getattr(self, '_aveFx2CC', None) is None: + I, J, V = [], [], [] + PM = [1./2.]*self.dim # 0.5, 0.5 + + for ii, ind in enumerate(self._sortedCells): + p = self._pointer(ind) + w = self._levelWidth(p[-1]) - if self.dim == 3: - PM = [1./4.]*4 # plus / plus - offsetx,offsety,offsetz = [0]*4, [self.ntEx]*4 , [self.ntEx+self.ntEy]*4 + if self.dim == 2: + facesx = [ + self._fx2i[self._index([ p[0] , p[1] , p[2]])], + self._fx2i[self._index([ p[0] + w, p[1] , p[2]])], + ] + + elif self.dim == 3: + facesx = [ + self._fx2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._fx2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], + ] + + for pm, face in zip(PM,facesx): + I += [ii] + J += [face] + V += [pm] + + Av = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.ntFx)) + Rf = self._deflationMatrix('Fx',asOnes=True,withHanging=True) + + self._aveFx2CC = Av*Rf + return self._aveFx2CC + + @property + def aveFy2CC(self): + if getattr(self, '_aveFy2CC', None) is None: + I, J, V = [], [], [] + PM = [1./2.]*2 # 0.5, 0.5 + + for ii, ind in enumerate(self._sortedCells): + p = self._pointer(ind) + w = self._levelWidth(p[-1]) + + if self.dim == 2: + facesy = [ + self._fy2i[self._index([ p[0] , p[1] , p[2]])], + self._fy2i[self._index([ p[0] , p[1] + w, p[2]])], + ] + elif self.dim == 3: + facesy = [ + self._fy2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._fy2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], + ] + + for pm, face in zip(PM,facesy): + I += [ii] + J += [face] + V += [pm] + + Av = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.ntFy)) + Rf = self._deflationMatrix('Fy',asOnes=True,withHanging=True) + + self._aveFy2CC = Av*Rf + return self._aveFy2CC + + @property + def aveFz2CC(self): + if getattr(self, '_aveFz2CC', None) is None: + I, J, V = [], [], [] + PM = [1./2.]*2 # 0.5, 0.5 for ii, ind in enumerate(self._sortedCells): p = self._pointer(ind) w = self._levelWidth(p[-1]) - edgesx = [ - self._ex2i[self._index([ p[0] , p[1] , p[2] , p[3]])], - self._ex2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], - self._ex2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])], - self._ex2i[self._index([ p[0] , p[1] + w, p[2] + w, p[3]])], - ] - edgesy = [ - self._ey2i[self._index([ p[0] , p[1] , p[2] , p[3]])], - self._ey2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], - self._ey2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])], - self._ey2i[self._index([ p[0] + w, p[1] , p[2] + w, p[3]])], - ] - edgesz = [ - self._ez2i[self._index([ p[0] , p[1] , p[2] , p[3]])], - self._ez2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], - self._ez2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], - self._ez2i[self._index([ p[0] + w, p[1] + w, p[2] , p[3]])] - ] + if self.dim == 2: + raise Exception('There are no z-faces in 2D') + elif self.dim == 3: + facesz = [ + self._fz2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._fz2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])], + ] - for off, pm, edge in zip(offsetx,PM,edgesx): + for pm, face in zip(PM,facesz): I += [ii] - J += [edge + off] + J += [face] V += [pm] - - for off, pm, edge in zip(offsety,PM,edgesy): - I += [ii + self.nC] - J += [edge + off] - V += [pm] - - for off, pm, edge in zip(offsetz,PM,edgesz): - I += [ii + self.nC*2.] - J += [edge + off] - V += [pm] - - - Av = sp.csr_matrix((V,(I,J)), shape=(self.nC*self.dim, self.ntE)) - Re = self._deflationMatrix('E',asOnes=False,withHanging=True) - - self._aveE2CCV = Av*Re - return self._aveE2CCV + + Av = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.ntFz)) + Rf = self._deflationMatrix('Fz',asOnes=True,withHanging=True) + self._aveFz2CC = Av*Rf + return self._aveFz2CC @property def aveF2CC(self): "Construct the averaging operator on cell faces to cell centers." if getattr(self, '_aveF2CC', None) is None: - # TODO: Preallocate! - I, J, V = [], [], [] - PM = [1./(2.*self.dim)]*2*self.dim # plus / plus - - # TODO total number of faces? - offset = [0]*2 + [self.ntFx]*2 + [self.ntFx+self.ntFy]*2 - - for ii, ind in enumerate(self._sortedCells): - - p = self._pointer(ind) - w = self._levelWidth(p[-1]) - - if self.dim == 2: - faces = [ - self._fx2i[self._index([ p[0] , p[1] , p[2]])], - self._fx2i[self._index([ p[0] + w, p[1] , p[2]])], - self._fy2i[self._index([ p[0] , p[1] , p[2]])], - self._fy2i[self._index([ p[0] , p[1] + w, p[2]])] - ] - elif self.dim == 3: - faces = [ - self._fx2i[self._index([ p[0] , p[1] , p[2] , p[3]])], - self._fx2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], - self._fy2i[self._index([ p[0] , p[1] , p[2] , p[3]])], - self._fy2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], - self._fz2i[self._index([ p[0] , p[1] , p[2] , p[3]])], - self._fz2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])] - ] - - for off, pm, face in zip(offset,PM,faces): - I += [ii] - J += [face + off] - V += [pm] - - - Av = sp.csr_matrix((V,(I,J)), shape=(self.nC*self.dim, self.ntF)) - Rf = self._deflationMatrix('F',asOnes=True,withHanging=True) - - self._aveF2CC = Av*Rf + if self.dim == 2: + self._aveF2CC = 1./self.dim*sp.hstack([self.aveFx2CC, self.aveFy2CC]) + elif self.dim == 3: + self._aveF2CC = 1./self.dim*sp.hstack([self.aveFx2CC, self.aveFy2CC, self.aveFz2CC]) return self._aveF2CC - @property def aveF2CCV(self): "Construct the averaging operator on cell faces to cell centers." if getattr(self, '_aveF2CCV', None) is None: - # TODO: Preallocate! - I, J, V = [], [], [] - PM = [1./2.]*2 # 0.5, 0.5 - - offsetx = [0]*2 - offsety = [self.ntFx]*2 - - if self.dim == 2: - for ii, ind in enumerate(self._sortedCells): - p = self._pointer(ind) - w = self._levelWidth(p[-1]) - - facesx = [ - self._fx2i[self._index([ p[0] , p[1] , p[2]])], - self._fx2i[self._index([ p[0] + w, p[1] , p[2]])], - ] - - facesy = [ - self._fy2i[self._index([ p[0] , p[1] , p[2]])], - self._fy2i[self._index([ p[0] , p[1] + w, p[2]])], - ] - - for off, pm, face in zip(offsetx,PM,facesx): - I += [ii] - J += [face + off] - V += [pm] - - for off, pm, face in zip(offsety,PM,facesy): - I += [ii + self.nC] - J += [face + off] - V += [pm] - - - - if self.dim == 3: - offsetz = [self.ntFx + self.ntFy]*2 - - for ii, ind in enumerate(self._sortedCells): - p = self._pointer(ind) - w = self._levelWidth(p[-1]) - - facesx = [ - self._fx2i[self._index([ p[0] , p[1] , p[2] , p[3]])], - self._fx2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], - ] - - facesy = [ - self._fy2i[self._index([ p[0] , p[1] , p[2] , p[3]])], - self._fy2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], - ] - facesz = [ - self._fz2i[self._index([ p[0] , p[1] , p[2] , p[3]])], - self._fz2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])] - ] - - for off, pm, face in zip(offsetx,PM,facesx): - I += [ii] - J += [face + off] - V += [pm] - - for off, pm, face in zip(offsety,PM,facesy): - I += [ii + self.nC] - J += [face + off] - V += [pm] - - for off, pm, face in zip(offsetz,PM,facesz): - I += [ii + self.nC*2] - J += [face + off] - V += [pm] - - Av = sp.csr_matrix((V,(I,J)), shape=(self.nC*self.dim, self.ntF)) - Rf = self._deflationMatrix('F',asOnes=True,withHanging=True) - - self._aveF2CCV = Av*Rf + if self.dim == 2: + self._aveF2CCV = sp.block_diag([self.aveFx2CC, self.aveFy2CC]) + elif self.dim == 3: + self._aveF2CCV = sp.block_diag([self.aveFx2CC, self.aveFy2CC, self.aveFz2CC]) return self._aveF2CCV diff --git a/tests/mesh/test_TreeOperators.py b/tests/mesh/test_TreeOperators.py index 7e36b15c..a5eb1358 100644 --- a/tests/mesh/test_TreeOperators.py +++ b/tests/mesh/test_TreeOperators.py @@ -445,6 +445,22 @@ class TestTreeAveraging2D(Tests.OrderTest): self.getAve = lambda M: M.aveF2CC self.orderTest() + def test_orderFx2CC(self): + self.name = "Averaging 2D: Fx2CC" + funX = lambda x, y: (np.cos(x)+np.sin(y)) + self.getHere = lambda M: np.r_[call2(funX, M.gridFx)] + self.getThere = lambda M: np.r_[call2(funX, M.gridCC)] + self.getAve = lambda M: M.aveFx2CC + self.orderTest() + + def test_orderFy2CC(self): + self.name = "Averaging 2D: Fy2CC" + funY = lambda x, y: (np.cos(y)*np.sin(x)) + self.getHere = lambda M: np.r_[call2(funY, M.gridFy)] + self.getThere = lambda M: np.r_[call2(funY, M.gridCC)] + self.getAve = lambda M: M.aveFy2CC + self.orderTest() + def test_orderF2CCV(self): self.name = "Averaging 2D: F2CCV" funX = lambda x, y: (np.cos(x)+np.sin(y)) @@ -464,28 +480,11 @@ class TestTreeAveraging2D(Tests.OrderTest): # self.orderTest() # self.expectedOrders = 2 - # def test_orderE2CC(self): - # self.name = "Averaging 2D: E2CC" - # fun = lambda x, y: (np.cos(x)+np.sin(y)) - # self.getHere = lambda M: np.r_[call2(fun, np.r_[M.gridEx, M.gridEy])] - # self.getThere = lambda M: call2(fun, M.gridCC) - # self.getAve = lambda M: M.aveE2CC - # self.orderTest() - - # def test_orderE2CCV(self): - # self.name = "Averaging 2D: E2CCV" - # funX = lambda x, y: (np.cos(x)+np.sin(y)) - # funY = lambda x, y: (np.cos(y)*np.sin(x)) - # self.getHere = lambda M: np.r_[call2(funX, M.gridEx), call2(funY, M.gridEy)] - # self.getThere = lambda M: np.r_[call2(funX, M.gridCC), call2(funY, M.gridCC)] - # self.getAve = lambda M: M.aveE2CCV - # self.orderTest() - class TestAveraging3D(Tests.OrderTest): name = "Averaging 3D" meshTypes = ['notatreeTree', 'uniformTree']#, 'randomTree'] meshDimension = 3 - meshSizes = [8,16,32] + meshSizes = [8,16] expectedOrders = [2,1] def getError(self): @@ -529,6 +528,30 @@ class TestAveraging3D(Tests.OrderTest): self.getAve = lambda M: M.aveF2CC self.orderTest() + def test_orderFx2CC(self): + self.name = "Averaging 3D: Fx2CC" + funX = lambda x, y, z: (np.cos(x)+np.sin(y)+np.exp(z)) + self.getHere = lambda M: np.r_[call3(funX, M.gridFx)] + self.getThere = lambda M: np.r_[call3(funX, M.gridCC)] + self.getAve = lambda M: M.aveFx2CC + self.orderTest() + + def test_orderFy2CC(self): + self.name = "Averaging 3D: Fy2CC" + funY = lambda x, y, z: (np.cos(x)+np.sin(y)*np.exp(z)) + self.getHere = lambda M: np.r_[call3(funY, M.gridFy)] + self.getThere = lambda M: np.r_[call3(funY, M.gridCC)] + self.getAve = lambda M: M.aveFy2CC + self.orderTest() + + def test_orderFz2CC(self): + self.name = "Averaging 3D: Fz2CC" + funZ = lambda x, y, z: (np.cos(x)+np.sin(y)*np.exp(z)) + self.getHere = lambda M: np.r_[call3(funZ, M.gridFz)] + self.getThere = lambda M: np.r_[call3(funZ, M.gridCC)] + self.getAve = lambda M: M.aveFz2CC + self.orderTest() + def test_orderF2CCV(self): self.name = "Averaging 3D: F2CCV" funX = lambda x, y, z: (np.cos(x)+np.sin(y)+np.exp(z)) @@ -539,6 +562,30 @@ class TestAveraging3D(Tests.OrderTest): self.getAve = lambda M: M.aveF2CCV self.orderTest() + def test_orderEx2CC(self): + self.name = "Averaging 3D: Ex2CC" + funX = lambda x, y, z: (np.cos(x)+np.sin(y)+np.exp(z)) + self.getHere = lambda M: np.r_[call3(funX, M.gridEx)] + self.getThere = lambda M: np.r_[call3(funX, M.gridCC)] + self.getAve = lambda M: M.aveEx2CC + self.orderTest() + + def test_orderEy2CC(self): + self.name = "Averaging 3D: Ey2CC" + funY = lambda x, y, z: (np.cos(x)+np.sin(y)+np.exp(z)) + self.getHere = lambda M: np.r_[call3(funY, M.gridEy)] + self.getThere = lambda M: np.r_[call3(funY, M.gridCC)] + self.getAve = lambda M: M.aveEy2CC + self.orderTest() + + def test_orderEz2CC(self): + self.name = "Averaging 3D: Ez2CC" + funZ = lambda x, y, z: (np.cos(x)+np.sin(y)+np.exp(z)) + self.getHere = lambda M: np.r_[call3(funZ, M.gridEz)] + self.getThere = lambda M: np.r_[call3(funZ, M.gridCC)] + self.getAve = lambda M: M.aveEz2CC + self.orderTest() + def test_orderE2CC(self): self.name = "Averaging 3D: E2CC" fun = lambda x, y, z: (np.cos(x)+np.sin(y)+np.exp(z)) From 5e20960335eedc7435a6093f0bb9db75f7a30d4d Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Sun, 15 Nov 2015 17:38:26 -0800 Subject: [PATCH 66/83] 50% speed up in refinement --- SimPEG/Mesh/BaseMesh.py | 3 +- SimPEG/Mesh/TreeMesh.py | 871 ++++++++++++++++++++-------------------- SimPEG/Tests.py | 4 +- 3 files changed, 444 insertions(+), 434 deletions(-) diff --git a/SimPEG/Mesh/BaseMesh.py b/SimPEG/Mesh/BaseMesh.py index 78fe4140..14b3aecf 100644 --- a/SimPEG/Mesh/BaseMesh.py +++ b/SimPEG/Mesh/BaseMesh.py @@ -27,6 +27,7 @@ class BaseMesh(object): # Ensure x0 & n are 1D vectors self._n = np.array(n, dtype=int).ravel() self._x0 = np.array(x0, dtype=float).ravel() + self._dim = len(self._x0) @property def x0(self): @@ -46,7 +47,7 @@ class BaseMesh(object): :rtype: int :return: dim """ - return len(self._n) + return self._dim @property def nC(self): diff --git a/SimPEG/Mesh/TreeMesh.py b/SimPEG/Mesh/TreeMesh.py index 59adaa3a..bce31344 100644 --- a/SimPEG/Mesh/TreeMesh.py +++ b/SimPEG/Mesh/TreeMesh.py @@ -103,6 +103,44 @@ import time MAX_BITS = 20 +class Cell(object): + def __init__(self, mesh, index, pointer): + self.mesh = mesh + self._index = index + self._pointer = pointer + + # @property + # def nodes(self): + # REFACTOR WITH self.x0 and self.h, mesh is not currently numbered!! + # p = self._pointer + # w = self.mesh._levelWidth(p[-1]) + # if self.dim == 2: + # return [self._n2i[self.mesh._index([p[0] , p[1] , p[2]])], + # self._n2i[self.mesh._index([p[0] + w, p[1] , p[2]])], + # self._n2i[self.mesh._index([p[0] , p[1] + w, p[2]])], + # self._n2i[self.mesh._index([p[0] + w, p[1] + w, p[2]])]] + # elif self.dim == 3: + # return [self._n2i[self.mesh._index([p[0] , p[1] , p[2] , p[3]])], + # self._n2i[self.mesh._index([p[0] + w, p[1] , p[2] , p[3]])], + # self._n2i[self.mesh._index([p[0] , p[1] + w, p[2] , p[3]])], + # self._n2i[self.mesh._index([p[0] + w, p[1] + w, p[2] , p[3]])], + # self._n2i[self.mesh._index([p[0] , p[1] , p[2] + w, p[3]])], + # self._n2i[self.mesh._index([p[0] + w, p[1] , p[2] + w, p[3]])], + # self._n2i[self.mesh._index([p[0] , p[1] + w, p[2] + w, p[3]])], + # self._n2i[self.mesh._index([p[0] + w, p[1] + w, p[2] + w, p[3]])]] + + @property + def center(self): + if getattr(self, '_center', None) is None: + self._center = self.mesh._cellC(self._pointer) + return self._center + @property + def h(self): return self.mesh._cellH(self._pointer) + @property + def x0(self): return self.mesh._cellN(self._pointer) + @property + def dim(self): return self.mesh.dim + class TreeMesh(BaseMesh, InnerProducts): def __init__(self, h_in, x0_in=None, levels=3): assert type(h_in) is list, 'h_in must be a list' @@ -149,7 +187,7 @@ class TreeMesh(BaseMesh, InnerProducts): @property def __dirty__(self): - return self.__dirtyFaces__ or self.__dirtyEdges__ or self.__dirtyNodes__ or self.__dirtyHanging__ + return self.__dirtyFaces__ or self.__dirtyEdges__ or self.__dirtyNodes__ or self.__dirtyHanging__ or self.__dirtySets__ @__dirty__.setter def __dirty__(self, val): @@ -158,6 +196,7 @@ class TreeMesh(BaseMesh, InnerProducts): self.__dirtyEdges__ = True self.__dirtyNodes__ = True self.__dirtyHanging__ = True + self.__dirtySets__ = True deleteThese = [ '__sortedCells', @@ -172,9 +211,6 @@ class TreeMesh(BaseMesh, InnerProducts): @property def levels(self): return self._levels - @property - def dim(self): return len(self.h) - @property def nC(self): return len(self._cells) @@ -377,7 +413,8 @@ class TreeMesh(BaseMesh, InnerProducts): tic = time.time() for cell in cells: p = self._pointer(cell) - do = function(self._cellC(cell)) > p[-1] + if p[-1] >= self.levels: continue + do = function(Cell(self, cell, p)) > p[-1] if do: recurse += self._refineCell(cell) @@ -679,28 +716,89 @@ class TreeMesh(BaseMesh, InnerProducts): p1 = self._asPointer(i1) return p0[-1] == p1[-1] - def _numberNodes(self, force=False): - if not self.__dirtyNodes__ and not force: return + def _createNumberingSets(self, force=False): + if not self.__dirtySets__ and not force: return self._nodes = set() + self._facesX = set() + self._facesY = set() + if self.dim == 3: + self._facesZ = set() + self._edgesX = set() + self._edgesY = set() + self._edgesZ = set() + + for ind in self._cells: p = self._asPointer(ind) w = self._levelWidth(p[-1]) if self.dim == 2: - self._nodes.add(self._index([p[0] , p[1] , p[2]])) - self._nodes.add(self._index([p[0] + w, p[1] , p[2]])) - self._nodes.add(self._index([p[0] , p[1] + w, p[2]])) - self._nodes.add(self._index([p[0] + w, p[1] + w, p[2]])) + i00 = ind + iw0 = self._index([p[0] + w, p[1] , p[2]]) + i0w = self._index([p[0] , p[1] + w, p[2]]) + iww = self._index([p[0] + w, p[1] + w, p[2]]) + + self._nodes.add(i00) + self._nodes.add(iw0) + self._nodes.add(i0w) + self._nodes.add(iww) + + self._facesX.add(i00) + self._facesX.add(iw0) + + self._facesY.add(i00) + self._facesY.add(i0w) + + elif self.dim == 3: - self._nodes.add(self._index([p[0] , p[1] , p[2] , p[3]])) - self._nodes.add(self._index([p[0] + w, p[1] , p[2] , p[3]])) - self._nodes.add(self._index([p[0] , p[1] + w, p[2] , p[3]])) - self._nodes.add(self._index([p[0] + w, p[1] + w, p[2] , p[3]])) - self._nodes.add(self._index([p[0] , p[1] , p[2] + w, p[3]])) - self._nodes.add(self._index([p[0] + w, p[1] , p[2] + w, p[3]])) - self._nodes.add(self._index([p[0] , p[1] + w, p[2] + w, p[3]])) - self._nodes.add(self._index([p[0] + w, p[1] + w, p[2] + w, p[3]])) + i000 = ind + iw00 = self._index([p[0] + w, p[1] , p[2] , p[3]]) + i0w0 = self._index([p[0] , p[1] + w, p[2] , p[3]]) + i00w = self._index([p[0] , p[1] , p[2] + w, p[3]]) + iww0 = self._index([p[0] + w, p[1] + w, p[2] , p[3]]) + iw0w = self._index([p[0] + w, p[1] , p[2] + w, p[3]]) + i0ww = self._index([p[0] , p[1] + w, p[2] + w, p[3]]) + iwww = self._index([p[0] + w, p[1] + w, p[2] + w, p[3]]) + + self._nodes.add(i000) + self._nodes.add(iw00) + self._nodes.add(i0w0) + self._nodes.add(iww0) + self._nodes.add(i00w) + self._nodes.add(iw0w) + self._nodes.add(i0ww) + self._nodes.add(iwww) + + self._facesX.add(i000) + self._facesX.add(iw00) + + self._facesY.add(i000) + self._facesY.add(i0w0) + + self._facesZ.add(i000) + self._facesZ.add(i00w) + + self._edgesX.add(i000) + self._edgesX.add(i0w0) + self._edgesX.add(i00w) + self._edgesX.add(i0ww) + + self._edgesY.add(i000) + self._edgesY.add(iw00) + self._edgesY.add(i00w) + self._edgesY.add(iw0w) + + self._edgesZ.add(i000) + self._edgesZ.add(iw00) + self._edgesZ.add(i0w0) + self._edgesZ.add(iww0) + + self.__dirtySets__ = False + + def _numberNodes(self, force=False): + if not self.__dirtyNodes__ and not force: return + self._createNumberingSets(force=force) gridN = [] self._n2i = dict() for ii, n in enumerate(sorted(self._nodes)): @@ -712,29 +810,12 @@ class TreeMesh(BaseMesh, InnerProducts): def _numberFaces(self, force=False): if not self.__dirtyFaces__ and not force: return - - self._facesX = set() - self._facesY = set() - if self.dim == 3: - self._facesZ = set() + self._createNumberingSets(force=force) for ind in self._cells: p = self._asPointer(ind) w = self._levelWidth(p[-1]) - if self.dim == 2: - self._facesX.add(self._index([p[0] , p[1] , p[2]])) - self._facesX.add(self._index([p[0] + w, p[1] , p[2]])) - self._facesY.add(self._index([p[0] , p[1] , p[2]])) - self._facesY.add(self._index([p[0] , p[1] + w, p[2]])) - elif self.dim == 3: - self._facesX.add(self._index([p[0] , p[1] , p[2] , p[3]])) - self._facesX.add(self._index([p[0] + w, p[1] , p[2] , p[3]])) - self._facesY.add(self._index([p[0] , p[1] , p[2] , p[3]])) - self._facesY.add(self._index([p[0] , p[1] + w, p[2] , p[3]])) - self._facesZ.add(self._index([p[0] , p[1] , p[2] , p[3]])) - self._facesZ.add(self._index([p[0] , p[1] , p[2] + w, p[3]])) - gridFx = [] areaFx = [] self._fx2i = dict() @@ -790,28 +871,7 @@ class TreeMesh(BaseMesh, InnerProducts): self.__dirtyEdges__ = False return if not self.__dirtyEdges__ and not force: return - - self._edgesX = set() - self._edgesY = set() - self._edgesZ = set() - - for ind in self._cells: - p = self._asPointer(ind) - w = self._levelWidth(p[-1]) - self._edgesX.add(self._index([p[0] , p[1] , p[2] , p[3]])) - self._edgesX.add(self._index([p[0] , p[1] + w, p[2] , p[3]])) - self._edgesX.add(self._index([p[0] , p[1] , p[2] + w, p[3]])) - self._edgesX.add(self._index([p[0] , p[1] + w, p[2] + w, p[3]])) - - self._edgesY.add(self._index([p[0] , p[1] , p[2] , p[3]])) - self._edgesY.add(self._index([p[0] + w, p[1] , p[2] , p[3]])) - self._edgesY.add(self._index([p[0] , p[1] , p[2] + w, p[3]])) - self._edgesY.add(self._index([p[0] + w, p[1] , p[2] + w, p[3]])) - - self._edgesZ.add(self._index([p[0] , p[1] , p[2] , p[3]])) - self._edgesZ.add(self._index([p[0] + w, p[1] , p[2] , p[3]])) - self._edgesZ.add(self._index([p[0] , p[1] + w, p[2] , p[3]])) - self._edgesZ.add(self._index([p[0] + w, p[1] + w, p[2] , p[3]])) + self._createNumberingSets(force=force) gridEx = [] edgeEx = [] @@ -911,48 +971,58 @@ class TreeMesh(BaseMesh, InnerProducts): n2 = self._index([p[0], p[1] , p[2] + 2*w, p[-1]]) n3 = self._index([p[0], p[1] + 2*w, p[2] + 2*w, p[-1]]) - self._hangingFx[self._fx2i[test ]] = ([self._fx2i[fx], chy0*chz0 / A ], ) - self._hangingFx[self._fx2i[self._index([p[0], p[1] + w, p[2] , sl])]] = ([self._fx2i[fx], chy1*chz0 / A ], ) - self._hangingFx[self._fx2i[self._index([p[0], p[1] , p[2] + w, sl])]] = ([self._fx2i[fx], chy0*chz1 / A ], ) - self._hangingFx[self._fx2i[self._index([p[0], p[1] + w, p[2] + w, sl])]] = ([self._fx2i[fx], chy1*chz1 / A ], ) + i000 = test + i010 = self._index([p[0], p[1] + w, p[2] , sl]) + i001 = self._index([p[0], p[1] , p[2] + w, sl]) + i011 = self._index([p[0], p[1] + w, p[2] + w, sl]) + i020 = self._index([p[0], p[1] + 2*w, p[2] , sl]) + i021 = self._index([p[0], p[1] + 2*w, p[2] + w, sl]) + i002 = self._index([p[0], p[1] , p[2] + 2*w, sl]) + i012 = self._index([p[0], p[1] + w, p[2] + 2*w, sl]) + i022 = self._index([p[0], p[1] + 2*w, p[2] + 2*w, sl]) - self._hangingEy[self._ey2i[test ]] = ([self._ey2i[ey0], 1.0], ) - self._hangingEy[self._ey2i[self._index([p[0], p[1] + w, p[2] , sl])]] = ([self._ey2i[ey0], 1.0], ) - self._hangingEy[self._ey2i[self._index([p[0], p[1] , p[2] + w, sl])]] = ([self._ey2i[ey0], 0.5], [self._ey2i[ey1], 0.5]) - self._hangingEy[self._ey2i[self._index([p[0], p[1] + w, p[2] + w, sl])]] = ([self._ey2i[ey0], 0.5], [self._ey2i[ey1], 0.5]) - self._hangingEy[self._ey2i[self._index([p[0], p[1] , p[2] + 2*w, sl])]] = ([self._ey2i[ey1], 1.0], ) - self._hangingEy[self._ey2i[self._index([p[0], p[1] + w, p[2] + 2*w, sl])]] = ([self._ey2i[ey1], 1.0], ) + self._hangingFx[self._fx2i[i000]] = ([self._fx2i[fx], chy0*chz0 / A ], ) + self._hangingFx[self._fx2i[i010]] = ([self._fx2i[fx], chy1*chz0 / A ], ) + self._hangingFx[self._fx2i[i001]] = ([self._fx2i[fx], chy0*chz1 / A ], ) + self._hangingFx[self._fx2i[i011]] = ([self._fx2i[fx], chy1*chz1 / A ], ) - self._hangingEz[self._ez2i[test ]] = ([self._ez2i[ez0], 1.0], ) - self._hangingEz[self._ez2i[self._index([p[0], p[1] , p[2] + w, sl])]] = ([self._ez2i[ez0], 1.0], ) - self._hangingEz[self._ez2i[self._index([p[0], p[1] + w, p[2] , sl])]] = ([self._ez2i[ez0], 0.5], [self._ez2i[ez1], 0.5]) - self._hangingEz[self._ez2i[self._index([p[0], p[1] + w, p[2] + w, sl])]] = ([self._ez2i[ez0], 0.5], [self._ez2i[ez1], 0.5]) - self._hangingEz[self._ez2i[self._index([p[0], p[1] + 2*w, p[2] , sl])]] = ([self._ez2i[ez1], 1.0], ) - self._hangingEz[self._ez2i[self._index([p[0], p[1] + 2*w, p[2] + w, sl])]] = ([self._ez2i[ez1], 1.0], ) + self._hangingEy[self._ey2i[i000]] = ([self._ey2i[ey0], 1.0], ) + self._hangingEy[self._ey2i[i010]] = ([self._ey2i[ey0], 1.0], ) + self._hangingEy[self._ey2i[i001]] = ([self._ey2i[ey0], 0.5], [self._ey2i[ey1], 0.5]) + self._hangingEy[self._ey2i[i011]] = ([self._ey2i[ey0], 0.5], [self._ey2i[ey1], 0.5]) + self._hangingEy[self._ey2i[i002]] = ([self._ey2i[ey1], 1.0], ) + self._hangingEy[self._ey2i[i012]] = ([self._ey2i[ey1], 1.0], ) - # self._hangingEy[self._ey2i[test ]] = ([self._ey2i[ey0], chy0 / lenY], ) - # self._hangingEy[self._ey2i[self._index([p[0], p[1] + w, p[2] , sl])]] = ([self._ey2i[ey0], chy1 / lenY], ) - # self._hangingEy[self._ey2i[self._index([p[0], p[1] , p[2] + w, sl])]] = ([self._ey2i[ey0], chy0 / lenY / 2.0], [self._ey2i[ey1], chy0 / lenY / 2.0]) - # self._hangingEy[self._ey2i[self._index([p[0], p[1] + w, p[2] + w, sl])]] = ([self._ey2i[ey0], chy1 / lenY / 2.0], [self._ey2i[ey1], chy1 / lenY / 2.0]) - # self._hangingEy[self._ey2i[self._index([p[0], p[1] , p[2] + 2*w, sl])]] = ([self._ey2i[ey1], chy0 / lenY], ) - # self._hangingEy[self._ey2i[self._index([p[0], p[1] + w, p[2] + 2*w, sl])]] = ([self._ey2i[ey1], chy1 / lenY], ) + self._hangingEz[self._ez2i[i000]] = ([self._ez2i[ez0], 1.0], ) + self._hangingEz[self._ez2i[i001]] = ([self._ez2i[ez0], 1.0], ) + self._hangingEz[self._ez2i[i010]] = ([self._ez2i[ez0], 0.5], [self._ez2i[ez1], 0.5]) + self._hangingEz[self._ez2i[i011]] = ([self._ez2i[ez0], 0.5], [self._ez2i[ez1], 0.5]) + self._hangingEz[self._ez2i[i020]] = ([self._ez2i[ez1], 1.0], ) + self._hangingEz[self._ez2i[i021]] = ([self._ez2i[ez1], 1.0], ) - # self._hangingEz[self._ez2i[test ]] = ([self._ez2i[ez0], chz0 / lenZ], ) - # self._hangingEz[self._ez2i[self._index([p[0], p[1] , p[2] + w, sl])]] = ([self._ez2i[ez0], chz1 / lenZ], ) - # self._hangingEz[self._ez2i[self._index([p[0], p[1] + w, p[2] , sl])]] = ([self._ez2i[ez0], chz0 / lenZ / 2.0], [self._ez2i[ez1], chz0 / lenZ / 2.0]) - # self._hangingEz[self._ez2i[self._index([p[0], p[1] + w, p[2] + w, sl])]] = ([self._ez2i[ez0], chz1 / lenZ / 2.0], [self._ez2i[ez1], chz1 / lenZ / 2.0]) - # self._hangingEz[self._ez2i[self._index([p[0], p[1] + 2*w, p[2] , sl])]] = ([self._ez2i[ez1], chz0 / lenZ], ) - # self._hangingEz[self._ez2i[self._index([p[0], p[1] + 2*w, p[2] + w, sl])]] = ([self._ez2i[ez1], chz1 / lenZ], ) + # self._hangingEy[self._ey2i[i000]] = ([self._ey2i[ey0], chy0 / lenY], ) + # self._hangingEy[self._ey2i[i010]] = ([self._ey2i[ey0], chy1 / lenY], ) + # self._hangingEy[self._ey2i[i001]] = ([self._ey2i[ey0], chy0 / lenY / 2.0], [self._ey2i[ey1], chy0 / lenY / 2.0]) + # self._hangingEy[self._ey2i[i011]] = ([self._ey2i[ey0], chy1 / lenY / 2.0], [self._ey2i[ey1], chy1 / lenY / 2.0]) + # self._hangingEy[self._ey2i[i002]] = ([self._ey2i[ey1], chy0 / lenY], ) + # self._hangingEy[self._ey2i[i012]] = ([self._ey2i[ey1], chy1 / lenY], ) - self._hangingN[ self._n2i[ test ]] = ([self._n2i[n0], 1.0], ) - self._hangingN[ self._n2i[ self._index([p[0], p[1] + w, p[2] , sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n1], 0.5]) - self._hangingN[ self._n2i[ self._index([p[0], p[1] + 2*w, p[2] , sl])]] = ([self._n2i[n1], 1.0], ) - self._hangingN[ self._n2i[ self._index([p[0], p[1] , p[2] + w, sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n2], 0.5]) - self._hangingN[ self._n2i[ self._index([p[0], p[1] + w, p[2] + w, sl])]] = ([self._n2i[n0], 0.25], [self._n2i[n1], 0.25], [self._n2i[n2], 0.25], [self._n2i[n3], 0.25]) - self._hangingN[ self._n2i[ self._index([p[0], p[1] + 2*w, p[2] + w, sl])]] = ([self._n2i[n1], 0.5], [self._n2i[n3], 0.5]) - self._hangingN[ self._n2i[ self._index([p[0], p[1] , p[2] + 2*w, sl])]] = ([self._n2i[n2], 1.0], ) - self._hangingN[ self._n2i[ self._index([p[0], p[1] + w, p[2] + 2*w, sl])]] = ([self._n2i[n2], 0.5], [self._n2i[n3], 0.5]) - self._hangingN[ self._n2i[ self._index([p[0], p[1] + 2*w, p[2] + 2*w, sl])]] = ([self._n2i[n3], 1.0], ) + # self._hangingEz[self._ez2i[i000]] = ([self._ez2i[ez0], chz0 / lenZ], ) + # self._hangingEz[self._ez2i[i001]] = ([self._ez2i[ez0], chz1 / lenZ], ) + # self._hangingEz[self._ez2i[i010]] = ([self._ez2i[ez0], chz0 / lenZ / 2.0], [self._ez2i[ez1], chz0 / lenZ / 2.0]) + # self._hangingEz[self._ez2i[i011]] = ([self._ez2i[ez0], chz1 / lenZ / 2.0], [self._ez2i[ez1], chz1 / lenZ / 2.0]) + # self._hangingEz[self._ez2i[i020]] = ([self._ez2i[ez1], chz0 / lenZ], ) + # self._hangingEz[self._ez2i[i021]] = ([self._ez2i[ez1], chz1 / lenZ], ) + + self._hangingN[ self._n2i[ i000]] = ([self._n2i[n0], 1.0], ) + self._hangingN[ self._n2i[ i010]] = ([self._n2i[n0], 0.5], [self._n2i[n1], 0.5]) + self._hangingN[ self._n2i[ i020]] = ([self._n2i[n1], 1.0], ) + self._hangingN[ self._n2i[ i001]] = ([self._n2i[n0], 0.5], [self._n2i[n2], 0.5]) + self._hangingN[ self._n2i[ i011]] = ([self._n2i[n0], 0.25], [self._n2i[n1], 0.25], [self._n2i[n2], 0.25], [self._n2i[n3], 0.25]) + self._hangingN[ self._n2i[ i021]] = ([self._n2i[n1], 0.5], [self._n2i[n3], 0.5]) + self._hangingN[ self._n2i[ i002]] = ([self._n2i[n2], 1.0], ) + self._hangingN[ self._n2i[ i012]] = ([self._n2i[n2], 0.5], [self._n2i[n3], 0.5]) + self._hangingN[ self._n2i[ i022]] = ([self._n2i[n3], 1.0], ) # Compute from y faces for fy in self._facesY: @@ -997,48 +1067,58 @@ class TreeMesh(BaseMesh, InnerProducts): n2 = self._index([p[0] , p[1], p[2] + 2*w, p[-1]]) n3 = self._index([p[0] + 2*w, p[1], p[2] + 2*w, p[-1]]) - self._hangingFy[self._fy2i[test ]] = ([self._fy2i[fy], chx0*chz0 / A ], ) - self._hangingFy[self._fy2i[self._index([p[0] + w, p[1], p[2] , sl])]] = ([self._fy2i[fy], chx1*chz0 / A ], ) - self._hangingFy[self._fy2i[self._index([p[0] , p[1], p[2] + w, sl])]] = ([self._fy2i[fy], chx0*chz1 / A ], ) - self._hangingFy[self._fy2i[self._index([p[0] + w, p[1], p[2] + w, sl])]] = ([self._fy2i[fy], chx1*chz1 / A ], ) + i000 = test + i100 = self._index([p[0] + w, p[1], p[2] , sl]) + i001 = self._index([p[0] , p[1], p[2] + w, sl]) + i101 = self._index([p[0] + w, p[1], p[2] + w, sl]) + i200 = self._index([p[0] + 2*w, p[1], p[2] , sl]) + i201 = self._index([p[0] + 2*w, p[1], p[2] + w, sl]) + i002 = self._index([p[0] , p[1], p[2] + 2*w, sl]) + i102 = self._index([p[0] + w, p[1], p[2] + 2*w, sl]) + i202 = self._index([p[0] + 2*w, p[1], p[2] + 2*w, sl]) - self._hangingEx[self._ex2i[test ]] = ([self._ex2i[ex0], 1.0], ) - self._hangingEx[self._ex2i[self._index([p[0] + w, p[1], p[2] , sl])]] = ([self._ex2i[ex0], 1.0], ) - self._hangingEx[self._ex2i[self._index([p[0] , p[1], p[2] + w, sl])]] = ([self._ex2i[ex0], 0.5], [self._ex2i[ex1], 0.5]) - self._hangingEx[self._ex2i[self._index([p[0] + w, p[1], p[2] + w, sl])]] = ([self._ex2i[ex0], 0.5], [self._ex2i[ex1], 0.5]) - self._hangingEx[self._ex2i[self._index([p[0] , p[1], p[2] + 2*w, sl])]] = ([self._ex2i[ex1], 1.0], ) - self._hangingEx[self._ex2i[self._index([p[0] + w, p[1], p[2] + 2*w, sl])]] = ([self._ex2i[ex1], 1.0], ) + self._hangingFy[self._fy2i[i000]] = ([self._fy2i[fy], chx0*chz0 / A ], ) + self._hangingFy[self._fy2i[i100]] = ([self._fy2i[fy], chx1*chz0 / A ], ) + self._hangingFy[self._fy2i[i001]] = ([self._fy2i[fy], chx0*chz1 / A ], ) + self._hangingFy[self._fy2i[i101]] = ([self._fy2i[fy], chx1*chz1 / A ], ) - self._hangingEz[self._ez2i[test ]] = ([self._ez2i[ez0], 1.0], ) - self._hangingEz[self._ez2i[self._index([p[0] , p[1], p[2] + w, sl])]] = ([self._ez2i[ez0], 1.0], ) - self._hangingEz[self._ez2i[self._index([p[0] + w, p[1], p[2] , sl])]] = ([self._ez2i[ez0], 0.5], [self._ez2i[ez1], 0.5]) - self._hangingEz[self._ez2i[self._index([p[0] + w, p[1], p[2] + w, sl])]] = ([self._ez2i[ez0], 0.5], [self._ez2i[ez1], 0.5]) - self._hangingEz[self._ez2i[self._index([p[0] + 2*w, p[1], p[2] , sl])]] = ([self._ez2i[ez1], 1.0], ) - self._hangingEz[self._ez2i[self._index([p[0] + 2*w, p[1], p[2] + w, sl])]] = ([self._ez2i[ez1], 1.0], ) + self._hangingEx[self._ex2i[i000]] = ([self._ex2i[ex0], 1.0], ) + self._hangingEx[self._ex2i[i100]] = ([self._ex2i[ex0], 1.0], ) + self._hangingEx[self._ex2i[i001]] = ([self._ex2i[ex0], 0.5], [self._ex2i[ex1], 0.5]) + self._hangingEx[self._ex2i[i101]] = ([self._ex2i[ex0], 0.5], [self._ex2i[ex1], 0.5]) + self._hangingEx[self._ex2i[i002]] = ([self._ex2i[ex1], 1.0], ) + self._hangingEx[self._ex2i[i102]] = ([self._ex2i[ex1], 1.0], ) - # self._hangingEx[self._ex2i[test ]] = ([self._ex2i[ex0], chx0 / lenX], ) - # self._hangingEx[self._ex2i[self._index([p[0] + w, p[1], p[2] , sl])]] = ([self._ex2i[ex0], chx1 / lenX], ) - # self._hangingEx[self._ex2i[self._index([p[0] , p[1], p[2] + w, sl])]] = ([self._ex2i[ex0], chx0 / lenX / 2.0], [self._ex2i[ex1], chx0 / lenX / 2.0]) - # self._hangingEx[self._ex2i[self._index([p[0] + w, p[1], p[2] + w, sl])]] = ([self._ex2i[ex0], chx1 / lenX / 2.0], [self._ex2i[ex1], chx1 / lenX / 2.0]) - # self._hangingEx[self._ex2i[self._index([p[0] , p[1], p[2] + 2*w, sl])]] = ([self._ex2i[ex1], chx0 / lenX], ) - # self._hangingEx[self._ex2i[self._index([p[0] + w, p[1], p[2] + 2*w, sl])]] = ([self._ex2i[ex1], chx1 / lenX], ) + self._hangingEz[self._ez2i[i000]] = ([self._ez2i[ez0], 1.0], ) + self._hangingEz[self._ez2i[i001]] = ([self._ez2i[ez0], 1.0], ) + self._hangingEz[self._ez2i[i100]] = ([self._ez2i[ez0], 0.5], [self._ez2i[ez1], 0.5]) + self._hangingEz[self._ez2i[i101]] = ([self._ez2i[ez0], 0.5], [self._ez2i[ez1], 0.5]) + self._hangingEz[self._ez2i[i200]] = ([self._ez2i[ez1], 1.0], ) + self._hangingEz[self._ez2i[i201]] = ([self._ez2i[ez1], 1.0], ) - # self._hangingEz[self._ez2i[test ]] = ([self._ez2i[ez0], chz0 / lenZ], ) - # self._hangingEz[self._ez2i[self._index([p[0] , p[1], p[2] + w, sl])]] = ([self._ez2i[ez0], chz1 / lenZ], ) - # self._hangingEz[self._ez2i[self._index([p[0] + w, p[1], p[2] , sl])]] = ([self._ez2i[ez0], chz0 / lenZ / 2.0], [self._ez2i[ez1], chz0 / lenZ / 2.0]) - # self._hangingEz[self._ez2i[self._index([p[0] + w, p[1], p[2] + w, sl])]] = ([self._ez2i[ez0], chz1 / lenZ / 2.0], [self._ez2i[ez1], chz1 / lenZ / 2.0]) - # self._hangingEz[self._ez2i[self._index([p[0] + 2*w, p[1], p[2] , sl])]] = ([self._ez2i[ez1], chz0 / lenZ], ) - # self._hangingEz[self._ez2i[self._index([p[0] + 2*w, p[1], p[2] + w, sl])]] = ([self._ez2i[ez1], chz1 / lenZ], ) + # self._hangingEx[self._ex2i[i000]] = ([self._ex2i[ex0], chx0 / lenX], ) + # self._hangingEx[self._ex2i[i100]] = ([self._ex2i[ex0], chx1 / lenX], ) + # self._hangingEx[self._ex2i[i001]] = ([self._ex2i[ex0], chx0 / lenX / 2.0], [self._ex2i[ex1], chx0 / lenX / 2.0]) + # self._hangingEx[self._ex2i[i101]] = ([self._ex2i[ex0], chx1 / lenX / 2.0], [self._ex2i[ex1], chx1 / lenX / 2.0]) + # self._hangingEx[self._ex2i[i002]] = ([self._ex2i[ex1], chx0 / lenX], ) + # self._hangingEx[self._ex2i[i102]] = ([self._ex2i[ex1], chx1 / lenX], ) - self._hangingN[ self._n2i[ test ]] = ([self._n2i[n0], 1.0], ) - self._hangingN[ self._n2i[ self._index([p[0] + w, p[1], p[2] , sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n1], 0.5]) - self._hangingN[ self._n2i[ self._index([p[0] + 2*w, p[1], p[2] , sl])]] = ([self._n2i[n1], 1.0], ) - self._hangingN[ self._n2i[ self._index([p[0] , p[1], p[2] + w, sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n2], 0.5]) - self._hangingN[ self._n2i[ self._index([p[0] + w, p[1], p[2] + w, sl])]] = ([self._n2i[n0], 0.25], [self._n2i[n1], 0.25], [self._n2i[n2], 0.25], [self._n2i[n3], 0.25]) - self._hangingN[ self._n2i[ self._index([p[0] + 2*w, p[1], p[2] + w, sl])]] = ([self._n2i[n1], 0.5], [self._n2i[n3], 0.5]) - self._hangingN[ self._n2i[ self._index([p[0] , p[1], p[2] + 2*w, sl])]] = ([self._n2i[n2], 1.0], ) - self._hangingN[ self._n2i[ self._index([p[0] + w, p[1], p[2] + 2*w, sl])]] = ([self._n2i[n2], 0.5], [self._n2i[n3], 0.5]) - self._hangingN[ self._n2i[ self._index([p[0] + 2*w, p[1], p[2] + 2*w, sl])]] = ([self._n2i[n3], 1.0], ) + # self._hangingEz[self._ez2i[i000]] = ([self._ez2i[ez0], chz0 / lenZ], ) + # self._hangingEz[self._ez2i[i001]] = ([self._ez2i[ez0], chz1 / lenZ], ) + # self._hangingEz[self._ez2i[i100]] = ([self._ez2i[ez0], chz0 / lenZ / 2.0], [self._ez2i[ez1], chz0 / lenZ / 2.0]) + # self._hangingEz[self._ez2i[i101]] = ([self._ez2i[ez0], chz1 / lenZ / 2.0], [self._ez2i[ez1], chz1 / lenZ / 2.0]) + # self._hangingEz[self._ez2i[i200]] = ([self._ez2i[ez1], chz0 / lenZ], ) + # self._hangingEz[self._ez2i[i201]] = ([self._ez2i[ez1], chz1 / lenZ], ) + + self._hangingN[ self._n2i[ i000]] = ([self._n2i[n0], 1.0], ) + self._hangingN[ self._n2i[ i100]] = ([self._n2i[n0], 0.5], [self._n2i[n1], 0.5]) + self._hangingN[ self._n2i[ i200]] = ([self._n2i[n1], 1.0], ) + self._hangingN[ self._n2i[ i001]] = ([self._n2i[n0], 0.5], [self._n2i[n2], 0.5]) + self._hangingN[ self._n2i[ i101]] = ([self._n2i[n0], 0.25], [self._n2i[n1], 0.25], [self._n2i[n2], 0.25], [self._n2i[n3], 0.25]) + self._hangingN[ self._n2i[ i201]] = ([self._n2i[n1], 0.5], [self._n2i[n3], 0.5]) + self._hangingN[ self._n2i[ i002]] = ([self._n2i[n2], 1.0], ) + self._hangingN[ self._n2i[ i102]] = ([self._n2i[n2], 0.5], [self._n2i[n3], 0.5]) + self._hangingN[ self._n2i[ i202]] = ([self._n2i[n3], 1.0], ) if self.dim == 2: self.__dirtyHanging__ = False @@ -1073,48 +1153,58 @@ class TreeMesh(BaseMesh, InnerProducts): n2 = self._index([p[0] , p[1] + 2*w, p[2], p[-1]]) n3 = self._index([p[0] + 2*w, p[1] + 2*w, p[2], p[-1]]) - self._hangingFz[self._fz2i[test ]] = ([self._fz2i[fz], chx0*chy0 / A ], ) - self._hangingFz[self._fz2i[self._index([p[0] + w, p[1] , p[2], sl])]] = ([self._fz2i[fz], chx1*chy0 / A ], ) - self._hangingFz[self._fz2i[self._index([p[0] , p[1] + w, p[2], sl])]] = ([self._fz2i[fz], chx0*chy1 / A ], ) - self._hangingFz[self._fz2i[self._index([p[0] + w, p[1] + w, p[2], sl])]] = ([self._fz2i[fz], chx1*chy1 / A ], ) + i000 = test + i100 = self._index([p[0] + w, p[1] , p[2], sl]) + i010 = self._index([p[0] , p[1] + w, p[2], sl]) + i110 = self._index([p[0] + w, p[1] + w, p[2], sl]) + i200 = self._index([p[0] + 2*w, p[1] , p[2], sl]) + i210 = self._index([p[0] + 2*w, p[1] + w, p[2], sl]) + i020 = self._index([p[0] , p[1] + 2*w, p[2], sl]) + i120 = self._index([p[0] + w, p[1] + 2*w, p[2], sl]) + i220 = self._index([p[0] + 2*w, p[1] + 2*w, p[2], sl]) - self._hangingEx[self._ex2i[test ]] = ([self._ex2i[ex0], 1.0], ) - self._hangingEx[self._ex2i[self._index([p[0] + w, p[1] , p[2], sl])]] = ([self._ex2i[ex0], 1.0], ) - self._hangingEx[self._ex2i[self._index([p[0] , p[1] + w, p[2], sl])]] = ([self._ex2i[ex0], 0.5], [self._ex2i[ex1], 0.5]) - self._hangingEx[self._ex2i[self._index([p[0] + w, p[1] + w, p[2], sl])]] = ([self._ex2i[ex0], 0.5], [self._ex2i[ex1], 0.5]) - self._hangingEx[self._ex2i[self._index([p[0] , p[1] + 2*w, p[2], sl])]] = ([self._ex2i[ex1], 1.0], ) - self._hangingEx[self._ex2i[self._index([p[0] + w, p[1] + 2*w, p[2], sl])]] = ([self._ex2i[ex1], 1.0], ) + self._hangingFz[self._fz2i[i000]] = ([self._fz2i[fz], chx0*chy0 / A ], ) + self._hangingFz[self._fz2i[i100]] = ([self._fz2i[fz], chx1*chy0 / A ], ) + self._hangingFz[self._fz2i[i010]] = ([self._fz2i[fz], chx0*chy1 / A ], ) + self._hangingFz[self._fz2i[i110]] = ([self._fz2i[fz], chx1*chy1 / A ], ) - self._hangingEy[self._ey2i[test ]] = ([self._ey2i[ey0], 1.0], ) - self._hangingEy[self._ey2i[self._index([p[0] , p[1] + w, p[2], sl])]] = ([self._ey2i[ey0], 1.0], ) - self._hangingEy[self._ey2i[self._index([p[0] + w, p[1] , p[2], sl])]] = ([self._ey2i[ey0], 0.5], [self._ey2i[ey1], 0.5]) - self._hangingEy[self._ey2i[self._index([p[0] + w, p[1] + w, p[2], sl])]] = ([self._ey2i[ey0], 0.5], [self._ey2i[ey1], 0.5]) - self._hangingEy[self._ey2i[self._index([p[0] + 2*w, p[1] , p[2], sl])]] = ([self._ey2i[ey1], 1.0], ) - self._hangingEy[self._ey2i[self._index([p[0] + 2*w, p[1] + w, p[2], sl])]] = ([self._ey2i[ey1], 1.0], ) + self._hangingEx[self._ex2i[i000]] = ([self._ex2i[ex0], 1.0], ) + self._hangingEx[self._ex2i[i100]] = ([self._ex2i[ex0], 1.0], ) + self._hangingEx[self._ex2i[i010]] = ([self._ex2i[ex0], 0.5], [self._ex2i[ex1], 0.5]) + self._hangingEx[self._ex2i[i110]] = ([self._ex2i[ex0], 0.5], [self._ex2i[ex1], 0.5]) + self._hangingEx[self._ex2i[i020]] = ([self._ex2i[ex1], 1.0], ) + self._hangingEx[self._ex2i[i120]] = ([self._ex2i[ex1], 1.0], ) - # self._hangingEx[self._ex2i[test ]] = ([self._ex2i[ex0], chx0 / lenX], ) - # self._hangingEx[self._ex2i[self._index([p[0] + w, p[1] , p[2], sl])]] = ([self._ex2i[ex0], chx1 / lenX], ) - # self._hangingEx[self._ex2i[self._index([p[0] , p[1] + w, p[2], sl])]] = ([self._ex2i[ex0], chx0 / lenX / 2.0], [self._ex2i[ex1], chx0 / lenX / 2.0]) - # self._hangingEx[self._ex2i[self._index([p[0] + w, p[1] + w, p[2], sl])]] = ([self._ex2i[ex0], chx1 / lenX / 2.0], [self._ex2i[ex1], chx1 / lenX / 2.0]) - # self._hangingEx[self._ex2i[self._index([p[0] , p[1] + 2*w, p[2], sl])]] = ([self._ex2i[ex1], chx0 / lenX], ) - # self._hangingEx[self._ex2i[self._index([p[0] + w, p[1] + 2*w, p[2], sl])]] = ([self._ex2i[ex1], chx1 / lenX], ) + self._hangingEy[self._ey2i[i000]] = ([self._ey2i[ey0], 1.0], ) + self._hangingEy[self._ey2i[i010]] = ([self._ey2i[ey0], 1.0], ) + self._hangingEy[self._ey2i[i100]] = ([self._ey2i[ey0], 0.5], [self._ey2i[ey1], 0.5]) + self._hangingEy[self._ey2i[i110]] = ([self._ey2i[ey0], 0.5], [self._ey2i[ey1], 0.5]) + self._hangingEy[self._ey2i[i200]] = ([self._ey2i[ey1], 1.0], ) + self._hangingEy[self._ey2i[i210]] = ([self._ey2i[ey1], 1.0], ) - # self._hangingEy[self._ey2i[test ]] = ([self._ey2i[ey0], chy0 / lenY], ) - # self._hangingEy[self._ey2i[self._index([p[0] , p[1] + w, p[2], sl])]] = ([self._ey2i[ey0], chy1 / lenY], ) - # self._hangingEy[self._ey2i[self._index([p[0] + w, p[1] , p[2], sl])]] = ([self._ey2i[ey0], chy0 / lenY / 2.0], [self._ey2i[ey1], chy0 / lenY / 2.0]) - # self._hangingEy[self._ey2i[self._index([p[0] + w, p[1] + w, p[2], sl])]] = ([self._ey2i[ey0], chy1 / lenY / 2.0], [self._ey2i[ey1], chy1 / lenY / 2.0]) - # self._hangingEy[self._ey2i[self._index([p[0] + 2*w, p[1] , p[2], sl])]] = ([self._ey2i[ey1], chy0 / lenY], ) - # self._hangingEy[self._ey2i[self._index([p[0] + 2*w, p[1] + w, p[2], sl])]] = ([self._ey2i[ey1], chy1 / lenY], ) + # self._hangingEx[self._ex2i[i000]] = ([self._ex2i[ex0], chx0 / lenX], ) + # self._hangingEx[self._ex2i[i100]] = ([self._ex2i[ex0], chx1 / lenX], ) + # self._hangingEx[self._ex2i[i010]] = ([self._ex2i[ex0], chx0 / lenX / 2.0], [self._ex2i[ex1], chx0 / lenX / 2.0]) + # self._hangingEx[self._ex2i[i110]] = ([self._ex2i[ex0], chx1 / lenX / 2.0], [self._ex2i[ex1], chx1 / lenX / 2.0]) + # self._hangingEx[self._ex2i[i020]] = ([self._ex2i[ex1], chx0 / lenX], ) + # self._hangingEx[self._ex2i[i120]] = ([self._ex2i[ex1], chx1 / lenX], ) - self._hangingN[ self._n2i[ test ]] = ([self._n2i[n0], 1.0], ) - self._hangingN[ self._n2i[ self._index([p[0] + w, p[1] , p[2], sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n1], 0.5]) - self._hangingN[ self._n2i[ self._index([p[0] + 2*w, p[1] , p[2], sl])]] = ([self._n2i[n1], 1.0], ) - self._hangingN[ self._n2i[ self._index([p[0] , p[1] + w, p[2], sl])]] = ([self._n2i[n0], 0.5], [self._n2i[n2], 0.5]) - self._hangingN[ self._n2i[ self._index([p[0] + w, p[1] + w, p[2], sl])]] = ([self._n2i[n0], 0.25], [self._n2i[n1], 0.25], [self._n2i[n2], 0.25], [self._n2i[n3], 0.25]) - self._hangingN[ self._n2i[ self._index([p[0] + 2*w, p[1] + w, p[2], sl])]] = ([self._n2i[n1], 0.5], [self._n2i[n3], 0.5]) - self._hangingN[ self._n2i[ self._index([p[0] , p[1] + 2*w, p[2], sl])]] = ([self._n2i[n2], 1.0], ) - self._hangingN[ self._n2i[ self._index([p[0] + w, p[1] + 2*w, p[2], sl])]] = ([self._n2i[n2], 0.5], [self._n2i[n3], 0.5]) - self._hangingN[ self._n2i[ self._index([p[0] + 2*w, p[1] + 2*w, p[2], sl])]] = ([self._n2i[n3], 1.0], ) + # self._hangingEy[self._ey2i[i000]] = ([self._ey2i[ey0], chy0 / lenY], ) + # self._hangingEy[self._ey2i[i010]] = ([self._ey2i[ey0], chy1 / lenY], ) + # self._hangingEy[self._ey2i[i100]] = ([self._ey2i[ey0], chy0 / lenY / 2.0], [self._ey2i[ey1], chy0 / lenY / 2.0]) + # self._hangingEy[self._ey2i[i110]] = ([self._ey2i[ey0], chy1 / lenY / 2.0], [self._ey2i[ey1], chy1 / lenY / 2.0]) + # self._hangingEy[self._ey2i[i200]] = ([self._ey2i[ey1], chy0 / lenY], ) + # self._hangingEy[self._ey2i[i210]] = ([self._ey2i[ey1], chy1 / lenY], ) + + self._hangingN[ self._n2i[ i000]] = ([self._n2i[n0], 1.0], ) + self._hangingN[ self._n2i[ i100]] = ([self._n2i[n0], 0.5], [self._n2i[n1], 0.5]) + self._hangingN[ self._n2i[ i200]] = ([self._n2i[n1], 1.0], ) + self._hangingN[ self._n2i[ i010]] = ([self._n2i[n0], 0.5], [self._n2i[n2], 0.5]) + self._hangingN[ self._n2i[ i110]] = ([self._n2i[n0], 0.25], [self._n2i[n1], 0.25], [self._n2i[n2], 0.25], [self._n2i[n3], 0.25]) + self._hangingN[ self._n2i[ i210]] = ([self._n2i[n1], 0.5], [self._n2i[n3], 0.5]) + self._hangingN[ self._n2i[ i020]] = ([self._n2i[n2], 1.0], ) + self._hangingN[ self._n2i[ i120]] = ([self._n2i[n2], 0.5], [self._n2i[n3], 0.5]) + self._hangingN[ self._n2i[ i220]] = ([self._n2i[n3], 1.0], ) self.__dirtyHanging__ = False @@ -1316,289 +1406,208 @@ class TreeMesh(BaseMesh, InnerProducts): # self._nodalGrad = Utils.sdiag(1/L)*G # return self._nodalGrad - # @property - # def aveE2CC(self): - # "Construct the averaging operator on cell edges to cell centers." - # if getattr(self, '_aveE2CC', None) is None: - - # # TODO: preallocate - # I, J, V = [], [], [] - - # if self.dim == 2: - # raise NotImplementedError('aveE2CC not implemented yet') - - # if self.dim == 3: - # PM = [1./(4.*self.dim)]*4*self.dim # plus / plus - # offset = [0]*4 + [self.ntEx]*4 + [self.ntEx+self.ntEy]*4 - - # for ii, ind in enumerate(self._sortedCells): - # p = self._pointer(ind) - # w = self._levelWidth(p[-1]) - - # edges = [ - # self._ex2i[self._index([ p[0] , p[1] , p[2] , p[3]])], - # self._ex2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], - # self._ex2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])], - # self._ex2i[self._index([ p[0] , p[1] + w, p[2] + w, p[3]])], - # self._ey2i[self._index([ p[0] , p[1] , p[2] , p[3]])], - # self._ey2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], - # self._ey2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])], - # self._ey2i[self._index([ p[0] + w, p[1] , p[2] + w, p[3]])], - # self._ez2i[self._index([ p[0] , p[1] , p[2] , p[3]])], - # self._ez2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], - # self._ez2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], - # self._ez2i[self._index([ p[0] + w, p[1] + w, p[2] , p[3]])] - # ] - - # for off, pm, edge in zip(offset,PM,edges): - # I += [ii] - # J += [edge + off] - # V += [pm] - - - # Av = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.ntE)) - # Re = self._deflationMatrix('E',asOnes=False,withHanging=True) - - # self._aveE2CC = Av*Re - - # return self._aveE2CC - - @property - def aveEx2CC(self): - if getattr(self, '_aveEx2CC', None) is None: - I, J, V = [], [], [] - - if self.dim == 2: - raise Exception('aveEx2CC not implemented in 2D') - - if self.dim == 3: - PM = [1./4.]*4 - - for ii, ind in enumerate(self._sortedCells): - p = self._pointer(ind) - w = self._levelWidth(p[-1]) - - edgesx = [ - self._ex2i[self._index([ p[0] , p[1] , p[2] , p[3]])], - self._ex2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], - self._ex2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])], - self._ex2i[self._index([ p[0] , p[1] + w, p[2] + w, p[3]])], - ] - - for pm, edge in zip(PM,edgesx): - I += [ii] - J += [edge] - V += [pm] - - Av = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.ntEx)) - Re = self._deflationMatrix('Ex',asOnes=False,withHanging=True) - - self._aveEx2CC = Av*Re - return self._aveEx2CC - - @property - def aveEy2CC(self): - "Construct the averaging operator on cell edges to cell centers." - if getattr(self, '_aveEy2CC', None) is None: - I, J, V = [], [], [] - - if self.dim == 2: - raise NotImplementedError('aveEy2CC not implemented in 2D') - - if self.dim == 3: - PM = [1./4.]*4 # plus / plus - - for ii, ind in enumerate(self._sortedCells): - p = self._pointer(ind) - w = self._levelWidth(p[-1]) - - edgesy = [ - self._ey2i[self._index([ p[0] , p[1] , p[2] , p[3]])], - self._ey2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], - self._ey2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])], - self._ey2i[self._index([ p[0] + w, p[1] , p[2] + w, p[3]])], - ] - - for pm, edge in zip(PM,edgesy): - I += [ii] - J += [edge] - V += [pm] - - Av = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.ntEy)) - Re = self._deflationMatrix('Ey',asOnes=False,withHanging=True) - - self._aveEy2CC = Av*Re - return self._aveEy2CC - - @property - def aveEz2CC(self): - "Construct the averaging operator on cell edges to cell centers." - # raise Exception('Not yet implemented!') - if getattr(self, '_aveEz2CC', None) is None: - I, J, V = [], [], [] - - if self.dim == 2: - raise Exception('There are no z edges in 2D') - - if self.dim == 3: - PM = [1./4.]*4 # plus / plus - - for ii, ind in enumerate(self._sortedCells): - p = self._pointer(ind) - w = self._levelWidth(p[-1]) - - edgesz = [ - self._ez2i[self._index([ p[0] , p[1] , p[2] , p[3]])], - self._ez2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], - self._ez2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], - self._ez2i[self._index([ p[0] + w, p[1] + w, p[2] , p[3]])], - ] - - for pm, edge in zip(PM,edgesz): - I += [ii] - J += [edge] - V += [pm] - - - Av = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.ntEz)) - Re = self._deflationMatrix('Ez',asOnes=False,withHanging=True) - - self._aveEz2CC = Av*Re - - return self._aveEz2CC - @property def aveE2CC(self): "Construct the averaging operator on cell edges to cell centers." if getattr(self, '_aveE2CC', None) is None: + + # TODO: preallocate + I, J, V = [], [], [] + if self.dim == 2: - raise Exception('aveE2CC not implemented in 2D') - elif self.dim == 3: - self._aveE2CC = 1./self.dim*sp.hstack([self.aveEx2CC, self.aveEy2CC, self.aveEz2CC]) + raise NotImplementedError('aveE2CC not implemented yet') + # PM = [1./(2.*self.dim)]*self.dim # plus / plus + # offset = [0]*2 + [self.ntEx]*2 + + # for ii, ind in enumerate(self._sortedCells): + # p = self._pointer(ind) + # w = self._levelWidth(p[-1]) + + # edges = [ + # self._ex2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + # self._ex2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], + # self._ex2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])], + # self._ex2i[self._index([ p[0] , p[1] + w, p[2] + w, p[3]])], + # self._ey2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + # self._ey2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], + # self._ey2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])], + # self._ey2i[self._index([ p[0] + w, p[1] , p[2] + w, p[3]])], + # self._ez2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + # self._ez2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], + # self._ez2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], + # self._ez2i[self._index([ p[0] + w, p[1] + w, p[2] , p[3]])] + # ] + + # for off, pm, edge in zip(offset,PM,edges): + # I += [ii] + # J += [edge + off] + # V += [pm] + + if self.dim == 3: + PM = [1./(4.*self.dim)]*4*self.dim # plus / plus + offset = [0]*4 + [self.ntEx]*4 + [self.ntEx+self.ntEy]*4 + + for ii, ind in enumerate(self._sortedCells): + p = self._pointer(ind) + w = self._levelWidth(p[-1]) + + edges = [ + self._ex2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._ex2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], + self._ex2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])], + self._ex2i[self._index([ p[0] , p[1] + w, p[2] + w, p[3]])], + self._ey2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._ey2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], + self._ey2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])], + self._ey2i[self._index([ p[0] + w, p[1] , p[2] + w, p[3]])], + self._ez2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._ez2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], + self._ez2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], + self._ez2i[self._index([ p[0] + w, p[1] + w, p[2] , p[3]])] + ] + + for off, pm, edge in zip(offset,PM,edges): + I += [ii] + J += [edge + off] + V += [pm] + + + Av = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.ntE)) + Re = self._deflationMatrix('E',asOnes=False,withHanging=True) + + self._aveE2CC = Av*Re + return self._aveE2CC @property def aveE2CCV(self): "Construct the averaging operator on cell edges to cell centers." - # raise Exception('Not yet implemented!') - if getattr(self, '_aveE2CCV', None) is None: - if self.dim == 2: - raise Exception('aveE2CC not implemented in 2D') - elif self.dim == 3: - self._aveE2CCV = sp.block_diag([self.aveEx2CC, self.aveEy2CC, self.aveEz2CC]) - return self._aveE2CCV - - @property - def aveFx2CC(self): - if getattr(self, '_aveFx2CC', None) is None: - I, J, V = [], [], [] - PM = [1./2.]*self.dim # 0.5, 0.5 - - for ii, ind in enumerate(self._sortedCells): - p = self._pointer(ind) - w = self._levelWidth(p[-1]) - - if self.dim == 2: - facesx = [ - self._fx2i[self._index([ p[0] , p[1] , p[2]])], - self._fx2i[self._index([ p[0] + w, p[1] , p[2]])], - ] - - elif self.dim == 3: - facesx = [ - self._fx2i[self._index([ p[0] , p[1] , p[2] , p[3]])], - self._fx2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], - ] - - for pm, face in zip(PM,facesx): - I += [ii] - J += [face] - V += [pm] - - Av = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.ntFx)) - Rf = self._deflationMatrix('Fx',asOnes=True,withHanging=True) - - self._aveFx2CC = Av*Rf - return self._aveFx2CC - - @property - def aveFy2CC(self): - if getattr(self, '_aveFy2CC', None) is None: - I, J, V = [], [], [] - PM = [1./2.]*2 # 0.5, 0.5 - - for ii, ind in enumerate(self._sortedCells): - p = self._pointer(ind) - w = self._levelWidth(p[-1]) - - if self.dim == 2: - facesy = [ - self._fy2i[self._index([ p[0] , p[1] , p[2]])], - self._fy2i[self._index([ p[0] , p[1] + w, p[2]])], - ] - elif self.dim == 3: - facesy = [ - self._fy2i[self._index([ p[0] , p[1] , p[2] , p[3]])], - self._fy2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], - ] - - for pm, face in zip(PM,facesy): - I += [ii] - J += [face] - V += [pm] - - Av = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.ntFy)) - Rf = self._deflationMatrix('Fy',asOnes=True,withHanging=True) - - self._aveFy2CC = Av*Rf - return self._aveFy2CC - - @property - def aveFz2CC(self): - if getattr(self, '_aveFz2CC', None) is None: - I, J, V = [], [], [] - PM = [1./2.]*2 # 0.5, 0.5 - - for ii, ind in enumerate(self._sortedCells): - p = self._pointer(ind) - w = self._levelWidth(p[-1]) - - if self.dim == 2: - raise Exception('There are no z-faces in 2D') - elif self.dim == 3: - facesz = [ - self._fz2i[self._index([ p[0] , p[1] , p[2] , p[3]])], - self._fz2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])], - ] - - for pm, face in zip(PM,facesz): - I += [ii] - J += [face] - V += [pm] - - Av = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.ntFz)) - Rf = self._deflationMatrix('Fz',asOnes=True,withHanging=True) - self._aveFz2CC = Av*Rf - return self._aveFz2CC + raise Exception('Not yet implemented!') @property def aveF2CC(self): "Construct the averaging operator on cell faces to cell centers." if getattr(self, '_aveF2CC', None) is None: - if self.dim == 2: - self._aveF2CC = 1./self.dim*sp.hstack([self.aveFx2CC, self.aveFy2CC]) - elif self.dim == 3: - self._aveF2CC = 1./self.dim*sp.hstack([self.aveFx2CC, self.aveFy2CC, self.aveFz2CC]) + # TODO: Preallocate! + I, J, V = [], [], [] + PM = [1./(2.*self.dim)]*2*self.dim # plus / plus + + # TODO total number of faces? + offset = [0]*2 + [self.ntFx]*2 + [self.ntFx+self.ntFy]*2 + + for ii, ind in enumerate(self._sortedCells): + + p = self._pointer(ind) + w = self._levelWidth(p[-1]) + + if self.dim == 2: + faces = [ + self._fx2i[self._index([ p[0] , p[1] , p[2]])], + self._fx2i[self._index([ p[0] + w, p[1] , p[2]])], + self._fy2i[self._index([ p[0] , p[1] , p[2]])], + self._fy2i[self._index([ p[0] , p[1] + w, p[2]])] + ] + elif self.dim == 3: + faces = [ + self._fx2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._fx2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], + self._fy2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._fy2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], + self._fz2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._fz2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])] + ] + + for off, pm, face in zip(offset,PM,faces): + I += [ii] + J += [face + off] + V += [pm] + + + Av = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.ntF)) + Rf = self._deflationMatrix('F',asOnes=True,withHanging=True) + + self._aveF2CC = Av*Rf return self._aveF2CC + @property def aveF2CCV(self): "Construct the averaging operator on cell faces to cell centers." if getattr(self, '_aveF2CCV', None) is None: + # TODO: Preallocate! + I, J, V = [], [], [] + PM = [1./2.]*2 # 0.5, 0.5 + + offsetx = [0]*2 + offsety = [self.ntFx]*2 + if self.dim == 2: - self._aveF2CCV = sp.block_diag([self.aveFx2CC, self.aveFy2CC]) - elif self.dim == 3: - self._aveF2CCV = sp.block_diag([self.aveFx2CC, self.aveFy2CC, self.aveFz2CC]) + for ii, ind in enumerate(self._sortedCells): + p = self._pointer(ind) + w = self._levelWidth(p[-1]) + + facesx = [ + self._fx2i[self._index([ p[0] , p[1] , p[2]])], + self._fx2i[self._index([ p[0] + w, p[1] , p[2]])], + ] + + facesy = [ + self._fy2i[self._index([ p[0] , p[1] , p[2]])], + self._fy2i[self._index([ p[0] , p[1] + w, p[2]])], + ] + + for off, pm, face in zip(offsetx,PM,facesx): + I += [ii] + J += [face + off] + V += [pm] + + for off, pm, face in zip(offsety,PM,facesy): + I += [ii + self.nC] + J += [face + off] + V += [pm] + + + + if self.dim == 3: + offsetz = [self.ntFx + self.ntFy]*2 + + for ii, ind in enumerate(self._sortedCells): + p = self._pointer(ind) + w = self._levelWidth(p[-1]) + + facesx = [ + self._fx2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._fx2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], + ] + + facesy = [ + self._fy2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._fy2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], + ] + facesz = [ + self._fz2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._fz2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])] + ] + + for off, pm, face in zip(offsetx,PM,facesx): + I += [ii] + J += [face + off] + V += [pm] + + for off, pm, face in zip(offsety,PM,facesy): + I += [ii + self.nC] + J += [face + off] + V += [pm] + + for off, pm, face in zip(offsetz,PM,facesz): + I += [ii + self.nC*2] + J += [face + off] + V += [pm] + + Av = sp.csr_matrix((V,(I,J)), shape=(self.nC*self.dim, self.ntF)) + Rf = self._deflationMatrix('F',asOnes=True,withHanging=True) + + self._aveF2CCV = Av*Rf return self._aveF2CCV diff --git a/SimPEG/Tests.py b/SimPEG/Tests.py index a881b6dc..6d414441 100644 --- a/SimPEG/Tests.py +++ b/SimPEG/Tests.py @@ -147,10 +147,10 @@ class OrderTest(unittest.TestCase): levels = int(np.log(nc)/np.log(2)) self.M = Tree(h[:self.meshDimension], levels=levels) - def function(xc): + def function(cell): if 'notatree' in self._meshType: return levels - 1 - r = xc - np.array([0.5]*len(xc)) + r = cell.center - np.array([0.5]*len(cell.center)) dist = np.sqrt(r.dot(r)) if dist < 0.2: return levels From 4ac85e81d6f8e84bc1ebef4d3f1721f56fbeecbf Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Sun, 15 Nov 2015 17:51:51 -0800 Subject: [PATCH 67/83] Updates to merging --- SimPEG/Mesh/TreeMesh.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/SimPEG/Mesh/TreeMesh.py b/SimPEG/Mesh/TreeMesh.py index bce31344..fc0e7265 100644 --- a/SimPEG/Mesh/TreeMesh.py +++ b/SimPEG/Mesh/TreeMesh.py @@ -1864,24 +1864,24 @@ class NotBalancedException(Exception): if __name__ == '__main__': - def function(xc): - r = xc - np.array([0.5*128]*len(xc)) + def function(cell): + r = cell.center - np.array([0.5]*len(cell.center)) dist = np.sqrt(r.dot(r)) # if dist < 0.05: # return 5 - if dist < 0.1*128: + if dist < 0.1: return 4 - if dist < 0.3*128: + if dist < 0.3: return 3 - if dist < 1.0*128: + if dist < 1.0: return 2 else: return 0 - # T = Tree([[(1,128)],[(1,128)],[(1,128)]],levels=7) - # T = Tree([128,128,128],levels=7) - T = Tree([[(1,16)],[(1,16)]],levels=4) - # T = Tree([[(1,128)],[(1,128)]],levels=7) + # T = TreeMesh([[(1,128)],[(1,128)],[(1,128)]],levels=7) + # T = TreeMesh([128,128,128],levels=7) + T = TreeMesh([16,16],levels=4) + # T = TreeMesh([[(1,128)],[(1,128)]],levels=7) # T.refine(lambda xc:1, balance=False) # T._index([0,0,0]) # T._pointer(0) @@ -1894,7 +1894,7 @@ if __name__ == '__main__': T.plotImage(np.random.rand(T.nC),showIt=True) - print T.getFaceInnerProduct() + # print T.getFaceInnerProduct() # print T.gridFz From 2c0045984672e239ad39dfc3362508fbdf5e1559 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Sun, 15 Nov 2015 17:59:05 -0800 Subject: [PATCH 68/83] Actually use Lindsey's changes... :) --- SimPEG/Mesh/TreeMesh.py | 348 ++++++++++++++++++++++------------------ 1 file changed, 192 insertions(+), 156 deletions(-) diff --git a/SimPEG/Mesh/TreeMesh.py b/SimPEG/Mesh/TreeMesh.py index fc0e7265..77d5c9de 100644 --- a/SimPEG/Mesh/TreeMesh.py +++ b/SimPEG/Mesh/TreeMesh.py @@ -203,7 +203,9 @@ class TreeMesh(BaseMesh, InnerProducts): '_gridCC', '_gridN', '_gridFx', '_gridFy', '_gridFz', '_gridEx', '_gridEy', '_gridEz', '_area', '_edge', '_vol', '_faceDiv', '_edgeCurl', '_nodalGrad', - '_aveF2CC', '_aveF2CCV', '_aveE2CC', '_aveE2CCV','_aveN2CC' + '_aveFx2CC', '_aveFy2CC', '_aveFz2CC', '_aveF2CC', '_aveF2CCV', + '_aveEx2CC', '_aveEy2CC', '_aveEz2CC', '_aveE2CC', '_aveE2CCV', + '_aveN2CC', ] for p in deleteThese: if hasattr(self, p): delattr(self, p) @@ -1407,207 +1409,241 @@ class TreeMesh(BaseMesh, InnerProducts): # return self._nodalGrad @property - def aveE2CC(self): - "Construct the averaging operator on cell edges to cell centers." - if getattr(self, '_aveE2CC', None) is None: - - # TODO: preallocate + def aveEx2CC(self): + if getattr(self, '_aveEx2CC', None) is None: I, J, V = [], [], [] if self.dim == 2: - raise NotImplementedError('aveE2CC not implemented yet') - # PM = [1./(2.*self.dim)]*self.dim # plus / plus - # offset = [0]*2 + [self.ntEx]*2 - - # for ii, ind in enumerate(self._sortedCells): - # p = self._pointer(ind) - # w = self._levelWidth(p[-1]) - - # edges = [ - # self._ex2i[self._index([ p[0] , p[1] , p[2] , p[3]])], - # self._ex2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], - # self._ex2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])], - # self._ex2i[self._index([ p[0] , p[1] + w, p[2] + w, p[3]])], - # self._ey2i[self._index([ p[0] , p[1] , p[2] , p[3]])], - # self._ey2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], - # self._ey2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])], - # self._ey2i[self._index([ p[0] + w, p[1] , p[2] + w, p[3]])], - # self._ez2i[self._index([ p[0] , p[1] , p[2] , p[3]])], - # self._ez2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], - # self._ez2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], - # self._ez2i[self._index([ p[0] + w, p[1] + w, p[2] , p[3]])] - # ] - - # for off, pm, edge in zip(offset,PM,edges): - # I += [ii] - # J += [edge + off] - # V += [pm] + raise Exception('aveEx2CC not implemented in 2D') if self.dim == 3: - PM = [1./(4.*self.dim)]*4*self.dim # plus / plus - offset = [0]*4 + [self.ntEx]*4 + [self.ntEx+self.ntEy]*4 + PM = [1./4.]*4 for ii, ind in enumerate(self._sortedCells): p = self._pointer(ind) w = self._levelWidth(p[-1]) - edges = [ + edgesx = [ self._ex2i[self._index([ p[0] , p[1] , p[2] , p[3]])], self._ex2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], self._ex2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])], self._ex2i[self._index([ p[0] , p[1] + w, p[2] + w, p[3]])], + ] + + for pm, edge in zip(PM,edgesx): + I += [ii] + J += [edge] + V += [pm] + + Av = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.ntEx)) + Re = self._deflationMatrix('Ex',asOnes=False,withHanging=True) + + self._aveEx2CC = Av*Re + return self._aveEx2CC + + @property + def aveEy2CC(self): + "Construct the averaging operator on cell edges to cell centers." + if getattr(self, '_aveEy2CC', None) is None: + I, J, V = [], [], [] + + if self.dim == 2: + raise NotImplementedError('aveEy2CC not implemented in 2D') + + if self.dim == 3: + PM = [1./4.]*4 # plus / plus + + for ii, ind in enumerate(self._sortedCells): + p = self._pointer(ind) + w = self._levelWidth(p[-1]) + + edgesy = [ self._ey2i[self._index([ p[0] , p[1] , p[2] , p[3]])], self._ey2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], self._ey2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])], self._ey2i[self._index([ p[0] + w, p[1] , p[2] + w, p[3]])], + ] + + for pm, edge in zip(PM,edgesy): + I += [ii] + J += [edge] + V += [pm] + + Av = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.ntEy)) + Re = self._deflationMatrix('Ey',asOnes=False,withHanging=True) + + self._aveEy2CC = Av*Re + return self._aveEy2CC + + @property + def aveEz2CC(self): + "Construct the averaging operator on cell edges to cell centers." + # raise Exception('Not yet implemented!') + if getattr(self, '_aveEz2CC', None) is None: + I, J, V = [], [], [] + + if self.dim == 2: + raise Exception('There are no z edges in 2D') + + if self.dim == 3: + PM = [1./4.]*4 # plus / plus + + for ii, ind in enumerate(self._sortedCells): + p = self._pointer(ind) + w = self._levelWidth(p[-1]) + + edgesz = [ self._ez2i[self._index([ p[0] , p[1] , p[2] , p[3]])], self._ez2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], self._ez2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], - self._ez2i[self._index([ p[0] + w, p[1] + w, p[2] , p[3]])] + self._ez2i[self._index([ p[0] + w, p[1] + w, p[2] , p[3]])], ] - for off, pm, edge in zip(offset,PM,edges): + for pm, edge in zip(PM,edgesz): I += [ii] - J += [edge + off] + J += [edge] V += [pm] - Av = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.ntE)) - Re = self._deflationMatrix('E',asOnes=False,withHanging=True) + Av = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.ntEz)) + Re = self._deflationMatrix('Ez',asOnes=False,withHanging=True) - self._aveE2CC = Av*Re + self._aveEz2CC = Av*Re + return self._aveEz2CC + + @property + def aveE2CC(self): + "Construct the averaging operator on cell edges to cell centers." + if getattr(self, '_aveE2CC', None) is None: + if self.dim == 2: + raise Exception('aveE2CC not implemented in 2D') + elif self.dim == 3: + self._aveE2CC = 1./self.dim*sp.hstack([self.aveEx2CC, self.aveEy2CC, self.aveEz2CC]) return self._aveE2CC @property def aveE2CCV(self): "Construct the averaging operator on cell edges to cell centers." - raise Exception('Not yet implemented!') + # raise Exception('Not yet implemented!') + if getattr(self, '_aveE2CCV', None) is None: + if self.dim == 2: + raise Exception('aveE2CC not implemented in 2D') + elif self.dim == 3: + self._aveE2CCV = sp.block_diag([self.aveEx2CC, self.aveEy2CC, self.aveEz2CC]) + return self._aveE2CCV + + @property + def aveFx2CC(self): + if getattr(self, '_aveFx2CC', None) is None: + I, J, V = [], [], [] + PM = [1./2.]*self.dim # 0.5, 0.5 + + for ii, ind in enumerate(self._sortedCells): + p = self._pointer(ind) + w = self._levelWidth(p[-1]) + + if self.dim == 2: + facesx = [ + self._fx2i[self._index([ p[0] , p[1] , p[2]])], + self._fx2i[self._index([ p[0] + w, p[1] , p[2]])], + ] + + elif self.dim == 3: + facesx = [ + self._fx2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._fx2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], + ] + + for pm, face in zip(PM,facesx): + I += [ii] + J += [face] + V += [pm] + + Av = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.ntFx)) + Rf = self._deflationMatrix('Fx',asOnes=True,withHanging=True) + + self._aveFx2CC = Av*Rf + return self._aveFx2CC + + @property + def aveFy2CC(self): + if getattr(self, '_aveFy2CC', None) is None: + I, J, V = [], [], [] + PM = [1./2.]*2 # 0.5, 0.5 + + for ii, ind in enumerate(self._sortedCells): + p = self._pointer(ind) + w = self._levelWidth(p[-1]) + + if self.dim == 2: + facesy = [ + self._fy2i[self._index([ p[0] , p[1] , p[2]])], + self._fy2i[self._index([ p[0] , p[1] + w, p[2]])], + ] + elif self.dim == 3: + facesy = [ + self._fy2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._fy2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], + ] + + for pm, face in zip(PM,facesy): + I += [ii] + J += [face] + V += [pm] + + Av = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.ntFy)) + Rf = self._deflationMatrix('Fy',asOnes=True,withHanging=True) + + self._aveFy2CC = Av*Rf + return self._aveFy2CC + + @property + def aveFz2CC(self): + if getattr(self, '_aveFz2CC', None) is None: + I, J, V = [], [], [] + PM = [1./2.]*2 # 0.5, 0.5 + + for ii, ind in enumerate(self._sortedCells): + p = self._pointer(ind) + w = self._levelWidth(p[-1]) + + if self.dim == 2: + raise Exception('There are no z-faces in 2D') + elif self.dim == 3: + facesz = [ + self._fz2i[self._index([ p[0] , p[1] , p[2] , p[3]])], + self._fz2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])], + ] + + for pm, face in zip(PM,facesz): + I += [ii] + J += [face] + V += [pm] + + Av = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.ntFz)) + Rf = self._deflationMatrix('Fz',asOnes=True,withHanging=True) + self._aveFz2CC = Av*Rf + return self._aveFz2CC @property def aveF2CC(self): "Construct the averaging operator on cell faces to cell centers." if getattr(self, '_aveF2CC', None) is None: - # TODO: Preallocate! - I, J, V = [], [], [] - PM = [1./(2.*self.dim)]*2*self.dim # plus / plus - - # TODO total number of faces? - offset = [0]*2 + [self.ntFx]*2 + [self.ntFx+self.ntFy]*2 - - for ii, ind in enumerate(self._sortedCells): - - p = self._pointer(ind) - w = self._levelWidth(p[-1]) - - if self.dim == 2: - faces = [ - self._fx2i[self._index([ p[0] , p[1] , p[2]])], - self._fx2i[self._index([ p[0] + w, p[1] , p[2]])], - self._fy2i[self._index([ p[0] , p[1] , p[2]])], - self._fy2i[self._index([ p[0] , p[1] + w, p[2]])] - ] - elif self.dim == 3: - faces = [ - self._fx2i[self._index([ p[0] , p[1] , p[2] , p[3]])], - self._fx2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], - self._fy2i[self._index([ p[0] , p[1] , p[2] , p[3]])], - self._fy2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], - self._fz2i[self._index([ p[0] , p[1] , p[2] , p[3]])], - self._fz2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])] - ] - - for off, pm, face in zip(offset,PM,faces): - I += [ii] - J += [face + off] - V += [pm] - - - Av = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.ntF)) - Rf = self._deflationMatrix('F',asOnes=True,withHanging=True) - - self._aveF2CC = Av*Rf + if self.dim == 2: + self._aveF2CC = 1./self.dim*sp.hstack([self.aveFx2CC, self.aveFy2CC]) + elif self.dim == 3: + self._aveF2CC = 1./self.dim*sp.hstack([self.aveFx2CC, self.aveFy2CC, self.aveFz2CC]) return self._aveF2CC - @property def aveF2CCV(self): "Construct the averaging operator on cell faces to cell centers." if getattr(self, '_aveF2CCV', None) is None: - # TODO: Preallocate! - I, J, V = [], [], [] - PM = [1./2.]*2 # 0.5, 0.5 - - offsetx = [0]*2 - offsety = [self.ntFx]*2 - if self.dim == 2: - for ii, ind in enumerate(self._sortedCells): - p = self._pointer(ind) - w = self._levelWidth(p[-1]) - - facesx = [ - self._fx2i[self._index([ p[0] , p[1] , p[2]])], - self._fx2i[self._index([ p[0] + w, p[1] , p[2]])], - ] - - facesy = [ - self._fy2i[self._index([ p[0] , p[1] , p[2]])], - self._fy2i[self._index([ p[0] , p[1] + w, p[2]])], - ] - - for off, pm, face in zip(offsetx,PM,facesx): - I += [ii] - J += [face + off] - V += [pm] - - for off, pm, face in zip(offsety,PM,facesy): - I += [ii + self.nC] - J += [face + off] - V += [pm] - - - - if self.dim == 3: - offsetz = [self.ntFx + self.ntFy]*2 - - for ii, ind in enumerate(self._sortedCells): - p = self._pointer(ind) - w = self._levelWidth(p[-1]) - - facesx = [ - self._fx2i[self._index([ p[0] , p[1] , p[2] , p[3]])], - self._fx2i[self._index([ p[0] + w, p[1] , p[2] , p[3]])], - ] - - facesy = [ - self._fy2i[self._index([ p[0] , p[1] , p[2] , p[3]])], - self._fy2i[self._index([ p[0] , p[1] + w, p[2] , p[3]])], - ] - facesz = [ - self._fz2i[self._index([ p[0] , p[1] , p[2] , p[3]])], - self._fz2i[self._index([ p[0] , p[1] , p[2] + w, p[3]])] - ] - - for off, pm, face in zip(offsetx,PM,facesx): - I += [ii] - J += [face + off] - V += [pm] - - for off, pm, face in zip(offsety,PM,facesy): - I += [ii + self.nC] - J += [face + off] - V += [pm] - - for off, pm, face in zip(offsetz,PM,facesz): - I += [ii + self.nC*2] - J += [face + off] - V += [pm] - - Av = sp.csr_matrix((V,(I,J)), shape=(self.nC*self.dim, self.ntF)) - Rf = self._deflationMatrix('F',asOnes=True,withHanging=True) - - self._aveF2CCV = Av*Rf + self._aveF2CCV = sp.block_diag([self.aveFx2CC, self.aveFy2CC]) + elif self.dim == 3: + self._aveF2CCV = sp.block_diag([self.aveFx2CC, self.aveFy2CC, self.aveFz2CC]) return self._aveF2CCV From 87eb02b76bb1db2873ddac4c20f0210cbb39f081 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Sun, 15 Nov 2015 18:16:07 -0800 Subject: [PATCH 69/83] Fancy mesh example --- SimPEG/Mesh/TreeMesh.py | 76 +++++++++++++++++------------------------ 1 file changed, 31 insertions(+), 45 deletions(-) diff --git a/SimPEG/Mesh/TreeMesh.py b/SimPEG/Mesh/TreeMesh.py index 77d5c9de..60410607 100644 --- a/SimPEG/Mesh/TreeMesh.py +++ b/SimPEG/Mesh/TreeMesh.py @@ -103,44 +103,6 @@ import time MAX_BITS = 20 -class Cell(object): - def __init__(self, mesh, index, pointer): - self.mesh = mesh - self._index = index - self._pointer = pointer - - # @property - # def nodes(self): - # REFACTOR WITH self.x0 and self.h, mesh is not currently numbered!! - # p = self._pointer - # w = self.mesh._levelWidth(p[-1]) - # if self.dim == 2: - # return [self._n2i[self.mesh._index([p[0] , p[1] , p[2]])], - # self._n2i[self.mesh._index([p[0] + w, p[1] , p[2]])], - # self._n2i[self.mesh._index([p[0] , p[1] + w, p[2]])], - # self._n2i[self.mesh._index([p[0] + w, p[1] + w, p[2]])]] - # elif self.dim == 3: - # return [self._n2i[self.mesh._index([p[0] , p[1] , p[2] , p[3]])], - # self._n2i[self.mesh._index([p[0] + w, p[1] , p[2] , p[3]])], - # self._n2i[self.mesh._index([p[0] , p[1] + w, p[2] , p[3]])], - # self._n2i[self.mesh._index([p[0] + w, p[1] + w, p[2] , p[3]])], - # self._n2i[self.mesh._index([p[0] , p[1] , p[2] + w, p[3]])], - # self._n2i[self.mesh._index([p[0] + w, p[1] , p[2] + w, p[3]])], - # self._n2i[self.mesh._index([p[0] , p[1] + w, p[2] + w, p[3]])], - # self._n2i[self.mesh._index([p[0] + w, p[1] + w, p[2] + w, p[3]])]] - - @property - def center(self): - if getattr(self, '_center', None) is None: - self._center = self.mesh._cellC(self._pointer) - return self._center - @property - def h(self): return self.mesh._cellH(self._pointer) - @property - def x0(self): return self.mesh._cellN(self._pointer) - @property - def dim(self): return self.mesh.dim - class TreeMesh(BaseMesh, InnerProducts): def __init__(self, h_in, x0_in=None, levels=3): assert type(h_in) is list, 'h_in must be a list' @@ -1854,6 +1816,23 @@ class TreeMesh(BaseMesh, InnerProducts): plt.colorbar(scalarMap) if showIt: plt.show() +class Cell(object): + def __init__(self, mesh, index, pointer): + self.mesh = mesh + self._index = index + self._pointer = pointer + + @property + def center(self): + if getattr(self, '_center', None) is None: + self._center = self.mesh._cellC(self._pointer) + return self._center + @property + def h(self): return self.mesh._cellH(self._pointer) + @property + def x0(self): return self.mesh._cellN(self._pointer) + @property + def dim(self): return self.mesh.dim def SortGrid(grid, offset=0): """ @@ -1899,24 +1878,31 @@ class NotBalancedException(Exception): if __name__ == '__main__': + def topo(x): + return np.sin(x*(2.*np.pi))*0.3 + 0.5 def function(cell): r = cell.center - np.array([0.5]*len(cell.center)) - dist = np.sqrt(r.dot(r)) + dist1 = np.sqrt(r.dot(r)) - 0.08 + dist2 = np.abs(cell.center[-1] - topo(cell.center[0])) + + dist = min([dist1,dist2]) # if dist < 0.05: # return 5 - if dist < 0.1: - return 4 + if dist < 0.05: + return 6 + if dist < 0.2: + return 5 if dist < 0.3: - return 3 + return 4 if dist < 1.0: - return 2 + return 3 else: return 0 # T = TreeMesh([[(1,128)],[(1,128)],[(1,128)]],levels=7) # T = TreeMesh([128,128,128],levels=7) - T = TreeMesh([16,16],levels=4) + T = TreeMesh([64,64],levels=6) # T = TreeMesh([[(1,128)],[(1,128)]],levels=7) # T.refine(lambda xc:1, balance=False) # T._index([0,0,0]) @@ -1928,7 +1914,7 @@ if __name__ == '__main__': print time.time() - tic print T.nC - T.plotImage(np.random.rand(T.nC),showIt=True) + T.plotImage(T.vol,showIt=True) # print T.getFaceInnerProduct() # print T.gridFz From eafa2bfbe8239a520a25c3d3472e211eaff4c7b0 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Sun, 15 Nov 2015 19:08:40 -0800 Subject: [PATCH 70/83] Minor performance updates. --- SimPEG/Mesh/TreeMesh.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/SimPEG/Mesh/TreeMesh.py b/SimPEG/Mesh/TreeMesh.py index 60410607..2de403ce 100644 --- a/SimPEG/Mesh/TreeMesh.py +++ b/SimPEG/Mesh/TreeMesh.py @@ -380,7 +380,7 @@ class TreeMesh(BaseMesh, InnerProducts): if p[-1] >= self.levels: continue do = function(Cell(self, cell, p)) > p[-1] if do: - recurse += self._refineCell(cell) + recurse += self._refineCell(cell, p) if verbose: print ' ', time.time() - tic @@ -391,9 +391,9 @@ class TreeMesh(BaseMesh, InnerProducts): self.balance() return recurse - def _refineCell(self, pointer): - pointer = self._asPointer(pointer) - ind = self._asIndex(pointer) + def _refineCell(self, ind, pointer=None): + ind = self._asIndex(ind) + pointer = self._asPointer(pointer if pointer is not None else ind) assert ind in self h = self._levelWidth(pointer[-1])/2 # halfWidth nL = pointer[-1] + 1 # new level From e0684a08203e6d7953a6ee82d549eb7e21646f56 Mon Sep 17 00:00:00 2001 From: Lindsey Heagy Date: Sun, 15 Nov 2015 21:33:54 -0800 Subject: [PATCH 71/83] aveN2CC --- SimPEG/Mesh/TreeMesh.py | 42 ++++++++++++++++++++++++++++++++ tests/mesh/test_TreeOperators.py | 28 ++++++++++----------- 2 files changed, 56 insertions(+), 14 deletions(-) diff --git a/SimPEG/Mesh/TreeMesh.py b/SimPEG/Mesh/TreeMesh.py index 2de403ce..4fc9451f 100644 --- a/SimPEG/Mesh/TreeMesh.py +++ b/SimPEG/Mesh/TreeMesh.py @@ -1608,6 +1608,48 @@ class TreeMesh(BaseMesh, InnerProducts): self._aveF2CCV = sp.block_diag([self.aveFx2CC, self.aveFy2CC, self.aveFz2CC]) return self._aveF2CCV + @property + def aveN2CC(self): + if getattr(self, '_aveN2CC', None) is None: + I, J, V = [], [], [] + PM = [1./2.**self.dim] * 2**self.dim + + for ii, ind in enumerate(self._sortedCells): + p = self._pointer(ind) + w = self._levelWidth(p[-1]) + + if self.dim == 2: + nodes = [ + self._n2i[self._index([ p[0] , p[1] , p[2] ])], + self._n2i[self._index([ p[0] + w, p[1] , p[2] ])], + self._n2i[self._index([ p[0] , p[1] + w, p[2] ])], + self._n2i[self._index([ p[0] + w, p[1] + w, p[2] ])], + ] + + + if self.dim == 3: + nodes = [ + self._n2i[self._index([ p[0] , p[1] , p[2] , p[3] ])], + self._n2i[self._index([ p[0] + w, p[1] , p[2] , p[3] ])], + self._n2i[self._index([ p[0] , p[1] + w, p[2] , p[3] ])], + self._n2i[self._index([ p[0] + w, p[1] + w, p[2] , p[3] ])], + self._n2i[self._index([ p[0] , p[1] , p[2] + w, p[3] ])], + self._n2i[self._index([ p[0] + w, p[1] , p[2] + w, p[3] ])], + self._n2i[self._index([ p[0] , p[1] + w, p[2] + w, p[3] ])], + self._n2i[self._index([ p[0] + w, p[1] + w, p[2] + w, p[3] ])], + ] + + for pm, node in zip(PM,nodes): + I += [ii] + J += [node] + V += [pm] + + Av = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.ntN)) + Re = self._deflationMatrix('N',asOnes=False,withHanging=True) + + self._aveN2CC = Av*Re + return self._aveN2CC + def _getFaceP(self, xFace, yFace, zFace): ind1, ind2, ind3 = [], [], [] diff --git a/tests/mesh/test_TreeOperators.py b/tests/mesh/test_TreeOperators.py index a5eb1358..1a62673e 100644 --- a/tests/mesh/test_TreeOperators.py +++ b/tests/mesh/test_TreeOperators.py @@ -413,13 +413,13 @@ class TestTreeAveraging2D(Tests.OrderTest): return err - # def test_orderN2CC(self): - # self.name = "Averaging 2D: N2CC" - # fun = lambda x, y: (np.cos(x)+np.sin(y)) - # self.getHere = lambda M: call2(fun, M.gridN) - # self.getThere = lambda M: call2(fun, M.gridCC) - # self.getAve = lambda M: M.aveN2CC - # self.orderTest() + def test_orderN2CC(self): + self.name = "Averaging 2D: N2CC" + fun = lambda x, y: (np.cos(x)+np.sin(y)) + self.getHere = lambda M: call2(fun, M.gridN) + self.getThere = lambda M: call2(fun, M.gridCC) + self.getAve = lambda M: M.aveN2CC + self.orderTest() # def test_orderN2F(self): # self.name = "Averaging 2D: N2F" @@ -496,13 +496,13 @@ class TestAveraging3D(Tests.OrderTest): err = np.linalg.norm((self.getThere(self.M)-num), np.inf) return err -# def test_orderN2CC(self): -# self.name = "Averaging 3D: N2CC" -# fun = lambda x, y, z: (np.cos(x)+np.sin(y)+np.exp(z)) -# self.getHere = lambda M: call3(fun, M.gridN) -# self.getThere = lambda M: call3(fun, M.gridCC) -# self.getAve = lambda M: M.aveN2CC -# self.orderTest() + def test_orderN2CC(self): + self.name = "Averaging 3D: N2CC" + fun = lambda x, y, z: (np.cos(x)+np.sin(y)+np.exp(z)) + self.getHere = lambda M: call3(fun, M.gridN) + self.getThere = lambda M: call3(fun, M.gridCC) + self.getAve = lambda M: M.aveN2CC + self.orderTest() # def test_orderN2F(self): # self.name = "Averaging 3D: N2F" From 61460261f0a6f4e6e8fc9ab444bc43f2280f07f2 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Tue, 17 Nov 2015 18:44:13 -0800 Subject: [PATCH 72/83] Updates to setup.py Add a cleanall, and try to make the cython build things in the correct place. --- setup.py | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/setup.py b/setup.py index bca20d59..04427658 100644 --- a/setup.py +++ b/setup.py @@ -5,10 +5,15 @@ SimPEG is a python package for simulation and gradient based parameter estimation in the context of geophysical applications. """ +import numpy as np + +import os +import sys +import subprocess + from distutils.core import setup from setuptools import find_packages from distutils.extension import Extension -import numpy as np CLASSIFIERS = [ 'Development Status :: 4 - Beta', @@ -26,14 +31,31 @@ CLASSIFIERS = [ 'Natural Language :: English', ] +args = sys.argv[1:] -from distutils.core import setup +# Make a `cleanall` rule to get rid of intermediate and library files +if "cleanall" in args: + print "Deleting cython files..." + # Just in case the build directory was created by accident, + # note that shell=True should be OK here because the command is constant. + subprocess.Popen("rm -rf build", shell=True, executable="/bin/bash") + subprocess.Popen("find . -name \*.c -type f -delete", shell=True, executable="/bin/bash") + subprocess.Popen("find . -name \*.so -type f -delete", shell=True, executable="/bin/bash") + # Now do a normal clean + sys.argv[sys.argv.index('cleanall')] = "clean" + +# We want to always use build_ext --inplace +if args.count("build_ext") > 0 and args.count("--inplace") == 0: + sys.argv.insert(sys.argv.index("build_ext")+1, "--inplace") try: from Cython.Build import cythonize + from Cython.Distutils import build_ext + cythonKwargs = dict(cmdclass={'build_ext': build_ext}) USE_CYTHON = True except Exception, e: USE_CYTHON = False + cythonKwargs = dict() ext = '.pyx' if USE_CYTHON else '.c' @@ -41,9 +63,9 @@ cython_files = [ "SimPEG/Utils/interputils_cython", "SimPEG/Mesh/TreeUtils" ] -extensions = [Extension(f, [f+ext]) for f in cython_files] +extensions = [Extension(f, [f+ext], include_dirs=[np.get_include()]) for f in cython_files] -if USE_CYTHON: +if USE_CYTHON and "cleanall" not in args: from Cython.Build import cythonize extensions = cythonize(extensions) @@ -71,6 +93,6 @@ setup( classifiers=CLASSIFIERS, platforms = ["Windows", "Linux", "Solaris", "Mac OS-X", "Unix"], use_2to3 = False, - include_dirs=[np.get_include()], - ext_modules = extensions + ext_modules = extensions, + **cythonKwargs ) From 5afaa54ad9f99c271f59b7ca9e03ad76402d69ad Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Tue, 17 Nov 2015 18:46:01 -0800 Subject: [PATCH 73/83] Remove compiling of C ext with numpy exts. This should be done at run time. --- setup.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 04427658..531dc539 100644 --- a/setup.py +++ b/setup.py @@ -63,7 +63,7 @@ cython_files = [ "SimPEG/Utils/interputils_cython", "SimPEG/Mesh/TreeUtils" ] -extensions = [Extension(f, [f+ext], include_dirs=[np.get_include()]) for f in cython_files] +extensions = [Extension(f, [f+ext]) for f in cython_files] if USE_CYTHON and "cleanall" not in args: from Cython.Build import cythonize @@ -93,6 +93,7 @@ setup( classifiers=CLASSIFIERS, platforms = ["Windows", "Linux", "Solaris", "Mac OS-X", "Unix"], use_2to3 = False, + include_dirs=[np.get_include()], ext_modules = extensions, **cythonKwargs ) From 1718e3506defd4f27078c06e7620c64c58d7f81b Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Tue, 17 Nov 2015 19:47:10 -0800 Subject: [PATCH 74/83] Interpolation --- SimPEG/Mesh/TreeMesh.py | 310 +++++++++++++++++++++++++-- SimPEG/Utils/interputils.py | 16 +- SimPEG/Utils/interputils_cython.c | 98 ++++----- SimPEG/Utils/interputils_cython.pyx | 14 +- tests/mesh/test_TreeInterpolation.py | 182 ++++++++++++++++ tests/mesh/test_TreeMesh.py | 93 +++++++- 6 files changed, 629 insertions(+), 84 deletions(-) create mode 100644 tests/mesh/test_TreeInterpolation.py diff --git a/SimPEG/Mesh/TreeMesh.py b/SimPEG/Mesh/TreeMesh.py index 4fc9451f..4f4e98d3 100644 --- a/SimPEG/Mesh/TreeMesh.py +++ b/SimPEG/Mesh/TreeMesh.py @@ -104,9 +104,12 @@ import time MAX_BITS = 20 class TreeMesh(BaseMesh, InnerProducts): + + _meshType = 'TREE' + def __init__(self, h_in, x0_in=None, levels=3): assert type(h_in) is list, 'h_in must be a list' - assert len(h_in) > 1, "len(h_in) must be greater than 1" + assert len(h_in) in [2,3], "There is only support for TreeMesh in 2D or 3D." h = range(len(h_in)) for i, h_i in enumerate(h_in): @@ -119,7 +122,7 @@ class TreeMesh(BaseMesh, InnerProducts): assert len(h_i.shape) == 1, ("h[%i] must be a 1D numpy array." % i) assert len(h_i) == 2**levels, "must make h and levels match" h[i] = h_i[:] # make a copy. - self.h = h + self._h = h x0 = np.zeros(len(h)) if x0_in is not None: @@ -149,7 +152,12 @@ class TreeMesh(BaseMesh, InnerProducts): @property def __dirty__(self): - return self.__dirtyFaces__ or self.__dirtyEdges__ or self.__dirtyNodes__ or self.__dirtyHanging__ or self.__dirtySets__ + return (self.__dirtyFaces__ or + self.__dirtyEdges__ or + self.__dirtyNodes__ or + self.__dirtyCells__ or + self.__dirtyHanging__ or + self.__dirtySets__) @__dirty__.setter def __dirty__(self, val): @@ -157,6 +165,7 @@ class TreeMesh(BaseMesh, InnerProducts): self.__dirtyFaces__ = True self.__dirtyEdges__ = True self.__dirtyNodes__ = True + self.__dirtyCells__ = True self.__dirtyHanging__ = True self.__dirtySets__ = True @@ -175,6 +184,95 @@ class TreeMesh(BaseMesh, InnerProducts): @property def levels(self): return self._levels + @property + def h(self): + """h is a list containing the cell widths of the tensor mesh in each dimension.""" + return self._h + + @property + def hx(self): + "Width of cells in the x direction" + return self._h[0] + + @property + def hy(self): + "Width of cells in the y direction" + return self._h[1] + + @property + def hz(self): + "Width of cells in the z direction" + return None if self.dim < 3 else self._h[2] + + @property + def vectorNx(self): + """Nodal grid vector (1D) in the x direction.""" + return np.r_[0., self.hx.cumsum()] + self.x0[0] + + @property + def vectorNy(self): + """Nodal grid vector (1D) in the y direction.""" + return np.r_[0., self.hy.cumsum()] + self.x0[1] + + @property + def vectorNz(self): + """Nodal grid vector (1D) in the z direction.""" + return None if self.dim < 3 else np.r_[0., self.hz.cumsum()] + self.x0[2] + + @property + def vectorCCx(self): + """Cell-centered grid vector (1D) in the x direction.""" + return np.r_[0, self.hx[:-1].cumsum()] + self.hx*0.5 + self.x0[0] + + @property + def vectorCCy(self): + """Cell-centered grid vector (1D) in the y direction.""" + return np.r_[0, self.hy[:-1].cumsum()] + self.hy*0.5 + self.x0[1] + + @property + def vectorCCz(self): + """Cell-centered grid vector (1D) in the z direction.""" + return None if self.dim < 3 else np.r_[0, self.hz[:-1].cumsum()] + self.hz*0.5 + self.x0[2] + + def getTensor(self, key): + """ Returns a tensor list. + + :param str key: What tensor (see below) + :rtype: list + :return: list of the tensors that make up the mesh. + + key can be:: + + 'CC' -> scalar field defined on cell centers + 'N' -> scalar field defined on nodes + 'Fx' -> x-component of field defined on faces + 'Fy' -> y-component of field defined on faces + 'Fz' -> z-component of field defined on faces + 'Ex' -> x-component of field defined on edges + 'Ey' -> y-component of field defined on edges + 'Ez' -> z-component of field defined on edges + + """ + + if key == 'Fx': + ten = [self.vectorNx , self.vectorCCy, self.vectorCCz] + elif key == 'Fy': + ten = [self.vectorCCx, self.vectorNy , self.vectorCCz] + elif key == 'Fz': + ten = [self.vectorCCx, self.vectorCCy, self.vectorNz ] + elif key == 'Ex': + ten = [self.vectorCCx, self.vectorNy , self.vectorNz ] + elif key == 'Ey': + ten = [self.vectorNx , self.vectorCCy, self.vectorNz ] + elif key == 'Ez': + ten = [self.vectorNx , self.vectorNy , self.vectorCCz] + elif key == 'CC': + ten = [self.vectorCCx, self.vectorCCy, self.vectorCCz] + elif key == 'N': + ten = [self.vectorNx , self.vectorNy , self.vectorNz ] + + return [t for t in ten if t is not None] + @property def nC(self): return len(self._cells) @@ -282,6 +380,10 @@ class TreeMesh(BaseMesh, InnerProducts): def ntF(self): return self.ntFx + self.ntFy + (0 if self.dim == 2 else self.ntFz) + @property + def vntF(self): + return [self.ntFx, self.ntFy] + ([] if self.dim == 2 else [self.ntFz]) + @property def ntFx(self): self.number() @@ -302,6 +404,10 @@ class TreeMesh(BaseMesh, InnerProducts): def ntE(self): return self.ntEx + self.ntEy + (0 if self.dim == 2 else self.ntEz) + @property + def vntE(self): + return [self.ntEx, self.ntEy] + ([] if self.dim == 2 else [self.ntEz]) + @property def ntEx(self): if self.dim == 2:return self.ntFy @@ -491,6 +597,7 @@ class TreeMesh(BaseMesh, InnerProducts): def _parentPointer(self, pointer): + if pointer[-1] == 0: return None mod = self._levelWidth(pointer[-1] - 1) return [p - (p % mod) for p in pointer[:-1]] + [pointer[-1]-1] @@ -760,6 +867,14 @@ class TreeMesh(BaseMesh, InnerProducts): self.__dirtySets__ = False + + def _numberCells(self, force=False): + if not self.__dirtyCells__ and not force: return + self._cc2i = dict() + for ii, c in enumerate(sorted(self._cells)): + self._cc2i[c] = ii + self.__dirtyCells__ = False + def _numberNodes(self, force=False): if not self.__dirtyNodes__ and not force: return self._createNumberingSets(force=force) @@ -878,6 +993,7 @@ class TreeMesh(BaseMesh, InnerProducts): def _hanging(self, force=False): if not self.__dirtyHanging__ and not force: return + self._numberCells(force=force) self._numberNodes(force=force) self._numberFaces(force=force) self._numberEdges(force=force) @@ -1649,7 +1765,7 @@ class TreeMesh(BaseMesh, InnerProducts): self._aveN2CC = Av*Re return self._aveN2CC - + def _getFaceP(self, xFace, yFace, zFace): ind1, ind2, ind3 = [], [], [] @@ -1723,12 +1839,165 @@ class TreeMesh(BaseMesh, InnerProducts): return Pxxx + def isInside(self, pts, locType='N'): + """ + Determines if a set of points are inside a mesh. + + :param numpy.ndarray pts: Location of points to test + :rtype numpy.ndarray + :return inside, numpy array of booleans + """ + pts = Utils.asArray_N_x_Dim(pts, self.dim) + + tensors = self.getTensor(locType) + + if locType == 'N' and self._meshType == 'CYL': + #NOTE: for a CYL mesh we add a node to check if we are inside in the radial direction! + tensors[0] = np.r_[0.,tensors[0]] + tensors[1] = np.r_[tensors[1], 2.0*np.pi] + + inside = np.ones(pts.shape[0],dtype=bool) + for i, tensor in enumerate(tensors): + TOL = np.diff(tensor).min() * 1.0e-10 + inside = inside & (pts[:,i] >= tensor.min()-TOL) & (pts[:,i] <= tensor.max()+TOL) + return inside + + def point2index(self, locs): + locs = Utils.asArray_N_x_Dim(locs, self.dim) + + TOL = 1e-10 + + Nx = self.vectorNx + Ny = self.vectorNy + Nz = self.vectorNz + + pointers = range(self.dim) + Nx = np.r_[Nx[0] - TOL, Nx[1:-1], Nx[-1] + TOL] + pointers[0] = np.searchsorted(Nx, locs[:,0]) + Ny = np.r_[Ny[0] - TOL, Ny[1:-1], Ny[-1] + TOL] + pointers[1] = np.searchsorted(Ny, locs[:,1]) + if self.dim == 3: + Nz = np.r_[Nz[0] - TOL, Nz[1:-1], Nz[-1] + TOL] + pointers[2] = np.searchsorted(Nz, locs[:,2]) + + if np.any([np.any(P == len(N)) or np.any(P == 0) for P,N in zip(pointers,[Nx,Ny,Nz])]): + raise Exception('There are points outside of the mesh.') + + out = [] + for pointer in zip(*pointers): + for level in range(self.levels+1): + width = self._levelWidth(level) + testPointer = [((p-1)//width)*width for p in pointer] + [level] + test = self._index(testPointer) + if test in self: + out += [test] + break + return out + + + def getInterpolationMat(self, locs, locType, zerosOutside=False): + """ Produces interpolation matrix + + :param numpy.ndarray locs: Location of points to interpolate to + :param str locType: What to interpolate (see below) + :rtype: scipy.sparse.csr.csr_matrix + :return: M, the interpolation matrix + + locType can be:: + + 'Ex' -> x-component of field defined on edges + 'Ey' -> y-component of field defined on edges + 'Ez' -> z-component of field defined on edges + 'Fx' -> x-component of field defined on faces + 'Fy' -> y-component of field defined on faces + 'Fz' -> z-component of field defined on faces + 'N' -> scalar field defined on nodes + 'CC' -> scalar field defined on cell centers + """ + if 'E' in locType and self.dim == 2: raise Exception('Interpolation for edges is not supported in 2D.') + locs = Utils.asArray_N_x_Dim(locs, self.dim) + + TOL = 1e-10 + self.number() + + cells = self.point2index(locs) + I,J,V=[],[],[] + numberer = getattr(self, '_'+locType.lower()+'2i') + + if zerosOutside is False: + assert np.all(self.isInside(locs)), "Points outside of mesh" + else: + indZeros = np.logical_not(self.isInside(locs)) + locs[indZeros, :] = np.array([v.mean() for v in self.getTensor('CC')]) + + if locType in ['Fx','Fy','Fz','Ex','Ey','Ez']: + ind = {'x':0, 'y':1, 'z':2}[locType[1]] + assert self.dim >= ind, 'mesh is not high enough dimension.' + antiInd = {'x':[1,2], 'y':[0,2], 'z':[0,1]}[locType[1]][:self.dim-1] + nF_nE = self.vntF if 'F' in locType else self.vntE + components = [Utils.spzeros(locs.shape[0], n) for n in nF_nE] + + for ii, cell in enumerate(cells): + loc = locs[ii,:] + p = self._asPointer(cell) + h, n = self._cellH(p), self._cellN(p) + w = self._levelWidth(p[-1]) + if 'E' in locType: + iLocs, weights = Utils.interputils._interpmat2D(np.array([(loc-n-self.x0)[antiInd]]),np.r_[0.,h[antiInd[0]]+TOL],np.r_[0.,h[antiInd[1]]+TOL]) + newJ = [numberer[self._index([__+w*iLocs[IND][0] if _ == antiInd[0] else __+w*iLocs[IND][1] if _ == antiInd[1] else __ for _, __ in enumerate(p[:-1])] + [p[-1]])] for IND in range(4)] #sorry + elif 'F' in locType: + _, weights = Utils.interputils._interpmat1D(np.r_[(loc-n-self.x0)[ind]],np.r_[0.,h[ind]+TOL]) + plusFace = self._index([__+w if _ == ind else __ for _, __ in enumerate(p[:-1])] + [p[-1]]) + newJ = [numberer[cell], numberer[plusFace]] + I += [ii]*len(newJ) + J += newJ + V += weights + + components[ind] = sp.csr_matrix((V,(I,J)), shape=(locs.shape[0], nF_nE[ind])) + # remove any zero blocks (hstack complains) + components = [comp for comp in components if comp.shape[1] > 0] + Q = sp.hstack(components).tocsr() + if 'E' in locType: + R = self._deflationMatrix(locType[0],asOnes=False,withHanging=True) + else: # faces + R = self._deflationMatrix(locType[0],asOnes=True,withHanging=True) + elif locType == 'N': + for ii, cell in enumerate(cells): + loc = locs[ii,:] + p = self._asPointer(cell) + h, n = self._cellH(p), self._cellN(p) + w = self._levelWidth(p[-1]) + + iLocs, weights = Utils.interputils._interpmat3D(np.array([(loc-n-self.x0)]),*[np.r_[0.,h[_]+TOL] for _ in range(3)]) + newJ = [numberer[self._index([__+w*iLocs[IND][_] for _, __ in enumerate(p[:-1])] + [p[-1]])] for IND in range(8)] #sorry + + I += [ii]*len(newJ) + J += newJ + V += weights + + Q = sp.csr_matrix((V,(I,J)), shape=(locs.shape[0], self.ntN)) + R = self._deflationMatrix('N',withHanging=True) + elif locType == 'CC': + for ii, cell in enumerate(cells): + I += [ii] + J += [numberer[cell]] + V += [1.0] + Q = sp.csr_matrix((V,(I,J)), shape=(locs.shape[0], self.nC)) + R = Utils.Identity() + else: + raise NotImplementedError('getInterpolationMat: locType=='+locType+' and mesh.dim=='+str(self.dim)) + + if zerosOutside: + Q[indZeros, :] = 0 + + return Q * R + def plotGrid(self, ax=None, showIt=False, - grid=True, - cells=True, cellLine=False, - nodes=False, - facesX=False, facesY=False, facesZ=False, - edgesX=False, edgesY=False, edgesZ=False): + grid=True, + cells=True, cellLine=False, + nodes=False, + facesX=False, facesY=False, facesZ=False, + edgesX=False, edgesY=False, edgesZ=False): # self.number() @@ -1840,7 +2109,6 @@ class TreeMesh(BaseMesh, InnerProducts): if showIt:plt.show() - def plotImage(self, I, ax=None, showIt=True): if self.dim == 3: raise Exception() @@ -1914,7 +2182,6 @@ def SortGrid(grid, offset=0): return sorted(range(offset,grid.shape[0]+offset), key=K) - class NotBalancedException(Exception): pass @@ -1944,19 +2211,26 @@ if __name__ == '__main__': # T = TreeMesh([[(1,128)],[(1,128)],[(1,128)]],levels=7) # T = TreeMesh([128,128,128],levels=7) - T = TreeMesh([64,64],levels=6) + # T = TreeMesh([64,64],levels=6) + T = TreeMesh([4,4,4],levels=2) # T = TreeMesh([[(1,128)],[(1,128)]],levels=7) - # T.refine(lambda xc:1, balance=False) + # T.refine(lambda xc:2, balance=False) # T._index([0,0,0]) # T._pointer(0) - tic = time.time() - T.refine(function)#, balance=False) - print time.time() - tic + # tic = time.time() + # T.refine(function)#, balance=False) + # print time.time() - tic + # print T.nC + print T.nC - T.plotImage(T.vol,showIt=True) + P = T.getInterpolationMat([0.2,0,0], 'Ex') + print P.todense() + blah + + # T.plotImage(np.arange(len(T.vol)),showIt=True) # print T.getFaceInnerProduct() # print T.gridFz @@ -1972,7 +2246,7 @@ if __name__ == '__main__': # T.__dirty__ = True - print T.gridFx.shape[0], T.nFx + # print T.gridFx.shape[0], T.nFx diff --git a/SimPEG/Utils/interputils.py b/SimPEG/Utils/interputils.py index 8fff1dcb..17b9b469 100644 --- a/SimPEG/Utils/interputils.py +++ b/SimPEG/Utils/interputils.py @@ -124,13 +124,13 @@ if not _interpCython: ind_x1, ind_x2, wx1, wx2 = _interp_point_1D(x, locs[i, 0]) ind_y1, ind_y2, wy1, wy2 = _interp_point_1D(y, locs[i, 1]) - inds += [( ind_x1, ind_y2), - ( ind_x1, ind_y1), + inds += [( ind_x1, ind_y1), + ( ind_x1, ind_y2), ( ind_x2, ind_y1), ( ind_x2, ind_y2)] - vals += [wx1*wy2, - wx1*wy1, + vals += [wx1*wy1, + wx1*wy2, wx2*wy1, wx2*wy2] @@ -152,8 +152,8 @@ if not _interpCython: ind_y1, ind_y2, wy1, wy2 = _interp_point_1D(y, locs[i, 1]) ind_z1, ind_z2, wz1, wz2 = _interp_point_1D(z, locs[i, 2]) - inds += [( ind_x1, ind_y2, ind_z1), - ( ind_x1, ind_y1, ind_z1), + inds += [( ind_x1, ind_y1, ind_z1), + ( ind_x1, ind_y2, ind_z1), ( ind_x2, ind_y1, ind_z1), ( ind_x2, ind_y2, ind_z1), ( ind_x1, ind_y1, ind_z2), @@ -161,8 +161,8 @@ if not _interpCython: ( ind_x2, ind_y1, ind_z2), ( ind_x2, ind_y2, ind_z2)] - vals += [wx1*wy2*wz1, - wx1*wy1*wz1, + vals += [wx1*wy1*wz1, + wx1*wy2*wz1, wx2*wy1*wz1, wx2*wy2*wz1, wx1*wy1*wz2, diff --git a/SimPEG/Utils/interputils_cython.c b/SimPEG/Utils/interputils_cython.c index ab5fdd3a..d03d682c 100644 --- a/SimPEG/Utils/interputils_cython.c +++ b/SimPEG/Utils/interputils_cython.c @@ -2546,7 +2546,7 @@ static PyObject *__pyx_pf_6SimPEG_5Utils_18interputils_cython_4_interpmat2D(CYTH * ind_x1, ind_x2, wx1, wx2 = _interp_point_1D(x, locs[i, 0]) * ind_y1, ind_y2, wy1, wy2 = _interp_point_1D(y, locs[i, 1]) # <<<<<<<<<<<<<< * - * inds += [( ind_x1, ind_y2), + * inds += [( ind_x1, ind_y1), */ __pyx_t_9 = __Pyx_GetModuleGlobalName(__pyx_n_s_interp_point_1D); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_9); @@ -2669,8 +2669,8 @@ static PyObject *__pyx_pf_6SimPEG_5Utils_18interputils_cython_4_interpmat2D(CYTH /* "SimPEG/Utils/interputils_cython.pyx":74 * ind_y1, ind_y2, wy1, wy2 = _interp_point_1D(y, locs[i, 1]) * - * inds += [( ind_x1, ind_y2), # <<<<<<<<<<<<<< - * ( ind_x1, ind_y1), + * inds += [( ind_x1, ind_y1), # <<<<<<<<<<<<<< + * ( ind_x1, ind_y2), * ( ind_x2, ind_y1), */ __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; __pyx_clineno = __LINE__; goto __pyx_L1_error;} @@ -2678,14 +2678,14 @@ static PyObject *__pyx_pf_6SimPEG_5Utils_18interputils_cython_4_interpmat2D(CYTH __Pyx_INCREF(__pyx_v_ind_x1); __Pyx_GIVEREF(__pyx_v_ind_x1); PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_ind_x1); - __Pyx_INCREF(__pyx_v_ind_y2); - __Pyx_GIVEREF(__pyx_v_ind_y2); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_ind_y2); + __Pyx_INCREF(__pyx_v_ind_y1); + __Pyx_GIVEREF(__pyx_v_ind_y1); + PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_ind_y1); /* "SimPEG/Utils/interputils_cython.pyx":75 * - * inds += [( ind_x1, ind_y2), - * ( ind_x1, ind_y1), # <<<<<<<<<<<<<< + * inds += [( ind_x1, ind_y1), + * ( ind_x1, ind_y2), # <<<<<<<<<<<<<< * ( ind_x2, ind_y1), * ( ind_x2, ind_y2)] */ @@ -2694,13 +2694,13 @@ static PyObject *__pyx_pf_6SimPEG_5Utils_18interputils_cython_4_interpmat2D(CYTH __Pyx_INCREF(__pyx_v_ind_x1); __Pyx_GIVEREF(__pyx_v_ind_x1); PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_v_ind_x1); - __Pyx_INCREF(__pyx_v_ind_y1); - __Pyx_GIVEREF(__pyx_v_ind_y1); - PyTuple_SET_ITEM(__pyx_t_11, 1, __pyx_v_ind_y1); + __Pyx_INCREF(__pyx_v_ind_y2); + __Pyx_GIVEREF(__pyx_v_ind_y2); + PyTuple_SET_ITEM(__pyx_t_11, 1, __pyx_v_ind_y2); /* "SimPEG/Utils/interputils_cython.pyx":76 - * inds += [( ind_x1, ind_y2), - * ( ind_x1, ind_y1), + * inds += [( ind_x1, ind_y1), + * ( ind_x1, ind_y2), * ( ind_x2, ind_y1), # <<<<<<<<<<<<<< * ( ind_x2, ind_y2)] * @@ -2715,11 +2715,11 @@ static PyObject *__pyx_pf_6SimPEG_5Utils_18interputils_cython_4_interpmat2D(CYTH PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_v_ind_y1); /* "SimPEG/Utils/interputils_cython.pyx":77 - * ( ind_x1, ind_y1), + * ( ind_x1, ind_y2), * ( ind_x2, ind_y1), * ( ind_x2, ind_y2)] # <<<<<<<<<<<<<< * - * vals += [wx1*wy2, wx1*wy1, wx2*wy1, wx2*wy2] + * vals += [wx1*wy1, wx1*wy2, wx2*wy1, wx2*wy2] */ __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 77; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); @@ -2733,8 +2733,8 @@ static PyObject *__pyx_pf_6SimPEG_5Utils_18interputils_cython_4_interpmat2D(CYTH /* "SimPEG/Utils/interputils_cython.pyx":74 * ind_y1, ind_y2, wy1, wy2 = _interp_point_1D(y, locs[i, 1]) * - * inds += [( ind_x1, ind_y2), # <<<<<<<<<<<<<< - * ( ind_x1, ind_y1), + * inds += [( ind_x1, ind_y1), # <<<<<<<<<<<<<< + * ( ind_x1, ind_y2), * ( ind_x2, ind_y1), */ __pyx_t_9 = PyList_New(4); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; __pyx_clineno = __LINE__; goto __pyx_L1_error;} @@ -2760,13 +2760,13 @@ static PyObject *__pyx_pf_6SimPEG_5Utils_18interputils_cython_4_interpmat2D(CYTH /* "SimPEG/Utils/interputils_cython.pyx":79 * ( ind_x2, ind_y2)] * - * vals += [wx1*wy2, wx1*wy1, wx2*wy1, wx2*wy2] # <<<<<<<<<<<<<< + * vals += [wx1*wy1, wx1*wy2, wx2*wy1, wx2*wy2] # <<<<<<<<<<<<<< * * return inds, vals */ - __pyx_t_1 = PyNumber_Multiply(__pyx_v_wx1, __pyx_v_wy2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_t_1 = PyNumber_Multiply(__pyx_v_wx1, __pyx_v_wy1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); - __pyx_t_9 = PyNumber_Multiply(__pyx_v_wx1, __pyx_v_wy1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_t_9 = PyNumber_Multiply(__pyx_v_wx1, __pyx_v_wy2); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_9); __pyx_t_8 = PyNumber_Multiply(__pyx_v_wx2, __pyx_v_wy1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_8); @@ -2794,7 +2794,7 @@ static PyObject *__pyx_pf_6SimPEG_5Utils_18interputils_cython_4_interpmat2D(CYTH } /* "SimPEG/Utils/interputils_cython.pyx":81 - * vals += [wx1*wy2, wx1*wy1, wx2*wy1, wx2*wy2] + * vals += [wx1*wy1, wx1*wy2, wx2*wy1, wx2*wy2] * * return inds, vals # <<<<<<<<<<<<<< * @@ -3376,7 +3376,7 @@ static PyObject *__pyx_pf_6SimPEG_5Utils_18interputils_cython_6_interpmat3D(CYTH * ind_y1, ind_y2, wy1, wy2 = _interp_point_1D(y, locs[i, 1]) * ind_z1, ind_z2, wz1, wz2 = _interp_point_1D(z, locs[i, 2]) # <<<<<<<<<<<<<< * - * inds += [( ind_x1, ind_y2, ind_z1), + * inds += [( ind_x1, ind_y1, ind_z1), */ __pyx_t_11 = __Pyx_GetModuleGlobalName(__pyx_n_s_interp_point_1D); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_11); @@ -3499,8 +3499,8 @@ static PyObject *__pyx_pf_6SimPEG_5Utils_18interputils_cython_6_interpmat3D(CYTH /* "SimPEG/Utils/interputils_cython.pyx":101 * ind_z1, ind_z2, wz1, wz2 = _interp_point_1D(z, locs[i, 2]) * - * inds += [( ind_x1, ind_y2, ind_z1), # <<<<<<<<<<<<<< - * ( ind_x1, ind_y1, ind_z1), + * inds += [( ind_x1, ind_y1, ind_z1), # <<<<<<<<<<<<<< + * ( ind_x1, ind_y2, ind_z1), * ( ind_x2, ind_y1, ind_z1), */ __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;} @@ -3508,17 +3508,17 @@ static PyObject *__pyx_pf_6SimPEG_5Utils_18interputils_cython_6_interpmat3D(CYTH __Pyx_INCREF(__pyx_v_ind_x1); __Pyx_GIVEREF(__pyx_v_ind_x1); PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_ind_x1); - __Pyx_INCREF(__pyx_v_ind_y2); - __Pyx_GIVEREF(__pyx_v_ind_y2); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_ind_y2); + __Pyx_INCREF(__pyx_v_ind_y1); + __Pyx_GIVEREF(__pyx_v_ind_y1); + PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_ind_y1); __Pyx_INCREF(__pyx_v_ind_z1); __Pyx_GIVEREF(__pyx_v_ind_z1); PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_v_ind_z1); /* "SimPEG/Utils/interputils_cython.pyx":102 * - * inds += [( ind_x1, ind_y2, ind_z1), - * ( ind_x1, ind_y1, ind_z1), # <<<<<<<<<<<<<< + * inds += [( ind_x1, ind_y1, ind_z1), + * ( ind_x1, ind_y2, ind_z1), # <<<<<<<<<<<<<< * ( ind_x2, ind_y1, ind_z1), * ( ind_x2, ind_y2, ind_z1), */ @@ -3527,16 +3527,16 @@ static PyObject *__pyx_pf_6SimPEG_5Utils_18interputils_cython_6_interpmat3D(CYTH __Pyx_INCREF(__pyx_v_ind_x1); __Pyx_GIVEREF(__pyx_v_ind_x1); PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_ind_x1); - __Pyx_INCREF(__pyx_v_ind_y1); - __Pyx_GIVEREF(__pyx_v_ind_y1); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_ind_y1); + __Pyx_INCREF(__pyx_v_ind_y2); + __Pyx_GIVEREF(__pyx_v_ind_y2); + PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_ind_y2); __Pyx_INCREF(__pyx_v_ind_z1); __Pyx_GIVEREF(__pyx_v_ind_z1); PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_v_ind_z1); /* "SimPEG/Utils/interputils_cython.pyx":103 - * inds += [( ind_x1, ind_y2, ind_z1), - * ( ind_x1, ind_y1, ind_z1), + * inds += [( ind_x1, ind_y1, ind_z1), + * ( ind_x1, ind_y2, ind_z1), * ( ind_x2, ind_y1, ind_z1), # <<<<<<<<<<<<<< * ( ind_x2, ind_y2, ind_z1), * ( ind_x1, ind_y1, ind_z2), @@ -3554,7 +3554,7 @@ static PyObject *__pyx_pf_6SimPEG_5Utils_18interputils_cython_6_interpmat3D(CYTH PyTuple_SET_ITEM(__pyx_t_8, 2, __pyx_v_ind_z1); /* "SimPEG/Utils/interputils_cython.pyx":104 - * ( ind_x1, ind_y1, ind_z1), + * ( ind_x1, ind_y2, ind_z1), * ( ind_x2, ind_y1, ind_z1), * ( ind_x2, ind_y2, ind_z1), # <<<<<<<<<<<<<< * ( ind_x1, ind_y1, ind_z2), @@ -3634,7 +3634,7 @@ static PyObject *__pyx_pf_6SimPEG_5Utils_18interputils_cython_6_interpmat3D(CYTH * ( ind_x2, ind_y1, ind_z2), * ( ind_x2, ind_y2, ind_z2)] # <<<<<<<<<<<<<< * - * vals += [wx1*wy2*wz1, + * vals += [wx1*wy1*wz1, */ __pyx_t_19 = PyTuple_New(3); if (unlikely(!__pyx_t_19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_19); @@ -3651,8 +3651,8 @@ static PyObject *__pyx_pf_6SimPEG_5Utils_18interputils_cython_6_interpmat3D(CYTH /* "SimPEG/Utils/interputils_cython.pyx":101 * ind_z1, ind_z2, wz1, wz2 = _interp_point_1D(z, locs[i, 2]) * - * inds += [( ind_x1, ind_y2, ind_z1), # <<<<<<<<<<<<<< - * ( ind_x1, ind_y1, ind_z1), + * inds += [( ind_x1, ind_y1, ind_z1), # <<<<<<<<<<<<<< + * ( ind_x1, ind_y2, ind_z1), * ( ind_x2, ind_y1, ind_z1), */ __pyx_t_20 = PyList_New(8); if (unlikely(!__pyx_t_20)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;} @@ -3690,11 +3690,11 @@ static PyObject *__pyx_pf_6SimPEG_5Utils_18interputils_cython_6_interpmat3D(CYTH /* "SimPEG/Utils/interputils_cython.pyx":110 * ( ind_x2, ind_y2, ind_z2)] * - * vals += [wx1*wy2*wz1, # <<<<<<<<<<<<<< - * wx1*wy1*wz1, + * vals += [wx1*wy1*wz1, # <<<<<<<<<<<<<< + * wx1*wy2*wz1, * wx2*wy1*wz1, */ - __pyx_t_19 = PyNumber_Multiply(__pyx_v_wx1, __pyx_v_wy2); if (unlikely(!__pyx_t_19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_t_19 = PyNumber_Multiply(__pyx_v_wx1, __pyx_v_wy1); if (unlikely(!__pyx_t_19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_19); __pyx_t_20 = PyNumber_Multiply(__pyx_t_19, __pyx_v_wz1); if (unlikely(!__pyx_t_20)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_20); @@ -3702,20 +3702,20 @@ static PyObject *__pyx_pf_6SimPEG_5Utils_18interputils_cython_6_interpmat3D(CYTH /* "SimPEG/Utils/interputils_cython.pyx":111 * - * vals += [wx1*wy2*wz1, - * wx1*wy1*wz1, # <<<<<<<<<<<<<< + * vals += [wx1*wy1*wz1, + * wx1*wy2*wz1, # <<<<<<<<<<<<<< * wx2*wy1*wz1, * wx2*wy2*wz1, */ - __pyx_t_19 = PyNumber_Multiply(__pyx_v_wx1, __pyx_v_wy1); if (unlikely(!__pyx_t_19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_t_19 = PyNumber_Multiply(__pyx_v_wx1, __pyx_v_wy2); if (unlikely(!__pyx_t_19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_19); __pyx_t_18 = PyNumber_Multiply(__pyx_t_19, __pyx_v_wz1); if (unlikely(!__pyx_t_18)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_18); __Pyx_DECREF(__pyx_t_19); __pyx_t_19 = 0; /* "SimPEG/Utils/interputils_cython.pyx":112 - * vals += [wx1*wy2*wz1, - * wx1*wy1*wz1, + * vals += [wx1*wy1*wz1, + * wx1*wy2*wz1, * wx2*wy1*wz1, # <<<<<<<<<<<<<< * wx2*wy2*wz1, * wx1*wy1*wz2, @@ -3727,7 +3727,7 @@ static PyObject *__pyx_pf_6SimPEG_5Utils_18interputils_cython_6_interpmat3D(CYTH __Pyx_DECREF(__pyx_t_19); __pyx_t_19 = 0; /* "SimPEG/Utils/interputils_cython.pyx":113 - * wx1*wy1*wz1, + * wx1*wy2*wz1, * wx2*wy1*wz1, * wx2*wy2*wz1, # <<<<<<<<<<<<<< * wx1*wy1*wz2, @@ -3794,8 +3794,8 @@ static PyObject *__pyx_pf_6SimPEG_5Utils_18interputils_cython_6_interpmat3D(CYTH /* "SimPEG/Utils/interputils_cython.pyx":110 * ( ind_x2, ind_y2, ind_z2)] * - * vals += [wx1*wy2*wz1, # <<<<<<<<<<<<<< - * wx1*wy1*wz1, + * vals += [wx1*wy1*wz1, # <<<<<<<<<<<<<< + * wx1*wy2*wz1, * wx2*wy1*wz1, */ __pyx_t_19 = PyList_New(8); if (unlikely(!__pyx_t_19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;} diff --git a/SimPEG/Utils/interputils_cython.pyx b/SimPEG/Utils/interputils_cython.pyx index f7d59bb3..accf8cd6 100644 --- a/SimPEG/Utils/interputils_cython.pyx +++ b/SimPEG/Utils/interputils_cython.pyx @@ -71,12 +71,12 @@ def _interpmat2D(np.ndarray[np.float64_t, ndim=2] locs, ind_x1, ind_x2, wx1, wx2 = _interp_point_1D(x, locs[i, 0]) ind_y1, ind_y2, wy1, wy2 = _interp_point_1D(y, locs[i, 1]) - inds += [( ind_x1, ind_y2), - ( ind_x1, ind_y1), + inds += [( ind_x1, ind_y1), + ( ind_x1, ind_y2), ( ind_x2, ind_y1), ( ind_x2, ind_y2)] - vals += [wx1*wy2, wx1*wy1, wx2*wy1, wx2*wy2] + vals += [wx1*wy1, wx1*wy2, wx2*wy1, wx2*wy2] return inds, vals @@ -98,8 +98,8 @@ def _interpmat3D(np.ndarray[np.float64_t, ndim=2] locs, ind_y1, ind_y2, wy1, wy2 = _interp_point_1D(y, locs[i, 1]) ind_z1, ind_z2, wz1, wz2 = _interp_point_1D(z, locs[i, 2]) - inds += [( ind_x1, ind_y2, ind_z1), - ( ind_x1, ind_y1, ind_z1), + inds += [( ind_x1, ind_y1, ind_z1), + ( ind_x1, ind_y2, ind_z1), ( ind_x2, ind_y1, ind_z1), ( ind_x2, ind_y2, ind_z1), ( ind_x1, ind_y1, ind_z2), @@ -107,8 +107,8 @@ def _interpmat3D(np.ndarray[np.float64_t, ndim=2] locs, ( ind_x2, ind_y1, ind_z2), ( ind_x2, ind_y2, ind_z2)] - vals += [wx1*wy2*wz1, - wx1*wy1*wz1, + vals += [wx1*wy1*wz1, + wx1*wy2*wz1, wx2*wy1*wz1, wx2*wy2*wz1, wx1*wy1*wz2, diff --git a/tests/mesh/test_TreeInterpolation.py b/tests/mesh/test_TreeInterpolation.py new file mode 100644 index 00000000..90860959 --- /dev/null +++ b/tests/mesh/test_TreeInterpolation.py @@ -0,0 +1,182 @@ +import numpy as np +import unittest +from SimPEG import Utils, Tests + +MESHTYPES = ['uniformTree'] #['randomTree', 'uniformTree'] +call2 = lambda fun, xyz: fun(xyz[:, 0], xyz[:, 1]) +call3 = lambda fun, xyz: fun(xyz[:, 0], xyz[:, 1], xyz[:, 2]) +cart_row2 = lambda g, xfun, yfun: np.c_[call2(xfun, g), call2(yfun, g)] +cart_row3 = lambda g, xfun, yfun, zfun: np.c_[call3(xfun, g), call3(yfun, g), call3(zfun, g)] +cartF2 = lambda M, fx, fy: np.vstack((cart_row2(M.gridFx, fx, fy), cart_row2(M.gridFy, fx, fy))) +cartE2 = lambda M, ex, ey: np.vstack((cart_row2(M.gridEx, ex, ey), cart_row2(M.gridEy, ex, ey))) +cartF3 = lambda M, fx, fy, fz: np.vstack((cart_row3(M.gridFx, fx, fy, fz), cart_row3(M.gridFy, fx, fy, fz), cart_row3(M.gridFz, fx, fy, fz))) +cartE3 = lambda M, ex, ey, ez: np.vstack((cart_row3(M.gridEx, ex, ey, ez), cart_row3(M.gridEy, ex, ey, ez), cart_row3(M.gridEz, ex, ey, ez))) + + +plotIt = False + + +MESHTYPES = ['uniformTree','notatreeTree'] + + +""" + + Face interpolation is O(h) + Edge interpolation is O(h^2) + +""" + +class TestInterpolation2d(Tests.OrderTest): + name = "Interpolation 2D" + np.random.seed(1) + LOCS = np.random.rand(50,2)*0.6+0.2 + # LOCS = np.c_[np.ones(100)*0.51, np.linspace(0.3,0.7,100)] + meshTypes = MESHTYPES + # tolerance = TOLERANCES + meshDimension = 2 + meshSizes = [8, 16, 32] + expectedOrders = 1 + + def getError(self): + funX = lambda x, y: np.cos(2.*np.pi*y)*np.cos(2.*np.pi*x) + x + funY = lambda x, y: np.cos(2.*np.pi*x)*np.cos(2.*np.pi*y) + y + + # self.LOCS = self.M.gridCC + + if 'x' in self.type: + ana = call2(funX, self.LOCS) + elif 'y' in self.type: + ana = call2(funY, self.LOCS) + else: + ana = call2(funX, self.LOCS) + + if 'F' in self.type: + Fc = cartF2(self.M, funX, funY) + grid = self.M.projectFaceVector(Fc) + elif 'E' in self.type: + Ec = cartE2(self.M, funX, funY) + grid = self.M.projectEdgeVector(Ec) + elif 'CC' == self.type: + grid = call2(funX, self.M.gridCC) + elif 'N' == self.type: + grid = call2(funX, self.M.gridN) + + P = self.M.getInterpolationMat(self.LOCS, self.type) + # print P + comp = P*grid + + err = np.linalg.norm((comp - ana), np.inf) + if plotIt: + import matplotlib.pyplot as plt + ax = plt.subplot(211) + self.M.plotGrid(ax=ax) + plt.plot(self.LOCS[:,0],self.LOCS[:,1], 'mx') + # ax = plt.subplot(111) + # self.M.plotImage(call2(funX, self.M.gridCC),ax=ax) + ax = plt.subplot(212) + plt.plot(self.LOCS[:,1],comp, 'bx') + plt.plot(self.LOCS[:,1],ana, 'ro') + plt.show() + return err + + def test_orderFx(self): + self.type = 'Fx' + self.name = 'TreeMesh Interpolation 2D: Fx' + self.orderTest() + + def test_orderFy(self): + self.type = 'Fy' + self.name = 'TreeMesh Interpolation 2D: Fy' + self.orderTest() + + + +class TestInterpolation3D(Tests.OrderTest): + name = "Interpolation" + LOCS = np.random.rand(50,3)*0.6+0.2 + meshTypes = MESHTYPES + # tolerance = TOLERANCES + meshDimension = 3 + meshSizes = [8, 16] + + def getError(self): + funX = lambda x, y, z: np.cos(2*np.pi*y) + funY = lambda x, y, z: np.cos(2*np.pi*z) + funZ = lambda x, y, z: np.cos(2*np.pi*x) + + if 'x' in self.type: + ana = call3(funX, self.LOCS) + elif 'y' in self.type: + ana = call3(funY, self.LOCS) + elif 'z' in self.type: + ana = call3(funZ, self.LOCS) + else: + ana = call3(funX, self.LOCS) + + if 'F' in self.type: + Fc = cartF3(self.M, funX, funY, funZ) + grid = self.M.projectFaceVector(Fc) + elif 'E' in self.type: + Ec = cartE3(self.M, funX, funY, funZ) + grid = self.M.projectEdgeVector(Ec) + elif 'CC' == self.type: + grid = call3(funX, self.M.gridCC) + elif 'N' == self.type: + grid = call3(funX, self.M.gridN) + + comp = self.M.getInterpolationMat(self.LOCS, self.type)*grid + + err = np.linalg.norm((comp - ana), np.inf) + return err + + def test_orderCC(self): + self.type = 'CC' + self.name = 'Interpolation 3D: CC' + self.expectedOrders = 1 + self.orderTest() + self.expectedOrders = 2 + + def test_orderN(self): + self.type = 'N' + self.name = 'Interpolation 3D: N' + self.orderTest() + + def test_orderFx(self): + self.type = 'Fx' + self.name = 'Interpolation 3D: Fx' + self.expectedOrders = 1 + self.orderTest() + self.expectedOrders = 2 + + def test_orderFy(self): + self.type = 'Fy' + self.name = 'Interpolation 3D: Fy' + self.expectedOrders = 1 + self.orderTest() + self.expectedOrders = 2 + + def test_orderFz(self): + self.type = 'Fz' + self.name = 'Interpolation 3D: Fz' + self.expectedOrders = 1 + self.orderTest() + self.expectedOrders = 2 + + def test_orderEx(self): + self.type = 'Ex' + self.name = 'Interpolation 3D: Ex' + self.orderTest() + + def test_orderEy(self): + self.type = 'Ey' + self.name = 'Interpolation 3D: Ey' + self.orderTest() + + def test_orderEz(self): + self.type = 'Ez' + self.name = 'Interpolation 3D: Ez' + self.orderTest() + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/mesh/test_TreeMesh.py b/tests/mesh/test_TreeMesh.py index 82288f99..61c2f9be 100644 --- a/tests/mesh/test_TreeMesh.py +++ b/tests/mesh/test_TreeMesh.py @@ -1,9 +1,9 @@ -from SimPEG import Mesh +from SimPEG import Mesh, Tests import numpy as np import matplotlib.pyplot as plt import unittest -TOL = 1e-10 +TOL = 1e-8 @@ -153,6 +153,95 @@ class TestOcTree(unittest.TestCase): assert np.max(np.abs((M.faceDiv * M.edgeCurl).todense().flatten())) < TOL assert np.max(np.abs((Mr.faceDiv * Mr.edgeCurl).todense().flatten())) < TOL +class Test2DInterpolation(unittest.TestCase): + + def setUp(self): + def topo(x): + return np.sin(x*(2.*np.pi))*0.3 + 0.5 + + def function(cell): + r = cell.center - np.array([0.5]*len(cell.center)) + dist1 = np.sqrt(r.dot(r)) - 0.08 + dist2 = np.abs(cell.center[-1] - topo(cell.center[0])) + + dist = min([dist1,dist2]) + # if dist < 0.05: + # return 5 + if dist < 0.05: + return 6 + if dist < 0.2: + return 5 + if dist < 0.3: + return 4 + if dist < 1.0: + return 3 + else: + return 0 + + M = Mesh.TreeMesh([64,64],levels=6) + M.refine(function) + self.M = M + + def test_fx(self): + r = np.random.rand(self.M.nFx) + P = self.M.getInterpolationMat(self.M.gridFx, 'Fx') + assert np.abs(P[:,:self.M.nFx]*r - r).max() < TOL + + def test_fy(self): + r = np.random.rand(self.M.nFy) + P = self.M.getInterpolationMat(self.M.gridFy, 'Fy') + assert np.abs(P[:,self.M.nFx:]*r - r).max() < TOL + + +class Test3DInterpolation(unittest.TestCase): + + def setUp(self): + def function(cell): + r = cell.center - np.array([0.5]*len(cell.center)) + dist = np.sqrt(r.dot(r)) + if dist < 0.2: + return 4 + if dist < 0.3: + return 3 + if dist < 1.0: + return 2 + else: + return 0 + + M = Mesh.TreeMesh([16,16,16],levels=4) + M.refine(function) + # M.plotGrid(showIt=True) + self.M = M + + def test_Fx(self): + r = np.random.rand(self.M.nFx) + P = self.M.getInterpolationMat(self.M.gridFx, 'Fx') + assert np.abs(P[:,:self.M.nFx]*r - r).max() < TOL + + def test_Fy(self): + r = np.random.rand(self.M.nFy) + P = self.M.getInterpolationMat(self.M.gridFy, 'Fy') + assert np.abs(P[:,self.M.nFx:(self.M.nFx+self.M.nFy)]*r - r).max() < TOL + + def test_Fz(self): + r = np.random.rand(self.M.nFz) + P = self.M.getInterpolationMat(self.M.gridFz, 'Fz') + assert np.abs(P[:,(self.M.nFx+self.M.nFy):]*r - r).max() < TOL + + def test_Ex(self): + r = np.random.rand(self.M.nEx) + P = self.M.getInterpolationMat(self.M.gridEx, 'Ex') + assert np.abs(P[:,:self.M.nEx]*r - r).max() < TOL + + def test_Ey(self): + r = np.random.rand(self.M.nEy) + P = self.M.getInterpolationMat(self.M.gridEy, 'Ey') + assert np.abs(P[:,self.M.nEx:(self.M.nEx+self.M.nEy)]*r - r).max() < TOL + + def test_Ez(self): + r = np.random.rand(self.M.nEz) + P = self.M.getInterpolationMat(self.M.gridEz, 'Ez') + assert np.abs(P[:,(self.M.nEx+self.M.nEy):]*r - r).max() < TOL if __name__ == '__main__': From c1b5f45ac79e523bd7fcb8d00f43b98717b1151f Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Wed, 18 Nov 2015 11:52:05 -0800 Subject: [PATCH 75/83] PlotSlice in OcTree --- SimPEG/Mesh/TensorMesh.py | 40 ++++----- SimPEG/Mesh/TreeMesh.py | 181 +++++++++++++++++++++++++++++++++----- SimPEG/Mesh/View.py | 1 + 3 files changed, 181 insertions(+), 41 deletions(-) diff --git a/SimPEG/Mesh/TensorMesh.py b/SimPEG/Mesh/TensorMesh.py index 37bfea86..6b0e6e65 100644 --- a/SimPEG/Mesh/TensorMesh.py +++ b/SimPEG/Mesh/TensorMesh.py @@ -413,34 +413,34 @@ class TensorMesh(BaseTensorMesh, TensorView, DiffOperators, InnerProducts): break if n == 1: - outStr = outStr + ' {0:.2f},'.format(h) + outStr += ' {0:.2f},'.format(h) else: - outStr = outStr + ' {0:d}*{1:.2f},'.format(n,h) + outStr += ' {0:d}*{1:.2f},'.format(n,h) return outStr[:-1] if self.dim == 1: - outStr = outStr + '\n x0: {0:.2f}'.format(self.x0[0]) - outStr = outStr + '\n nCx: {0:d}'.format(self.nCx) - outStr = outStr + printH(self.hx, outStr='\n hx:') + outStr += '\n x0: {0:.2f}'.format(self.x0[0]) + outStr += '\n nCx: {0:d}'.format(self.nCx) + outStr += printH(self.hx, outStr='\n hx:') pass elif self.dim == 2: - outStr = outStr + '\n x0: {0:.2f}'.format(self.x0[0]) - outStr = outStr + '\n y0: {0:.2f}'.format(self.x0[1]) - outStr = outStr + '\n nCx: {0:d}'.format(self.nCx) - outStr = outStr + '\n nCy: {0:d}'.format(self.nCy) - outStr = outStr + printH(self.hx, outStr='\n hx:') - outStr = outStr + printH(self.hy, outStr='\n hy:') + outStr += '\n x0: {0:.2f}'.format(self.x0[0]) + outStr += '\n y0: {0:.2f}'.format(self.x0[1]) + outStr += '\n nCx: {0:d}'.format(self.nCx) + outStr += '\n nCy: {0:d}'.format(self.nCy) + outStr += printH(self.hx, outStr='\n hx:') + outStr += printH(self.hy, outStr='\n hy:') elif self.dim == 3: - outStr = outStr + '\n x0: {0:.2f}'.format(self.x0[0]) - outStr = outStr + '\n y0: {0:.2f}'.format(self.x0[1]) - outStr = outStr + '\n z0: {0:.2f}'.format(self.x0[2]) - outStr = outStr + '\n nCx: {0:d}'.format(self.nCx) - outStr = outStr + '\n nCy: {0:d}'.format(self.nCy) - outStr = outStr + '\n nCz: {0:d}'.format(self.nCz) - outStr = outStr + printH(self.hx, outStr='\n hx:') - outStr = outStr + printH(self.hy, outStr='\n hy:') - outStr = outStr + printH(self.hz, outStr='\n hz:') + outStr += '\n x0: {0:.2f}'.format(self.x0[0]) + outStr += '\n y0: {0:.2f}'.format(self.x0[1]) + outStr += '\n z0: {0:.2f}'.format(self.x0[2]) + outStr += '\n nCx: {0:d}'.format(self.nCx) + outStr += '\n nCy: {0:d}'.format(self.nCy) + outStr += '\n nCz: {0:d}'.format(self.nCz) + outStr += printH(self.hx, outStr='\n hx:') + outStr += printH(self.hy, outStr='\n hy:') + outStr += printH(self.hz, outStr='\n hz:') return outStr diff --git a/SimPEG/Mesh/TreeMesh.py b/SimPEG/Mesh/TreeMesh.py index 4f4e98d3..55b5101e 100644 --- a/SimPEG/Mesh/TreeMesh.py +++ b/SimPEG/Mesh/TreeMesh.py @@ -99,6 +99,7 @@ import matplotlib.cm as cmx import TreeUtils from InnerProducts import InnerProducts from BaseMesh import BaseMesh +from TensorMesh import TensorMesh import time MAX_BITS = 20 @@ -107,7 +108,7 @@ class TreeMesh(BaseMesh, InnerProducts): _meshType = 'TREE' - def __init__(self, h_in, x0_in=None, levels=3): + def __init__(self, h_in, x0_in=None, levels=None): assert type(h_in) is list, 'h_in must be a list' assert len(h_in) in [2,3], "There is only support for TreeMesh in 2D or 3D." @@ -120,6 +121,7 @@ class TreeMesh(BaseMesh, InnerProducts): h_i = Utils.meshTensor(h_i) assert isinstance(h_i, np.ndarray), ("h[%i] is not a numpy array." % i) assert len(h_i.shape) == 1, ("h[%i] must be a 1D numpy array." % i) + if levels is None:levels = int(np.log2(len(h_i))) assert len(h_i) == 2**levels, "must make h and levels match" h[i] = h_i[:] # make a copy. self._h = h @@ -184,6 +186,58 @@ class TreeMesh(BaseMesh, InnerProducts): @property def levels(self): return self._levels + @property + def fill(self): + return float(self.nC)/((2**self.maxLevel)**self.dim) + + @property + def maxLevel(self): + l = 0 + for cell in self._cells: + p = self._pointer(cell) + l = max(l,p[-1]) + return l + + def __str__(self): + outStr = ' ---- %sTreeMesh ---- '%('Oc' if self.dim == 3 else 'Quad') + def printH(hx, outStr=''): + i = -1 + while True: + i = i + 1 + if i > hx.size: + break + elif i == hx.size: + break + h = hx[i] + n = 1 + for j in range(i+1, hx.size): + if hx[j] == h: + n = n + 1 + i = i + 1 + else: + break + if n == 1: + outStr += ' {0:.2f},'.format(h) + else: + outStr += ' {0:d}*{1:.2f},'.format(n,h) + return outStr[:-1] + + if self.dim == 2: + outStr += '\n x0: {0:.2f}'.format(self.x0[0]) + outStr += '\n y0: {0:.2f}'.format(self.x0[1]) + outStr += printH(self.hx, outStr='\n hx:') + outStr += printH(self.hy, outStr='\n hy:') + elif self.dim == 3: + outStr += '\n x0: {0:.2f}'.format(self.x0[0]) + outStr += '\n y0: {0:.2f}'.format(self.x0[1]) + outStr += '\n z0: {0:.2f}'.format(self.x0[2]) + outStr += printH(self.hx, outStr='\n hx:') + outStr += printH(self.hy, outStr='\n hy:') + outStr += printH(self.hz, outStr='\n hz:') + outStr += '\n nC: {0:d}'.format(self.nC) + outStr += '\n Fill: %2.2f%%'%(self.fill*100) + return outStr + @property def h(self): """h is a list containing the cell widths of the tensor mesh in each dimension.""" @@ -2109,8 +2163,8 @@ class TreeMesh(BaseMesh, InnerProducts): if showIt:plt.show() - def plotImage(self, I, ax=None, showIt=True): - if self.dim == 3: raise Exception() + def plotImage(self, I, ax=None, showIt=True, grid=False): + if self.dim == 3: raise Exception('Use plot slice?') if ax is None: ax = plt.subplot(111) jet = cm = plt.get_cmap('jet') @@ -2120,12 +2174,102 @@ class TreeMesh(BaseMesh, InnerProducts): ax.set_ylim((self.x0[1], self.h[1].sum())) for ii, node in enumerate(self._sortedCells): x0, sz = self._cellN(node), self._cellH(node) - ax.add_patch(plt.Rectangle((x0[0], x0[1]), sz[0], sz[1], facecolor=scalarMap.to_rgba(I[ii]), edgecolor='k')) + ax.add_patch(plt.Rectangle((x0[0], x0[1]), sz[0], sz[1], facecolor=scalarMap.to_rgba(I[ii]), edgecolor='k' if grid else 'none')) # if text: ax.text(self.center[0],self.center[1],self.num) scalarMap._A = [] # http://stackoverflow.com/questions/8342549/matplotlib-add-colorbar-to-a-sequence-of-line-plots plt.colorbar(scalarMap) if showIt: plt.show() + def plotSlice(self, v, vType='CC', + normal='Z', ind=None, grid=True, view='real', + ax=None, clim=None, showIt=False, + pcolorOpts={}, + streamOpts={'color':'k'}, + gridOpts={'color':'k'}): + + assert vType in ['CC','F','E'] + assert self.dim == 3 + + szSliceDim = len(getattr(self, 'h'+normal.lower())) #: Size of the sliced dimension + if ind is None: ind = int(szSliceDim/2) + assert type(ind) in [int, long], 'ind must be an integer' + indLoc = getattr(self,'vectorCC'+normal.lower())[ind] + normalInd = {'X':0,'Y':1,'Z':2}[normal] + antiNormalInd = {'X':[1,2],'Y':[0,2],'Z':[0,1]}[normal] + h2d = [] + x2d = [] + if 'X' not in normal: + h2d.append(self.hx) + x2d.append(self.x0[0]) + if 'Y' not in normal: + h2d.append(self.hy) + x2d.append(self.x0[1]) + if 'Z' not in normal: + h2d.append(self.hz) + x2d.append(self.x0[2]) + tM = TensorMesh(h2d, x2d) #: Temp Mesh + + def getLocs(*args): + if len(args) == 1: + grids = (args[0],args[0],args[0]) + else: + assert len(args) == 3 + grids = args + one = np.ones((grids[0].shape[0],1))*indLoc + if normal == 'X': + return np.hstack((one, grids[0][:,[0]], grids[1][:,[1]])) + if normal == 'Y': + return np.hstack((grids[0][:,[0]], one, grids[1][:,[1]])) + if normal == 'Z': + return np.hstack((grids[0][:,[0]], grids[1][:,[1]], one)) + def doSlice(v): + if vType == 'CC': + P = self.getInterpolationMat(getLocs(tM.gridCC),'CC') + elif vType in ['F', 'E']: + Ps = [] + gridX = getLocs(getattr(tM, 'grid' + vType + 'x')) + gridY = getLocs(getattr(tM, 'grid' + vType + 'y')) + Ps += [self.getInterpolationMat(gridX,vType + ('y' if normal == 'X' else 'x'))] + Ps += [self.getInterpolationMat(gridY,vType + ('y' if normal == 'Z' else 'z'))] + P = sp.vstack(Ps) + return P*v + + v2d = doSlice(v) + + if ax is None: + fig = plt.figure() + ax = plt.subplot(111) + else: + assert isinstance(ax, matplotlib.axes.Axes), "ax must be an matplotlib.axes.Axes" + fig = ax.figure + + out = tM._plotImage2D(v2d, vType=vType, view=view, + ax=ax, clim=clim, + pcolorOpts=pcolorOpts, streamOpts=streamOpts) + + ax.set_xlabel('y' if normal == 'X' else 'x') + ax.set_ylabel('y' if normal == 'Z' else 'z') + ax.set_title('Slice %d, %s = %4.2f' % (ind,normal,indLoc)) + + if grid: + _ = antiNormalInd + X = [] + Y = [] + for cell in self._cells: + p = self._pointer(cell) + n, h = self._cellN(p), self._cellH(p) + if n[normalInd]indLoc: + X += [n[_[0]] , n[_[0]] + h[_[0]], n[_[0]] + h[_[0]], n[_[0]] , n[_[0]], np.nan] + Y += [n[_[1]] , n[_[1]] , n[_[1]] + h[_[1]], n[_[1]] + h[_[1]], n[_[1]], np.nan] + out = list(out) + out += ax.plot(X,Y, **gridOpts) + if len(out) > 2: # this is not robust, searching for the streamlines would be better + out[1].lines.set_zorder(200) + out[1].arrows.set_zorder(201) + if showIt: plt.show() + return tuple(out) + + class Cell(object): def __init__(self, mesh, index, pointer): self.mesh = mesh @@ -2192,27 +2336,24 @@ if __name__ == '__main__': def function(cell): r = cell.center - np.array([0.5]*len(cell.center)) - dist1 = np.sqrt(r.dot(r)) - 0.08 - dist2 = np.abs(cell.center[-1] - topo(cell.center[0])) + dist = np.sqrt(r.dot(r)) + # dist2 = np.abs(cell.center[-1] - topo(cell.center[0])) - dist = min([dist1,dist2]) + # dist = min([dist1,dist2]) # if dist < 0.05: # return 5 - if dist < 0.05: - return 6 - if dist < 0.2: + if dist < 0.1: return 5 - if dist < 0.3: + if dist < 0.2: return 4 - if dist < 1.0: + if dist < 0.4: return 3 - else: - return 0 + return 2 # T = TreeMesh([[(1,128)],[(1,128)],[(1,128)]],levels=7) - # T = TreeMesh([128,128,128],levels=7) + T = TreeMesh([128,128,128]) # T = TreeMesh([64,64],levels=6) - T = TreeMesh([4,4,4],levels=2) + # T = TreeMesh([4,4,4],levels=2) # T = TreeMesh([[(1,128)],[(1,128)]],levels=7) # T.refine(lambda xc:2, balance=False) # T._index([0,0,0]) @@ -2220,14 +2361,12 @@ if __name__ == '__main__': # tic = time.time() - # T.refine(function)#, balance=False) + T.refine(function)#, balance=False) # print time.time() - tic # print T.nC + T.plotSlice(np.log(T.vol))#np.random.rand(T.nC)) - print T.nC - - P = T.getInterpolationMat([0.2,0,0], 'Ex') - print P.todense() + plt.show() blah # T.plotImage(np.arange(len(T.vol)),showIt=True) diff --git a/SimPEG/Mesh/View.py b/SimPEG/Mesh/View.py index 38432d3c..272a2f47 100644 --- a/SimPEG/Mesh/View.py +++ b/SimPEG/Mesh/View.py @@ -216,6 +216,7 @@ class TensorView(object): if ind is None: ind = int(szSliceDim/2) assert type(ind) in [int, long], 'ind must be an integer' + assert not (v.dtype == complex and view == 'vec'), 'Can not plot a complex vector.' # The slicing and plotting code!! def getIndSlice(v): From 033a64d53f5d14c0f944d630d8e540f60f7accd1 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Wed, 18 Nov 2015 12:57:15 -0800 Subject: [PATCH 76/83] Updates to inheritance and faster innerproducts on treemesh. --- SimPEG/Mesh/CylMesh.py | 4 +- SimPEG/Mesh/TensorMesh.py | 11 +- SimPEG/Mesh/TreeMesh.py | 157 ++------------------------ tests/mesh/test_TreeOperators.py | 2 +- tests/mesh/test_innerProductDerivs.py | 36 +++--- 5 files changed, 36 insertions(+), 174 deletions(-) diff --git a/SimPEG/Mesh/CylMesh.py b/SimPEG/Mesh/CylMesh.py index d3ff51be..ecdf36ac 100644 --- a/SimPEG/Mesh/CylMesh.py +++ b/SimPEG/Mesh/CylMesh.py @@ -2,12 +2,12 @@ import numpy as np import scipy.sparse as sp from scipy.constants import pi from SimPEG.Utils import mkvc, ndgrid, sdiag, kron3, speye, spzeros, ddx, av, avExtrap -from TensorMesh import BaseTensorMesh +from TensorMesh import BaseTensorMesh, BaseRectangularMesh from InnerProducts import InnerProducts from View import CylView -class CylMesh(BaseTensorMesh, InnerProducts, CylView): +class CylMesh(BaseTensorMesh, BaseRectangularMesh, InnerProducts, CylView): """ CylMesh is a mesh class for cylindrical problems diff --git a/SimPEG/Mesh/TensorMesh.py b/SimPEG/Mesh/TensorMesh.py index 6b0e6e65..c76306fe 100644 --- a/SimPEG/Mesh/TensorMesh.py +++ b/SimPEG/Mesh/TensorMesh.py @@ -1,10 +1,10 @@ from SimPEG import Utils, np, sp -from BaseMesh import BaseRectangularMesh +from BaseMesh import BaseMesh, BaseRectangularMesh from View import TensorView from DiffOperators import DiffOperators from InnerProducts import InnerProducts -class BaseTensorMesh(BaseRectangularMesh): +class BaseTensorMesh(BaseMesh): __metaclass__ = Utils.SimPEGMetaClass @@ -42,7 +42,10 @@ class BaseTensorMesh(BaseRectangularMesh): else: raise Exception("x0[%i] must be a scalar or '0' to be zero, 'C' to center, or 'N' to be negative." % i) - BaseRectangularMesh.__init__(self, np.array([x.size for x in h]), x0) + if isinstance(self, BaseRectangularMesh): + BaseRectangularMesh.__init__(self, np.array([x.size for x in h]), x0) + else: + BaseMesh.__init__(self, np.array([x.size for x in h]), x0) # Ensure h contains 1D vectors self._h = [Utils.mkvc(x.astype(float)) for x in h] @@ -356,7 +359,7 @@ class BaseTensorMesh(BaseRectangularMesh): -class TensorMesh(BaseTensorMesh, TensorView, DiffOperators, InnerProducts): +class TensorMesh(BaseTensorMesh, BaseRectangularMesh, TensorView, DiffOperators, InnerProducts): """ TensorMesh is a mesh class that deals with tensor product meshes. diff --git a/SimPEG/Mesh/TreeMesh.py b/SimPEG/Mesh/TreeMesh.py index 55b5101e..88b2d26e 100644 --- a/SimPEG/Mesh/TreeMesh.py +++ b/SimPEG/Mesh/TreeMesh.py @@ -98,51 +98,23 @@ import matplotlib.cm as cmx import TreeUtils from InnerProducts import InnerProducts -from BaseMesh import BaseMesh -from TensorMesh import TensorMesh +from TensorMesh import TensorMesh, BaseTensorMesh import time MAX_BITS = 20 -class TreeMesh(BaseMesh, InnerProducts): +class TreeMesh(BaseTensorMesh, InnerProducts): _meshType = 'TREE' - def __init__(self, h_in, x0_in=None, levels=None): - assert type(h_in) is list, 'h_in must be a list' - assert len(h_in) in [2,3], "There is only support for TreeMesh in 2D or 3D." + def __init__(self, h, x0=None, levels=None): + assert type(h) is list, 'h must be a list' + assert len(h) in [2,3], "There is only support for TreeMesh in 2D or 3D." - h = range(len(h_in)) - for i, h_i in enumerate(h_in): - if type(h_i) in [int, long, float]: - # This gives you something over the unit cube. - h_i = np.ones(int(h_i))/int(h_i) - elif type(h_i) is list: - h_i = Utils.meshTensor(h_i) - assert isinstance(h_i, np.ndarray), ("h[%i] is not a numpy array." % i) - assert len(h_i.shape) == 1, ("h[%i] must be a 1D numpy array." % i) - if levels is None:levels = int(np.log2(len(h_i))) - assert len(h_i) == 2**levels, "must make h and levels match" - h[i] = h_i[:] # make a copy. - self._h = h + BaseTensorMesh.__init__(self, h, x0) - x0 = np.zeros(len(h)) - if x0_in is not None: - assert len(h) == len(x0_in), "Dimension mismatch. x0 != len(h)" - for i in range(len(h)): - x_i, h_i = x0_in[i], h[i] - if Utils.isScalar(x_i): - x0[i] = x_i - elif x_i == '0': - x0[i] = 0.0 - elif x_i == 'C': - x0[i] = -h_i.sum()*0.5 - elif x_i == 'N': - x0[i] = -h_i.sum() - else: - raise Exception("x0[%i] must be a scalar or '0' to be zero, 'C' to center, or 'N' to be negative." % i) - - BaseMesh.__init__(self, [len(_) for _ in h], x0) + if levels is None:levels = int(np.log2(len(self._h[0]))) + assert np.all(len(_) == 2**levels for _ in self._h), "must make h and levels match" self._levels = levels self._levelBits = int(np.ceil(np.sqrt(levels)))+1 @@ -238,95 +210,6 @@ class TreeMesh(BaseMesh, InnerProducts): outStr += '\n Fill: %2.2f%%'%(self.fill*100) return outStr - @property - def h(self): - """h is a list containing the cell widths of the tensor mesh in each dimension.""" - return self._h - - @property - def hx(self): - "Width of cells in the x direction" - return self._h[0] - - @property - def hy(self): - "Width of cells in the y direction" - return self._h[1] - - @property - def hz(self): - "Width of cells in the z direction" - return None if self.dim < 3 else self._h[2] - - @property - def vectorNx(self): - """Nodal grid vector (1D) in the x direction.""" - return np.r_[0., self.hx.cumsum()] + self.x0[0] - - @property - def vectorNy(self): - """Nodal grid vector (1D) in the y direction.""" - return np.r_[0., self.hy.cumsum()] + self.x0[1] - - @property - def vectorNz(self): - """Nodal grid vector (1D) in the z direction.""" - return None if self.dim < 3 else np.r_[0., self.hz.cumsum()] + self.x0[2] - - @property - def vectorCCx(self): - """Cell-centered grid vector (1D) in the x direction.""" - return np.r_[0, self.hx[:-1].cumsum()] + self.hx*0.5 + self.x0[0] - - @property - def vectorCCy(self): - """Cell-centered grid vector (1D) in the y direction.""" - return np.r_[0, self.hy[:-1].cumsum()] + self.hy*0.5 + self.x0[1] - - @property - def vectorCCz(self): - """Cell-centered grid vector (1D) in the z direction.""" - return None if self.dim < 3 else np.r_[0, self.hz[:-1].cumsum()] + self.hz*0.5 + self.x0[2] - - def getTensor(self, key): - """ Returns a tensor list. - - :param str key: What tensor (see below) - :rtype: list - :return: list of the tensors that make up the mesh. - - key can be:: - - 'CC' -> scalar field defined on cell centers - 'N' -> scalar field defined on nodes - 'Fx' -> x-component of field defined on faces - 'Fy' -> y-component of field defined on faces - 'Fz' -> z-component of field defined on faces - 'Ex' -> x-component of field defined on edges - 'Ey' -> y-component of field defined on edges - 'Ez' -> z-component of field defined on edges - - """ - - if key == 'Fx': - ten = [self.vectorNx , self.vectorCCy, self.vectorCCz] - elif key == 'Fy': - ten = [self.vectorCCx, self.vectorNy , self.vectorCCz] - elif key == 'Fz': - ten = [self.vectorCCx, self.vectorCCy, self.vectorNz ] - elif key == 'Ex': - ten = [self.vectorCCx, self.vectorNy , self.vectorNz ] - elif key == 'Ey': - ten = [self.vectorNx , self.vectorCCy, self.vectorNz ] - elif key == 'Ez': - ten = [self.vectorNx , self.vectorNy , self.vectorCCz] - elif key == 'CC': - ten = [self.vectorCCx, self.vectorCCy, self.vectorCCz] - elif key == 'N': - ten = [self.vectorNx , self.vectorNy , self.vectorNz ] - - return [t for t in ten if t is not None] - @property def nC(self): return len(self._cells) @@ -1892,30 +1775,6 @@ class TreeMesh(BaseMesh, InnerProducts): return self._getEdgeP(xEdge, yEdge, zEdge) return Pxxx - - def isInside(self, pts, locType='N'): - """ - Determines if a set of points are inside a mesh. - - :param numpy.ndarray pts: Location of points to test - :rtype numpy.ndarray - :return inside, numpy array of booleans - """ - pts = Utils.asArray_N_x_Dim(pts, self.dim) - - tensors = self.getTensor(locType) - - if locType == 'N' and self._meshType == 'CYL': - #NOTE: for a CYL mesh we add a node to check if we are inside in the radial direction! - tensors[0] = np.r_[0.,tensors[0]] - tensors[1] = np.r_[tensors[1], 2.0*np.pi] - - inside = np.ones(pts.shape[0],dtype=bool) - for i, tensor in enumerate(tensors): - TOL = np.diff(tensor).min() * 1.0e-10 - inside = inside & (pts[:,i] >= tensor.min()-TOL) & (pts[:,i] <= tensor.max()+TOL) - return inside - def point2index(self, locs): locs = Utils.asArray_N_x_Dim(locs, self.dim) diff --git a/tests/mesh/test_TreeOperators.py b/tests/mesh/test_TreeOperators.py index 1a62673e..73385842 100644 --- a/tests/mesh/test_TreeOperators.py +++ b/tests/mesh/test_TreeOperators.py @@ -105,7 +105,7 @@ class TestCurl(Tests.OrderTest): class TestTreeInnerProducts(Tests.OrderTest): """Integrate an function over a unit cube domain using edgeInnerProducts and faceInnerProducts.""" - meshTypes = ['uniformTree'] #['uniformTensorMesh', 'uniformCurv', 'rotateCurv'] + meshTypes = ['uniformTree', 'notatreeTree'] #['uniformTensorMesh', 'uniformCurv', 'rotateCurv'] meshDimension = 3 meshSizes = [4, 8] diff --git a/tests/mesh/test_innerProductDerivs.py b/tests/mesh/test_innerProductDerivs.py index ba074ede..41ba5dcd 100644 --- a/tests/mesh/test_innerProductDerivs.py +++ b/tests/mesh/test_innerProductDerivs.py @@ -218,18 +218,18 @@ class TestInnerProductsDerivs(unittest.TestCase): def test_FaceIP_3D_tensor_Tree(self): self.assertTrue(self.doTestFace([8, 8, 8],6, False, 'Tree')) - # def test_FaceIP_2D_float_fast_Tree(self): - # self.assertTrue(self.doTestFace([8, 8],0, True, 'Tree')) - # def test_FaceIP_3D_float_fast_Tree(self): - # self.assertTrue(self.doTestFace([8, 8, 8],0, True, 'Tree')) - # def test_FaceIP_2D_isotropic_fast_Tree(self): - # self.assertTrue(self.doTestFace([8, 8],1, True, 'Tree')) - # def test_FaceIP_3D_isotropic_fast_Tree(self): - # self.assertTrue(self.doTestFace([8, 8, 8],1, True, 'Tree')) - # def test_FaceIP_2D_anisotropic_fast_Tree(self): - # self.assertTrue(self.doTestFace([8, 8],2, True, 'Tree')) - # def test_FaceIP_3D_anisotropic_fast_Tree(self): - # self.assertTrue(self.doTestFace([8, 8, 8],3, True, 'Tree')) + def test_FaceIP_2D_float_fast_Tree(self): + self.assertTrue(self.doTestFace([8, 8],0, True, 'Tree')) + def test_FaceIP_3D_float_fast_Tree(self): + self.assertTrue(self.doTestFace([8, 8, 8],0, True, 'Tree')) + def test_FaceIP_2D_isotropic_fast_Tree(self): + self.assertTrue(self.doTestFace([8, 8],1, True, 'Tree')) + def test_FaceIP_3D_isotropic_fast_Tree(self): + self.assertTrue(self.doTestFace([8, 8, 8],1, True, 'Tree')) + def test_FaceIP_2D_anisotropic_fast_Tree(self): + self.assertTrue(self.doTestFace([8, 8],2, True, 'Tree')) + def test_FaceIP_3D_anisotropic_fast_Tree(self): + self.assertTrue(self.doTestFace([8, 8, 8],3, True, 'Tree')) # def test_EdgeIP_2D_float_Tree(self): # self.assertTrue(self.doTestEdge([8, 8],0, False, 'Tree')) @@ -250,16 +250,16 @@ class TestInnerProductsDerivs(unittest.TestCase): # def test_EdgeIP_2D_float_fast_Tree(self): # self.assertTrue(self.doTestEdge([8, 8],0, True, 'Tree')) - # def test_EdgeIP_3D_float_fast_Tree(self): - # self.assertTrue(self.doTestEdge([8, 8, 8],0, True, 'Tree')) + def test_EdgeIP_3D_float_fast_Tree(self): + self.assertTrue(self.doTestEdge([8, 8, 8],0, True, 'Tree')) # def test_EdgeIP_2D_isotropic_fast_Tree(self): # self.assertTrue(self.doTestEdge([8, 8],1, True, 'Tree')) - # def test_EdgeIP_3D_isotropic_fast_Tree(self): - # self.assertTrue(self.doTestEdge([8, 8, 8],1, True, 'Tree')) + def test_EdgeIP_3D_isotropic_fast_Tree(self): + self.assertTrue(self.doTestEdge([8, 8, 8],1, True, 'Tree')) # def test_EdgeIP_2D_anisotropic_fast_Tree(self): # self.assertTrue(self.doTestEdge([8, 8],2, True, 'Tree')) - # def test_EdgeIP_3D_anisotropic_fast_Tree(self): - # self.assertTrue(self.doTestEdge([8, 8, 8],3, True, 'Tree')) + def test_EdgeIP_3D_anisotropic_fast_Tree(self): + self.assertTrue(self.doTestEdge([8, 8, 8],3, True, 'Tree')) if __name__ == '__main__': unittest.main() From 81a36684ca236beb6ddae6465ece4c9c5b0e03b9 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Wed, 18 Nov 2015 15:34:55 -0800 Subject: [PATCH 77/83] NodalGrad --- SimPEG/Mesh/TreeMesh.py | 84 +++++++++++++++++++++++--------- tests/mesh/test_TreeOperators.py | 62 ++++++++++++++++++++++- 2 files changed, 122 insertions(+), 24 deletions(-) diff --git a/SimPEG/Mesh/TreeMesh.py b/SimPEG/Mesh/TreeMesh.py index 88b2d26e..75f22773 100644 --- a/SimPEG/Mesh/TreeMesh.py +++ b/SimPEG/Mesh/TreeMesh.py @@ -1231,7 +1231,7 @@ class TreeMesh(BaseTensorMesh, InnerProducts): self._hanging(force=force) def _deflationMatrix(self, location, withHanging=True, asOnes=False): - assert location in ['N','F','Fx','Fy'] + (['Fz','E','Ex','Ey','Ez'] if self.dim == 3 else []) + assert location in ['N','F','Fx','Fy','E','Ex','Ey'] + (['Fz','Ez'] if self.dim == 3 else []) args = dict() args['N'] = (self._nodes, self._hangingN, self._n2i ) @@ -1242,6 +1242,9 @@ class TreeMesh(BaseTensorMesh, InnerProducts): args['Ex'] = (self._edgesX, self._hangingEx, self._ex2i) args['Ey'] = (self._edgesY, self._hangingEy, self._ey2i) args['Ez'] = (self._edgesZ, self._hangingEz, self._ez2i) + elif self.dim == 2: + args['Ex'] = (self._facesY, self._hangingFy, self._fy2i) + args['Ey'] = (self._facesX, self._hangingFx, self._fx2i) if location in ['F', 'E']: Rlist = [self._deflationMatrix(location + subLoc, withHanging=withHanging, asOnes=asOnes) for subLoc in ['x','y','z'][:self.dim]] return sp.block_diag(Rlist) @@ -1401,27 +1404,64 @@ class TreeMesh(BaseTensorMesh, InnerProducts): @property def nodalGrad(self): - raise Exception('Not yet implemented!') - # if getattr(self, '_nodalGrad', None) is None: - # self.number() - # # TODO: Preallocate! - # I, J, V = [], [], [] - # # kinda a hack for the 2D gradient - # # because edges are not stored - # edges = self.faces if self.dim == 2 else self.edges - # for edge in edges: - # if self.dim == 3: - # I += [edge.num, edge.num] - # elif self.dim == 2 and edge.faceType == 'x': - # I += [edge.num + self.nFy, edge.num + self.nFy] - # elif self.dim == 2 and edge.faceType == 'y': - # I += [edge.num - self.nFx, edge.num - self.nFx] - # J += [edge.node0.num, edge.node1.num] - # V += [-1, 1] - # G = sp.csr_matrix((V,(I,J)), shape=(self.nE, self.nN)) - # L = self.edge - # self._nodalGrad = Utils.sdiag(1/L)*G - # return self._nodalGrad + if getattr(self, '_nodalGrad', None) is None: + self.number() + # TODO: Preallocate! + I, J, V = [], [], [] + # kinda a hack for the 2D gradient + # because edges are not stored + edgesX = self._facesY if self.dim == 2 else self._edgesX + offset = 0 + for ex in edgesX: + p = self._pointer(ex) + w = self._levelWidth(p[-1]) + if self.dim == 2: + I += [self._fy2i[ex] + offset]*2 + nodePlus = self._index([ p[0] + w, p[1], p[2]]) + elif self.dim == 3: + I += [self._ex2i[ex] + offset]*2 + nodePlus = self._index([ p[0] + w, p[1], p[2], p[3]]) + J += [self._n2i[ex], self._n2i[nodePlus]] + V += [-1, 1] + + edgesY = self._facesX if self.dim == 2 else self._edgesY + offset = self.ntFy if self.dim == 2 else self.ntEx + for ey in edgesY: + p = self._pointer(ey) + w = self._levelWidth(p[-1]) + if self.dim == 2: + I += [self._fx2i[ey] + offset]*2 + nodePlus = self._index([ p[0], p[1] + w, p[2]]) + elif self.dim == 3: + I += [self._ey2i[ey] + offset]*2 + nodePlus = self._index([ p[0], p[1] + w, p[2], p[3]]) + J += [self._n2i[ey], self._n2i[nodePlus]] + V += [-1, 1] + if self.dim == 3: + + edgesZ = self._edgesZ + offset = self.ntEx + self.ntEy + for ez in edgesZ: + p = self._pointer(ez) + w = self._levelWidth(p[-1]) + I += [self._ez2i[ez] + offset]*2 + nodePlus = self._index([ p[0], p[1], p[2] + w, p[3]]) + J += [self._n2i[ez], self._n2i[nodePlus]] + V += [-1, 1] + + G = sp.csr_matrix((V,(I,J)), shape=(self.ntE, self.ntN)) + if self.dim == 2: + L = np.r_[self._areaFyFull, self._areaFxFull] + elif self.dim == 3: + L = np.r_[self._edgeExFull, self._edgeEyFull, self._edgeEzFull] + + Rn = self._deflationMatrix('N') + Re = self._deflationMatrix('E', withHanging=True, asOnes=False) + + Re_ave = Utils.sdiag(1./Re.sum(axis=0)) * Re.T + + self._nodalGrad = Re_ave*Utils.sdiag(1/L)*G*Rn + return self._nodalGrad @property def aveEx2CC(self): diff --git a/tests/mesh/test_TreeOperators.py b/tests/mesh/test_TreeOperators.py index 73385842..c16f6b23 100644 --- a/tests/mesh/test_TreeOperators.py +++ b/tests/mesh/test_TreeOperators.py @@ -69,9 +69,9 @@ class TestFaceDiv3D(Tests.OrderTest): class TestCurl(Tests.OrderTest): name = "Curl" - meshTypes = MESHTYPES + meshTypes = ['notatreeTree', 'uniformTree'] #, 'randomTree']#, 'uniformTree'] meshSizes = [8, 16]#, 32] - expectedOrders = 1 # This is due to linear interpolation in the Re projection + expectedOrders = [2,1] # This is due to linear interpolation in the Re projection def getError(self): # fun: i (cos(y)) + j (cos(z)) + k (cos(x)) @@ -102,6 +102,62 @@ class TestCurl(Tests.OrderTest): self.orderTest() +class TestNodalGrad(Tests.OrderTest): + name = "Nodal Gradient" + meshTypes = ['notatreeTree', 'uniformTree'] #['randomTree', 'uniformTree'] + meshSizes = [8, 16]#, 32] + expectedOrders = [2,1] + + def getError(self): + #Test function + fun = lambda x, y, z: (np.cos(x)+np.cos(y)+np.cos(z)) + # i (sin(x)) + j (sin(y)) + k (sin(z)) + solX = lambda x, y, z: -np.sin(x) + solY = lambda x, y, z: -np.sin(y) + solZ = lambda x, y, z: -np.sin(z) + + phi = call3(fun, self.M.gridN) + gradE = self.M.nodalGrad.dot(phi) + + Ec = cartE3(self.M, solX, solY, solZ) + gradE_ana = self.M.projectEdgeVector(Ec) + + err = np.linalg.norm((gradE-gradE_ana), np.inf) + + return err + + def test_order(self): + self.orderTest() + + +class TestNodalGrad2D(Tests.OrderTest): + name = "Nodal Gradient 2D" + meshTypes = ['notatreeTree', 'uniformTree'] #['randomTree', 'uniformTree'] + meshSizes = [8, 16]#, 32] + expectedOrders = [2,1] + meshDimension = 2 + + def getError(self): + #Test function + fun = lambda x, y: (np.cos(x)+np.cos(y)) + # i (sin(x)) + j (sin(y)) + k (sin(z)) + solX = lambda x, y: -np.sin(x) + solY = lambda x, y: -np.sin(y) + + phi = call2(fun, self.M.gridN) + gradE = self.M.nodalGrad.dot(phi) + + Ec = cartE2(self.M, solX, solY) + gradE_ana = self.M.projectEdgeVector(Ec) + + err = np.linalg.norm((gradE-gradE_ana), np.inf) + + return err + + def test_order(self): + self.orderTest() + + class TestTreeInnerProducts(Tests.OrderTest): """Integrate an function over a unit cube domain using edgeInnerProducts and faceInnerProducts.""" @@ -613,5 +669,7 @@ class TestAveraging3D(Tests.OrderTest): # self.expectedOrders = 1 # self.orderTest() # self.expectedOrders = 2 + + if __name__ == '__main__': unittest.main() From ca05d0599ecfbd8a796cee325a93838807efd8c6 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Wed, 18 Nov 2015 16:12:59 -0800 Subject: [PATCH 78/83] Grid x0 locations. --- SimPEG/Mesh/TreeMesh.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/SimPEG/Mesh/TreeMesh.py b/SimPEG/Mesh/TreeMesh.py index 75f22773..28a892f3 100644 --- a/SimPEG/Mesh/TreeMesh.py +++ b/SimPEG/Mesh/TreeMesh.py @@ -639,54 +639,54 @@ class TreeMesh(BaseTensorMesh, InnerProducts): self._gridCC = np.zeros((len(self._cells),self.dim)) for ii, ind in enumerate(self._sortedCells): p = self._asPointer(ind) - self._gridCC[ii, :] = self._cellC(p) + self._gridCC[ii, :] = self._cellC(p) + self.x0 return self._gridCC @property def gridN(self): self.number() R = self._deflationMatrix('N', withHanging=False) - return R.T * self._gridN + return R.T * self._gridN + np.repeat([self.x0],self.nN,axis=0) @property def gridFx(self): self.number() R = self._deflationMatrix('Fx', withHanging=False) - return R.T * self._gridFx + return R.T * self._gridFx + np.repeat([self.x0],self.nFx,axis=0) @property def gridFy(self): self.number() R = self._deflationMatrix('Fy', withHanging=False) - return R.T * self._gridFy + return R.T * self._gridFy + np.repeat([self.x0],self.nFy,axis=0) @property def gridFz(self): if self.dim < 3: return None self.number() R = self._deflationMatrix('Fz', withHanging=False) - return R.T * self._gridFz + return R.T * self._gridFz + np.repeat([self.x0],self.nFz,axis=0) @property def gridEx(self): if self.dim == 2: return self.gridFy self.number() R = self._deflationMatrix('Ex', withHanging=False) - return R.T * self._gridEx + return R.T * self._gridEx + np.repeat([self.x0],self.nEx,axis=0) @property def gridEy(self): if self.dim == 2: return self.gridFx self.number() R = self._deflationMatrix('Ey', withHanging=False) - return R.T * self._gridEy + return R.T * self._gridEy + np.repeat([self.x0],self.nEy,axis=0) @property def gridEz(self): if self.dim < 3: return None self.number() R = self._deflationMatrix('Ez', withHanging=False) - return R.T * self._gridEz + return R.T * self._gridEz + np.repeat([self.x0],self.nEz,axis=0) @property def vol(self): From dcb9b8787d2e22e6c67ecf76195914e97367c232 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Wed, 18 Nov 2015 17:15:26 -0800 Subject: [PATCH 79/83] Corsen Trees --- SimPEG/Mesh/TreeMesh.py | 114 +++++++++++++++++++++++------------- tests/mesh/test_TreeMesh.py | 62 +++++++++++++++++++- 2 files changed, 132 insertions(+), 44 deletions(-) diff --git a/SimPEG/Mesh/TreeMesh.py b/SimPEG/Mesh/TreeMesh.py index 28a892f3..c510a842 100644 --- a/SimPEG/Mesh/TreeMesh.py +++ b/SimPEG/Mesh/TreeMesh.py @@ -411,6 +411,10 @@ class TreeMesh(BaseTensorMesh, InnerProducts): def refine(self, function=None, recursive=True, cells=None, balance=True, verbose=False, _inRecursion=False): + if type(function) in [int, long]: + level = function + function = lambda cell: level + if not _inRecursion: self.__dirty__ = True if verbose: print 'Refining Mesh' @@ -421,65 +425,86 @@ class TreeMesh(BaseTensorMesh, InnerProducts): for cell in cells: p = self._pointer(cell) if p[-1] >= self.levels: continue - do = function(Cell(self, cell, p)) > p[-1] + result = function(Cell(self, cell, p)) + if type(result) is bool: + do = result + elif type(result) in [int,long]: + do = result > p[-1] + else: + raise Exception('You must tell the program what to refine. Use BOOL or INT (level)') if do: recurse += self._refineCell(cell, p) if verbose: print ' ', time.time() - tic if recursive and len(recurse) > 0: - recurse += self.refine(function=function, recursive=True, cells=recurse, balance=balance, _inRecursion=True) + recurse += self.refine(function=function, recursive=True, cells=recurse, balance=balance, verbose=verbose, _inRecursion=True) if balance and not _inRecursion: self.balance() return recurse + def corsen(self, function=None, recursive=True, cells=None, balance=True, verbose=False, _inRecursion=False): + + if type(function) in [int, long]: + level = function + function = lambda cell: level + + if not _inRecursion: + self.__dirty__ = True + if verbose: print 'Corsening Mesh' + + cells = cells if cells is not None else sorted(self._cells) + recurse = [] + tic = time.time() + for cell in cells: + if cell not in self._cells: continue # already removed + p = self._pointer(cell) + if p[-1] >= self.levels: continue + result = function(Cell(self, cell, p)) + if type(result) is bool: + do = result + elif type(result) in [int,long]: + do = result < p[-1] + else: + raise Exception('You must tell the program what to corsen. Use BOOL or INT (level)') + if do: + recurse += self._corsenCell(cell, p) + + if verbose: print ' ', time.time() - tic + + if recursive and len(recurse) > 0: + recurse += self.corsen(function=function, recursive=True, cells=recurse, balance=balance, verbose=verbose, _inRecursion=True) + + if balance and not _inRecursion: + self.balance() + return recurse + + if verbose: print ' ', time.time() - tic + def _refineCell(self, ind, pointer=None): ind = self._asIndex(ind) pointer = self._asPointer(pointer if pointer is not None else ind) - assert ind in self - h = self._levelWidth(pointer[-1])/2 # halfWidth - nL = pointer[-1] + 1 # new level - add = lambda p:p[0]+p[1] - added = [] - def addCell(p): - i = self._index(p+[nL]) - self._cells.add(i) - added.append(i) - - addCell(map(add, zip(pointer[:-1], [0,0,0][:self.dim]))) - addCell(map(add, zip(pointer[:-1], [h,0,0][:self.dim]))) - addCell(map(add, zip(pointer[:-1], [0,h,0][:self.dim]))) - addCell(map(add, zip(pointer[:-1], [h,h,0][:self.dim]))) - if self.dim == 3: - addCell(map(add, zip(pointer[:-1], [0,0,h]))) - addCell(map(add, zip(pointer[:-1], [h,0,h]))) - addCell(map(add, zip(pointer[:-1], [0,h,h]))) - addCell(map(add, zip(pointer[:-1], [h,h,h]))) + if ind not in self: + raise CellLookUpException(ind) + children = self._childPointers(pointer, returnAll=True) + for child in children: + self._cells.add(self._asIndex(child)) self._cells.remove(ind) - return added + return [self._asIndex(child) for child in children] - def corsen(self, function=None): - self.__dirty__ = True - raise Exception('Not yet implemented') - - - def _corsenCell(self, pointer): - raise Exception('Not yet implemented') - - # something like this: ?? - pointer = self._asPointer(pointer) - ind = self._asIndex(pointer) - assert ind in self - - parent = self._parentPointer(ind) - children = _childPointers(parent) + def _corsenCell(self, ind, pointer=None): + ind = self._asIndex(ind) + pointer = self._asPointer(pointer if pointer is not None else ind) + if ind not in self: + raise CellLookUpException(ind) + parent = self._parentPointer(pointer) + children = self._childPointers(parent, returnAll=True) for child in children: self._cells.remove(self._asIndex(child)) - parentInd = self._asIndex(parent) self._cells.add(parentInd) - return parentInd + return [parentInd] def _asPointer(self, ind): if type(ind) in [int, long]: @@ -2225,7 +2250,12 @@ def SortGrid(grid, offset=0): return sorted(range(offset,grid.shape[0]+offset), key=K) -class NotBalancedException(Exception): + +class TreeException(Exception): + pass +class NotBalancedException(TreeException): + pass +class CellLookUpException(TreeException): pass if __name__ == '__main__': @@ -2250,9 +2280,9 @@ if __name__ == '__main__': return 2 # T = TreeMesh([[(1,128)],[(1,128)],[(1,128)]],levels=7) - T = TreeMesh([128,128,128]) + # T = TreeMesh([128,128,128]) # T = TreeMesh([64,64],levels=6) - # T = TreeMesh([4,4,4],levels=2) + T = TreeMesh([4,4,4]) # T = TreeMesh([[(1,128)],[(1,128)]],levels=7) # T.refine(lambda xc:2, balance=False) # T._index([0,0,0]) diff --git a/tests/mesh/test_TreeMesh.py b/tests/mesh/test_TreeMesh.py index 61c2f9be..e624ce87 100644 --- a/tests/mesh/test_TreeMesh.py +++ b/tests/mesh/test_TreeMesh.py @@ -1,12 +1,11 @@ from SimPEG import Mesh, Tests +from SimPEG.Mesh.TreeMesh import CellLookUpException import numpy as np import matplotlib.pyplot as plt import unittest TOL = 1e-8 - - class TestSimpleQuadTree(unittest.TestCase): def test_counts(self): @@ -19,6 +18,7 @@ class TestSimpleQuadTree(unittest.TestCase): M._refineCell([0,0,1]) M.number() # M.plotGrid(showIt=True) + print M assert M.nhFx == 2 assert M.nFx == 9 @@ -26,6 +26,64 @@ class TestSimpleQuadTree(unittest.TestCase): assert np.allclose(np.r_[M._areaFxFull, M._areaFyFull], M._deflationMatrix('F') * M.area) + def test_refine(self): + M = Mesh.TreeMesh([4,4,4]) + M.refine(1) + assert M.nC == 8 + M.refine(0) + assert M.nC == 8 + M.corsen(0) + assert M.nC == 1 + + def test_corsen(self): + nc = 8 + h1 = np.random.rand(nc)*nc*0.5 + nc*0.5 + h2 = np.random.rand(nc)*nc*0.5 + nc*0.5 + h = [hi/np.sum(hi) for hi in [h1, h2]] # normalize + M = Mesh.TreeMesh(h) + M._refineCell([0,0,0]) + M._refineCell([0,0,1]) + self.assertRaises(CellLookUpException, M._refineCell, [0,0,1]) + assert M._index([0,0,1]) not in M + assert M._index([0,0,2]) in M + assert M._index([2,0,2]) in M + assert M._index([0,2,2]) in M + assert M._index([2,2,2]) in M + + self.assertRaises(CellLookUpException, M._corsenCell, [0,0,1]) + M._corsenCell([0,0,2]) + assert M._index([0,0,1]) in M + assert M._index([0,0,2]) not in M + assert M._index([2,0,2]) not in M + assert M._index([0,2,2]) not in M + assert M._index([2,2,2]) not in M + M._refineCell([0,0,1]) + + self.assertRaises(CellLookUpException, M._corsenCell, [0,0,1]) + M._corsenCell([2,0,2]) + assert M._index([0,0,1]) in M + assert M._index([0,0,2]) not in M + assert M._index([2,0,2]) not in M + assert M._index([0,2,2]) not in M + assert M._index([2,2,2]) not in M + M._refineCell([0,0,1]) + + self.assertRaises(CellLookUpException, M._corsenCell, [0,0,1]) + M._corsenCell([0,2,2]) + assert M._index([0,0,1]) in M + assert M._index([0,0,2]) not in M + assert M._index([2,0,2]) not in M + assert M._index([0,2,2]) not in M + assert M._index([2,2,2]) not in M + M._refineCell([0,0,1]) + + self.assertRaises(CellLookUpException, M._corsenCell, [0,0,1]) + M._corsenCell([2,2,2]) + assert M._index([0,0,1]) in M + assert M._index([0,0,2]) not in M + assert M._index([2,0,2]) not in M + assert M._index([0,2,2]) not in M + assert M._index([2,2,2]) not in M def test_faceDiv(self): From f928ab801995c56cde78b9150161067cb0c671e5 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Wed, 18 Nov 2015 17:16:32 -0800 Subject: [PATCH 80/83] Refactoring. --- SimPEG/Mesh/TreeMesh.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/SimPEG/Mesh/TreeMesh.py b/SimPEG/Mesh/TreeMesh.py index c510a842..c9dfde32 100644 --- a/SimPEG/Mesh/TreeMesh.py +++ b/SimPEG/Mesh/TreeMesh.py @@ -480,8 +480,6 @@ class TreeMesh(BaseTensorMesh, InnerProducts): self.balance() return recurse - if verbose: print ' ', time.time() - tic - def _refineCell(self, ind, pointer=None): ind = self._asIndex(ind) pointer = self._asPointer(pointer if pointer is not None else ind) @@ -524,7 +522,6 @@ class TreeMesh(BaseTensorMesh, InnerProducts): return self._index(pointer) raise Exception - def _childPointers(self, pointer, direction=0, positive=True, returnAll=False): l = self._levelWidth(pointer[-1] + 1) @@ -557,7 +554,6 @@ class TreeMesh(BaseTensorMesh, InnerProducts): return children return [children[_] for _ in ind[:(self.dim-1)*2]] - def _parentPointer(self, pointer): if pointer[-1] == 0: return None mod = self._levelWidth(pointer[-1] - 1) From ccc3e4fe8ffdaca60854d5df831cc1eab5e2464d Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Wed, 18 Nov 2015 17:18:55 -0800 Subject: [PATCH 81/83] docstrs --- SimPEG/Mesh/TreeMesh.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/SimPEG/Mesh/TreeMesh.py b/SimPEG/Mesh/TreeMesh.py index c9dfde32..040a300d 100644 --- a/SimPEG/Mesh/TreeMesh.py +++ b/SimPEG/Mesh/TreeMesh.py @@ -160,10 +160,12 @@ class TreeMesh(BaseTensorMesh, InnerProducts): @property def fill(self): + """How filled is the mesh compared to a TensorMesh? As a fraction: [0,1].""" return float(self.nC)/((2**self.maxLevel)**self.dim) @property def maxLevel(self): + """The maximum level used, which may be less than `levels`.""" l = 0 for cell in self._cells: p = self._pointer(cell) @@ -307,7 +309,6 @@ class TreeMesh(BaseTensorMesh, InnerProducts): self.number() return len(self._hangingEz) - @property def ntN(self): self.number() From c775917bb365b07f0286165862d1d6206ba69b24 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Wed, 18 Nov 2015 17:21:34 -0800 Subject: [PATCH 82/83] Refactoring --- SimPEG/Mesh/TreeMesh.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/SimPEG/Mesh/TreeMesh.py b/SimPEG/Mesh/TreeMesh.py index 040a300d..c4cc88cc 100644 --- a/SimPEG/Mesh/TreeMesh.py +++ b/SimPEG/Mesh/TreeMesh.py @@ -741,11 +741,6 @@ class TreeMesh(BaseTensorMesh, InnerProducts): return self._edge - def _onSameLevel(self, i0, i1): - p0 = self._asPointer(i0) - p1 = self._asPointer(i1) - return p0[-1] == p1[-1] - def _createNumberingSets(self, force=False): if not self.__dirtySets__ and not force: return From 1a4360078143bd6feb78320f684b5c059bff5dd5 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Fri, 20 Nov 2015 15:08:37 -0800 Subject: [PATCH 83/83] Updates to MeshSlice view. --- SimPEG/Mesh/TreeMesh.py | 6 +----- SimPEG/Mesh/View.py | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/SimPEG/Mesh/TreeMesh.py b/SimPEG/Mesh/TreeMesh.py index c4cc88cc..1e6c91c0 100644 --- a/SimPEG/Mesh/TreeMesh.py +++ b/SimPEG/Mesh/TreeMesh.py @@ -821,7 +821,6 @@ class TreeMesh(BaseTensorMesh, InnerProducts): self.__dirtySets__ = False - def _numberCells(self, force=False): if not self.__dirtyCells__ and not force: return self._cc2i = dict() @@ -1418,7 +1417,6 @@ class TreeMesh(BaseTensorMesh, InnerProducts): self._edgeCurl = Rf_ave*Utils.sdiag(1.0/S)*C*Utils.sdiag(L)*Re return self._edgeCurl - @property def nodalGrad(self): if getattr(self, '_nodalGrad', None) is None: @@ -1760,7 +1758,6 @@ class TreeMesh(BaseTensorMesh, InnerProducts): self._aveN2CC = Av*Re return self._aveN2CC - def _getFaceP(self, xFace, yFace, zFace): ind1, ind2, ind3 = [], [], [] for ind in self._sortedCells: @@ -1864,7 +1861,6 @@ class TreeMesh(BaseTensorMesh, InnerProducts): break return out - def getInterpolationMat(self, locs, locType, zerosOutside=False): """ Produces interpolation matrix @@ -2101,7 +2097,7 @@ class TreeMesh(BaseTensorMesh, InnerProducts): ax=None, clim=None, showIt=False, pcolorOpts={}, streamOpts={'color':'k'}, - gridOpts={'color':'k'}): + gridOpts={'color':'k', 'alpha':0.5}): assert vType in ['CC','F','E'] assert self.dim == 3 diff --git a/SimPEG/Mesh/View.py b/SimPEG/Mesh/View.py index 272a2f47..b078eb66 100644 --- a/SimPEG/Mesh/View.py +++ b/SimPEG/Mesh/View.py @@ -173,7 +173,7 @@ class TensorView(object): ax=None, clim=None, showIt=False, pcolorOpts={}, streamOpts={'color':'k'}, - gridOpts={'color':'k'} + gridOpts={'color':'k', 'alpha':0.5} ): """