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/.travis.yml b/.travis.yml index e31b94e3..c2c672bf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,20 @@ language: python python: - 2.7 +sudo: false + +env: + - TEST_DIR=tests/em/examples + - TEST_DIR=tests/em/fdem/forward + - TEST_DIR=tests/em/fdem/inverse/derivs + - TEST_DIR=tests/em/fdem/inverse/adjoint + - TEST_DIR=tests/em/tdem + - TEST_DIR=tests/mesh + - TEST_DIR=tests/flow + - TEST_DIR=tests/utils + - TEST_DIR=tests/base + - TEST_DIR=tests/examples + # Setup anaconda before_install: - if [ ${TRAVIS_PYTHON_VERSION:0:1} == "2" ]; then wget http://repo.continuum.io/miniconda/Miniconda-3.8.3-Linux-x86_64.sh -O miniconda.sh; else wget http://repo.continuum.io/miniconda/Miniconda3-3.8.3-Linux-x86_64.sh -O miniconda.sh; fi @@ -9,20 +23,18 @@ before_install: - ./miniconda.sh -b - export PATH=/home/travis/anaconda/bin:/home/travis/miniconda/bin:$PATH - conda update --yes conda - # The next couple lines fix a crash with multiprocessing on Travis and are not specific to using Miniconda - - sudo rm -rf /dev/shm - - sudo ln -s /run/shm /dev/shm # Install packages install: - - conda install --yes pip python=$TRAVIS_PYTHON_VERSION numpy scipy matplotlib cython + - conda install --yes pip python=$TRAVIS_PYTHON_VERSION numpy scipy matplotlib cython ipython - pip install nose-cov python-coveralls # - pip install -r requirements.txt - python setup.py install + - python setup.py build_ext --inplace # Run test script: - - nosetests --with-cov --cov SimPEG --cov-config .coveragerc -v -s + - nosetests $TEST_DIR --with-cov --cov SimPEG --cov-config .coveragerc -v -s # Calculate coverage after_success: diff --git a/CITATION.rst b/CITATION.rst new file mode 100644 index 00000000..a3a13d7e --- /dev/null +++ b/CITATION.rst @@ -0,0 +1,22 @@ +Citing SimPEG +============= + +There is a paper about SimPEG! + + + Cockett, R., Kang, S., Heagy, L. J., Pidlisecky, A., & Oldenburg, D. W. (2015). SimPEG: An open source framework for simulation and gradient based parameter estimation in geophysical applications. Computers & Geosciences. + + +BibTex: +------- + +.. code:: + + @article{cockett2015simpeg, + title={SimPEG: An open source framework for simulation and gradient based parameter estimation in geophysical applications}, + author={Cockett, Rowan and Kang, Seogi and Heagy, Lindsey J and Pidlisecky, Adam and Oldenburg, Douglas W}, + journal={Computers \& Geosciences}, + year={2015}, + publisher={Elsevier} + } + diff --git a/README.rst b/README.rst index 6d41a597..71d5af88 100644 --- a/README.rst +++ b/README.rst @@ -36,6 +36,28 @@ The vision is to create a package for finite volume simulation with applications * designed for large-scale inversions +Citing SimPEG: +-------------- + +There is a paper about SimPEG! + + + Cockett, R., Kang, S., Heagy, L. J., Pidlisecky, A., & Oldenburg, D. W. (2015). SimPEG: An open source framework for simulation and gradient based parameter estimation in geophysical applications. Computers & Geosciences. + + +**BibTex:** + +.. code:: + + @article{cockett2015simpeg, + title={SimPEG: An open source framework for simulation and gradient based parameter estimation in geophysical applications}, + author={Cockett, Rowan and Kang, Seogi and Heagy, Lindsey J and Pidlisecky, Adam and Oldenburg, Douglas W}, + journal={Computers \& Geosciences}, + year={2015}, + publisher={Elsevier} + } + + Website: http://simpeg.xyz @@ -57,4 +79,4 @@ https://github.com/simpeg/simpeg/issues Code Snippets & Tutorials: -http://www.row1.ca/simpeg +http://simpeg.xyz/Journal diff --git a/SimPEG/Directives.py b/SimPEG/Directives.py index 3ec9e96e..48d7abcf 100644 --- a/SimPEG/Directives.py +++ b/SimPEG/Directives.py @@ -149,7 +149,7 @@ class TargetMisfit(InversionDirective): @property def target(self): if getattr(self, '_target', None) is None: - self._target = self.survey.nD + self._target = self.survey.nD*0.5 return self._target @target.setter def target(self, val): diff --git a/SimPEG/EM/Analytics/FDEM.py b/SimPEG/EM/Analytics/FDEM.py new file mode 100644 index 00000000..ce7e623d --- /dev/null +++ b/SimPEG/EM/Analytics/FDEM.py @@ -0,0 +1,153 @@ +from __future__ import division +import numpy as np +from scipy.constants import mu_0, pi +from scipy.special import erf +import matplotlib.pyplot as plt +from SimPEG import Utils + + +def hzAnalyticDipoleF(r, freq, sigma, secondary=True, mu=mu_0): + """ + 4.56 in Ward and Hohmann + + .. plot:: + + import matplotlib.pyplot as plt + from SimPEG import EM + freq = np.logspace(-1, 6, 61) + test = EM.Analytics.FDEM.hzAnalyticDipoleF(100, freq, 0.001, secondary=False) + plt.loglog(freq, abs(test.real)) + plt.loglog(freq, abs(test.imag)) + plt.title('Response at $r$=100m') + plt.xlabel('Frequency') + plt.ylabel('Response') + plt.legend(('real','imag')) + plt.show() + + """ + r = np.abs(r) + k = np.sqrt(-1j*2.*np.pi*freq*mu*sigma) + + m = 1 + front = m / (2. * np.pi * (k**2) * (r**5) ) + back = 9 - ( 9 + 9j * k * r - 4 * (k**2) * (r**2) - 1j * (k**3) * (r**3)) * np.exp(-1j*k*r) + hz = front*back + + if secondary: + hp =-1/(4*np.pi*r**3) + hz = hz-hp + + if hz.ndim == 1: + hz = Utils.mkvc(hz,2) + + return hz + +def MagneticDipoleWholeSpace(XYZ, srcLoc, sig, f, moment=1., orientation='X', mu = mu_0): + """ + Analytical solution for a dipole in a whole-space. + + Equation 2.57 of Ward and Hohmann + + TODOs: + - set it up to instead take a mesh & survey + - add E-fields + - handle multiple frequencies + - add divide by zero safety + + + .. plot:: + + from SimPEG import EM + import matplotlib.pyplot as plt + freqs = np.logspace(-2,5,100) + Bx, By, Bz = EM.Analytics.FDEM.AnalyticMagDipoleWholeSpace([0,100,0], [0,0,0], 1e-2, freqs, m=1, orientation='Z') + plt.loglog(freqs, np.abs(Bz.real)/mu_0, 'b') + plt.loglog(freqs, np.abs(Bz.imag)/mu_0, 'r') + plt.legend(('real','imag')) + plt.show() + + + """ + + XYZ = Utils.asArray_N_x_Dim(XYZ, 3) + + dx = XYZ[:,0]-srcLoc[0] + dy = XYZ[:,1]-srcLoc[1] + dz = XYZ[:,2]-srcLoc[2] + + r = np.sqrt( dx**2. + dy**2. + dz**2.) + k = np.sqrt( -1j*2.*np.pi*f*mu*sig ) + kr = k*r + + front = moment / (4.*pi * r**3.) * np.exp(-1j*kr) + mid = -kr**2. + 3.*1j*kr + 3. + + if orientation.upper() == 'X': + Hx = front*( (dx/r)**2. * mid + (kr**2. - 1j*kr - 1.) ) + Hy = front*( (dx*dy/r**2.) * mid ) + Hz = front*( (dx*dz/r**2.) * mid ) + + elif orientation.upper() == 'Y': + Hx = front*( (dy*dx/r**2.) * mid ) + Hy = front*( (dy/r)**2. * mid + (kr**2. - 1j*kr - 1.) ) + Hz = front*( (dy*dz/r**2.) * mid ) + + elif orientation.upper() == 'Z': + Hx = front*( (dx*dz/r**2.) * mid ) + Hy = front*( (dy*dz/r**2.) * mid ) + Hz = front*( (dz/r)**2. * mid + (kr**2. - 1j*kr - 1.) ) + + Bx = mu*Hx + By = mu*Hy + Bz = mu*Hz + + if Bx.ndim is 1: + Bx = Utils.mkvc(Bx,2) + + if By.ndim is 1: + By = Utils.mkvc(By,2) + + if Bz.ndim is 1: + Bz = Utils.mkvc(Bz,2) + + return Bx, By, Bz + + +def ElectricDipoleWholeSpace(XYZ, srcLoc, sig, f, current=1., length=1., orientation='X', mu=mu_0): + XYZ = Utils.asArray_N_x_Dim(XYZ, 3) + + dx = XYZ[:,0]-srcLoc[0] + dy = XYZ[:,1]-srcLoc[1] + dz = XYZ[:,2]-srcLoc[2] + + r = np.sqrt( dx**2. + dy**2. + dz**2.) + k = np.sqrt( -1j*2.*np.pi*f*mu*sig ) + kr = k*r + + front = current * length / (4. * np.pi * sig * r**3) * np.exp(-1j*k*r) + mid = -k**2 * r**2 + 3*1j*k*r + 3 + + # Ex = front*((dx**2 / r**2)*mid + (k**2 * r**2 -1j*k*r)) + # Ey = front*(dx*dy / r**2)*mid + # Ez = front*(dx*dz / r**2)*mid + + if orientation.upper() == 'X': + Ex = front*((dx**2 / r**2)*mid + (k**2 * r**2 -1j*k*r-1.)) + Ey = front*(dx*dy / r**2)*mid + Ez = front*(dx*dz / r**2)*mid + return Ex, Ey, Ez + + elif orientation.upper() == 'Y': + # x--> y, y--> z, z-->x + Ey = front*((dy**2 / r**2)*mid + (k**2 * r**2 -1j*k*r-1.)) + Ez = front*(dy*dz / r**2)*mid + Ex = front*(dy*dx / r**2)*mid + return Ex, Ey, Ez + + elif orientation.upper() == 'Z': + # x --> z, y --> x, z --> y + Ez = front*((dz**2 / r**2)*mid + (k**2 * r**2 -1j*k*r-1.)) + Ex = front*(dz*dx / r**2)*mid + Ey = front*(dz*dy / r**2)*mid + return Ex, Ey, Ez + # return Ey, Ez, Ex diff --git a/SimPEG/EM/Analytics/FDEMcasing.py b/SimPEG/EM/Analytics/FDEMcasing.py new file mode 100644 index 00000000..d3db381d --- /dev/null +++ b/SimPEG/EM/Analytics/FDEMcasing.py @@ -0,0 +1,98 @@ +from SimPEG import Utils, np +from scipy.constants import mu_0, epsilon_0 +from SimPEG.EM.Utils.EMUtils import k + +def getKc(freq,sigma,a,b,mu=mu_0,eps=epsilon_0): + a = float(a) + b = float(b) + # return 1./(2*np.pi) * np.sqrt(b / a) * np.exp(-1j*k(freq,sigma,mu,eps)*(b-a)) + return np.sqrt(b / a) * np.exp(-1j*k(freq,sigma,mu,eps)*(b-a)) + +def _r2(xyz): + return np.sum(xyz**2,1) + +def _getCasingHertzMagDipole(srcloc,obsloc,freq,sigma,a,b,mu=mu_0*np.ones(3),eps=epsilon_0,moment=1.): + Kc1 = getKc(freq,sigma[1],a,b,mu[1],eps) + + nobs = obsloc.shape[0] + dxyz = obsloc - np.c_[np.ones(nobs)]*np.r_[srcloc] + + r2 = _r2(dxyz[:,:2]) + sqrtr2z2 = np.sqrt(r2 + dxyz[:,2]**2) + k2 = k(freq,sigma[2],mu[2],eps) + + return Kc1 * moment / (4.*np.pi) *np.exp(-1j*k2*sqrtr2z2) / sqrtr2z2 + + +def _getCasingHertzMagDipoleDeriv_r(srcloc,obsloc,freq,sigma,a,b,mu=mu_0*np.ones(3),eps=epsilon_0,moment=1.): + HertzZ = _getCasingHertzMagDipole(srcloc,obsloc,freq,sigma,a,b,mu,eps,moment) + + nobs = obsloc.shape[0] + dxyz = obsloc - np.c_[np.ones(nobs)]*np.r_[srcloc] + + r2 = _r2(dxyz[:,:2]) + sqrtr2z2 = np.sqrt(r2 + dxyz[:,2]**2) + k2 = k(freq,sigma[2],mu[2],eps) + + return -HertzZ * np.sqrt(r2) / sqrtr2z2 * (1j*k2 + 1./ sqrtr2z2) + + +def _getCasingHertzMagDipoleDeriv_z(srcloc,obsloc,freq,sigma,a,b,mu=mu_0*np.ones(3),eps=epsilon_0,moment=1.): + HertzZ = _getCasingHertzMagDipole(srcloc,obsloc,freq,sigma,a,b,mu,eps,moment) + + nobs = obsloc.shape[0] + dxyz = obsloc - np.c_[np.ones(nobs)]*np.r_[srcloc] + + r2z2 = _r2(dxyz) + sqrtr2z2 = np.sqrt(r2z2) + k2 = k(freq,sigma[2],mu[2],eps) + + return -HertzZ*dxyz[:,2] /sqrtr2z2 * (1j*k2 + 1./sqrtr2z2) + +def _getCasingHertzMagDipole2Deriv_z_r(srcloc,obsloc,freq,sigma,a,b,mu=mu_0*np.ones(3),eps=epsilon_0,moment=1.): + HertzZ = _getCasingHertzMagDipole(srcloc,obsloc,freq,sigma,a,b,mu,eps,moment) + dHertzZdr = _getCasingHertzMagDipoleDeriv_r(srcloc,obsloc,freq,sigma,a,b,mu,eps,moment) + + nobs = obsloc.shape[0] + dxyz = obsloc - np.c_[np.ones(nobs)]*np.r_[srcloc] + + r2 = _r2(dxyz[:,:2]) + r = np.sqrt(r2) + z = dxyz[:,2] + sqrtr2z2 = np.sqrt(r2 + z**2) + k2 = k(freq,sigma[2],mu[2],eps) + + return dHertzZdr*(-z/sqrtr2z2)*(1j*k2+1./sqrtr2z2) + HertzZ*(z*r/sqrtr2z2**3)*(1j*k2 + 2./sqrtr2z2) + +def _getCasingHertzMagDipole2Deriv_z_z(srcloc,obsloc,freq,sigma,a,b,mu=mu_0*np.ones(3),eps=epsilon_0,moment=1.): + HertzZ = _getCasingHertzMagDipole(srcloc,obsloc,freq,sigma,a,b,mu,eps,moment) + dHertzZdz = _getCasingHertzMagDipoleDeriv_z(srcloc,obsloc,freq,sigma,a,b,mu,eps,moment) + + nobs = obsloc.shape[0] + dxyz = obsloc - np.c_[np.ones(nobs)]*np.r_[srcloc] + + r2 = _r2(dxyz[:,:2]) + r = np.sqrt(r2) + z = dxyz[:,2] + sqrtr2z2 = np.sqrt(r2 + z**2) + k2 = k(freq,sigma[2],mu[2],eps) + + return (dHertzZdz*z + HertzZ)/sqrtr2z2*(-1j*k2 - 1./sqrtr2z2) + HertzZ*z/sqrtr2z2**3*(1j*k2*z + 2.*z/sqrtr2z2) + +def getCasingEphiMagDipole(srcloc,obsloc,freq,sigma,a,b,mu=mu_0*np.ones(3),eps=epsilon_0,moment=1.): + return 1j * omega(freq) * mu * _getCasingHertzMagDipoleDeriv_r(srcloc,obsloc,freq,sigma,a,b,mu,eps,moment) + +def getCasingHrMagDipole(srcloc,obsloc,freq,sigma,a,b,mu=mu_0*np.ones(3),eps=epsilon_0,moment=1.): + return _getCasingHertzMagDipole2Deriv_z_r(srcloc,obsloc,freq,sigma,a,b,mu,eps,moment) + +def getCasingHzMagDipole(srcloc,obsloc,freq,sigma,a,b,mu=mu_0*np.ones(3),eps=epsilon_0,moment=1.): + d2HertzZdz2 = _getCasingHertzMagDipole2Deriv_z_z(srcloc,obsloc,freq,sigma,a,b,mu,eps,moment) + k2 = k(freq,sigma[2],mu[2],eps) + HertzZ = _getCasingHertzMagDipole(srcloc,obsloc,freq,sigma,a,b,mu,eps,moment) + return d2HertzZdz2 + k2**2 * HertzZ + +def getCasingBrMagDipole(srcloc,obsloc,freq,sigma,a,b,mu=mu_0*np.ones(3),eps=epsilon_0,moment=1.): + return mu_0 * getCasingHrMagDipole(srcloc,obsloc,freq,sigma,a,b,mu,eps,moment) + +def getCasingBzMagDipole(srcloc,obsloc,freq,sigma,a,b,mu=mu_0*np.ones(3),eps=epsilon_0,moment=1.): + return mu_0 * getCasingHzMagDipole(srcloc,obsloc,freq,sigma,a,b,mu,eps,moment) diff --git a/SimPEG/EM/Analytics/TDEM.py b/SimPEG/EM/Analytics/TDEM.py new file mode 100644 index 00000000..b20e8191 --- /dev/null +++ b/SimPEG/EM/Analytics/TDEM.py @@ -0,0 +1,12 @@ +import numpy as np +from scipy.constants import mu_0, pi +from scipy.special import erf + +def hzAnalyticDipoleT(r, t, sigma): + theta = np.sqrt((sigma*mu_0)/(4*t)) + tr = theta*r + etr = erf(tr) + t1 = (9/(2*tr**2) - 1)*etr + t2 = (1/np.sqrt(pi))*(9/tr + 4*tr)*np.exp(-tr**2) + hz = (t1 - t2)/(4*pi*r**3) + return hz diff --git a/SimPEG/EM/Analytics/__init__.py b/SimPEG/EM/Analytics/__init__.py new file mode 100644 index 00000000..5b7a8851 --- /dev/null +++ b/SimPEG/EM/Analytics/__init__.py @@ -0,0 +1,3 @@ +from TDEM import hzAnalyticDipoleT +from FDEM import hzAnalyticDipoleF +from FDEMcasing import * diff --git a/SimPEG/EM/Base.py b/SimPEG/EM/Base.py new file mode 100644 index 00000000..32018f7e --- /dev/null +++ b/SimPEG/EM/Base.py @@ -0,0 +1,186 @@ +from SimPEG import Survey, Problem, Utils, Models, Maps, PropMaps, np, sp, Solver as SimpegSolver +from scipy.constants import mu_0 + +class EMPropMap(Maps.PropMap): + """ + Property Map for EM Problems. The electrical conductivity (\\(\\sigma\\)) is the default inversion property, and the default value of the magnetic permeability is that of free space (\\(\\mu = 4\\pi\\times 10^{-7} \\) H/m) + """ + + sigma = Maps.Property("Electrical Conductivity", defaultInvProp = True, propertyLink=('rho',Maps.ReciprocalMap)) + mu = Maps.Property("Inverse Magnetic Permeability", defaultVal = mu_0, propertyLink=('mui',Maps.ReciprocalMap)) + + rho = Maps.Property("Electrical Resistivity", propertyLink=('sigma', Maps.ReciprocalMap)) + mui = Maps.Property("Inverse Magnetic Permeability", defaultVal = 1./mu_0, propertyLink=('mu', Maps.ReciprocalMap)) + + +class BaseEMProblem(Problem.BaseProblem): + + def __init__(self, mesh, **kwargs): + Problem.BaseProblem.__init__(self, mesh, **kwargs) + + + surveyPair = Survey.BaseSurvey + dataPair = Survey.Data + + PropMap = EMPropMap + + Solver = SimpegSolver + solverOpts = {} + + verbose = False + + #################################################### + # Make A Symmetric + #################################################### + @property + def _makeASymmetric(self): + if getattr(self, '__makeASymmetric', None) is None: + self.__makeASymmetric = True + return self.__makeASymmetric + + + #################################################### + # Mass Matrices + #################################################### + + @property + def deleteTheseOnModelUpdate(self): + toDelete = [] + if self.mapping.sigmaMap is not None or self.mapping.rhoMap is not None: + toDelete += ['_MeSigma', '_MeSigmaI','_MfRho','_MfRhoI'] + if self.mapping.muMap is not None or self.mapping.muiMap is not None: + toDelete += ['_MeMu', '_MeMuI','_MfMui','_MfMuiI'] + return toDelete + + @property + def Me(self): + """ + Edge inner product matrix + """ + if getattr(self, '_Me', None) is None: + self._Me = self.mesh.getEdgeInnerProduct() + return self._Me + + @property + def Mf(self): + """ + Face inner product matrix + """ + if getattr(self, '_Mf', None) is None: + self._Mf = self.mesh.getFaceInnerProduct() + return self._Mf + + + # ----- Magnetic Permeability ----- # + @property + def MfMui(self): + """ + Face inner product matrix for \\(\\mu^{-1}\\). Used in the E-B formulation + """ + if getattr(self, '_MfMui', None) is None: + self._MfMui = self.mesh.getFaceInnerProduct(self.curModel.mui) + return self._MfMui + + @property + def MfMuiI(self): + """ + Inverse of :code:`MfMui`. + """ + if getattr(self, '_MfMuiI', None) is None: + self._MfMuiI = self.mesh.getFaceInnerProduct(self.curModel.mui, invMat=True) + return self._MfMuiI + + @property + def MeMu(self): + """ + Edge inner product matrix for \\(\\mu\\). Used in the H-J formulation + """ + if getattr(self, '_MeMu', None) is None: + self._MeMu = self.mesh.getEdgeInnerProduct(self.curModel.mu) + return self._MeMu + + @property + def MeMuI(self): + """ + Inverse of :code:`MeMu` + """ + if getattr(self, '_MeMuI', None) is None: + self._MeMuI = self.mesh.getEdgeInnerProduct(self.curModel.mu, invMat=True) + return self._MeMuI + + + # ----- Electrical Conductivity ----- # + #TODO: hardcoded to sigma as the model + @property + def MeSigma(self): + """ + Edge inner product matrix for \\(\\sigma\\). Used in the E-B formulation + """ + if getattr(self, '_MeSigma', None) is None: + self._MeSigma = self.mesh.getEdgeInnerProduct(self.curModel.sigma) + return self._MeSigma + + # TODO: This should take a vector + def MeSigmaDeriv(self, u): + """ + Derivative of MeSigma with respect to the model + """ + return self.mesh.getEdgeInnerProductDeriv(self.curModel.sigma)(u) * self.curModel.sigmaDeriv + + + @property + def MeSigmaI(self): + """ + Inverse of the edge inner product matrix for \\(\\sigma\\). + """ + if getattr(self, '_MeSigmaI', None) is None: + self._MeSigmaI = self.mesh.getEdgeInnerProduct(self.curModel.sigma, invMat=True) + return self._MeSigmaI + + # TODO: This should take a vector + def MeSigmaIDeriv(self, u): + """ + Derivative of :code:`MeSigma` with respect to the model + """ + # TODO: only works for diagonal tensors. getEdgeInnerProductDeriv, invMat=True should be implemented in SimPEG + + dMeSigmaI_dI = -self.MeSigmaI**2 + dMe_dsig = self.mesh.getEdgeInnerProductDeriv(self.curModel.sigma)(u) + dsig_dm = self.curModel.sigmaDeriv + return dMeSigmaI_dI * ( dMe_dsig * ( dsig_dm)) + # return self.mesh.getEdgeInnerProductDeriv(self.curModel.sigma, invMat=True)(u) + + + @property + def MfRho(self): + """ + Face inner product matrix for \\(\\rho\\). Used in the H-J formulation + """ + if getattr(self, '_MfRho', None) is None: + self._MfRho = self.mesh.getFaceInnerProduct(self.curModel.rho) + return self._MfRho + + # TODO: This should take a vector + def MfRhoDeriv(self,u): + """ + Derivative of :code:`MfRho` with respect to the model. + """ + return self.mesh.getFaceInnerProductDeriv(self.curModel.rho)(u) * (-Utils.sdiag(self.curModel.rho**2) * self.curModel.sigmaDeriv) + # self.curModel.rhoDeriv + + @property + def MfRhoI(self): + """ + Inverse of :code:`MfRho` + """ + if getattr(self, '_MfRhoI', None) is None: + self._MfRhoI = self.mesh.getFaceInnerProduct(self.curModel.rho, invMat=True) + return self._MfRhoI + + # TODO: This isn't going to work yet + # TODO: This should take a vector + def MfRhoIDeriv(self,u): + """ + Derivative of :code:`MfRhoI` with respect to the model. + """ + return self.mesh.getFaceInnerProductDeriv(self.curModel.rho, invMat=True)(u) * self.curModel.rhoDeriv diff --git a/SimPEG/EM/Examples/CylInversion.py b/SimPEG/EM/Examples/CylInversion.py new file mode 100644 index 00000000..cfcfcfc1 --- /dev/null +++ b/SimPEG/EM/Examples/CylInversion.py @@ -0,0 +1,97 @@ +from SimPEG import * +import SimPEG.EM as EM +from scipy.constants import mu_0 +import matplotlib.pyplot as plt + +def run(plotIt=True): + + cs, ncx, ncz, npad = 5., 25, 15, 15 + hx = [(cs,ncx), (cs,npad,1.3)] + hz = [(cs,npad,-1.3), (cs,ncz), (cs,npad,1.3)] + mesh = Mesh.CylMesh([hx,1,hz], '00C') + + active = mesh.vectorCCz<0. + layer = (mesh.vectorCCz<0.) & (mesh.vectorCCz>=-100.) + actMap = Maps.ActiveCells(mesh, active, np.log(1e-8), nC=mesh.nCz) + mapping = Maps.ExpMap(mesh) * Maps.Vertical1DMap(mesh) * actMap + sig_half = 2e-3 + sig_air = 1e-8 + sig_layer = 1e-3 + sigma = np.ones(mesh.nCz)*sig_air + sigma[active] = sig_half + sigma[layer] = sig_layer + mtrue = np.log(sigma[active]) + + + if plotIt: + fig, ax = plt.subplots(1,1, figsize = (3, 6)) + plt.semilogx(sigma[active], mesh.vectorCCz[active]) + ax.set_ylim(-600, 0) + ax.set_xlim(1e-4, 1e-2) + ax.set_xlabel('Conductivity (S/m)', fontsize = 14) + ax.set_ylabel('Depth (m)', fontsize = 14) + ax.grid(color='k', alpha=0.5, linestyle='dashed', linewidth=0.5) + + + rxOffset=1e-3 + rx = EM.TDEM.RxTDEM(np.array([[rxOffset, 0., 30]]), np.logspace(-5,-3, 31), 'bz') + src = EM.TDEM.SrcTDEM_VMD_MVP([rx], np.array([0., 0., 80])) + survey = EM.TDEM.SurveyTDEM([src]) + prb = EM.TDEM.ProblemTDEM_b(mesh, mapping=mapping) + + prb.Solver = SolverLU + prb.timeSteps = [(1e-06, 20),(1e-05, 20), (0.0001, 20)] + prb.pair(survey) + dtrue = survey.dpred(mtrue) + + + survey.dtrue = dtrue + std = 0.05 + noise = std*abs(survey.dtrue)*np.random.randn(*survey.dtrue.shape) + survey.dobs = survey.dtrue+noise + survey.std = survey.dobs*0 + std + survey.Wd = 1/(abs(survey.dobs)*std) + + if plotIt: + fig, ax = plt.subplots(1,1, figsize = (10, 6)) + ax.loglog(rx.times, dtrue, 'b.-') + ax.loglog(rx.times, survey.dobs, 'r.-') + ax.legend(('Noisefree', '$d^{obs}$'), fontsize = 16) + ax.set_xlabel('Time (s)', fontsize = 14) + ax.set_ylabel('$B_z$ (T)', fontsize = 16) + ax.set_xlabel('Time (s)', fontsize = 14) + ax.grid(color='k', alpha=0.5, linestyle='dashed', linewidth=0.5) + + dmisfit = DataMisfit.l2_DataMisfit(survey) + regMesh = Mesh.TensorMesh([mesh.hz[mapping.maps[-1].indActive]]) + reg = Regularization.Tikhonov(regMesh) + opt = Optimization.InexactGaussNewton(maxIter = 5) + invProb = InvProblem.BaseInvProblem(dmisfit, reg, opt) + # Create an inversion object + beta = Directives.BetaSchedule(coolingFactor=5, coolingRate=2) + betaest = Directives.BetaEstimate_ByEig(beta0_ratio=1e0) + inv = Inversion.BaseInversion(invProb, directiveList=[beta,betaest]) + m0 = np.log(np.ones(mtrue.size)*sig_half) + reg.alpha_s = 1e-2 + reg.alpha_x = 1. + prb.counter = opt.counter = Utils.Counter() + opt.LSshorten = 0.5 + opt.remember('xc') + + mopt = inv.run(m0) + + if plotIt: + fig, ax = plt.subplots(1,1, figsize = (3, 6)) + plt.semilogx(sigma[active], mesh.vectorCCz[active]) + plt.semilogx(np.exp(mopt), mesh.vectorCCz[active]) + ax.set_ylim(-600, 0) + ax.set_xlim(1e-4, 1e-2) + ax.set_xlabel('Conductivity (S/m)', fontsize = 14) + ax.set_ylabel('Depth (m)', fontsize = 14) + ax.grid(color='k', alpha=0.5, linestyle='dashed', linewidth=0.5) + plt.legend(['$\sigma_{true}$', '$\sigma_{pred}$']) + plt.show() + + +if __name__ == '__main__': + run() diff --git a/SimPEG/EM/Examples/__init__.py b/SimPEG/EM/Examples/__init__.py new file mode 100644 index 00000000..eb36678d --- /dev/null +++ b/SimPEG/EM/Examples/__init__.py @@ -0,0 +1 @@ +import CylInversion diff --git a/SimPEG/EM/FDEM/FDEM.py b/SimPEG/EM/FDEM/FDEM.py new file mode 100644 index 00000000..cce32964 --- /dev/null +++ b/SimPEG/EM/FDEM/FDEM.py @@ -0,0 +1,661 @@ +from SimPEG import Problem, Utils, np, sp, Solver as SimpegSolver +from scipy.constants import mu_0 +from SurveyFDEM import Survey as SurveyFDEM +from FieldsFDEM import Fields, Fields_e, Fields_b, Fields_h, Fields_j +from SimPEG.EM.Base import BaseEMProblem +from SimPEG.EM.Utils import omega + + +class BaseFDEMProblem(BaseEMProblem): + """ + We start by looking at Maxwell's equations in the electric + field \\\(\\\mathbf{e}\\\) and the magnetic flux + density \\\(\\\mathbf{b}\\\) + + .. math :: + + \mathbf{C} \mathbf{e} + i \omega \mathbf{b} = \mathbf{s_m} \\\\ + {\mathbf{C}^T \mathbf{M_{\mu^{-1}}^f} \mathbf{b} - \mathbf{M_{\sigma}^e} \mathbf{e} = \mathbf{M^e} \mathbf{s_e}} + + if using the E-B formulation (:code:`Problem_e` + or :code:`Problem_b`) or the magnetic field + \\\(\\\mathbf{h}\\\) and current density \\\(\\\mathbf{j}\\\) + + .. math :: + + \mathbf{C}^T \mathbf{M_{\\rho}^f} \mathbf{j} + i \omega \mathbf{M_{\mu}^e} \mathbf{h} = \mathbf{M^e} \mathbf{s_m} \\\\ + \mathbf{C} \mathbf{h} - \mathbf{j} = \mathbf{s_e} + + if using the H-J formulation (:code:`Problem_j` or :code:`Problem_h`). + + The problem performs the elimination so that we are solving the system for \\\(\\\mathbf{e},\\\mathbf{b},\\\mathbf{j} \\\) or \\\(\\\mathbf{h}\\\) + """ + + surveyPair = SurveyFDEM + fieldsPair = Fields + + def fields(self, m=None): + """ + Solve the forward problem for the fields. + """ + + self.curModel = m + F = self.fieldsPair(self.mesh, self.survey) + + for freq in self.survey.freqs: + A = self.getA(freq) + rhs = self.getRHS(freq) + Ainv = self.Solver(A, **self.solverOpts) + sol = Ainv * rhs + Srcs = self.survey.getSrcByFreq(freq) + ftype = self._fieldType + 'Solution' + F[Srcs, ftype] = sol + + return F + + def Jvec(self, m, v, f=None): + """ + Sensitivity times a vector + """ + + if f is None: + f = self.fields(m) + + self.curModel = m + + Jv = self.dataPair(self.survey) + + for freq in self.survey.freqs: + dA_du = self.getA(freq) # + dA_duI = self.Solver(dA_du, **self.solverOpts) + + for src in self.survey.getSrcByFreq(freq): + ftype = self._fieldType + 'Solution' + u_src = f[src, ftype] + dA_dm = self.getADeriv_m(freq, u_src, v) + dRHS_dm = self.getRHSDeriv_m(src, v) + if dRHS_dm is None: + du_dm = dA_duI * ( - dA_dm ) + else: + du_dm = dA_duI * ( - dA_dm + dRHS_dm ) + for rx in src.rxList: + # df_duFun = u.deriv_u(rx.fieldsUsed, m) + df_duFun = getattr(f, '_%sDeriv_u'%rx.projField, None) + df_du = df_duFun(src, du_dm, adjoint=False) + if df_du is not None: + du_dm = df_du + + df_dmFun = getattr(f, '_%sDeriv_m'%rx.projField, None) + df_dm = df_dmFun(src, v, adjoint=False) + if df_dm is not None: + du_dm += df_dm + + P = lambda v: rx.projectFieldsDeriv(src, self.mesh, f, v) # wrt u, also have wrt m + + + Jv[src, rx] = P(du_dm) + + return Utils.mkvc(Jv) + + def Jtvec(self, m, v, f=None): + """ + Sensitivity transpose times a vector + """ + + if f is None: + f = self.fields(m) + + self.curModel = m + + # Ensure v is a data object. + if not isinstance(v, self.dataPair): + v = self.dataPair(self.survey, v) + + Jtv = np.zeros(m.size) + + for freq in self.survey.freqs: + AT = self.getA(freq).T + ATinv = self.Solver(AT, **self.solverOpts) + + for src in self.survey.getSrcByFreq(freq): + ftype = self._fieldType + 'Solution' + u_src = f[src, ftype] + + for rx in src.rxList: + PTv = rx.projectFieldsDeriv(src, self.mesh, f, v[src, rx], adjoint=True) # wrt u, need possibility wrt m + + df_duTFun = getattr(f, '_%sDeriv_u'%rx.projField, None) + df_duT = df_duTFun(src, PTv, adjoint=True) + if df_duT is not None: + dA_duIT = ATinv * df_duT + else: + dA_duIT = ATinv * PTv + + dA_dmT = self.getADeriv_m(freq, u_src, dA_duIT, adjoint=True) + + dRHS_dmT = self.getRHSDeriv_m(src, dA_duIT, adjoint=True) + + if dRHS_dmT is None: + du_dmT = - dA_dmT + else: + du_dmT = -dA_dmT + dRHS_dmT + + df_dmFun = getattr(f, '_%sDeriv_m'%rx.projField, None) + dfT_dm = df_dmFun(src, PTv, adjoint=True) + if dfT_dm is not None: + du_dmT += dfT_dm + + real_or_imag = rx.projComp + if real_or_imag == 'real': + Jtv += du_dmT.real + elif real_or_imag == 'imag': + Jtv += - du_dmT.real + else: + raise Exception('Must be real or imag') + + return Jtv + + def getSourceTerm(self, freq): + """ + Evaluates the sources for a given frequency and puts them in matrix form + + :param float freq: Frequency + :rtype: numpy.ndarray (nE or nF, nSrc) + :return: S_m, S_e + """ + Srcs = self.survey.getSrcByFreq(freq) + if self._eqLocs is 'FE': + S_m = np.zeros((self.mesh.nF,len(Srcs)), dtype=complex) + S_e = np.zeros((self.mesh.nE,len(Srcs)), dtype=complex) + elif self._eqLocs is 'EF': + S_m = np.zeros((self.mesh.nE,len(Srcs)), dtype=complex) + S_e = np.zeros((self.mesh.nF,len(Srcs)), dtype=complex) + + for i, src in enumerate(Srcs): + smi, sei = src.eval(self) + if smi is not None: + S_m[:,i] = Utils.mkvc(smi) + if sei is not None: + S_e[:,i] = Utils.mkvc(sei) + + return S_m, S_e + + +########################################################################################## +################################ E-B Formulation ######################################### +########################################################################################## + +class Problem_e(BaseFDEMProblem): + """ + By eliminating the magnetic flux density using + + .. math :: + + \mathbf{b} = \\frac{1}{i \omega}\\left(-\mathbf{C} \mathbf{e} + \mathbf{s_m}\\right) + + + we can write Maxwell's equations as a second order system in \\\(\\\mathbf{e}\\\) only: + + .. math :: + + \\left(\mathbf{C}^T \mathbf{M_{\mu^{-1}}^f} \mathbf{C}+ i \omega \mathbf{M^e_{\sigma}} \\right)\mathbf{e} = \mathbf{C}^T \mathbf{M_{\mu^{-1}}^f}\mathbf{s_m} -i\omega\mathbf{M^e}\mathbf{s_e} + + which we solve for \\\(\\\mathbf{e}\\\). + """ + + _fieldType = 'e' + _eqLocs = 'FE' + fieldsPair = Fields_e + + def __init__(self, mesh, **kwargs): + BaseFDEMProblem.__init__(self, mesh, **kwargs) + + def getA(self, freq): + """ + .. math :: + \mathbf{A} = \mathbf{C}^T \mathbf{M_{\mu^{-1}}^f} \mathbf{C} + i \omega \mathbf{M^e_{\sigma}} + + :param float freq: Frequency + :rtype: scipy.sparse.csr_matrix + :return: A + """ + MfMui = self.MfMui + MeSigma = self.MeSigma + C = self.mesh.edgeCurl + + return C.T*MfMui*C + 1j*omega(freq)*MeSigma + + + def getADeriv_m(self, freq, u, v, adjoint=False): + dsig_dm = self.curModel.sigmaDeriv + dMe_dsig = self.MeSigmaDeriv(u) + + if adjoint: + return 1j * omega(freq) * ( dMe_dsig.T * v ) + + return 1j * omega(freq) * ( dMe_dsig * v ) + + def getRHS(self, freq): + """ + .. math :: + \mathbf{RHS} = \mathbf{C}^T \mathbf{M_{\mu^{-1}}^f}\mathbf{s_m} -i\omega\mathbf{M_e}\mathbf{s_e} + + :param float freq: Frequency + :rtype: numpy.ndarray (nE, nSrc) + :return: RHS + """ + + S_m, S_e = self.getSourceTerm(freq) + C = self.mesh.edgeCurl + MfMui = self.MfMui + + # RHS = C.T * (MfMui * S_m) -1j * omega(freq) * Me * S_e + RHS = C.T * (MfMui * S_m) -1j * omega(freq) * S_e + + return RHS + + def getRHSDeriv_m(self, src, v, adjoint=False): + C = self.mesh.edgeCurl + MfMui = self.MfMui + S_mDeriv, S_eDeriv = src.evalDeriv(self, adjoint) + + if adjoint: + dRHS = MfMui * (C * v) + S_mDerivv = S_mDeriv(dRHS) + S_eDerivv = S_eDeriv(v) + if S_mDerivv is not None and S_eDerivv is not None: + return S_mDerivv - 1j * omega(freq) * S_eDerivv + elif S_mDerivv is not None: + return S_mDerivv + elif S_eDerivv is not None: + return - 1j * omega(freq) * S_eDerivv + else: + return None + else: + S_mDerivv, S_eDerivv = S_mDeriv(v), S_eDeriv(v) + + if S_mDerivv is not None and S_eDerivv is not None: + return C.T * (MfMui * S_mDerivv) -1j * omega(freq) * S_eDerivv + elif S_mDerivv is not None: + return C.T * (MfMui * S_mDerivv) + elif S_eDerivv is not None: + return -1j * omega(freq) * S_eDerivv + else: + return None + + +class Problem_b(BaseFDEMProblem): + """ + We eliminate \\\(\\\mathbf{e}\\\) using + + .. math :: + + \mathbf{e} = \mathbf{M^e_{\sigma}}^{-1} \\left(\mathbf{C}^T \mathbf{M_{\mu^{-1}}^f} \mathbf{b} - \mathbf{s_e}\\right) + + and solve for \\\(\\\mathbf{b}\\\) using: + + .. math :: + + \\left(\mathbf{C} \mathbf{M^e_{\sigma}}^{-1} \mathbf{C}^T \mathbf{M_{\mu^{-1}}^f} + i \omega \\right)\mathbf{b} = \mathbf{s_m} + \mathbf{M^e_{\sigma}}^{-1}\mathbf{M^e}\mathbf{s_e} + + .. note :: + The inverse problem will not work with full anisotropy + """ + + _fieldType = 'b' + _eqLocs = 'FE' + fieldsPair = Fields_b + + def __init__(self, mesh, **kwargs): + BaseFDEMProblem.__init__(self, mesh, **kwargs) + + def getA(self, freq): + """ + .. math :: + \mathbf{A} = \mathbf{C} \mathbf{M^e_{\sigma}}^{-1} \mathbf{C}^T \mathbf{M_{\mu^{-1}}^f} + i \omega + + :param float freq: Frequency + :rtype: scipy.sparse.csr_matrix + :return: A + """ + + MfMui = self.MfMui + MeSigmaI = self.MeSigmaI + C = self.mesh.edgeCurl + iomega = 1j * omega(freq) * sp.eye(self.mesh.nF) + + A = C * (MeSigmaI * (C.T * MfMui)) + iomega + + if self._makeASymmetric is True: + return MfMui.T*A + return A + + def getADeriv_m(self, freq, u, v, adjoint=False): + + MfMui = self.MfMui + C = self.mesh.edgeCurl + MeSigmaIDeriv = self.MeSigmaIDeriv + vec = C.T * (MfMui * u) + + MeSigmaIDeriv = MeSigmaIDeriv(vec) + + if adjoint: + if self._makeASymmetric is True: + v = MfMui * v + return MeSigmaIDeriv.T * (C.T * v) + + if self._makeASymmetric is True: + return MfMui.T * ( C * ( MeSigmaIDeriv * v ) ) + return C * ( MeSigmaIDeriv * v ) + + + def getRHS(self, freq): + """ + .. math :: + \mathbf{RHS} = \mathbf{s_m} + \mathbf{M^e_{\sigma}}^{-1}\mathbf{s_e} + + :param float freq: Frequency + :rtype: numpy.ndarray (nE, nSrc) + :return: RHS + """ + + S_m, S_e = self.getSourceTerm(freq) + C = self.mesh.edgeCurl + MeSigmaI = self.MeSigmaI + # Me = self.Me + + RHS = S_m + C * ( MeSigmaI * S_e ) + + if self._makeASymmetric is True: + MfMui = self.MfMui + return MfMui.T * RHS + + return RHS + + def getRHSDeriv_m(self, src, v, adjoint=False): + C = self.mesh.edgeCurl + S_m, S_e = src.eval(self) + MfMui = self.MfMui + # Me = self.Me + + if self._makeASymmetric and adjoint: + v = self.MfMui * v + + if S_e is not None: + MeSigmaIDeriv = self.MeSigmaIDeriv(S_e) + if not adjoint: + RHSderiv = C * (MeSigmaIDeriv * v) + elif adjoint: + RHSderiv = MeSigmaIDeriv.T * (C.T * v) + else: + RHSderiv = None + + S_mDeriv, S_eDeriv = src.evalDeriv(self, adjoint) + S_mDeriv, S_eDeriv = S_mDeriv(v), S_eDeriv(v) + if S_mDeriv is not None and S_eDeriv is not None: + if not adjoint: + SrcDeriv = S_mDeriv + C * (self.MeSigmaI * S_eDeriv) + elif adjoint: + SrcDeriv = S_mDeriv + Self.MeSigmaI.T * ( C.T * S_eDeriv) + elif S_mDeriv is not None: + SrcDeriv = S_mDeriv + elif S_eDeriv is not None: + if not adjoint: + SrcDeriv = C * (self.MeSigmaI * S_eDeriv) + elif adjoint: + SrcDeriv = self.MeSigmaI.T * ( C.T * S_eDeriv) + else: + SrcDeriv = None + + if RHSderiv is not None and SrcDeriv is not None: + RHSderiv += SrcDeriv + elif SrcDeriv is not None: + RHSderiv = SrcDeriv + + if RHSderiv is not None: + if self._makeASymmetric is True and not adjoint: + return MfMui.T * RHSderiv + + return RHSderiv + + + +########################################################################################## +################################ H-J Formulation ######################################### +########################################################################################## + + +class Problem_j(BaseFDEMProblem): + """ + We eliminate \\\(\\\mathbf{h}\\\) using + + .. math :: + + \mathbf{h} = \\frac{1}{i \omega} \mathbf{M_{\mu}^e}^{-1} \\left(-\mathbf{C}^T \mathbf{M_{\\rho}^f} \mathbf{j} + \mathbf{M^e} \mathbf{s_m} \\right) + + and solve for \\\(\\\mathbf{j}\\\) using + + .. math :: + + \\left(\mathbf{C} \mathbf{M_{\mu}^e}^{-1} \mathbf{C}^T \mathbf{M_{\\rho}^f} + i \omega\\right)\mathbf{j} = \mathbf{C} \mathbf{M_{\mu}^e}^{-1} \mathbf{M^e} \mathbf{s_m} -i\omega\mathbf{s_e} + + .. note:: + This implementation does not yet work with full anisotropy!! + + """ + + _fieldType = 'j' + _eqLocs = 'EF' + fieldsPair = Fields_j + + def __init__(self, mesh, **kwargs): + BaseFDEMProblem.__init__(self, mesh, **kwargs) + + def getA(self, freq): + """ + .. math :: + \\mathbf{A} = \\mathbf{C} \\mathbf{M^e_{mu^{-1}}} \\mathbf{C}^T \\mathbf{M^f_{\\sigma^{-1}}} + i\\omega + + :param float freq: Frequency + :rtype: scipy.sparse.csr_matrix + :return: A + """ + + MeMuI = self.MeMuI + MfRho = self.MfRho + C = self.mesh.edgeCurl + iomega = 1j * omega(freq) * sp.eye(self.mesh.nF) + + A = C * MeMuI * C.T * MfRho + iomega + + if self._makeASymmetric is True: + return MfRho.T*A + return A + + + def getADeriv_m(self, freq, u, v, adjoint=False): + """ + In this case, we assume that electrical conductivity, \\\(\\\sigma\\\) is the physical property of interest (i.e. \\\(\\\sigma\\\) = model.transform). Then we want + + .. math :: + + \\frac{\mathbf{A(\sigma)} \mathbf{v}}{d \\mathbf{m}} &= \\mathbf{C} \\mathbf{M^e_{mu^{-1}}} \\mathbf{C^T} \\frac{d \\mathbf{M^f_{\\sigma^{-1}}}}{d \\mathbf{m}} + &= \\mathbf{C} \\mathbf{M^e_{mu}^{-1}} \\mathbf{C^T} \\frac{d \\mathbf{M^f_{\\sigma^{-1}}}}{d \\mathbf{\\sigma^{-1}}} \\frac{d \\mathbf{\\sigma^{-1}}}{d \\mathbf{\\sigma}} \\frac{d \\mathbf{\\sigma}}{d \\mathbf{m}} + """ + + MeMuI = self.MeMuI + MfRho = self.MfRho + C = self.mesh.edgeCurl + MfRhoDeriv_m = self.MfRhoDeriv(u) + + if adjoint: + if self._makeASymmetric is True: + v = MfRho * v + return MfRhoDeriv_m.T * (C * (MeMuI.T * (C.T * v))) + + if self._makeASymmetric is True: + return MfRho.T * (C * ( MeMuI * (C.T * (MfRhoDeriv_m * v) ))) + return C * (MeMuI * (C.T * (MfRhoDeriv_m * v))) + + + def getRHS(self, freq): + """ + .. math :: + + \mathbf{RHS} = \mathbf{C} \mathbf{M_{\mu}^e}^{-1}\mathbf{s_m} -i\omega \mathbf{s_e} + :param float freq: Frequency + :rtype: numpy.ndarray (nE, nSrc) + :return: RHS + """ + + S_m, S_e = self.getSourceTerm(freq) + C = self.mesh.edgeCurl + MeMuI = self.MeMuI + + RHS = C * (MeMuI * S_m) - 1j * omega(freq) * S_e + if self._makeASymmetric is True: + MfRho = self.MfRho + return MfRho.T*RHS + + return RHS + + def getRHSDeriv_m(self, src, v, adjoint=False): + C = self.mesh.edgeCurl + MeMuI = self.MeMuI + S_mDeriv, S_eDeriv = src.evalDeriv(self, adjoint) + + if adjoint: + if self._makeASymmetric: + MfRho = self.MfRho + v = MfRho*v + S_mDerivv = S_mDeriv(MeMuI.T * (C.T * v)) + S_eDerivv = S_eDeriv(v) + if S_mDerivv is not None and S_eDerivv is not None: + return S_mDerivv - 1j * omega(freq) * S_eDerivv + elif S_mDerivv is not None: + return S_mDerivv + elif S_eDerivv is not None: + return - 1j * omega(freq) * S_eDerivv + else: + return None + else: + S_mDerivv, S_eDerivv = S_mDeriv(v), S_eDeriv(v) + + if S_mDerivv is not None and S_eDerivv is not None: + RHSDeriv = C * (MeMuI * S_mDerivv) - 1j * omega(freq) * S_eDerivv + elif S_mDerivv is not None: + RHSDeriv = C * (MeMuI * S_mDerivv) + elif S_eDerivv is not None: + RHSDeriv = - 1j * omega(freq) * S_eDerivv + else: + return None + + if self._makeASymmetric: + MfRho = self.MfRho + return MfRho.T * RHSDeriv + return RHSDeriv + + + + +class Problem_h(BaseFDEMProblem): + """ + We eliminate \\\(\\\mathbf{j}\\\) using + + .. math :: + + \mathbf{j} = \mathbf{C} \mathbf{h} - \mathbf{s_e} + + and solve for \\\(\\\mathbf{h}\\\) using + + .. math :: + + \\left(\mathbf{C}^T \mathbf{M_{\\rho}^f} \mathbf{C} + i \omega \mathbf{M_{\mu}^e}\\right) \mathbf{h} = \mathbf{M^e} \mathbf{s_m} + \mathbf{C}^T \mathbf{M_{\\rho}^f} \mathbf{s_e} + + """ + + _fieldType = 'h' + _eqLocs = 'EF' + fieldsPair = Fields_h + + def __init__(self, mesh, **kwargs): + BaseFDEMProblem.__init__(self, mesh, **kwargs) + + def getA(self, freq): + """ + .. math :: + + \mathbf{A} = \mathbf{C}^T \mathbf{M_{\\rho}^f} \mathbf{C} + i \omega \mathbf{M_{\mu}^e} + + :param float freq: Frequency + :rtype: scipy.sparse.csr_matrix + :return: A + """ + + MeMu = self.MeMu + MfRho = self.MfRho + C = self.mesh.edgeCurl + + return C.T * (MfRho * C) + 1j*omega(freq)*MeMu + + def getADeriv_m(self, freq, u, v, adjoint=False): + + MeMu = self.MeMu + C = self.mesh.edgeCurl + MfRhoDeriv_m = self.MfRhoDeriv(C*u) + + if adjoint: + return MfRhoDeriv_m.T * (C * v) + return C.T * (MfRhoDeriv_m * v) + + def getRHS(self, freq): + """ + .. math :: + + \mathbf{RHS} = \mathbf{M^e} \mathbf{s_m} + \mathbf{C}^T \mathbf{M_{\\rho}^f} \mathbf{s_e} + + :param float freq: Frequency + :rtype: numpy.ndarray (nE, nSrc) + :return: RHS + """ + + S_m, S_e = self.getSourceTerm(freq) + C = self.mesh.edgeCurl + MfRho = self.MfRho + + RHS = S_m + C.T * ( MfRho * S_e ) + + return RHS + + def getRHSDeriv_m(self, src, v, adjoint=False): + _, S_e = src.eval(self) + C = self.mesh.edgeCurl + MfRho = self.MfRho + + RHSDeriv = None + + if S_e is not None: + MfRhoDeriv = self.MfRhoDeriv(S_e) + if not adjoint: + RHSDeriv = C.T * (MfRhoDeriv * v) + elif adjoint: + RHSDeriv = MfRhoDeriv.T * (C * v) + + S_mDeriv, S_eDeriv = src.evalDeriv(self, adjoint) + + S_mDeriv = S_mDeriv(v) + S_eDeriv = S_eDeriv(v) + + if S_mDeriv is not None: + if RHSDeriv is not None: + RHSDeriv += S_mDeriv(v) + else: + RHSDeriv = S_mDeriv(v) + if S_eDeriv is not None: + if RHSDeriv is not None: + RHSDeriv += C.T * (MfRho * S_e) + else: + RHSDeriv = C.T * (MfRho * S_e) + + return RHSDeriv + diff --git a/SimPEG/EM/FDEM/FieldsFDEM.py b/SimPEG/EM/FDEM/FieldsFDEM.py new file mode 100644 index 00000000..d83877c3 --- /dev/null +++ b/SimPEG/EM/FDEM/FieldsFDEM.py @@ -0,0 +1,377 @@ +import numpy as np +import scipy.sparse as sp +import SimPEG +from SimPEG import Utils +from SimPEG.EM.Utils import omega + + +class Fields(SimPEG.Problem.Fields): + """Fancy Field Storage for a FDEM survey.""" + knownFields = {} + dtype = complex + +class Fields_e(Fields): + knownFields = {'eSolution':'E'} + aliasFields = { + 'e' : ['eSolution','E','_e'], + 'ePrimary' : ['eSolution','E','_ePrimary'], + 'eSecondary' : ['eSolution','E','_eSecondary'], + 'b' : ['eSolution','F','_b'], + 'bPrimary' : ['eSolution','F','_bPrimary'], + 'bSecondary' : ['eSolution','F','_bSecondary'] + } + + def __init__(self,mesh,survey,**kwargs): + Fields.__init__(self,mesh,survey,**kwargs) + + def startup(self): + self.prob = self.survey.prob + self._edgeCurl = self.survey.prob.mesh.edgeCurl + + def _ePrimary(self, eSolution, srcList): + ePrimary = np.zeros_like(eSolution) + for i, src in enumerate(srcList): + ep = src.ePrimary(self.prob) + if ep is not None: + ePrimary[:,i] = ep + return ePrimary + + def _eSecondary(self, eSolution, srcList): + return eSolution + + def _e(self, eSolution, srcList): + return self._ePrimary(eSolution,srcList) + self._eSecondary(eSolution,srcList) + + def _eDeriv_u(self, src, v, adjoint = False): + return None + + def _eDeriv_m(self, src, v, adjoint = False): + # assuming primary does not depend on the model + return None + + def _bPrimary(self, eSolution, srcList): + bPrimary = np.zeros([self._edgeCurl.shape[0],eSolution.shape[1]],dtype = complex) + for i, src in enumerate(srcList): + bp = src.bPrimary(self.prob) + if bp is not None: + bPrimary[:,i] += bp + return bPrimary + + def _bSecondary(self, eSolution, srcList): + C = self._edgeCurl + b = (C * eSolution) + for i, src in enumerate(srcList): + b[:,i] *= - 1./(1j*omega(src.freq)) + S_m, _ = src.eval(self.prob) + if S_m is not None: + b[:,i] += 1./(1j*omega(src.freq)) * S_m + return b + + def _bSecondaryDeriv_u(self, src, v, adjoint = False): + C = self._edgeCurl + if adjoint: + return - 1./(1j*omega(src.freq)) * (C.T * v) + return - 1./(1j*omega(src.freq)) * (C * v) + + def _bSecondaryDeriv_m(self, src, v, adjoint = False): + S_mDeriv, _ = src.evalDeriv(self.prob, adjoint) + S_mDeriv = S_mDeriv(v) + if S_mDeriv is not None: + return 1./(1j * omega(src.freq)) * S_mDeriv + return None + + def _b(self, eSolution, srcList): + return self._bPrimary(eSolution, srcList) + self._bSecondary(eSolution, srcList) + + def _bDeriv_u(self, src, v, adjoint=False): + # Primary does not depend on u + return self._bSecondaryDeriv_u(src, v, adjoint) + + def _bDeriv_m(self, src, v, adjoint=False): + # Assuming the primary does not depend on the model + return self._bSecondaryDeriv_m(src, v, adjoint) + + +class Fields_b(Fields): + knownFields = {'bSolution':'F'} + aliasFields = { + 'b' : ['bSolution','F','_b'], + 'bPrimary' : ['bSolution','F','_bPrimary'], + 'bSecondary' : ['bSolution','F','_bSecondary'], + 'e' : ['bSolution','E','_e'], + 'ePrimary' : ['bSolution','E','_ePrimary'], + 'eSecondary' : ['bSolution','E','_eSecondary'], + } + + def __init__(self,mesh,survey,**kwargs): + Fields.__init__(self,mesh,survey,**kwargs) + + def startup(self): + self.prob = self.survey.prob + self._edgeCurl = self.survey.prob.mesh.edgeCurl + self._MeSigmaI = self.survey.prob.MeSigmaI + self._MfMui = self.survey.prob.MfMui + self._MeSigmaIDeriv = self.survey.prob.MeSigmaIDeriv + self._Me = self.survey.prob.Me + + def _bPrimary(self, bSolution, srcList): + bPrimary = np.zeros_like(bSolution) + for i, src in enumerate(srcList): + bp = src.bPrimary(self.prob) + if bp is not None: + bPrimary[:,i] = bp + return bPrimary + + def _bSecondary(self, bSolution, srcList): + return bSolution + + def _b(self, bSolution, srcList): + return self._bPrimary(bSolution, srcList) + self._bSecondary(bSolution, srcList) + + def _bDeriv_u(self, src, v, adjoint=False): + return None + + def _bDeriv_m(self, src, v, adjoint=False): + # assuming primary does not depend on the model + return None + + def _ePrimary(self, bSolution, srcList): + ePrimary = np.zeros([self._edgeCurl.shape[1],bSolution.shape[1]],dtype = complex) + for i,src in enumerate(srcList): + ep = src.ePrimary(self.prob) + if ep is not None: + ePrimary[:,i] = ep + return ePrimary + + def _eSecondary(self, bSolution, srcList): + e = self._MeSigmaI * ( self._edgeCurl.T * ( self._MfMui * bSolution)) + for i,src in enumerate(srcList): + _,S_e = src.eval(self.prob) + if S_e is not None: + e[:,i] += -self._MeSigmaI * S_e + return e + + def _eSecondaryDeriv_u(self, src, v, adjoint=False): + if not adjoint: + return self._MeSigmaI * ( self._edgeCurl.T * ( self._MfMui * v) ) + else: + return self._MfMui.T * (self._edgeCurl * (self._MeSigmaI.T * v)) + + def _eSecondaryDeriv_m(self, src, v, adjoint=False): + bSolution = self[[src],'bSolution'] + _,S_e = src.eval(self.prob) + Me = self._Me + + if adjoint: + Me = Me.T + + w = self._edgeCurl.T * (self._MfMui * bSolution) + if S_e is not None: + w += -Utils.mkvc(Me * S_e,2) + + if not adjoint: + de_dm = self._MeSigmaIDeriv(w) * v + elif adjoint: + de_dm = self._MeSigmaIDeriv(w).T * v + + _, S_eDeriv = src.evalDeriv(self.prob, adjoint) + Se_Deriv = S_eDeriv(v) + + if Se_Deriv is not None: + de_dm += -self._MeSigmaI * Se_Deriv + + return de_dm + + def _e(self, bSolution, srcList): + return self._ePrimary(bSolution, srcList) + self._eSecondary(bSolution, srcList) + + def _eDeriv_u(self, src, v, adjoint=False): + return self._eSecondaryDeriv_u(src, v, adjoint) + + def _eDeriv_m(self, src, v, adjoint=False): + # assuming primary doesn't depend on model + return self._eSecondaryDeriv_m(src, v, adjoint) + + +class Fields_j(Fields): + knownFields = {'jSolution':'F'} + aliasFields = { + 'j' : ['jSolution','F','_j'], + 'jPrimary' : ['jSolution','F','_jPrimary'], + 'jSecondary' : ['jSolution','F','_jSecondary'], + 'h' : ['jSolution','E','_h'], + 'hPrimary' : ['jSolution','E','_hPrimary'], + 'hSecondary' : ['jSolution','E','_hSecondary'], + } + + def __init__(self,mesh,survey,**kwargs): + Fields.__init__(self,mesh,survey,**kwargs) + + def startup(self): + self.prob = self.survey.prob + self._edgeCurl = self.survey.prob.mesh.edgeCurl + self._MeMuI = self.survey.prob.MeMuI + self._MfRho = self.survey.prob.MfRho + self._MfRhoDeriv = self.survey.prob.MfRhoDeriv + self._Me = self.survey.prob.Me + + def _jPrimary(self, jSolution, srcList): + jPrimary = np.zeros_like(jSolution,dtype = complex) + for i, src in enumerate(srcList): + jp = src.jPrimary(self.prob) + if jp is not None: + jPrimary[:,i] += jp + return jPrimary + + def _jSecondary(self, jSolution, srcList): + return jSolution + + def _j(self, jSolution, srcList): + return self._jPrimary(jSolution, srcList) + self._jSecondary(jSolution, srcList) + + def _jDeriv_u(self, src, v, adjoint=False): + return None + + def _jDeriv_m(self, src, v, adjoint=False): + # assuming primary does not depend on the model + return None + + def _hPrimary(self, jSolution, srcList): + hPrimary = np.zeros([self._edgeCurl.shape[1],jSolution.shape[1]],dtype = complex) + for i, src in enumerate(srcList): + hp = src.hPrimary(self.prob) + if hp is not None: + hPrimary[:,i] = hp + return hPrimary + + def _hSecondary(self, jSolution, srcList): + h = self._MeMuI * (self._edgeCurl.T * (self._MfRho * jSolution) ) + for i, src in enumerate(srcList): + h[:,i] *= -1./(1j*omega(src.freq)) + S_m,_ = src.eval(self.prob) + if S_m is not None: + h[:,i] += 1./(1j*omega(src.freq)) * self._MeMuI * (S_m) + return h + + def _hSecondaryDeriv_u(self, src, v, adjoint=False): + if not adjoint: + return -1./(1j*omega(src.freq)) * self._MeMuI * (self._edgeCurl.T * (self._MfRho * v) ) + elif adjoint: + return -1./(1j*omega(src.freq)) * self._MfRho.T * (self._edgeCurl * ( self._MeMuI.T * v)) + + def _hSecondaryDeriv_m(self, src, v, adjoint=False): + jSolution = self[[src],'jSolution'] + MeMuI = self._MeMuI + C = self._edgeCurl + MfRho = self._MfRho + MfRhoDeriv = self._MfRhoDeriv + Me = self._Me + + if not adjoint: + hDeriv_m = -1./(1j*omega(src.freq)) * MeMuI * (C.T * (MfRhoDeriv(jSolution)*v ) ) + elif adjoint: + hDeriv_m = -1./(1j*omega(src.freq)) * MfRhoDeriv(jSolution).T * ( C * (MeMuI.T * v ) ) + + S_mDeriv,_ = src.evalDeriv(self.prob, adjoint) + + if not adjoint: + S_mDeriv = S_mDeriv(v) + if S_mDeriv is not None: + hDeriv_m += 1./(1j*omega(src.freq)) * MeMuI * (Me * S_mDeriv) + elif adjoint: + S_mDeriv = S_mDeriv(Me.T * (MeMuI.T * v)) + if S_mDeriv is not None: + hDeriv_m += 1./(1j*omega(src.freq)) * S_mDeriv + return hDeriv_m + + + def _h(self, jSolution, srcList): + return self._hPrimary(jSolution, srcList) + self._hSecondary(jSolution, srcList) + + def _hDeriv_u(self, src, v, adjoint=False): + return self._hSecondaryDeriv_u(src, v, adjoint) + + def _hDeriv_m(self, src, v, adjoint=False): + # assuming the primary doesn't depend on the model + return self._hSecondaryDeriv_m(src, v, adjoint) + + +class Fields_h(Fields): + knownFields = {'hSolution':'E'} + aliasFields = { + 'h' : ['hSolution','E','_h'], + 'hPrimary' : ['hSolution','E','_hPrimary'], + 'hSecondary' : ['hSolution','E','_hSecondary'], + 'j' : ['hSolution','F','_j'], + 'jPrimary' : ['hSolution','F','_jPrimary'], + 'jSecondary' : ['hSolution','F','_jSecondary'] + } + + def __init__(self,mesh,survey,**kwargs): + Fields.__init__(self,mesh,survey,**kwargs) + + def startup(self): + self.prob = self.survey.prob + self._edgeCurl = self.survey.prob.mesh.edgeCurl + self._MeMuI = self.survey.prob.MeMuI + self._MfRho = self.survey.prob.MfRho + + def _hPrimary(self, hSolution, srcList): + hPrimary = np.zeros_like(hSolution,dtype = complex) + for i, src in enumerate(srcList): + hp = src.hPrimary(self.prob) + if hp is not None: + hPrimary[:,i] += hp + return hPrimary + + def _hSecondary(self, hSolution, srcList): + return hSolution + + def _h(self, hSolution, srcList): + return self._hPrimary(hSolution, srcList) + self._hSecondary(hSolution, srcList) + + def _hDeriv_u(self, src, v, adjoint=False): + return None + + def _hDeriv_m(self, src, v, adjoint=False): + # assuming primary does not depend on the model + return None + + def _jPrimary(self, hSolution, srcList): + jPrimary = np.zeros([self._edgeCurl.shape[0], hSolution.shape[1]], dtype = complex) + for i, src in enumerate(srcList): + jp = src.jPrimary(self.prob) + if jp is not None: + jPrimary[:,i] = jp + return jPrimary + + def _jSecondary(self, hSolution, srcList): + j = self._edgeCurl*hSolution + for i, src in enumerate(srcList): + _,S_e = src.eval(self.prob) + if S_e is not None: + j[:,i] += -S_e + return j + + def _jSecondaryDeriv_u(self, src, v, adjoint=False): + if not adjoint: + return self._edgeCurl*v + elif adjoint: + return self._edgeCurl.T*v + + def _jSecondaryDeriv_m(self, src, v, adjoint=False): + _,S_eDeriv = src.evalDeriv(self.prob, adjoint) + S_eDeriv = S_eDeriv(v) + if S_eDeriv is not None: + return -S_eDeriv + return None + + def _j(self, hSolution, srcList): + return self._jPrimary(hSolution, srcList) + self._jSecondary(hSolution, srcList) + + def _jDeriv_u(self, src, v, adjoint=False): + return self._jSecondaryDeriv_u(src,v,adjoint) + + def _jDeriv_m(self, src, v, adjoint=False): + # assuming the primary does not depend on the model + return self._jSecondaryDeriv_m(src,v,adjoint) diff --git a/SimPEG/EM/FDEM/SrcFDEM.py b/SimPEG/EM/FDEM/SrcFDEM.py new file mode 100644 index 00000000..5dcf9407 --- /dev/null +++ b/SimPEG/EM/FDEM/SrcFDEM.py @@ -0,0 +1,347 @@ +from SimPEG import Survey, Problem, Utils, np, sp +from scipy.constants import mu_0 +from SimPEG.EM.Utils import * +# from SurveyFDEM import Rx + + +class BaseSrc(Survey.BaseSrc): + freq = None + # rxPair = Rx + integrate = True + + def eval(self, prob): + S_m = self.S_m(prob) + S_e = self.S_e(prob) + return S_m, S_e + + def evalDeriv(self, prob, v, adjoint=False): + return lambda v: self.S_mDeriv(prob,v,adjoint), lambda v: self.S_eDeriv(prob,v,adjoint) + + def bPrimary(self, prob): + return None + + def hPrimary(self, prob): + return None + + def ePrimary(self, prob): + return None + + def jPrimary(self, prob): + return None + + def S_m(self, prob): + return None + + def S_e(self, prob): + return None + + def S_mDeriv(self, prob, v, adjoint = False): + return None + + def S_eDeriv(self, prob, v, adjoint = False): + return None + + +class RawVec_e(BaseSrc): + """ + RawVec electric source. It is defined by the user provided vector S_e + + :param numpy.array S_e: electric source term + :param float freq: frequency + :param rxList: receiver list + """ + + def __init__(self, rxList, freq, S_e, ePrimary=None, bPrimary=None, hPrimary=None, jPrimary=None): + self._S_e = np.array(S_e,dtype=complex) + self._ePrimary = ePrimary + self._bPrimary = bPrimary + self._hPrimary = hPrimary + self._jPrimary = jPrimary + self.freq = float(freq) + BaseSrc.__init__(self, rxList) + + def S_e(self, prob): + return self._S_e + + def ePrimary(self, prob): + return self._ePrimary + + def bPrimary(self, prob): + return self._bPrimary + + def hPrimary(self, prob): + return self._hPrimary + + def jPrimary(self, prob): + return self._jPrimary + + +class RawVec_m(BaseSrc): + """ + RawVec magnetic source. It is defined by the user provided vector S_m + + :param numpy.array S_m: magnetic source term + :param float freq: frequency + :param rxList: receiver list + """ + + def __init__(self, rxList, freq, S_m, integrate = True, ePrimary=None, bPrimary=None, hPrimary=None, jPrimary=None): + self._S_m = np.array(S_m,dtype=complex) + self.freq = float(freq) + self.integrate = integrate + self._ePrimary = np.array(ePrimary,dtype=complex) + self._bPrimary = np.array(bPrimary,dtype=complex) + self._hPrimary = np.array(hPrimary,dtype=complex) + self._jPrimary = np.array(jPrimary,dtype=complex) + + BaseSrc.__init__(self, rxList) + + def S_m(self, prob): + return self._S_m + + def ePrimary(self, prob): + return self._ePrimary + + def bPrimary(self, prob): + return self._bPrimary + + def hPrimary(self, prob): + return self._hPrimary + + def jPrimary(self, prob): + return self._jPrimary + + +class RawVec(BaseSrc): + """ + RawVec source. It is defined by the user provided vectors S_m, S_e + + :param numpy.array S_m: magnetic source term + :param numpy.array S_e: electric source term + :param float freq: frequency + :param rxList: receiver list + """ + def __init__(self, rxList, freq, S_m, S_e, integrate = True): + self._S_m = np.array(S_m,dtype=complex) + self._S_e = np.array(S_e,dtype=complex) + self.freq = float(freq) + self.integrate = integrate + BaseSrc.__init__(self, rxList) + + def S_m(self, prob): + if prob._eqLocs is 'EF' and self.integrate is True: + return prob.Me * self._S_m + return self._S_m + + def S_e(self, prob): + if prob._eqLocs is 'FE' and self.integrate is True: + return prob.Me * self._S_e + return self._S_e + + +class MagDipole(BaseSrc): + + #TODO: right now, orientation doesn't actually do anything! The methods in SrcUtils should take care of that + def __init__(self, rxList, freq, loc, orientation='Z', moment=1., mu = mu_0): + self.freq = float(freq) + self.loc = loc + self.orientation = orientation + self.moment = moment + self.mu = mu + self.integrate = False + BaseSrc.__init__(self, rxList) + + def bPrimary(self, prob): + eqLocs = prob._eqLocs + + if eqLocs is 'FE': + gridX = prob.mesh.gridEx + gridY = prob.mesh.gridEy + gridZ = prob.mesh.gridEz + C = prob.mesh.edgeCurl + + elif eqLocs is 'EF': + gridX = prob.mesh.gridFx + gridY = prob.mesh.gridFy + gridZ = prob.mesh.gridFz + C = prob.mesh.edgeCurl.T + + + if prob.mesh._meshType is 'CYL': + if not prob.mesh.isSymmetric: + # TODO ? + raise NotImplementedError('Non-symmetric cyl mesh not implemented yet!') + a = MagneticDipoleVectorPotential(self.loc, gridY, 'y', mu=self.mu, moment=self.moment) + + else: + srcfct = MagneticDipoleVectorPotential + ax = srcfct(self.loc, gridX, 'x', mu=self.mu, moment=self.moment) + ay = srcfct(self.loc, gridY, 'y', mu=self.mu, moment=self.moment) + az = srcfct(self.loc, gridZ, 'z', mu=self.mu, moment=self.moment) + a = np.concatenate((ax, ay, az)) + + return C*a + + def hPrimary(self, prob): + b = self.bPrimary(prob) + return h_from_b(prob,b) + + def S_m(self, prob): + b_p = self.bPrimary(prob) + return -1j*omega(self.freq)*b_p + + def S_e(self, prob): + if all(np.r_[self.mu] == np.r_[prob.curModel.mu]): + return None + else: + eqLocs = prob._eqLocs + + if eqLocs is 'FE': + mui_s = prob.curModel.mui - 1./self.mu + MMui_s = prob.mesh.getFaceInnerProduct(mui_s) + C = prob.mesh.edgeCurl + elif eqLocs is 'EF': + mu_s = prob.curModel.mu - self.mu + MMui_s = prob.mesh.getEdgeInnerProduct(mu_s,invMat=True) + C = prob.mesh.edgeCurl.T + + return -C.T * (MMui_s * self.bPrimary(prob)) + + +class MagDipole_Bfield(BaseSrc): + + #TODO: right now, orientation doesn't actually do anything! The methods in SrcUtils should take care of that + #TODO: neither does moment + def __init__(self, rxList, freq, loc, orientation='Z', moment=1., mu = mu_0): + self.freq = float(freq) + self.loc = loc + self.orientation = orientation + self.moment = moment + self.mu = mu + BaseSrc.__init__(self, rxList) + + def bPrimary(self, prob): + eqLocs = prob._eqLocs + + if eqLocs is 'FE': + gridX = prob.mesh.gridFx + gridY = prob.mesh.gridFy + gridZ = prob.mesh.gridFz + C = prob.mesh.edgeCurl + + elif eqLocs is 'EF': + gridX = prob.mesh.gridEx + gridY = prob.mesh.gridEy + gridZ = prob.mesh.gridEz + C = prob.mesh.edgeCurl.T + + srcfct = MagneticDipoleFields + if prob.mesh._meshType is 'CYL': + if not prob.mesh.isSymmetric: + # TODO ? + raise NotImplementedError('Non-symmetric cyl mesh not implemented yet!') + bx = srcfct(self.loc, gridX, 'x', mu=self.mu, moment=self.moment) + bz = srcfct(self.loc, gridZ, 'z', mu=self.mu, moment=self.moment) + b = np.concatenate((bx,bz)) + else: + bx = srcfct(self.loc, gridX, 'x', mu=self.mu, moment=self.moment) + by = srcfct(self.loc, gridY, 'y', mu=self.mu, moment=self.moment) + bz = srcfct(self.loc, gridZ, 'z', mu=self.mu, moment=self.moment) + b = np.concatenate((bx,by,bz)) + + return b + + def hPrimary(self, prob): + b = self.bPrimary(prob) + return h_from_b(prob, b) + + def S_m(self, prob): + b = self.bPrimary(prob) + return -1j*omega(self.freq)*b + + def S_e(self, prob): + if all(np.r_[self.mu] == np.r_[prob.curModel.mu]): + return None + else: + eqLocs = prob._eqLocs + + if eqLocs is 'FE': + mui_s = prob.curModel.mui - 1./self.mu + MMui_s = prob.mesh.getFaceInnerProduct(mui_s) + C = prob.mesh.edgeCurl + elif eqLocs is 'EF': + mu_s = prob.curModel.mu - self.mu + MMui_s = prob.mesh.getEdgeInnerProduct(mu_s,invMat=True) + C = prob.mesh.edgeCurl.T + + return -C.T * (MMui_s * self.bPrimary(prob)) + + +class CircularLoop(BaseSrc): + + #TODO: right now, orientation doesn't actually do anything! The methods in SrcUtils should take care of that + def __init__(self, rxList, freq, loc, orientation='Z', radius = 1., mu=mu_0): + self.freq = float(freq) + self.orientation = orientation + self.radius = radius + self.mu = mu + self.loc = loc + self.integrate = False + BaseSrc.__init__(self, rxList) + + def bPrimary(self, prob): + eqLocs = prob._eqLocs + + if eqLocs is 'FE': + gridX = prob.mesh.gridEx + gridY = prob.mesh.gridEy + gridZ = prob.mesh.gridEz + C = prob.mesh.edgeCurl + + elif eqLocs is 'EF': + gridX = prob.mesh.gridFx + gridY = prob.mesh.gridFy + gridZ = prob.mesh.gridFz + C = prob.mesh.edgeCurl.T + + if prob.mesh._meshType is 'CYL': + if not prob.mesh.isSymmetric: + # TODO ? + raise NotImplementedError('Non-symmetric cyl mesh not implemented yet!') + a = MagneticDipoleVectorPotential(self.loc, gridY, 'y', moment=self.radius, mu=self.mu) + + else: + srcfct = MagneticDipoleVectorPotential + ax = srcfct(self.loc, gridX, 'x', self.radius, mu=self.mu) + ay = srcfct(self.loc, gridY, 'y', self.radius, mu=self.mu) + az = srcfct(self.loc, gridZ, 'z', self.radius, mu=self.mu) + a = np.concatenate((ax, ay, az)) + + return C*a + + def hPrimary(self, prob): + b = self.bPrimary(prob) + return 1./self.mu*b + + def S_m(self, prob): + b = self.bPrimary(prob) + return -1j*omega(self.freq)*b + + def S_e(self, prob): + if all(np.r_[self.mu] == np.r_[prob.curModel.mu]): + return None + else: + eqLocs = prob._eqLocs + + if eqLocs is 'FE': + mui_s = prob.curModel.mui - 1./self.mu + MMui_s = prob.mesh.getFaceInnerProduct(mui_s) + C = prob.mesh.edgeCurl + elif eqLocs is 'EF': + mu_s = prob.curModel.mu - self.mu + MMui_s = prob.mesh.getEdgeInnerProduct(mu_s,invMat=True) + C = prob.mesh.edgeCurl.T + + return -C.T * (MMui_s * self.bPrimary(prob)) + + diff --git a/SimPEG/EM/FDEM/SurveyFDEM.py b/SimPEG/EM/FDEM/SurveyFDEM.py new file mode 100644 index 00000000..150a6c00 --- /dev/null +++ b/SimPEG/EM/FDEM/SurveyFDEM.py @@ -0,0 +1,146 @@ +import SimPEG +from SimPEG.EM.Utils import * +from scipy.constants import mu_0 +import SrcFDEM as Src + +#################################################### +# Receivers +#################################################### + +class Rx(SimPEG.Survey.BaseRx): + + knownRxTypes = { + 'exr':['e', 'Ex', 'real'], + 'eyr':['e', 'Ey', 'real'], + 'ezr':['e', 'Ez', 'real'], + 'exi':['e', 'Ex', 'imag'], + 'eyi':['e', 'Ey', 'imag'], + 'ezi':['e', 'Ez', 'imag'], + + 'bxr':['b', 'Fx', 'real'], + 'byr':['b', 'Fy', 'real'], + 'bzr':['b', 'Fz', 'real'], + 'bxi':['b', 'Fx', 'imag'], + 'byi':['b', 'Fy', 'imag'], + 'bzi':['b', 'Fz', 'imag'], + + 'jxr':['j', 'Fx', 'real'], + 'jyr':['j', 'Fy', 'real'], + 'jzr':['j', 'Fz', 'real'], + 'jxi':['j', 'Fx', 'imag'], + 'jyi':['j', 'Fy', 'imag'], + 'jzi':['j', 'Fz', 'imag'], + + 'hxr':['h', 'Ex', 'real'], + 'hyr':['h', 'Ey', 'real'], + 'hzr':['h', 'Ez', 'real'], + 'hxi':['h', 'Ex', 'imag'], + 'hyi':['h', 'Ey', 'imag'], + 'hzi':['h', 'Ez', 'imag'], + } + radius = None + + def __init__(self, locs, rxType): + SimPEG.Survey.BaseRx.__init__(self, locs, rxType) + + @property + def projField(self): + """Field Type projection (e.g. e b ...)""" + return self.knownRxTypes[self.rxType][0] + + @property + def projGLoc(self): + """Grid Location projection (e.g. Ex Fy ...)""" + return self.knownRxTypes[self.rxType][1] + + @property + def projComp(self): + """Component projection (real/imag)""" + return self.knownRxTypes[self.rxType][2] + + def projectFields(self, src, mesh, u): + P = self.getP(mesh) + u_part_complex = u[src, self.projField] + # get the real or imag component + real_or_imag = self.projComp + u_part = getattr(u_part_complex, real_or_imag) + return P*u_part + + def projectFieldsDeriv(self, src, mesh, u, v, adjoint=False): + P = self.getP(mesh) + + if not adjoint: + Pv_complex = P * v + real_or_imag = self.projComp + Pv = getattr(Pv_complex, real_or_imag) + elif adjoint: + Pv_real = P.T * v + + real_or_imag = self.projComp + if real_or_imag == 'imag': + Pv = 1j*Pv_real + elif real_or_imag == 'real': + Pv = Pv_real.astype(complex) + else: + raise NotImplementedError('must be real or imag') + + return Pv + + +#################################################### +# Survey +#################################################### + +class Survey(SimPEG.Survey.BaseSurvey): + """ + docstring for SurveyFDEM + """ + + srcPair = Src.BaseSrc + + def __init__(self, srcList, **kwargs): + # Sort these by frequency + self.srcList = srcList + SimPEG.Survey.BaseSurvey.__init__(self, **kwargs) + + _freqDict = {} + for src in srcList: + if src.freq not in _freqDict: + _freqDict[src.freq] = [] + _freqDict[src.freq] += [src] + + self._freqDict = _freqDict + self._freqs = sorted([f for f in self._freqDict]) + + @property + def freqs(self): + """Frequencies""" + return self._freqs + + @property + def nFreq(self): + """Number of frequencies""" + return len(self._freqDict) + + @property + def nSrcByFreq(self): + if getattr(self, '_nSrcByFreq', None) is None: + self._nSrcByFreq = {} + for freq in self.freqs: + self._nSrcByFreq[freq] = len(self.getSrcByFreq(freq)) + return self._nSrcByFreq + + def getSrcByFreq(self, freq): + """Returns the sources associated with a specific frequency.""" + assert freq in self._freqDict, "The requested frequency is not in this survey." + return self._freqDict[freq] + + def projectFields(self, u): + data = SimPEG.Survey.Data(self) + for src in self.srcList: + for rx in src.rxList: + data[src, rx] = rx.projectFields(src, self.mesh, u) + return data + + def projectFieldsDeriv(self, u): + raise Exception('Use Sources to project fields deriv.') diff --git a/SimPEG/EM/FDEM/__init__.py b/SimPEG/EM/FDEM/__init__.py new file mode 100644 index 00000000..978972f5 --- /dev/null +++ b/SimPEG/EM/FDEM/__init__.py @@ -0,0 +1,3 @@ +from SurveyFDEM import Rx, Src, Survey +from FDEM import BaseFDEMProblem, Problem_e, Problem_b, Problem_j, Problem_h +from FieldsFDEM import * \ No newline at end of file diff --git a/SimPEG/EM/TDEM/BaseTDEM.py b/SimPEG/EM/TDEM/BaseTDEM.py new file mode 100644 index 00000000..e36d76b8 --- /dev/null +++ b/SimPEG/EM/TDEM/BaseTDEM.py @@ -0,0 +1,155 @@ +from SimPEG import Solver, Problem +from SimPEG.Problem import BaseTimeProblem +from SimPEG.EM.Utils import * +from scipy.constants import mu_0 +from SimPEG.Utils import sdiag, mkvc +from SimPEG import Utils, Mesh +from SimPEG.EM.Base import BaseEMProblem +import numpy as np + + +class FieldsTDEM(Problem.TimeFields): + """Fancy Field Storage for a TDEM survey.""" + knownFields = {'b': 'F', 'e': 'E'} + + def tovec(self): + nSrc, nF, nE = self.survey.nSrc, self.mesh.nF, self.mesh.nE + u = np.empty((0,nSrc)) #((0,1) if nSrc == 1 else (0, nSrc)) + + for i in range(self.survey.prob.nT): + if 'b' in self: + b = self[:,'b',i+1] + else: + b = np.zeros((nF,nSrc)) # if nSrc == 1 else (nF, nSrc)) + + if 'e' in self: + e = self[:,'e',i+1] + else: + e = np.zeros((nE,nSrc)) # if nSrc == 1 else (nE, nSrc)) + u = np.concatenate((u, b, e)) + return Utils.mkvc(u,nSrc) + + +class BaseTDEMProblem(BaseTimeProblem, BaseEMProblem): + """docstring for ProblemTDEM1D""" + def __init__(self, mesh, mapping=None, **kwargs): + BaseTimeProblem.__init__(self, mesh, mapping=mapping, **kwargs) + + _FieldsForward_pair = FieldsTDEM #: used for the forward calculation only + + def fields(self, m): + if self.verbose: print '%s\nCalculating fields(m)\n%s'%('*'*50,'*'*50) + self.curModel = m + # Create a fields storage object + F = self._FieldsForward_pair(self.mesh, self.survey) + for src in self.survey.srcList: + # Set the initial conditions + F[src,:,0] = src.getInitialFields(self.mesh) + F = self.forward(m, self.getRHS, F=F) + if self.verbose: print '%s\nDone calculating fields(m)\n%s'%('*'*50,'*'*50) + return F + + def forward(self, m, RHS, F=None): + self.curModel = m + F = F or FieldsTDEM(self.mesh, self.survey) + + dtFact = None + Ainv = None + for tInd, dt in enumerate(self.timeSteps): + if dt != dtFact: + dtFact = dt + if Ainv is not None: + Ainv.clean() + A = self.getA(tInd) + if self.verbose: print 'Factoring... (dt = %e)'%dt + Ainv = self.Solver(A, **self.solverOpts) + if self.verbose: print 'Done' + rhs = RHS(tInd, F) + if self.verbose: print ' Solving... (tInd = %d)'%tInd + sol = Ainv * rhs + if self.verbose: print ' Done...' + if sol.ndim == 1: + sol.shape = (sol.size,1) + F[:,self.solType,tInd+1] = sol + Ainv.clean() + return F + + def adjoint(self, m, RHS, F=None): + self.curModel = m + F = F or FieldsTDEM(self.mesh, self.survey) + + dtFact = None + Ainv = None + for tInd, dt in reversed(list(enumerate(self.timeSteps))): + if dt != dtFact: + dtFact = dt + if Ainv is not None: + Ainv.clean() + A = self.getA(tInd) + if self.verbose: print 'Factoring (Adjoint)... (dt = %e)'%dt + Ainv = self.Solver(A, **self.solverOpts) + if self.verbose: print 'Done' + rhs = RHS(tInd, F) + if self.verbose: print ' Solving (Adjoint)... (tInd = %d)'%tInd + sol = Ainv * rhs + if self.verbose: print ' Done...' + if sol.ndim == 1: + sol.shape = (sol.size,1) + F[:,self.solType,tInd+1] = sol + Ainv.clean() + return F + + def Jvec(self, m, v, u=None): + """ + :param numpy.array m: Conductivity model + :param numpy.ndarray v: vector (model object) + :param simpegEM.TDEM.FieldsTDEM u: Fields resulting from m + :rtype: numpy.ndarray + :return: w (data object) + + Multiplying \\\(\\\mathbf{J}\\\) onto a vector can be broken into three steps + + * Compute \\\(\\\\vec{p} = \\\mathbf{G}v\\\) + * Solve \\\(\\\hat{\\\mathbf{A}} \\\\vec{y} = \\\\vec{p}\\\) + * Compute \\\(\\\\vec{w} = -\\\mathbf{Q} \\\\vec{y}\\\) + + """ + if self.verbose: print '%s\nCalculating J(v)\n%s'%('*'*50,'*'*50) + self.curModel = m + if u is None: + u = self.fields(m) + p = self.Gvec(m, v, u) + y = self.solveAh(m, p) + Jv = self.survey.projectFieldsDeriv(u, v=y) + if self.verbose: print '%s\nDone calculating J(v)\n%s'%('*'*50,'*'*50) + return - mkvc(Jv) + + def Jtvec(self, m, v, u=None): + """ + :param numpy.array m: Conductivity model + :param numpy.ndarray,SimPEG.Survey.Data v: vector (data object) + :param simpegEM.TDEM.FieldsTDEM u: Fields resulting from m + :rtype: numpy.ndarray + :return: w (model object) + + Multiplying \\\(\\\mathbf{J}^\\\\top\\\) onto a vector can be broken into three steps + + * Compute \\\(\\\\vec{p} = \\\mathbf{Q}^\\\\top \\\\vec{v}\\\) + * Solve \\\(\\\hat{\\\mathbf{A}}^\\\\top \\\\vec{y} = \\\\vec{p}\\\) + * Compute \\\(\\\\vec{w} = -\\\mathbf{G}^\\\\top y\\\) + + """ + if self.verbose: print '%s\nCalculating J^T(v)\n%s'%('*'*50,'*'*50) + self.curModel = m + if u is None: + u = self.fields(m) + + if not isinstance(v, self.dataPair): + v = self.dataPair(self.survey, v) + + p = self.survey.projectFieldsDeriv(u, v=v, adjoint=True) + y = self.solveAht(m, p) + w = self.Gtvec(m, y, u) + if self.verbose: print '%s\nDone calculating J^T(v)\n%s'%('*'*50,'*'*50) + return - mkvc(w) + diff --git a/SimPEG/EM/TDEM/SurveyTDEM.py b/SimPEG/EM/TDEM/SurveyTDEM.py new file mode 100644 index 00000000..7f6e5c04 --- /dev/null +++ b/SimPEG/EM/TDEM/SurveyTDEM.py @@ -0,0 +1,162 @@ +from SimPEG import Utils, Survey, np +from SimPEG.Survey import BaseSurvey +from SimPEG.EM.Utils import * +from BaseTDEM import FieldsTDEM + + +class RxTDEM(Survey.BaseTimeRx): + + knownRxTypes = { + 'ex':['e', 'Ex', 'N'], + 'ey':['e', 'Ey', 'N'], + 'ez':['e', 'Ez', 'N'], + + 'bx':['b', 'Fx', 'N'], + 'by':['b', 'Fy', 'N'], + 'bz':['b', 'Fz', 'N'], + + 'dbxdt':['b', 'Fx', 'CC'], + 'dbydt':['b', 'Fy', 'CC'], + 'dbzdt':['b', 'Fz', 'CC'], + } + + def __init__(self, locs, times, rxType): + Survey.BaseTimeRx.__init__(self, locs, times, rxType) + + @property + def projField(self): + """Field Type projection (e.g. e b ...)""" + return self.knownRxTypes[self.rxType][0] + + @property + def projGLoc(self): + """Grid Location projection (e.g. Ex Fy ...)""" + return self.knownRxTypes[self.rxType][1] + + @property + def projTLoc(self): + """Time Location projection (e.g. CC N)""" + return self.knownRxTypes[self.rxType][2] + + def getTimeP(self, timeMesh): + """ + Returns the time projection matrix. + + .. note:: + + This is not stored in memory, but is created on demand. + """ + if self.rxType in ['dbxdt','dbydt','dbzdt']: + return timeMesh.getInterpolationMat(self.times, self.projTLoc)*timeMesh.faceDiv + else: + return timeMesh.getInterpolationMat(self.times, self.projTLoc) + + def projectFields(self, src, mesh, timeMesh, u): + P = self.getP(mesh, timeMesh) + u_part = Utils.mkvc(u[src, self.projField, :]) + return P*u_part + + def projectFieldsDeriv(self, src, mesh, timeMesh, u, v, adjoint=False): + P = self.getP(mesh, timeMesh) + + if not adjoint: + return P * Utils.mkvc(v[src, self.projField, :]) + elif adjoint: + return P.T * v[src, self] + + +class SrcTDEM(Survey.BaseSrc): + rxPair = RxTDEM + radius = None + + def getInitialFields(self, mesh): + F0 = getattr(self, '_getInitialFields_' + self.srcType)(mesh) + return F0 + + def getJs(self, mesh, time): + return None + + +class SrcTDEM_VMD_MVP(SrcTDEM): + + def __init__(self,rxList,loc): + self.loc = loc + SrcTDEM.__init__(self,rxList) + + def getInitialFields(self, mesh): + """Vertical magnetic dipole, magnetic vector potential""" + if mesh._meshType is 'CYL': + if mesh.isSymmetric: + MVP = MagneticDipoleVectorPotential(self.loc, mesh, 'Ey') + else: + raise NotImplementedError('Non-symmetric cyl mesh not implemented yet!') + elif mesh._meshType is 'TENSOR': + MVP = MagneticDipoleVectorPotential(self.loc, mesh, ['Ex','Ey','Ez']) + else: + raise Exception('Unknown mesh for VMD') + + return {"b": mesh.edgeCurl*MVP} + + +class SrcTDEM_CircularLoop_MVP(SrcTDEM): + + def __init__(self,rxList,loc,radius): + self.loc = loc + self.radius = radius + SrcTDEM.__init__(self,rxList) + + def getInitialFields(self, mesh): + """Circular Loop, magnetic vector potential""" + if mesh._meshType is 'CYL': + if mesh.isSymmetric: + MVP = MagneticLoopVectorPotential(self.loc, mesh, 'Ey', self.radius) + else: + raise NotImplementedError('Non-symmetric cyl mesh not implemented yet!') + elif mesh._meshType is 'TENSOR': + MVP = MagneticLoopVectorPotential(self.loc, mesh, ['Ex','Ey','Ez'], self.radius) + else: + raise Exception('Unknown mesh for CircularLoop') + + return {"b": mesh.edgeCurl*MVP} + + +class SurveyTDEM(Survey.BaseSurvey): + """ + docstring for SurveyTDEM + """ + srcPair = SrcTDEM + + def __init__(self, srcList, **kwargs): + # Sort these by frequency + self.srcList = srcList + Survey.BaseSurvey.__init__(self, **kwargs) + + def projectFields(self, u): + data = Survey.Data(self) + for src in self.srcList: + for rx in src.rxList: + data[src, rx] = rx.projectFields(src, self.mesh, self.prob.timeMesh, u) + return data + + def projectFieldsDeriv(self, u, v=None, adjoint=False): + assert v is not None, 'v to multiply must be provided.' + + if not adjoint: + data = Survey.Data(self) + for src in self.srcList: + for rx in src.rxList: + data[src, rx] = rx.projectFieldsDeriv(src, self.mesh, self.prob.timeMesh, u, v) + return data + else: + f = FieldsTDEM(self.mesh, self) + for src in self.srcList: + for rx in src.rxList: + Ptv = rx.projectFieldsDeriv(src, self.mesh, self.prob.timeMesh, u, v, adjoint=True) + Ptv = Ptv.reshape((-1, self.prob.timeMesh.nN), order='F') + if rx.projField not in f: # first time we are projecting + f[src, rx.projField, :] = Ptv + else: # there are already fields, so let's add to them! + f[src, rx.projField, :] += Ptv + return f + + diff --git a/SimPEG/EM/TDEM/TDEM_b.py b/SimPEG/EM/TDEM/TDEM_b.py new file mode 100644 index 00000000..cd38660c --- /dev/null +++ b/SimPEG/EM/TDEM/TDEM_b.py @@ -0,0 +1,356 @@ +from BaseTDEM import BaseTDEMProblem, FieldsTDEM +from SimPEG.Utils import mkvc, sdiag +import numpy as np +from SurveyTDEM import SurveyTDEM + + +class FieldsTDEM_e_from_b(FieldsTDEM): + """Fancy Field Storage for a TDEM survey.""" + knownFields = {'b': 'F'} + aliasFields = {'e': ['b','E','e_from_b']} + + def startup(self): + self.MeSigmaI = self.survey.prob.MeSigmaI + self.edgeCurlT = self.survey.prob.mesh.edgeCurl.T + self.MfMui = self.survey.prob.MfMui + + def e_from_b(self, b, srcInd, timeInd): + # TODO: implement non-zero js + return self.MeSigmaI*(self.edgeCurlT*(self.MfMui*b)) + +class FieldsTDEM_e_from_b_Ah(FieldsTDEM): + """Fancy Field Storage for a TDEM survey. + + This is used when solving Ahat and AhatT + """ + knownFields = {'b': 'F'} + aliasFields = {'e': ['b','E','e_from_b']} + p = None + + def startup(self): + self.MeSigmaI = self.survey.prob.MeSigmaI + self.edgeCurlT = self.survey.prob.mesh.edgeCurl.T + self.MfMui = self.survey.prob.MfMui + + def e_from_b(self, y_b, srcInd, tInd): + y_e = self.MeSigmaI*(self.edgeCurlT*(self.MfMui*y_b)) + if 'e' in self.p: + y_e = y_e - self.MeSigmaI*self.p[srcInd,'e',tInd] + return y_e + +class ProblemTDEM_b(BaseTDEMProblem): + """ + Time-Domain EM problem - B-formulation + + TDEM_b treats the following discretization of Maxwell's equations + + .. math:: + \dcurl \e^{(t+1)} + \\frac{\\b^{(t+1)} - \\b^{(t)}}{\delta t} = 0 \\\\ + \dcurl^\\top \MfMui \\b^{(t+1)} - \MeSig \e^{(t+1)} = \Me \j_s^{(t+1)} + + with \\\(\\b\\\) defined on cell faces and \\\(\e\\\) defined on edges. + """ + def __init__(self, mesh, mapping=None, **kwargs): + BaseTDEMProblem.__init__(self, mesh, mapping=mapping, **kwargs) + + solType = 'b' #: Type of the solution, in this case the 'b' field + + surveyPair = SurveyTDEM + _FieldsForward_pair = FieldsTDEM_e_from_b #: used for the forward calculation only + + #################################################### + # Internal Methods + #################################################### + + def getA(self, tInd): + """ + :param int tInd: Time index + :rtype: scipy.sparse.csr_matrix + :return: A + """ + dt = self.timeSteps[tInd] + return self.MfMui*self.mesh.edgeCurl*self.MeSigmaI*self.mesh.edgeCurl.T*self.MfMui + (1.0/dt)*self.MfMui + + def getRHS(self, tInd, F): + dt = self.timeSteps[tInd] + B_n = np.c_[[F[src,'b',tInd] for src in self.survey.srcList]].T + if B_n.shape[0] is not 1: + raise NotImplementedError('getRHS not implemented for this shape of B_n') + RHS = (1.0/dt)*self.MfMui*B_n[0,:,:] #TODO: This is a hack + return RHS + + #################################################### + # Derivatives + #################################################### + + def Gvec(self, m, vec, u=None): + """ + :param numpy.array m: Conductivity model + :param numpy.array vec: vector (like a model) + :param simpegEM.TDEM.FieldsTDEM u: Fields resulting from m + :rtype: simpegEM.TDEM.FieldsTDEM + :return: f + + Multiply G by a vector + """ + if u is None: + u = self.fields(m) + self.curModel = m + + # Note: Fields has shape (nF/E, nSrc, nT+1) + # However, p will only really fill (:,:,1:nT+1) + # meaning the 'initial fields' are zero (:,:,0) + p = FieldsTDEM(self.mesh, self.survey) + # 'b' at all times is zero. + # However, to save memory we will **not** do: + # + # p[:, 'b', :] = 0.0 + + # fake initial 'e' fields + p[:, 'e', 0] = 0.0 + dMdsig = self.MeSigmaDeriv + # self.mesh.getEdgeInnerProductDeriv(self.curModel.transform) + # dsigdm_x_v = self.curModel.sigmaDeriv*vec + # dsigdm_x_v = self.curModel.transformDeriv*vec + for i in range(1,self.nT+1): + # TODO: G[1] may be dependent on the model + # for a galvanic source (deriv of the dc problem) + # + # Do multiplication for all src in self.survey.srcList + for src in self.survey.srcList: + p[src, 'e', i] = - dMdsig(u[src,'e',i]) * vec + return p + + def Gtvec(self, m, vec, u=None): + """ + :param numpy.array m: Conductivity model + :param numpy.array vec: vector (like a fields) + :param simpegEM.TDEM.FieldsTDEM u: Fields resulting from m + :rtype: np.ndarray (like a model) + :return: p + + Multiply G.T by a vector + """ + if u is None: + u = self.fields(m) + self.curModel = m + # dMdsig = self.mesh.getEdgeInnerProductDeriv(self.curModel.transform) + # dsigdm = self.curModel.transformDeriv + MeSigmaDeriv = self.MeSigmaDeriv + + nSrc = self.survey.nSrc + VUs = None + # Here we can do internal multiplications of Gt*v and then multiply by MsigDeriv.T in one go. + for i in range(1,self.nT+1): + vu = None + for src in self.survey.srcList: + vusrc = MeSigmaDeriv(u[src,'e',i]).T * vec[src,'e',i] + vu = vusrc if vu is None else vu + vusrc + VUs = vu if VUs is None else VUs + vu + # p = -dsigdm.T*VUs + return -VUs + + def solveAh(self, m, p): + """ + :param numpy.array m: Conductivity model + :param simpegEM.TDEM.FieldsTDEM p: Fields object + :rtype: simpegEM.TDEM.FieldsTDEM + :return: y + + Solve the block-matrix system \\\(\\\hat{A} \\\hat{y} = \\\hat{p}\\\): + + .. math:: + \mathbf{\hat{A}} = \left[ + \\begin{array}{cccc} + A & 0 & & \\\\ + B & A & & \\\\ + & \ddots & \ddots & \\\\ + & & B & A + \end{array} + \\right] \\\\ + \mathbf{A} = + \left[ + \\begin{array}{cc} + \\frac{1}{\delta t} \MfMui & \MfMui\dcurl \\\\ + \dcurl^\\top \MfMui & -\MeSig + \end{array} + \\right] \\\\ + \mathbf{B} = + \left[ + \\begin{array}{cc} + -\\frac{1}{\delta t} \MfMui & 0 \\\\ + 0 & 0 + \end{array} + \\right] \\\\ + """ + + def AhRHS(tInd, y): + rhs = self.MfMui*(self.mesh.edgeCurl*(self.MeSigmaI*p[:,'e',tInd+1])) + if 'b' in p: + rhs = rhs + p[:,'b',tInd+1] + if tInd == 0: + return rhs + dt = self.timeSteps[tInd] + return rhs + 1.0/dt*self.MfMui*y[:,'b',tInd] + + F = FieldsTDEM_e_from_b_Ah(self.mesh, self.survey, p=p) + + return self.forward(m, AhRHS, F) + + def solveAht(self, m, p): + """ + :param numpy.array m: Conductivity model + :param simpegEM.TDEM.FieldsTDEM p: Fields object + :rtype: simpegEM.TDEM.FieldsTDEM + :return: y + + Solve the block-matrix system \\\(\\\hat{A}^\\\\top \\\hat{y} = \\\hat{p}\\\): + + .. math:: + \mathbf{\hat{A}}^\\top = \left[ + \\begin{array}{cccc} + A & B & & \\\\ + & \ddots & \ddots & \\\\ + & & A & B \\\\ + & & 0 & A + \end{array} + \\right] \\\\ + \mathbf{A} = + \left[ + \\begin{array}{cc} + \\frac{1}{\delta t} \MfMui & \MfMui\dcurl \\\\ + \dcurl^\\top \MfMui & -\MeSig + \end{array} + \\right] \\\\ + \mathbf{B} = + \left[ + \\begin{array}{cc} + -\\frac{1}{\delta t} \MfMui & 0 \\\\ + 0 & 0 + \end{array} + \\right] \\\\ + """ + + # Mini Example: + # + # nT = 3, len(times) == 4, fields stored in F[:,:,1:4] + # + # 0 is held for initial conditions (this shifts the storage by +1) + # ^ + # fLoc 0 1 2 3 + # |-----|-----|-----| + # tInd 0 1 2 + # / ___/ + # 2 (tInd=2 uses fields 3 and would use 4 but it doesn't exist) + # / ___/ + # 1 (tInd=1 uses fields 2 and 3) + + def AhtRHS(tInd, y): + nSrc, nF = self.survey.nSrc, self.mesh.nF + rhs = np.zeros((nF,1) if nSrc == 1 else (nF, nSrc)) + + if 'e' in p: + rhs += self.MfMui*(self.mesh.edgeCurl*(self.MeSigmaI*p[:,'e',tInd+1])) + if 'b' in p: + rhs += p[:,'b',tInd+1] + + if tInd == self.nT-1: + return rhs + dt = self.timeSteps[tInd+1] + return rhs + 1.0/dt*self.MfMui*y[:,'b',tInd+2] + + F = FieldsTDEM_e_from_b_Ah(self.mesh, self.survey, p=p) + + return self.adjoint(m, AhtRHS, F) + + #################################################### + # Functions for tests + #################################################### + + def _AhVec(self, m, vec): + """ + :param numpy.array m: Conductivity model + :param simpegEM.TDEM.FieldsTDEM vec: Fields object + :rtype: simpegEM.TDEM.FieldsTDEM + :return: f + + Multiply the matrix \\\(\\\hat{A}\\\) by a fields vector where + + .. math:: + \mathbf{\hat{A}} = \left[ + \\begin{array}{cccc} + A & 0 & & \\\\ + B & A & & \\\\ + & \ddots & \ddots & \\\\ + & & B & A + \end{array} + \\right] \\\\ + \mathbf{A} = + \left[ + \\begin{array}{cc} + \\frac{1}{\delta t} \MfMui & \MfMui\dcurl \\\\ + \dcurl^\\top \MfMui & -\MeSig + \end{array} + \\right] \\\\ + \mathbf{B} = + \left[ + \\begin{array}{cc} + -\\frac{1}{\delta t} \MfMui & 0 \\\\ + 0 & 0 + \end{array} + \\right] \\\\ + """ + + self.curModel = m + f = FieldsTDEM(self.mesh, self.survey) + for i in range(1,self.nT+1): + dt = self.timeSteps[i-1] + b = 1.0/dt*self.MfMui*vec[:,'b',i] + self.MfMui*(self.mesh.edgeCurl*vec[:,'e',i]) + if i > 1: + b = b - 1.0/dt*self.MfMui*vec[:,'b',i-1] + f[:,'b',i] = b + f[:,'e',i] = self.mesh.edgeCurl.T*(self.MfMui*vec[:,'b',i]) - self.MeSigma*vec[:,'e',i] + return f + + def _AhtVec(self, m, vec): + """ + :param numpy.array m: Conductivity model + :param simpegEM.TDEM.FieldsTDEM vec: Fields object + :rtype: simpegEM.TDEM.FieldsTDEM + :return: f + + Multiply the matrix \\\(\\\hat{A}\\\) by a fields vector where + + .. math:: + \mathbf{\hat{A}}^\\top = \left[ + \\begin{array}{cccc} + A & B & & \\\\ + & \ddots & \ddots & \\\\ + & & A & B \\\\ + & & 0 & A + \end{array} + \\right] \\\\ + \mathbf{A} = + \left[ + \\begin{array}{cc} + \\frac{1}{\delta t} \MfMui & \MfMui\dcurl \\\\ + \dcurl^\\top \MfMui & -\MeSig + \end{array} + \\right] \\\\ + \mathbf{B} = + \left[ + \\begin{array}{cc} + -\\frac{1}{\delta t} \MfMui & 0 \\\\ + 0 & 0 + \end{array} + \\right] \\\\ + """ + self.curModel = m + f = FieldsTDEM(self.mesh, self.survey) + for i in range(self.nT): + b = 1.0/self.timeSteps[i]*self.MfMui*vec[:,'b',i+1] + self.MfMui*(self.mesh.edgeCurl*vec[:,'e',i+1]) + if i < self.nT-1: + b = b - 1.0/self.timeSteps[i+1]*self.MfMui*vec[:,'b',i+2] + f[:,'b', i+1] = b + f[:,'e', i+1] = self.mesh.edgeCurl.T*(self.MfMui*vec[:,'b',i+1]) - self.MeSigma*vec[:,'e',i+1] + return f diff --git a/SimPEG/EM/TDEM/__init__.py b/SimPEG/EM/TDEM/__init__.py new file mode 100644 index 00000000..dd5a8bce --- /dev/null +++ b/SimPEG/EM/TDEM/__init__.py @@ -0,0 +1,3 @@ +from SurveyTDEM import * #SurveyTDEM, RxTDEM, SrcTDEM +from BaseTDEM import BaseTDEMProblem, FieldsTDEM +from TDEM_b import ProblemTDEM_b diff --git a/SimPEG/EM/Utils/AnalyticUtils.py b/SimPEG/EM/Utils/AnalyticUtils.py new file mode 100644 index 00000000..1827f6b2 --- /dev/null +++ b/SimPEG/EM/Utils/AnalyticUtils.py @@ -0,0 +1,203 @@ +from SimPEG import * +from scipy.special import ellipk, ellipe +from scipy.constants import mu_0, pi + +def MagneticDipoleVectorPotential(srcLoc, obsLoc, component, moment=1., dipoleMoment=(0., 0., 1.), mu = mu_0): + """ + Calculate the vector potential of a set of magnetic dipoles + at given locations 'ref. ' + + :param numpy.ndarray srcLoc: Location of the source(s) (x, y, z) + :param numpy.ndarray,SimPEG.Mesh obsLoc: Where the potentials will be calculated (x, y, z) or a SimPEG Mesh + :param str,list component: The component to calculate - 'x', 'y', or 'z' if an array, or grid type if mesh, can be a list + :param numpy.ndarray dipoleMoment: The vector dipole moment + :rtype: numpy.ndarray + :return: The vector potential each dipole at each observation location + """ + #TODO: break this out! + + if type(component) in [list, tuple]: + out = range(len(component)) + for i, comp in enumerate(component): + out[i] = MagneticDipoleVectorPotential(srcLoc, obsLoc, comp, dipoleMoment=dipoleMoment) + return np.concatenate(out) + + if isinstance(obsLoc, Mesh.BaseMesh): + mesh = obsLoc + assert component in ['Ex','Ey','Ez','Fx','Fy','Fz'], "Components must be in: ['Ex','Ey','Ez','Fx','Fy','Fz']" + return MagneticDipoleVectorPotential(srcLoc, getattr(mesh,'grid'+component), component[1], dipoleMoment=dipoleMoment) + + if component == 'x': + dimInd = 0 + elif component == 'y': + dimInd = 1 + elif component == 'z': + dimInd = 2 + else: + raise ValueError('Invalid component') + + srcLoc = np.atleast_2d(srcLoc) + obsLoc = np.atleast_2d(obsLoc) + dipoleMoment = np.atleast_2d(dipoleMoment) + + nEdges = obsLoc.shape[0] + nSrc = srcLoc.shape[0] + + m = np.array(dipoleMoment).repeat(nEdges, axis=0) + A = np.empty((nEdges, nSrc)) + for i in range(nSrc): + dR = obsLoc - srcLoc[i, np.newaxis].repeat(nEdges, axis=0) + mCr = np.cross(m, dR) + r = np.sqrt((dR**2).sum(axis=1)) + A[:, i] = +(mu/(4*pi)) * mCr[:,dimInd]/(r**3) + if nSrc == 1: + return A.flatten() + return A + + +def MagneticDipoleFields(srcLoc, obsLoc, component, moment=1., mu = mu_0): + """ + Calculate the vector potential of a set of magnetic dipoles + at given locations 'ref. ' + + :param numpy.ndarray srcLoc: Location of the source(s) (x, y, z) + :param numpy.ndarray obsLoc: Where the potentials will be calculated (x, y, z) + :param str component: The component to calculate - 'x', 'y', or 'z' + :param numpy.ndarray moment: The vector dipole moment (vertical) + :rtype: numpy.ndarray + :return: The vector potential each dipole at each observation location + """ + + if component=='x': + dimInd = 0 + elif component=='y': + dimInd = 1 + elif component=='z': + dimInd = 2 + else: + raise ValueError('Invalid component') + + srcLoc = np.atleast_2d(srcLoc) + obsLoc = np.atleast_2d(obsLoc) + moment = np.atleast_2d(moment) + + nFaces = obsLoc.shape[0] + nSrc = srcLoc.shape[0] + + m = np.array(moment).repeat(nFaces, axis=0) + B = np.empty((nFaces, nSrc)) + for i in range(nSrc): + dR = obsLoc - srcLoc[i, np.newaxis].repeat(nFaces, axis=0) + r = np.sqrt((dR**2).sum(axis=1)) + if dimInd == 0: + B[:, i] = +(mu/(4*pi)) /(r**3) * (3*dR[:,2]*dR[:,0]/r**2) + elif dimInd == 1: + B[:, i] = +(mu/(4*pi)) /(r**3) * (3*dR[:,2]*dR[:,1]/r**2) + elif dimInd == 2: + B[:, i] = +(mu/(4*pi)) /(r**3) * (3*dR[:,2]**2/r**2-1) + else: + raise Exception("Not Implemented") + if nSrc == 1: + return B.flatten() + return B + + + +def MagneticLoopVectorPotential(srcLoc, obsLoc, component, radius, mu=mu_0): + """ + Calculate the vector potential of horizontal circular loop + at given locations + + :param numpy.ndarray srcLoc: Location of the source(s) (x, y, z) + :param numpy.ndarray,SimPEG.Mesh obsLoc: Where the potentials will be calculated (x, y, z) or a SimPEG Mesh + :param str,list component: The component to calculate - 'x', 'y', or 'z' if an array, or grid type if mesh, can be a list + :param numpy.ndarray I: Input current of the loop + :param numpy.ndarray radius: radius of the loop + :rtype: numpy.ndarray + :return: The vector potential each dipole at each observation location + """ + + if type(component) in [list, tuple]: + out = range(len(component)) + for i, comp in enumerate(component): + out[i] = MagneticLoopVectorPotential(srcLoc, obsLoc, comp, radius, mu) + return np.concatenate(out) + + if isinstance(obsLoc, Mesh.BaseMesh): + mesh = obsLoc + assert component in ['Ex','Ey','Ez','Fx','Fy','Fz'], "Components must be in: ['Ex','Ey','Ez','Fx','Fy','Fz']" + return MagneticLoopVectorPotential(srcLoc, getattr(mesh,'grid'+component), component[1], radius, mu) + + srcLoc = np.atleast_2d(srcLoc) + obsLoc = np.atleast_2d(obsLoc) + + n = obsLoc.shape[0] + nSrc = srcLoc.shape[0] + + if component=='z': + A = np.zeros((n, nSrc)) + if nSrc ==1: + return A.flatten() + return A + + else: + + A = np.zeros((n, nSrc)) + for i in range (nSrc): + x = obsLoc[:, 0] - srcLoc[i, 0] + y = obsLoc[:, 1] - srcLoc[i, 1] + z = obsLoc[:, 2] - srcLoc[i, 2] + r = np.sqrt(x**2 + y**2) + m = (4 * radius * r) / ((radius + r)**2 + z**2) + m[m > 1.] = 1. + # m might be slightly larger than 1 due to rounding errors + # but ellipke requires 0 <= m <= 1 + K = ellipk(m) + E = ellipe(m) + ind = (r > 0) & (m < 1) + # % 1/r singular at r = 0 and K(m) singular at m = 1 + Aphi = np.zeros(n) + # % Common factor is (mu * I) / pi with I = 1 and mu = 4e-7 * pi. + Aphi[ind] = 4e-7 / np.sqrt(m[ind]) * np.sqrt(radius / r[ind]) *((1. - m[ind] / 2.) * K[ind] - E[ind]) + if component == 'x': + A[ind, i] = Aphi[ind] * (-y[ind] / r[ind] ) + elif component == 'y': + A[ind, i] = Aphi[ind] * ( x[ind] / r[ind] ) + else: + raise ValueError('Invalid component') + + if nSrc == 1: + return A.flatten() + return A + +if __name__ == '__main__': + from SimPEG import Mesh + import matplotlib.pyplot as plt + cs = 20 + ncx, ncy, ncz = 41, 41, 40 + hx = np.ones(ncx)*cs + hy = np.ones(ncy)*cs + hz = np.ones(ncz)*cs + mesh = Mesh.TensorMesh([hx, hy, hz], 'CCC') + srcLoc = np.r_[0., 0., 0.] + Ax = MagneticLoopVectorPotential(srcLoc, mesh.gridEx, 'x', 200) + Ay = MagneticLoopVectorPotential(srcLoc, mesh.gridEy, 'y', 200) + Az = MagneticLoopVectorPotential(srcLoc, mesh.gridEz, 'z', 200) + A = np.r_[Ax, Ay, Az] + B0 = mesh.edgeCurl*A + J0 = mesh.edgeCurl.T*B0 + + # mesh.plotImage(A, vType = 'Ex') + # mesh.plotImage(A, vType = 'Ey') + + mesh.plotImage(B0, vType = 'Fx') + mesh.plotImage(B0, vType = 'Fy') + mesh.plotImage(B0, vType = 'Fz') + + # # mesh.plotImage(J0, vType = 'Ex') + # mesh.plotImage(J0, vType = 'Ey') + # mesh.plotImage(J0, vType = 'Ez') + + plt.show() + + diff --git a/SimPEG/EM/Utils/EMUtils.py b/SimPEG/EM/Utils/EMUtils.py new file mode 100644 index 00000000..4a342acb --- /dev/null +++ b/SimPEG/EM/Utils/EMUtils.py @@ -0,0 +1,49 @@ +import numpy as np +from scipy.constants import mu_0, epsilon_0 + +# useful params +def omega(freq): + """Angular frequency, omega""" + return 2.*np.pi*freq + +def k(freq, sigma, mu=mu_0, eps=epsilon_0): + """ Eq 1.47 - 1.49 in Ward and Hohmann """ + w = omega(freq) + alp = w * np.sqrt( mu*eps/2 * ( np.sqrt(1. + (sigma / (eps*w))**2 ) + 1) ) + beta = w * np.sqrt( mu*eps/2 * ( np.sqrt(1. + (sigma / (eps*w))**2 ) - 1) ) + return alp - 1j*beta + +# Constitutive relations +def e_from_j(prob,j): + eqLocs = prob._eqLocs + if eqLocs is 'FE': + MSigmaI = prob.MeSigmaI + elif eqLocs is 'EF': + MSigmaI = prob.MfRho + return MSigmaI*j + +def j_from_e(prob,e): + eqLocs = prob._eqLocs + if eqLocs is 'FE': + MSigma = prob.MeSigma + elif eqLocs is 'EF': + MSigma = prob.MfRhoI + return MSigma*e + +def b_from_h(prob,h): + eqLocs = prob._eqLocs + if eqLocs is 'FE': + MMu = prob.MfMuiI + elif eqLocs is 'EF': + MMu = prob.MeMu + return MMu*h + +def h_from_b(prob,b): + eqLocs = prob._eqLocs + if eqLocs is 'FE': + MMuI = prob.MfMui + elif eqLocs is 'EF': + MMuI = prob.MeMuI + return MMuI*b + + diff --git a/SimPEG/EM/Utils/__init__.py b/SimPEG/EM/Utils/__init__.py new file mode 100644 index 00000000..18dddde9 --- /dev/null +++ b/SimPEG/EM/Utils/__init__.py @@ -0,0 +1,5 @@ +# import Sources +# import Ana +# import Solver +from EMUtils import omega, e_from_j, j_from_e, b_from_h, h_from_b +from AnalyticUtils import MagneticDipoleFields, MagneticDipoleVectorPotential, MagneticLoopVectorPotential \ No newline at end of file diff --git a/SimPEG/EM/Utils/testingUtils.py b/SimPEG/EM/Utils/testingUtils.py new file mode 100644 index 00000000..8c703083 --- /dev/null +++ b/SimPEG/EM/Utils/testingUtils.py @@ -0,0 +1,75 @@ +import unittest +from SimPEG import * +from SimPEG import EM +import sys +from scipy.constants import mu_0 + +def getFDEMProblem(fdemType, comp, SrcList, freq, verbose=False): + cs = 5. + ncx, ncy, ncz = 6, 6, 6 + npad = 3 + hx = [(cs,npad,-1.3), (cs,ncx), (cs,npad,1.3)] + hy = [(cs,npad,-1.3), (cs,ncy), (cs,npad,1.3)] + hz = [(cs,npad,-1.3), (cs,ncz), (cs,npad,1.3)] + mesh = Mesh.TensorMesh([hx,hy,hz],['C','C','C']) + + mapping = Maps.ExpMap(mesh) + + x = np.array([np.linspace(-30,-15,3),np.linspace(15,30,3)]) #don't sample right by the source + XYZ = Utils.ndgrid(x,x,np.r_[0.]) + Rx0 = EM.FDEM.Rx(XYZ, comp) + + Src = [] + + for SrcType in SrcList: + if SrcType is 'MagDipole': + Src.append(EM.FDEM.Src.MagDipole([Rx0], freq=freq, loc=np.r_[0.,0.,0.])) + elif SrcType is 'MagDipole_Bfield': + Src.append(EM.FDEM.Src.MagDipole_Bfield([Rx0], freq=freq, loc=np.r_[0.,0.,0.])) + elif SrcType is 'CircularLoop': + Src.append(EM.FDEM.Src.CircularLoop([Rx0], freq=freq, loc=np.r_[0.,0.,0.])) + elif SrcType is 'RawVec': + if fdemType is 'e' or fdemType is 'b': + S_m = np.zeros(mesh.nF) + S_e = np.zeros(mesh.nE) + S_m[Utils.closestPoints(mesh,[0.,0.,0.],'Fz') + np.sum(mesh.vnF[:1])] = 1. + S_e[Utils.closestPoints(mesh,[0.,0.,0.],'Ez') + np.sum(mesh.vnE[:1])] = 1. + Src.append(EM.FDEM.Src.RawVec([Rx0], freq, S_m, S_e)) + + elif fdemType is 'h' or fdemType is 'j': + S_m = np.zeros(mesh.nE) + S_e = np.zeros(mesh.nF) + S_m[Utils.closestPoints(mesh,[0.,0.,0.],'Ez') + np.sum(mesh.vnE[:1])] = 1. + S_e[Utils.closestPoints(mesh,[0.,0.,0.],'Fz') + np.sum(mesh.vnF[:1])] = 1. + Src.append(EM.FDEM.Src.RawVec([Rx0], freq, S_m, S_e)) + + if verbose: + print ' Fetching %s problem' % (fdemType) + + if fdemType == 'e': + survey = EM.FDEM.Survey(Src) + prb = EM.FDEM.Problem_e(mesh, mapping=mapping) + + elif fdemType == 'b': + survey = EM.FDEM.Survey(Src) + prb = EM.FDEM.Problem_b(mesh, mapping=mapping) + + elif fdemType == 'j': + survey = EM.FDEM.Survey(Src) + prb = EM.FDEM.Problem_j(mesh, mapping=mapping) + + elif fdemType == 'h': + survey = EM.FDEM.Survey(Src) + prb = EM.FDEM.Problem_h(mesh, mapping=mapping) + + else: + raise NotImplementedError() + prb.pair(survey) + + try: + from pymatsolver import MumpsSolver + prb.Solver = MumpsSolver + except ImportError, e: + pass + + return prb \ No newline at end of file diff --git a/SimPEG/EM/__init__.py b/SimPEG/EM/__init__.py new file mode 100644 index 00000000..6a1ca774 --- /dev/null +++ b/SimPEG/EM/__init__.py @@ -0,0 +1,6 @@ +# from EM import * +import TDEM +import FDEM +import Base +import Analytics +import Utils diff --git a/SimPEG/Examples/DCfwd.py b/SimPEG/Examples/DCfwd.py index 385babf6..33e7aad5 100644 --- a/SimPEG/Examples/DCfwd.py +++ b/SimPEG/Examples/DCfwd.py @@ -5,67 +5,71 @@ from matplotlib.mlab import griddata ## 2D DC forward modeling example with Tensor and Curvilinear Meshes -# Step1: Generate Tensor and Curvilinear Mesh -sz = [40,40] -# Tensor Mesh -tM = Mesh.TensorMesh(sz) -# Curvilinear Mesh -rM = Mesh.CurvilinearMesh(Utils.meshutils.exampleLrmGrid(sz,'rotate')) +def run(plotIt=True): + # Step1: Generate Tensor and Curvilinear Mesh + sz = [40,40] + # Tensor Mesh + tM = Mesh.TensorMesh(sz) + # Curvilinear Mesh + rM = Mesh.CurvilinearMesh(Utils.meshutils.exampleLrmGrid(sz,'rotate')) -# Step2: Direct Current (DC) operator -def DCfun(mesh, pts): - D = mesh.faceDiv - G = D.T - sigma = 1e-2*np.ones(mesh.nC) - Msigi = mesh.getFaceInnerProduct(1./sigma) - MsigI = Utils.sdInv(Msigi) - A = D*MsigI*G - A[-1,-1] /= mesh.vol[-1] # Remove null space - rhs = np.zeros(mesh.nC) - txind = Utils.meshutils.closestPoints(mesh, pts) - rhs[txind] = np.r_[1,-1] - return A, rhs + # Step2: Direct Current (DC) operator + def DCfun(mesh, pts): + D = mesh.faceDiv + G = D.T + sigma = 1e-2*np.ones(mesh.nC) + Msigi = mesh.getFaceInnerProduct(1./sigma) + MsigI = Utils.sdInv(Msigi) + A = D*MsigI*G + A[-1,-1] /= mesh.vol[-1] # Remove null space + rhs = np.zeros(mesh.nC) + txind = Utils.meshutils.closestPoints(mesh, pts) + rhs[txind] = np.r_[1,-1] + return A, rhs -pts = np.vstack((np.r_[0.25, 0.5], np.r_[0.75, 0.5])) + pts = np.vstack((np.r_[0.25, 0.5], np.r_[0.75, 0.5])) -#Step3: Solve DC problem (LU solver) -AtM, rhstM = DCfun(tM, pts) -AinvtM = SolverLU(AtM) -phitM = AinvtM*rhstM + #Step3: Solve DC problem (LU solver) + AtM, rhstM = DCfun(tM, pts) + AinvtM = SolverLU(AtM) + phitM = AinvtM*rhstM -ArM, rhsrM = DCfun(rM, pts) -AinvrM = SolverLU(ArM) -phirM = AinvrM*rhsrM + ArM, rhsrM = DCfun(rM, pts) + AinvrM = SolverLU(ArM) + phirM = AinvrM*rhsrM -#Step4: Making Figure -fig, axes = plt.subplots(1,2,figsize=(12*1.2,4*1.2)) -label = ["(a)", "(b)"] -opts = {} -vmin, vmax = phitM.min(), phitM.max() -dat = tM.plotImage(phitM, ax=axes[0], clim=(vmin, vmax), grid=True) + if not plotIt: return + #Step4: Making Figure + fig, axes = plt.subplots(1,2,figsize=(12*1.2,4*1.2)) + label = ["(a)", "(b)"] + opts = {} + vmin, vmax = phitM.min(), phitM.max() + dat = tM.plotImage(phitM, ax=axes[0], clim=(vmin, vmax), grid=True) -#TODO: At the moment Curvilinear Mesh do not have plotimage + #TODO: At the moment Curvilinear Mesh do not have plotimage -Xi = tM.gridCC[:,0].reshape(sz[0], sz[1], order='F') -Yi = tM.gridCC[:,1].reshape(sz[0], sz[1], order='F') -PHIrM = griddata(rM.gridCC[:,0], rM.gridCC[:,1], phirM, Xi, Yi, interp='linear') -axes[1].contourf(Xi, Yi, PHIrM, 100, vmin=vmin, vmax=vmax) + Xi = tM.gridCC[:,0].reshape(sz[0], sz[1], order='F') + Yi = tM.gridCC[:,1].reshape(sz[0], sz[1], order='F') + PHIrM = griddata(rM.gridCC[:,0], rM.gridCC[:,1], phirM, Xi, Yi, interp='linear') + axes[1].contourf(Xi, Yi, PHIrM, 100, vmin=vmin, vmax=vmax) -cb = plt.colorbar(dat[0], ax=axes[0]); cb.set_label("Voltage (V)") -cb = plt.colorbar(dat[0], ax=axes[1]); cb.set_label("Voltage (V)") + cb = plt.colorbar(dat[0], ax=axes[0]); cb.set_label("Voltage (V)") + cb = plt.colorbar(dat[0], ax=axes[1]); cb.set_label("Voltage (V)") -tM.plotGrid(ax=axes[0], **opts) -axes[0].set_title('TensorMesh') -rM.plotGrid(ax=axes[1], **opts) -axes[1].set_title('CurvilinearMesh') -for i in range(2): - axes[i].set_xlim(0.025, 0.975) - axes[i].set_ylim(0.025, 0.975) - axes[i].text(0., 1.0, label[i], fontsize=20) - if i==0: - axes[i].set_ylabel("y") - else: - axes[i].set_ylabel(" ") - axes[i].set_xlabel("x") + tM.plotGrid(ax=axes[0], **opts) + axes[0].set_title('TensorMesh') + rM.plotGrid(ax=axes[1], **opts) + axes[1].set_title('CurvilinearMesh') + for i in range(2): + axes[i].set_xlim(0.025, 0.975) + axes[i].set_ylim(0.025, 0.975) + axes[i].text(0., 1.0, label[i], fontsize=20) + if i==0: + axes[i].set_ylabel("y") + else: + axes[i].set_ylabel(" ") + axes[i].set_xlabel("x") -plt.show() + +if __name__ == '__main__': + run() diff --git a/SimPEG/Examples/__init__.py b/SimPEG/Examples/__init__.py index 2c5d0eac..3fec0b99 100644 --- a/SimPEG/Examples/__init__.py +++ b/SimPEG/Examples/__init__.py @@ -1 +1 @@ -import Linear +import Linear, DCfwd diff --git a/SimPEG/FLOW/Examples/Celia1990.py b/SimPEG/FLOW/Examples/Celia1990.py new file mode 100644 index 00000000..24ae82a6 --- /dev/null +++ b/SimPEG/FLOW/Examples/Celia1990.py @@ -0,0 +1,52 @@ +from SimPEG import * +from SimPEG.FLOW import Richards +import matplotlib.pyplot as plt + +def run(plotIt=True): + M = Mesh.TensorMesh([np.ones(40)]) + M.setCellGradBC('dirichlet') + params = Richards.Empirical.HaverkampParams().celia1990 + params['Ks'] = np.log(params['Ks']) + E = Richards.Empirical.Haverkamp(M, **params) + + bc = np.array([-61.5,-20.7]) + h = np.zeros(M.nC) + bc[0] + + + def getFields(timeStep,method): + timeSteps = np.ones(360/timeStep)*timeStep + prob = Richards.RichardsProblem(M, mapping=E, timeSteps=timeSteps, + boundaryConditions=bc, initialConditions=h, + doNewton=False, method=method) + return prob.fields(params['Ks']) + + Hs_M10 = getFields(10., 'mixed') + Hs_M30 = getFields(30., 'mixed') + Hs_M120= getFields(120.,'mixed') + Hs_H10 = getFields(10., 'head') + Hs_H30 = getFields(30., 'head') + Hs_H120= getFields(120.,'head') + + if not plotIt:return + plt.figure(figsize=(13,5)) + plt.subplot(121) + plt.plot(40-M.gridCC, Hs_M10[-1],'b-') + plt.plot(40-M.gridCC, Hs_M30[-1],'r-') + plt.plot(40-M.gridCC, Hs_M120[-1],'k-') + plt.ylim([-70,-10]) + plt.title('Mixed Method') + plt.xlabel('Depth, cm') + plt.ylabel('Pressure Head, cm') + plt.legend(('$\Delta t$ = 10 sec','$\Delta t$ = 30 sec','$\Delta t$ = 120 sec')) + plt.subplot(122) + plt.plot(40-M.gridCC, Hs_H10[-1],'b-') + plt.plot(40-M.gridCC, Hs_H30[-1],'r-') + plt.plot(40-M.gridCC, Hs_H120[-1],'k-') + plt.ylim([-70,-10]) + plt.title('Head-Based Method') + plt.xlabel('Depth, cm') + plt.ylabel('Pressure Head, cm') + plt.legend(('$\Delta t$ = 10 sec','$\Delta t$ = 30 sec','$\Delta t$ = 120 sec')) + +if __name__ == '__main__': + run() diff --git a/SimPEG/FLOW/Examples/__init__.py b/SimPEG/FLOW/Examples/__init__.py new file mode 100644 index 00000000..7a894e11 --- /dev/null +++ b/SimPEG/FLOW/Examples/__init__.py @@ -0,0 +1 @@ +import Celia1990 diff --git a/SimPEG/FLOW/Richards/Empirical.py b/SimPEG/FLOW/Richards/Empirical.py new file mode 100644 index 00000000..1bb163b5 --- /dev/null +++ b/SimPEG/FLOW/Richards/Empirical.py @@ -0,0 +1,578 @@ +from SimPEG import Mesh, Maps, Utils, np + + +class NonLinearMap(object): + """ + SimPEG NonLinearMap + + """ + + __metaclass__ = Utils.SimPEGMetaClass + + counter = None #: A SimPEG.Utils.Counter object + mesh = None #: A SimPEG Mesh + + def __init__(self, mesh): + self.mesh = mesh + + def _transform(self, u, m): + """ + :param numpy.array u: fields + :param numpy.array m: model + :rtype: numpy.array + :return: transformed model + + The *transform* changes the model into the physical property. + + """ + return m + + def derivU(self, u, m): + """ + :param numpy.array u: fields + :param numpy.array m: model + :rtype: scipy.csr_matrix + :return: derivative of transformed model + + The *transform* changes the model into the physical property. + The *transformDerivU* provides the derivative of the *transform* with respect to the fields. + """ + raise NotImplementedError('The transformDerivU is not implemented.') + + + def derivM(self, u, m): + """ + :param numpy.array u: fields + :param numpy.array m: model + :rtype: scipy.csr_matrix + :return: derivative of transformed model + + The *transform* changes the model into the physical property. + The *transformDerivU* provides the derivative of the *transform* with respect to the model. + """ + raise NotImplementedError('The transformDerivM is not implemented.') + + @property + def nP(self): + """Number of parameters in the model.""" + return self.mesh.nC + + def example(self): + raise NotImplementedError('The example is not implemented.') + + def test(self, m=None): + raise NotImplementedError('The test is not implemented.') + + +class RichardsMap(object): + """docstring for RichardsMap""" + + mesh = None #: SimPEG mesh + + @property + def thetaModel(self): + """Model for moisture content""" + return self._thetaModel + + @property + def kModel(self): + """Model for hydraulic conductivity""" + return self._kModel + + def __init__(self, mesh, thetaModel, kModel): + self.mesh = mesh + assert isinstance(thetaModel, NonLinearMap) + assert isinstance(kModel, NonLinearMap) + + self._thetaModel = thetaModel + self._kModel = kModel + + def theta(self, u, m): + return self.thetaModel.transform(u, m) + + def thetaDerivM(self, u, m): + return self.thetaModel.transformDerivM(u, m) + + def thetaDerivU(self, u, m): + return self.thetaModel.transformDerivU(u, m) + + def k(self, u, m): + return self.kModel.transform(u, m) + + def kDerivM(self, u, m): + return self.kModel.transformDerivM(u, m) + + def kDerivU(self, u, m): + return self.kModel.transformDerivU(u, m) + + def plot(self, m): + import matplotlib.pyplot as plt + + m = m[0] + h = np.linspace(-100, 20, 1000) + ax = plt.subplot(121) + ax.plot(self.theta(h, m), h) + ax = plt.subplot(122) + ax.semilogx(self.k(h, m), h) + + def _assertMatchesPair(self, pair): + assert isinstance(self, pair), "Mapping object must be an instance of a %s class."%(pair.__name__) + + + +def _ModelProperty(name, models, doc=None, default=None): + + def fget(self): + model = models[0] + if getattr(self, model, None) is not None: + MOD = getattr(self, model) + return getattr(MOD, name, default) + return default + + def fset(self, value): + for model in models: + if getattr(self, model, None) is not None: + MOD = getattr(self, model) + setattr(MOD, name, value) + + return property(fget, fset=fset, doc=doc) + + +class HaverkampParams(object): + """Holds some default parameterizations for the Haverkamp model.""" + def __init__(self): pass + @property + def celia1990(self): + """ + Parameters used in: + + Celia, Michael A., Efthimios T. Bouloutas, and Rebecca L. Zarba. + "A general mass-conservative numerical solution for the unsaturated flow equation." + Water Resources Research 26.7 (1990): 1483-1496. + + """ + return {'alpha':1.611e+06, 'beta':3.96, + 'theta_r':0.075, 'theta_s':0.287, + 'Ks':9.44e-03, 'A':1.175e+06, + 'gamma':4.74} + + +class _haverkamp_theta(NonLinearMap): + + theta_s = 0.430 + theta_r = 0.078 + alpha = 0.036 + beta = 3.960 + + def __init__(self, mesh, **kwargs): + NonLinearMap.__init__(self, mesh) + Utils.setKwargs(self, **kwargs) + + def setModel(self, m): + self._currentModel = m + + def transform(self, u, m): + self.setModel(m) + f = (self.alpha*(self.theta_s - self.theta_r )/ + (self.alpha + abs(u)**self.beta) + self.theta_r) + if Utils.isScalar(self.theta_s): + f[u >= 0] = self.theta_s + else: + f[u >= 0] = self.theta_s[u >= 0] + return f + + def transformDerivM(self, u, m): + self.setModel(m) + + def transformDerivU(self, u, m): + self.setModel(m) + g = (self.alpha*((self.theta_s - self.theta_r)/ + (self.alpha + abs(u)**self.beta)**2) + *(-self.beta*abs(u)**(self.beta-1)*np.sign(u))) + g[u >= 0] = 0 + g = Utils.sdiag(g) + return g + + +class _haverkamp_k(NonLinearMap): + + A = 1.175e+06 + gamma = 4.74 + Ks = np.log(24.96) + + def __init__(self, mesh, **kwargs): + NonLinearMap.__init__(self, mesh) + Utils.setKwargs(self, **kwargs) + + def setModel(self, m): + self._currentModel = m + #TODO: Fix me! + self.Ks = m + + def transform(self, u, m): + self.setModel(m) + f = np.exp(self.Ks)*self.A/(self.A+abs(u)**self.gamma) + if Utils.isScalar(self.Ks): + f[u >= 0] = np.exp(self.Ks) + else: + f[u >= 0] = np.exp(self.Ks[u >= 0]) + return f + + def transformDerivM(self, u, m): + self.setModel(m) + #A + # dA = np.exp(self.Ks)/(self.A+abs(u)**self.gamma) - np.exp(self.Ks)*self.A/(self.A+abs(u)**self.gamma)**2 + #gamma + # dgamma = -(self.A*np.exp(self.Ks)*np.log(abs(u))*abs(u)**self.gamma)/(self.A + abs(u)**self.gamma)**2 + + # This assumes that the the model is Ks + return Utils.sdiag(self.transform(u, m)) + + def transformDerivU(self, u, m): + self.setModel(m) + g = -(np.exp(self.Ks)*self.A*self.gamma*abs(u)**(self.gamma-1)*np.sign(u))/((self.A+abs(u)**self.gamma)**2) + g[u >= 0] = 0 + g = Utils.sdiag(g) + return g + +class Haverkamp(RichardsMap): + """Haverkamp Model""" + + alpha = _ModelProperty('alpha', ['thetaModel'], default=1.6110e+06) + beta = _ModelProperty('beta', ['thetaModel'], default=3.96) + theta_r = _ModelProperty('theta_r', ['thetaModel'], default=0.075) + theta_s = _ModelProperty('theta_s', ['thetaModel'], default=0.287) + + Ks = _ModelProperty('Ks', ['kModel'], default=np.log(24.96)) + A = _ModelProperty('A', ['kModel'], default=1.1750e+06) + gamma = _ModelProperty('gamma', ['kModel'], default=4.74) + + def __init__(self, mesh, **kwargs): + RichardsMap.__init__(self, mesh, + _haverkamp_theta(mesh), + _haverkamp_k(mesh)) + Utils.setKwargs(self, **kwargs) + + + + +class _vangenuchten_theta(NonLinearMap): + + theta_s = 0.430 + theta_r = 0.078 + alpha = 0.036 + n = 1.560 + + def __init__(self, mesh, **kwargs): + NonLinearMap.__init__(self, mesh) + Utils.setKwargs(self, **kwargs) + + def setModel(self, m): + self._currentModel = m + + def transform(self, u, m): + self.setModel(m) + m = 1 - 1.0/self.n + f = (( self.theta_s - self.theta_r )/ + ((1+abs(self.alpha*u)**self.n)**m) + self.theta_r) + if Utils.isScalar(self.theta_s): + f[u >= 0] = self.theta_s + else: + f[u >= 0] = self.theta_s[u >= 0] + + return f + + def transformDerivM(self, u, m): + self.setModel(m) + + def transformDerivU(self, u, m): + g = -self.alpha*self.n*abs(self.alpha*u)**(self.n - 1)*np.sign(self.alpha*u)*(1./self.n - 1)*(self.theta_r - self.theta_s)*(abs(self.alpha*u)**self.n + 1)**(1./self.n - 2) + g[u >= 0] = 0 + g = Utils.sdiag(g) + return g + + +class _vangenuchten_k(NonLinearMap): + + I = 0.500 + alpha = 0.036 + n = 1.560 + Ks = np.log(24.96) + + def __init__(self, mesh, **kwargs): + NonLinearMap.__init__(self, mesh) + Utils.setKwargs(self, **kwargs) + + def setModel(self, m): + self._currentModel = m + #TODO: Fix me! + self.Ks = m + + def transform(self, u, m): + self.setModel(m) + + alpha = self.alpha + I = self.I + n = self.n + Ks = self.Ks + m = 1.0 - 1.0/n + + theta_e = 1.0/((1.0+abs(alpha*u)**n)**m) + f = np.exp(Ks)*theta_e**I* ( ( 1.0 - ( 1.0 - theta_e**(1.0/m) )**m )**2 ) + if Utils.isScalar(self.Ks): + f[u >= 0] = np.exp(self.Ks) + else: + f[u >= 0] = np.exp(self.Ks[u >= 0]) + return f + + def transformDerivM(self, u, m): + self.setModel(m) +# #alpha +# # dA = I*u*n*np.exp(Ks)*abs(alpha*u)**(n - 1)*np.sign(alpha*u)*(1.0/n - 1)*((abs(alpha*u)**n + 1)**(1.0/n - 1))**(I - 1)*((1 - 1.0/((abs(alpha*u)**n + 1)**(1.0/n - 1))**(1.0/(1.0/n - 1)))**(1 - 1.0/n) - 1)**2*(abs(alpha*u)**n + 1)**(1.0/n - 2) - (2*u*n*np.exp(Ks)*abs(alpha*u)**(n - 1)*np.sign(alpha*u)*(1.0/n - 1)*((abs(alpha*u)**n + 1)**(1.0/n - 1))**I*((1 - 1.0/((abs(alpha*u)**n + 1)**(1.0/n - 1))**(1.0/(1.0/n - 1)))**(1 - 1.0/n) - 1)*(abs(alpha*u)**n + 1)**(1.0/n - 2))/(((abs(alpha*u)**n + 1)**(1.0/n - 1))**(1.0/(1.0/n - 1) + 1)*(1 - 1.0/((abs(alpha*u)**n + 1)**(1.0/n - 1))**(1.0/(1.0/n - 1)))**(1.0/n)); +# #n +# # dn = 2*np.exp(Ks)*((np.log(1 - 1.0/((abs(alpha*u)**n + 1)**(1.0/n - 1))**(1.0/(1.0/n - 1)))*(1 - 1.0/((abs(alpha*u)**n + 1)**(1.0/n - 1))**(1.0/(1.0/n - 1)))**(1 - 1.0/n))/n**2 + ((1.0/n - 1)*(((np.log(abs(alpha*u)**n + 1)*(abs(alpha*u)**n + 1)**(1.0/n - 1))/n**2 - abs(alpha*u)**n*np.log(abs(alpha*u))*(1.0/n - 1)*(abs(alpha*u)**n + 1)**(1.0/n - 2))/((1.0/n - 1)*((abs(alpha*u)**n + 1)**(1.0/n - 1))**(1.0/(1.0/n - 1) + 1)) - np.log((abs(alpha*u)**n + 1)**(1.0/n - 1))/(n**2*(1.0/n - 1)**2*((abs(alpha*u)**n + 1)**(1.0/n - 1))**(1.0/(1.0/n - 1)))))/(1 - 1.0/((abs(alpha*u)**n + 1)**(1.0/n - 1))**(1.0/(1.0/n - 1)))**(1.0/n))*((abs(alpha*u)**n + 1)**(1.0/n - 1))**I*((1 - 1.0/((abs(alpha*u)**n + 1)**(1.0/n - 1))**(1.0/(1.0/n - 1)))**(1 - 1.0/n) - 1) - I*np.exp(Ks)*((np.log(abs(alpha*u)**n + 1)*(abs(alpha*u)**n + 1)**(1.0/n - 1))/n**2 - abs(alpha*u)**n*np.log(abs(alpha*u))*(1.0/n - 1)*(abs(alpha*u)**n + 1)**(1.0/n - 2))*((abs(alpha*u)**n + 1)**(1.0/n - 1))**(I - 1)*((1 - 1.0/((abs(alpha*u)**n + 1)**(1.0/n - 1))**(1.0/(1.0/n - 1)))**(1 - 1.0/n) - 1)**2; +# #I +# # dI = np.exp(Ks)*np.log((abs(alpha*u)**n + 1)**(1.0/n - 1))*((abs(alpha*u)**n + 1)**(1.0/n - 1))**I*((1 - 1.0/((abs(alpha*u)**n + 1)**(1.0/n - 1))**(1.0/(1.0/n - 1)))**(1 - 1.0/n) - 1)**2; + return Utils.sdiag(self.transform(u, m)) # This assumes that the the model is Ks + + def transformDerivU(self, u, m): + self.setModel(m) + alpha = self.alpha + I = self.I + n = self.n + Ks = self.Ks + m = 1.0 - 1.0/n + + g = I*alpha*n*np.exp(Ks)*abs(alpha*u)**(n - 1.0)*np.sign(alpha*u)*(1.0/n - 1.0)*((abs(alpha*u)**n + 1)**(1.0/n - 1))**(I - 1)*((1 - 1.0/((abs(alpha*u)**n + 1)**(1.0/n - 1))**(1.0/(1.0/n - 1)))**(1 - 1.0/n) - 1)**2*(abs(alpha*u)**n + 1)**(1.0/n - 2) - (2*alpha*n*np.exp(Ks)*abs(alpha*u)**(n - 1)*np.sign(alpha*u)*(1.0/n - 1)*((abs(alpha*u)**n + 1)**(1.0/n - 1))**I*((1 - 1.0/((abs(alpha*u)**n + 1)**(1.0/n - 1))**(1.0/(1.0/n - 1)))**(1 - 1.0/n) - 1)*(abs(alpha*u)**n + 1)**(1.0/n - 2))/(((abs(alpha*u)**n + 1)**(1.0/n - 1))**(1.0/(1.0/n - 1) + 1)*(1 - 1.0/((abs(alpha*u)**n + 1)**(1.0/n - 1))**(1.0/(1.0/n - 1)))**(1.0/n)) + g[u >= 0] = 0 + g = Utils.sdiag(g) + return g + +class VanGenuchten(RichardsMap): + """vanGenuchten Model""" + + theta_r = _ModelProperty('theta_r', ['thetaModel'], default=0.075) + theta_s = _ModelProperty('theta_s', ['thetaModel'], default=0.287) + + alpha = _ModelProperty('alpha', ['thetaModel', 'kModel'], default=0.036) + n = _ModelProperty('n', ['thetaModel', 'kModel'], default=1.560) + + Ks = _ModelProperty('Ks', ['kModel'], default=np.log(24.96)) + I = _ModelProperty('I', ['kModel'], default=0.500) + + def __init__(self, mesh, **kwargs): + RichardsMap.__init__(self, mesh, + _vangenuchten_theta(mesh), + _vangenuchten_k(mesh)) + Utils.setKwargs(self, **kwargs) + + +class VanGenuchtenParams(object): + """ + The RETC code for quantifying the hydraulic functions of unsaturated soils, + Van Genuchten, M Th, Leij, F J, Yates, S R + + Table 3: Average values for selected soil water retention and hydraulic + conductivity parameters for 11 major soil textural groups + according to Rawls et al. [1982] + + """ + def __init__(self): pass + @property + def sand(self): + return {"theta_r": 0.020, "theta_s": 0.417, "alpha": 0.138*100., "n": 1.592, "Ks": 504.0/100./24./60./60.} + @property + def loamySand(self): + return {"theta_r": 0.035, "theta_s": 0.401, "alpha": 0.115*100., "n": 1.474, "Ks": 146.6/100./24./60./60.} + @property + def sandyLoam(self): + return {"theta_r": 0.041, "theta_s": 0.412, "alpha": 0.068*100., "n": 1.322, "Ks": 62.16/100./24./60./60.} + @property + def loam(self): + return {"theta_r": 0.027, "theta_s": 0.434, "alpha": 0.090*100., "n": 1.220, "Ks": 16.32/100./24./60./60.} + @property + def siltLoam(self): + return {"theta_r": 0.015, "theta_s": 0.486, "alpha": 0.048*100., "n": 1.211, "Ks": 31.68/100./24./60./60.} + @property + def sandyClayLoam(self): + return {"theta_r": 0.068, "theta_s": 0.330, "alpha": 0.036*100., "n": 1.250, "Ks": 10.32/100./24./60./60.} + @property + def clayLoam(self): + return {"theta_r": 0.075, "theta_s": 0.390, "alpha": 0.039*100., "n": 1.194, "Ks": 5.52/100./24./60./60.} + @property + def siltyClayLoam(self): + return {"theta_r": 0.040, "theta_s": 0.432, "alpha": 0.031*100., "n": 1.151, "Ks": 3.60/100./24./60./60.} + @property + def sandyClay(self): + return {"theta_r": 0.109, "theta_s": 0.321, "alpha": 0.034*100., "n": 1.168, "Ks": 2.88/100./24./60./60.} + @property + def siltyClay(self): + return {"theta_r": 0.056, "theta_s": 0.423, "alpha": 0.029*100., "n": 1.127, "Ks": 2.16/100./24./60./60.} + @property + def clay(self): + return {"theta_r": 0.090, "theta_s": 0.385, "alpha": 0.027*100., "n": 1.131, "Ks": 1.44/100./24./60./60.} + + + # From: INDIRECT METHODS FOR ESTIMATING THE HYDRAULIC PROPERTIES OF UNSATURATED SOILS + # @property + # def siltLoamGE3(self): + # """Soil Index: 3310""" + # return {"theta_r": 0.139, "theta_s": 0.394, "alpha": 0.00414, "n": 2.15} + # @property + # def yoloLightClayK_WC(self): + # """Soil Index: None""" + # return {"theta_r": 0.205, "theta_s": 0.499, "alpha": 0.02793, "n": 1.71} + # @property + # def yoloLightClayK_H(self): + # """Soil Index: None""" + # return {"theta_r": 0.205, "theta_s": 0.499, "alpha": 0.02793, "n": 1.71} + # @property + # def hygieneSandstone(self): + # """Soil Index: 4130""" + # return {"theta_r": 0.000, "theta_s": 0.256, "alpha": 0.00562, "n": 3.27} + # @property + # def lambcrgClay(self): + # """Soil Index: 1003""" + # return {"theta_r": 0.000, "theta_s": 0.502, "alpha": 0.140, "n": 1.93} + # @property + # def beitNetofaClaySoil(self): + # """Soil Index: 1006""" + # return {"theta_r": 0.000, "theta_s": 0.447, "alpha": 0.00156, "n": 1.17} + # @property + # def shiohotSiltyClay(self): + # """Soil Index: 1101""" + # return {"theta_r": 0.000, "theta_s": 0.456, "alpha": 183, "n":1.17} + # @property + # def siltColumbia(self): + # """Soil Index: 2001""" + # return {"theta_r": 0.146, "theta_s": 0.397, "alpha": 0.0145, "n": 1.85} + # @property + # def siltMontCenis(self): + # """Soil Index: 2002""" + # return {"theta_r": 0.000, "theta_s": 0.425, "alpha": 0.0103, "n": 1.34} + # @property + # def slateDust(self): + # """Soil Index: 2004""" + # return {"theta_r": 0.000, "theta_s": 0.498, "alpha": 0.00981, "n": 6.75} + # @property + # def weldSiltyClayLoam(self): + # """Soil Index: 3001""" + # return {"theta_r": 0.159, "theta_s": 0.496, "alpha": 0.0136, "n": 5.45} + # @property + # def rideauClayLoam_Wetting(self): + # """Soil Index: 3101a""" + # return {"theta_r": 0.279, "theta_s": 0.419, "alpha": 0.0661, "n": 1.89} + # @property + # def rideauClayLoam_Drying(self): + # """Soil Index: 3101b""" + # return {"theta_r": 0.290, "theta_s": 0.419, "alpha": 0.0177, "n": 3.18} + # @property + # def caribouSiltLoam_Drying(self): + # """Soil Index: 3301a""" + # return {"theta_r": 0.000, "theta_s": 0.451, "alpha": 0.00845, "n": 1.29} + # @property + # def caribouSiltLoam_Wetting(self): + # """Soil Index: 3301b""" + # return {"theta_r": 0.000, "theta_s": 0.450, "alpha": 0.140, "n": 1.09} + # @property + # def grenvilleSiltLoam_Wetting(self): + # """Soil Index: 3302a""" + # return {"theta_r": 0.013, "theta_s": 0523, "alpha": 0.0630, "n": 1.24} + # @property + # def grenvilleSiltLoam_Drying(self): + # """Soil Index: 3302c""" + # return {"theta_r": 0.000, "theta_s": 0.488, "alpha": 0.0112, "n": 1.23} + # @property + # def touchetSiltLoam(self): + # """Soil Index: 3304""" + # return {"theta_r": 0.183, "theta_s": 0.498, "alpha": 0.0104, "n": 5.78} + # @property + # def gilatLoam(self): + # """Soil Index: 3402a""" + # return {"theta_r": 0.000, "theta_s": 0.454, "alpha": 0.0291, "n": 1.47} + # @property + # def pachapaLoam(self): + # """Soil Index: 3403""" + # return {"theta_r": 0.000, "theta_s": 0.472, "alpha": 0.00829, "n": 1.62} + # @property + # def adelantoLoam(self): + # """Soil Index: 3404""" + # return {"theta_r": 0.000, "theta_s": 0.444, "alpha": 0.00710, "n": 1.26} + # @property + # def indioLoam(self): + # """Soil Index: 3405a""" + # return {"theta_r": 0.000, "theta_s": 0.507, "alpha": 0.00847, "n": 1.60} + # @property + # def guclphLoam(self): + # """Soil Index: 3407a""" + # return {"theta_r": 0.000, "theta_s": 0.563, "alpha": 0.0275, "n": 1.27} + # @property + # def guclphLoam(self): + # """Soil Index: 3407b""" + # return {"theta_r": 0.236, "theta_s": 0.435, "alpha": 0.0271, "n": 262} + # @property + # def rubiconSandyLoam(self): + # """Soil Index: 3501a""" + # return {"theta_r": 0.000, "theta_s": 0.393, "alpha": 0.00972, "n": 2.18} + # @property + # def rubiconSandyLoam(self): + # """Soil Index: 350lb""" + # return {"theta_r": 0.000, "theta_s": 0.433, "alpha": 0.147, "n": 1.28} + # @property + # def pachapaFmeSandyClay(self): + # """Soil Index: 3503a""" + # return {"theta_r": 0.000, "theta_s": 0.340, "alpha": 0.0194, "n": 1.45} + # @property + # def gilatSandyLoam(self): + # """Soil Index: 3504""" + # return {"theta_r": 0.000, "theta_s": 0.432, "alpha": 0.0103, "n": 1.48} + # @property + # def plainfieldSand_210to250(self): + # """Soil Index: 4101a""" + # return {"theta_r": 0.000, "theta_s": 0.351, "alpha": 0.0236, "n": 12.30} + # @property + # def plainfieldSand_210to250(self): + # """Soil Index: 4101b""" + # return {"theta_r": 0.000, "theta_s": 0.312, "alpha": 0.0387, "n": 4.48} + # @property + # def plainfieldSand_177to210(self): + # """Soil Index: 4102a""" + # return {"theta_r": 0.000, "theta_s": 0.361, "alpha": 0.0207, "n": 10.0} + # @property + # def plainfieldSand_177to210(self): + # """Soil Index: 4102b""" + # return {"theta_r": 0.022, "theta_s": 0.309, "alpha": 0.0328, "n": 6.23} + # @property + # def plainfieldSand_149to177(self): + # """Soil Index: 4103a""" + # return {"theta_r": 0.000, "theta_s": 0.387, "alpha": 0.0173, "n": 7.80} + # @property + # def plainfieldSand_149to177(self): + # """Soil Index: 4103b""" + # return {"theta_r": 0.025, "theta_s": 0.321, "alpha": 0.0272, "n": 6.69} + # @property + # def plainfieldSand_l25to149(self): + # """Soil Index: 4104a""" + # return {"theta_r": 0.000, "theta_s": 03770, "alpha": 0.0145, "n": 10.60} + # @property + # def plainfieldSand_125to149(self): + # """Soil Index: 4104b""" + # return {"theta_r": 0.000, "theta_s": 0.342, "alpha": 0.0230, "n": 5.18} + + +if __name__ == '__main__': + import matplotlib.pyplot as plt + M = Mesh.TensorMesh([10]) + VGparams = VanGenuchtenParams() + leg = [] + for p in dir(VGparams): + if p[0] == '_': continue + leg += [p] + params = getattr(VGparams, p) + model = VanGenuchten(M, **params) + ks = np.log(np.r_[params['Ks']]) + model.plot(ks) + + plt.legend(leg) + + plt.show() diff --git a/SimPEG/FLOW/Richards/RichardsProblem.py b/SimPEG/FLOW/Richards/RichardsProblem.py new file mode 100644 index 00000000..7c61c221 --- /dev/null +++ b/SimPEG/FLOW/Richards/RichardsProblem.py @@ -0,0 +1,304 @@ +from SimPEG import * +from Empirical import RichardsMap +import time + + +class RichardsRx(Survey.BaseTimeRx): + """Richards Receiver Object""" + + knownRxTypes = ['saturation','pressureHead'] + + def projectFields(self, U, m, mapping, mesh, timeMesh): + + if self.rxType == 'pressureHead': + u = np.concatenate(U) + elif self.rxType == 'saturation': + u = np.concatenate([mapping.theta(ui, m) for ui in U]) + + return self.getP(mesh, timeMesh) * u + + def projectFieldsDeriv(self, U, m, mapping, mesh, timeMesh): + + P = self.getP(mesh, timeMesh) + if self.rxType == 'pressureHead': + return P + elif self.rxType == 'saturation': + #TODO: if m is a parameter in the theta + # distribution, we may need to do + # some more chain rule here. + dT = sp.block_diag([mapping.thetaDerivU(ui, m) for ui in U]) + return P*dT + + +class RichardsSurvey(Survey.BaseSurvey): + """docstring for RichardsSurvey""" + + rxList = None + + def __init__(self, rxList, **kwargs): + self.rxList = rxList + Survey.BaseSurvey.__init__(self, **kwargs) + + @property + def nD(self): + return np.array([rx.nD for rx in self.rxList]).sum() + + @Utils.count + @Utils.requires('prob') + def dpred(self, m, u=None): + """ + Create the projected data from a model. + The field, u, (if provided) will be used for the predicted data + instead of recalculating the fields (which may be expensive!). + + .. math:: + d_\\text{pred} = P(u(m), m) + + Where P is a projection of the fields onto the data space. + """ + if u is None: u = self.prob.fields(m) + return Utils.mkvc(self.projectFields(u, m)) + + @Utils.requires('prob') + def projectFields(self, U, m): + Ds = range(len(self.rxList)) + for ii, rx in enumerate(self.rxList): + Ds[ii] = rx.projectFields(U, m, + self.prob.mapping, + self.prob.mesh, + self.prob.timeMesh) + + return np.concatenate(Ds) + + @Utils.requires('prob') + def projectFieldsDeriv(self, U, m): + """The Derivative with respect to the fields.""" + Ds = range(len(self.rxList)) + for ii, rx in enumerate(self.rxList): + Ds[ii] = rx.projectFieldsDeriv(U, m, + self.prob.mapping, + self.prob.mesh, + self.prob.timeMesh) + + return sp.vstack(Ds) + +class RichardsProblem(Problem.BaseTimeProblem): + """docstring for RichardsProblem""" + + boundaryConditions = None + initialConditions = None + + surveyPair = RichardsSurvey + mapPair = RichardsMap + + debug=True + + Solver = Solver + solverOpts = {} + + def __init__(self, mesh, mapping=None, **kwargs): + Problem.BaseTimeProblem.__init__(self, mesh, mapping=mapping, **kwargs) + + def getBoundaryConditions(self, ii, u_ii): + if type(self.boundaryConditions) is np.ndarray: + return self.boundaryConditions + + time = self.timeMesh.vectorCCx[ii] + + return self.boundaryConditions(time, u_ii) + + @property + def method(self): + """Method must be either 'mixed' or 'head'. See notes in Celia et al., 1990.""" + return getattr(self, '_method', 'mixed') + @method.setter + def method(self, value): + assert value in ['mixed','head'], "method must be 'mixed' or 'head'." + self._method = value + + # Setting doNewton will clear the rootFinder, which will be reinitialized when called + doNewton = Utils.dependentProperty('_doNewton', False, ['_rootFinder'], + "Do a Newton iteration. If False, a Picard iteration will be completed.") + + maxIterRootFinder = Utils.dependentProperty('_maxIterRootFinder', 30, ['_rootFinder'], + "Maximum iterations for rootFinder iteration.") + tolRootFinder = Utils.dependentProperty('_tolRootFinder', 1e-4, ['_rootFinder'], + "Maximum iterations for rootFinder iteration.") + + @property + def rootFinder(self): + """Root-finding Algorithm""" + if getattr(self, '_rootFinder', None) is None: + self._rootFinder = Optimization.NewtonRoot(doLS=self.doNewton, maxIter=self.maxIterRootFinder, tol=self.tolRootFinder, Solver=self.Solver) + return self._rootFinder + + @Utils.timeIt + def fields(self, m): + tic = time.time() + u = range(self.nT+1) + u[0] = self.initialConditions + for ii, dt in enumerate(self.timeSteps): + bc = self.getBoundaryConditions(ii, u[ii]) + u[ii+1] = self.rootFinder.root(lambda hn1m, return_g=True: self.getResidual(m, u[ii], hn1m, dt, bc, return_g=return_g), u[ii]) + if self.debug: print "Solving Fields (%4d/%d - %3.1f%% Done) %d Iterations, %4.2f seconds"%(ii+1, self.nT, 100.0*(ii+1)/self.nT, self.rootFinder.iter, time.time() - tic) + return u + + @Utils.timeIt + def diagsJacobian(self, m, hn, hn1, dt, bc): + + DIV = self.mesh.faceDiv + GRAD = self.mesh.cellGrad + BC = self.mesh.cellGradBC + AV = self.mesh.aveF2CC.T + if self.mesh.dim == 1: + Dz = self.mesh.faceDivx + elif self.mesh.dim == 2: + Dz = sp.hstack((Utils.spzeros(self.mesh.nC,self.mesh.vnF[0]), self.mesh.faceDivy),format='csr') + elif self.mesh.dim == 3: + Dz = sp.hstack((Utils.spzeros(self.mesh.nC,self.mesh.vnF[0]+self.mesh.vnF[1]), self.mesh.faceDivz),format='csr') + + dT = self.mapping.thetaDerivU(hn, m) + dT1 = self.mapping.thetaDerivU(hn1, m) + K1 = self.mapping.k(hn1, m) + dK1 = self.mapping.kDerivU(hn1, m) + dKm1 = self.mapping.kDerivM(hn1, m) + + # Compute part of the derivative of: + # + # DIV*diag(GRAD*hn1+BC*bc)*(AV*(1.0/K))^-1 + + DdiagGh1 = DIV*Utils.sdiag(GRAD*hn1+BC*bc) + diagAVk2_AVdiagK2 = Utils.sdiag((AV*(1./K1))**(-2)) * AV*Utils.sdiag(K1**(-2)) + + # The matrix that we are computing has the form: + # + # - - - - - - + # | Adiag | | h1 | | b1 | + # | Asub Adiag | | h2 | | b2 | + # | Asub Adiag | | h3 | = | b3 | + # | ... ... | | .. | | .. | + # | Asub Adiag | | hn | | bn | + # - - - - - - + + Asub = (-1.0/dt)*dT + + Adiag = ( + (1.0/dt)*dT1 + -DdiagGh1*diagAVk2_AVdiagK2*dK1 + -DIV*Utils.sdiag(1./(AV*(1./K1)))*GRAD + -Dz*diagAVk2_AVdiagK2*dK1 + ) + + B = DdiagGh1*diagAVk2_AVdiagK2*dKm1 + Dz*diagAVk2_AVdiagK2*dKm1 + + return Asub, Adiag, B + + @Utils.timeIt + def getResidual(self, m, hn, h, dt, bc, return_g=True): + """ + Where h is the proposed value for the next time iterate (h_{n+1}) + """ + DIV = self.mesh.faceDiv + GRAD = self.mesh.cellGrad + BC = self.mesh.cellGradBC + AV = self.mesh.aveF2CC.T + if self.mesh.dim == 1: + Dz = self.mesh.faceDivx + elif self.mesh.dim == 2: + Dz = sp.hstack((Utils.spzeros(self.mesh.nC,self.mesh.vnF[0]), self.mesh.faceDivy),format='csr') + elif self.mesh.dim == 3: + Dz = sp.hstack((Utils.spzeros(self.mesh.nC,self.mesh.vnF[0]+self.mesh.vnF[1]), self.mesh.faceDivz),format='csr') + + T = self.mapping.theta(h, m) + dT = self.mapping.thetaDerivU(h, m) + Tn = self.mapping.theta(hn, m) + K = self.mapping.k(h, m) + dK = self.mapping.kDerivU(h, m) + + aveK = 1./(AV*(1./K)) + + RHS = DIV*Utils.sdiag(aveK)*(GRAD*h+BC*bc) + Dz*aveK + if self.method == 'mixed': + r = (T-Tn)/dt - RHS + elif self.method == 'head': + r = dT*(h - hn)/dt - RHS + + if not return_g: return r + + J = dT/dt - DIV*Utils.sdiag(aveK)*GRAD + if self.doNewton: + DDharmAve = Utils.sdiag(aveK**2)*AV*Utils.sdiag(K**(-2)) * dK + J = J - DIV*Utils.sdiag(GRAD*h + BC*bc)*DDharmAve - Dz*DDharmAve + + return r, J + + @Utils.timeIt + def Jfull(self, m, u=None): + if u is None: + u = self.fields(m) + + nn = len(u)-1 + Asubs, Adiags, Bs = range(nn), range(nn), range(nn) + for ii in range(nn): + dt = self.timeSteps[ii] + bc = self.getBoundaryConditions(ii, u[ii]) + Asubs[ii], Adiags[ii], Bs[ii] = self.diagsJacobian(m, u[ii], u[ii+1], dt, bc) + Ad = sp.block_diag(Adiags) + zRight = Utils.spzeros((len(Asubs)-1)*Asubs[0].shape[0],Adiags[0].shape[1]) + zTop = Utils.spzeros(Adiags[0].shape[0], len(Adiags)*Adiags[0].shape[1]) + As = sp.vstack((zTop,sp.hstack((sp.block_diag(Asubs[1:]),zRight)))) + A = As + Ad + B = np.array(sp.vstack(Bs).todense()) + + Ainv = self.Solver(A, **self.solverOpts) + P = self.survey.projectFieldsDeriv(u, m) + AinvB = Ainv * B + z = np.zeros((self.mesh.nC, B.shape[1])) + zAinvB = np.vstack((z, AinvB)) + J = P * zAinvB + return J + + @Utils.timeIt + def Jvec(self, m, v, u=None): + if u is None: + u = self.fields(m) + + JvC = range(len(u)-1) # Cell to hold each row of the long vector. + + # This is done via forward substitution. + bc = self.getBoundaryConditions(0, u[0]) + temp, Adiag, B = self.diagsJacobian(m, u[0], u[1], self.timeSteps[0], bc) + Adiaginv = self.Solver(Adiag, **self.solverOpts) + JvC[0] = Adiaginv * (B*v) + + for ii in range(1,len(u)-1): + bc = self.getBoundaryConditions(ii, u[ii]) + Asub, Adiag, B = self.diagsJacobian(m, u[ii], u[ii+1], self.timeSteps[ii], bc) + Adiaginv = self.Solver(Adiag, **self.solverOpts) + JvC[ii] = Adiaginv * (B*v - Asub*JvC[ii-1]) + + P = self.survey.projectFieldsDeriv(u, m) + return P * np.concatenate([np.zeros(self.mesh.nC)] + JvC) + + @Utils.timeIt + def Jtvec(self, m, v, u=None): + if u is None: + u = self.field(m) + + P = self.survey.projectFieldsDeriv(u, m) + PTv = P.T*v + + # This is done via backward substitution. + minus = 0 + BJtv = 0 + for ii in range(len(u)-1,0,-1): + bc = self.getBoundaryConditions(ii-1, u[ii-1]) + Asub, Adiag, B = self.diagsJacobian(m, u[ii-1], u[ii], self.timeSteps[ii-1], bc) + #select the correct part of v + vpart = range((ii)*Adiag.shape[0], (ii+1)*Adiag.shape[0]) + AdiaginvT = self.Solver(Adiag.T, **self.solverOpts) + JTvC = AdiaginvT * (PTv[vpart] - minus) + minus = Asub.T*JTvC # this is now the super diagonal. + BJtv = BJtv + B.T*JTvC + + return BJtv diff --git a/SimPEG/FLOW/Richards/__init__.py b/SimPEG/FLOW/Richards/__init__.py new file mode 100644 index 00000000..6e25d292 --- /dev/null +++ b/SimPEG/FLOW/Richards/__init__.py @@ -0,0 +1,2 @@ +import Empirical +from RichardsProblem import * diff --git a/SimPEG/FLOW/__init__.py b/SimPEG/FLOW/__init__.py new file mode 100644 index 00000000..622d2f2f --- /dev/null +++ b/SimPEG/FLOW/__init__.py @@ -0,0 +1 @@ +import Richards diff --git a/SimPEG/Maps.py b/SimPEG/Maps.py index 6dca13dd..5b4782ac 100644 --- a/SimPEG/Maps.py +++ b/SimPEG/Maps.py @@ -1,7 +1,9 @@ import Utils, numpy as np, scipy.sparse as sp +from scipy.sparse.linalg import LinearOperator from Tests import checkDerivative from PropMaps import PropMap, Property - +from numpy.polynomial import polynomial +from scipy.interpolate import UnivariateSpline class IdentityMap(object): """ @@ -289,7 +291,7 @@ class FullMap(IdentityMap): """ FullMap - Given a scalar, the FullMap maps the value to the + Given a scalar, the FullMap maps the value to the full model space. """ @@ -314,8 +316,8 @@ class FullMap(IdentityMap): :rtype: numpy.array :return: derivative of transformed model """ - return np.ones([self.mesh.nC,1]) - + return np.ones([self.mesh.nC,1]) + class Vertical1DMap(IdentityMap): """Vertical1DMap @@ -469,11 +471,11 @@ class ActiveCells(IdentityMap): self.indActive = indActive self.indInactive = np.logical_not(indActive) if Utils.isScalar(valInactive): - valInactive = np.ones(self.nC)*float(valInactive) - - valInactive[self.indActive] = 0 - self.valInactive = valInactive - + self.valInactive = np.ones(self.nC)*float(valInactive) + else: + self.valInactive = valInactive.copy() + self.valInactive[self.indActive] = 0 + inds = np.nonzero(self.indActive)[0] self.P = sp.csr_matrix((np.ones(inds.size),(inds, range(inds.size))), shape=(self.nC, self.nP)) @@ -639,7 +641,7 @@ class ComplexMap(IdentityMap): return v[:nC] + v[nC:]*1j def adj(v): return np.r_[v.real,v.imag] - return Utils.SimPEGLinearOperator(shp,fwd,adj) + return LinearOperator(shp,matvec=fwd,rmatvec=adj) inverse = deriv @@ -696,4 +698,304 @@ class CircleMap(IdentityMap): g3 = a*(-X + x)*(-sig1 + sig2)/(np.pi*(a**2*(-r + np.sqrt((X - x)**2 + (Y - y)**2))**2 + 1)*np.sqrt((X - x)**2 + (Y - y)**2)) g4 = a*(-Y + y)*(-sig1 + sig2)/(np.pi*(a**2*(-r + np.sqrt((X - x)**2 + (Y - y)**2))**2 + 1)*np.sqrt((X - x)**2 + (Y - y)**2)) g5 = -a*(-sig1 + sig2)/(np.pi*(a**2*(-r + np.sqrt((X - x)**2 + (Y - y)**2))**2 + 1)) - return np.c_[g1,g2,g3,g4,g5] + return sp.csr_matrix(np.c_[g1,g2,g3,g4,g5]) + + +class PolyMap(IdentityMap): + + """PolyMap + + Parameterize the model space using a polynomials in a wholespace. + + ..math:: + + y = \mathbf{V} c + + Define the model as: + + ..math:: + + m = [\sigma_1, \sigma_2, c] + + """ + def __init__(self, mesh, order, logSigma=True, normal='X'): + IdentityMap.__init__(self, mesh) + self.logSigma = logSigma + self.order = order + self.normal = normal + + slope = 1e4 + + @property + def nP(self): + if np.isscalar(self.order): + nP = self.order+3 + else: + nP =(self.order[0]+1)*(self.order[1]+1)+2 + return nP + + def _transform(self, m): + # Set model parameters + alpha = self.slope + sig1,sig2 = m[0],m[1] + c = m[2:] + if self.logSigma: + sig1, sig2 = np.exp(sig1), np.exp(sig2) + #2D + if self.mesh.dim == 2: + X = self.mesh.gridCC[:,0] + Y = self.mesh.gridCC[:,1] + if self.normal =='X': + f = polynomial.polyval(Y, c) - X + elif self.normal =='Y': + f = polynomial.polyval(X, c) - Y + else: + raise(Exception("Input for normal = X or Y or Z")) + #3D + elif self.mesh.dim == 3: + X = self.mesh.gridCC[:,0] + Y = self.mesh.gridCC[:,1] + Z = self.mesh.gridCC[:,2] + if self.normal =='X': + f = polynomial.polyval2d(Y, Z, c.reshape((self.order[0]+1,self.order[1]+1))) - X + elif self.normal =='Y': + f = polynomial.polyval2d(X, Z, c.reshape((self.order[0]+1,self.order[1]+1))) - Y + elif self.normal =='Z': + f = polynomial.polyval2d(X, Y, c.reshape((self.order[0]+1,self.order[1]+1))) - Z + else: + raise(Exception("Input for normal = X or Y or Z")) + else: + raise(Exception("Only supports 2D")) + + + return sig1+(sig2-sig1)*(np.arctan(alpha*f)/np.pi+0.5) + + def deriv(self, m): + alpha = self.slope + sig1,sig2, c = m[0],m[1],m[2:] + if self.logSigma: + sig1, sig2 = np.exp(sig1), np.exp(sig2) + #2D + if self.mesh.dim == 2: + X = self.mesh.gridCC[:,0] + Y = self.mesh.gridCC[:,1] + + if self.normal =='X': + f = polynomial.polyval(Y, c) - X + V = polynomial.polyvander(Y, len(c)-1) + elif self.normal =='Y': + f = polynomial.polyval(X, c) - Y + V = polynomial.polyvander(X, len(c)-1) + else: + raise(Exception("Input for normal = X or Y or Z")) + #3D + elif self.mesh.dim == 3: + X = self.mesh.gridCC[:,0] + Y = self.mesh.gridCC[:,1] + Z = self.mesh.gridCC[:,2] + + if self.normal =='X': + f = polynomial.polyval2d(Y, Z, c.reshape((self.order[0]+1,self.order[1]+1))) - X + V = polynomial.polyvander2d(Y, Z, self.order) + elif self.normal =='Y': + f = polynomial.polyval2d(X, Z, c.reshape((self.order[0]+1,self.order[1]+1))) - Y + V = polynomial.polyvander2d(X, Z, self.order) + elif self.normal =='Z': + f = polynomial.polyval2d(X, Y, c.reshape((self.order[0]+1,self.order[1]+1))) - Z + V = polynomial.polyvander2d(X, Y, self.order) + else: + raise(Exception("Input for normal = X or Y or Z")) + + if self.logSigma: + g1 = -(np.arctan(alpha*f)/np.pi + 0.5)*sig1 + sig1 + g2 = (np.arctan(alpha*f)/np.pi + 0.5)*sig2 + else: + g1 = -(np.arctan(alpha*f)/np.pi + 0.5) + 1.0 + g2 = (np.arctan(alpha*f)/np.pi + 0.5) + + g3 = Utils.sdiag(alpha*(sig2-sig1)/(1.+(alpha*f)**2)/np.pi)*V + + return sp.csr_matrix(np.c_[g1,g2,g3]) + +class SplineMap(IdentityMap): + + """SplineMap + + Parameterize the boundary of two geological units using a spline interpolation + + ..math:: + + g = f(x)-y + + Define the model as: + + ..math:: + + m = [\sigma_1, \sigma_2, y] + + """ + def __init__(self, mesh, pts, ptsv=None,order=3, logSigma=True, normal='X'): + IdentityMap.__init__(self, mesh) + self.logSigma = logSigma + self.order = order + self.normal = normal + self.pts= pts + self.npts = np.size(pts) + self.ptsv = ptsv + self.spl = None + + slope = 1e4 + @property + def nP(self): + if self.mesh.dim == 2: + return np.size(self.pts)+2 + elif self.mesh.dim == 3: + return np.size(self.pts)*2+2 + else: + raise(Exception("Only supports 2D and 3D")) + + def _transform(self, m): + # Set model parameters + alpha = self.slope + sig1,sig2 = m[0],m[1] + c = m[2:] + if self.logSigma: + sig1, sig2 = np.exp(sig1), np.exp(sig2) + #2D + if self.mesh.dim == 2: + X = self.mesh.gridCC[:,0] + Y = self.mesh.gridCC[:,1] + self.spl = UnivariateSpline(self.pts, c, k=self.order, s=0) + if self.normal =='X': + f = self.spl(Y) - X + elif self.normal =='Y': + f = self.spl(X) - Y + else: + raise(Exception("Input for normal = X or Y or Z")) + + # 3D: + # Comments: + # Make two spline functions and link them using linear interpolation. + # This is not quite direct extension of 2D to 3D case + # Using 2D interpolation is possible + + elif self.mesh.dim == 3: + X = self.mesh.gridCC[:,0] + Y = self.mesh.gridCC[:,1] + Z = self.mesh.gridCC[:,2] + + npts = np.size(self.pts) + if np.mod(c.size, 2): + raise(Exception("Put even points!")) + + self.spl = {"splb":UnivariateSpline(self.pts, c[:npts], k=self.order, s=0), + "splt":UnivariateSpline(self.pts, c[npts:], k=self.order, s=0)} + + if self.normal =='X': + zb = self.ptsv[0] + zt = self.ptsv[1] + flines = (self.spl["splt"](Y)-self.spl["splb"](Y))*(Z-zb)/(zt-zb) + self.spl["splb"](Y) + f = flines - X + # elif self.normal =='Y': + # elif self.normal =='Z': + else: + raise(Exception("Input for normal = X or Y or Z")) + else: + raise(Exception("Only supports 2D and 3D")) + + + return sig1+(sig2-sig1)*(np.arctan(alpha*f)/np.pi+0.5) + + def deriv(self, m): + alpha = self.slope + sig1,sig2, c = m[0],m[1],m[2:] + if self.logSigma: + sig1, sig2 = np.exp(sig1), np.exp(sig2) + #2D + if self.mesh.dim == 2: + X = self.mesh.gridCC[:,0] + Y = self.mesh.gridCC[:,1] + + if self.normal =='X': + f = self.spl(Y) - X + elif self.normal =='Y': + f = self.spl(X) - Y + else: + raise(Exception("Input for normal = X or Y or Z")) + #3D + elif self.mesh.dim == 3: + X = self.mesh.gridCC[:,0] + Y = self.mesh.gridCC[:,1] + Z = self.mesh.gridCC[:,2] + if self.normal =='X': + zb = self.ptsv[0] + zt = self.ptsv[1] + flines = (self.spl["splt"](Y)-self.spl["splb"](Y))*(Z-zb)/(zt-zb) + self.spl["splb"](Y) + f = flines - X + # elif self.normal =='Y': + # elif self.normal =='Z': + else: + raise(Exception("Not Implemented for Y and Z, your turn :)")) + + if self.logSigma: + g1 = -(np.arctan(alpha*f)/np.pi + 0.5)*sig1 + sig1 + g2 = (np.arctan(alpha*f)/np.pi + 0.5)*sig2 + else: + g1 = -(np.arctan(alpha*f)/np.pi + 0.5) + 1.0 + g2 = (np.arctan(alpha*f)/np.pi + 0.5) + + + if self.mesh.dim ==2: + g3 = np.zeros((self.mesh.nC, self.npts)) + if self.normal =='Y': + # Here we use perturbation to compute sensitivity + # TODO: bit more generalization of this ... + # Modfications for X and Z directions ... + for i in range(np.size(self.pts)): + ctemp = c[i] + ind = np.argmin(abs(self.mesh.vectorCCy-ctemp)) + ca = c.copy() + cb = c.copy() + dy = self.mesh.hy[ind]*1.5 + ca[i] = ctemp+dy + cb[i] = ctemp-dy + spla = UnivariateSpline(self.pts, ca, k=self.order, s=0) + splb = UnivariateSpline(self.pts, cb, k=self.order, s=0) + fderiv = (spla(X)-splb(X))/(2*dy) + g3[:,i] = Utils.sdiag(alpha*(sig2-sig1)/(1.+(alpha*f)**2)/np.pi)*fderiv + + elif self.mesh.dim==3: + g3 = np.zeros((self.mesh.nC, self.npts*2)) + if self.normal =='X': + # Here we use perturbation to compute sensitivity + for i in range(self.npts*2): + ctemp = c[i] + ind = np.argmin(abs(self.mesh.vectorCCy-ctemp)) + ca = c.copy() + cb = c.copy() + dy = self.mesh.hy[ind]*1.5 + ca[i] = ctemp+dy + cb[i] = ctemp-dy + #treat bottom boundary + if i< self.npts: + splba = UnivariateSpline(self.pts, ca[:self.npts], k=self.order, s=0) + splbb = UnivariateSpline(self.pts, cb[:self.npts], k=self.order, s=0) + flinesa = (self.spl["splt"](Y)-splba(Y))*(Z-zb)/(zt-zb) + splba(Y) - X + flinesb = (self.spl["splt"](Y)-splbb(Y))*(Z-zb)/(zt-zb) + splbb(Y) - X + #treat top boundary + else: + splta = UnivariateSpline(self.pts, ca[self.npts:], k=self.order, s=0) + spltb = UnivariateSpline(self.pts, ca[self.npts:], k=self.order, s=0) + flinesa = (self.spl["splt"](Y)-splta(Y))*(Z-zb)/(zt-zb) + splta(Y) - X + flinesb = (self.spl["splt"](Y)-spltb(Y))*(Z-zb)/(zt-zb) + spltb(Y) - X + fderiv = (flinesa-flinesb)/(2*dy) + g3[:,i] = Utils.sdiag(alpha*(sig2-sig1)/(1.+(alpha*f)**2)/np.pi)*fderiv + else : + raise(Exception("Not Implemented for Y and Z, your turn :)")) + return sp.csr_matrix(np.c_[g1,g2,g3]) + + + + + + \ No newline at end of file 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/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 37bfea86..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. @@ -413,34 +416,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 d2d18972..1e6c91c0 100644 --- a/SimPEG/Mesh/TreeMesh.py +++ b/SimPEG/Mesh/TreeMesh.py @@ -1,26 +1,2224 @@ +# ___ ___ ___ ___ ___ +# /\ \ ___ /\__\ /\ \ /\ \ /\ \ +# /::\ \ /\ \ /::| | /::\ \ /::\ \ /::\ \ +# /:/\ \ \ \:\ \ /:|:| | /:/\:\ \ /:/\:\ \ /:/\:\ \ +# _\:\~\ \ \ /::\__\ /:/|:|__|__ /::\~\:\ \ /::\~\:\ \ /:/ \:\ \ +# /\ \:\ \ \__\ __/:/\/__//:/ |::::\__\/:/\:\ \:\__\/:/\:\ \:\__\/:/__/_\:\__\ +# \:\ \:\ \/__//\/:/ / \/__/~~/:/ /\/__\:\/:/ /\:\~\:\ \/__/\:\ /\ \/__/ +# \:\ \:\__\ \::/__/ /:/ / \::/ / \:\ \:\__\ \:\ \:\__\ +# \:\/:/ / \:\__\ /:/ / \/__/ \:\ \/__/ \:\/:/ / +# \::/ / \/__/ /:/ / \:\__\ \::/ / +# \/__/ \/__/ \/__/ \/__/ +# ___ ___ ___ ___ ___ ___ +# /\ \ /\ \ /\ \ /\ \ /\ \ /\ \ +# /::\ \ /::\ \ \:\ \ /::\ \ /::\ \ /::\ \ +# /:/\:\ \ /:/\:\ \ \:\ \ /:/\:\ \ /:/\:\ \ /:/\:\ \ +# /:/ \:\ \ /:/ \:\ \ /::\ \ /::\~\:\ \ /::\~\:\ \ /::\~\:\ \ +# /:/__/ \:\__\/:/__/ \:\__\ /:/\:\__\/:/\:\ \:\__\/:/\:\ \:\__\/:/\:\ \:\__\ +# \:\ \ /:/ /\:\ \ \/__//:/ \/__/\/_|::\/:/ /\:\~\:\ \/__/\:\~\:\ \/__/ +# \:\ /:/ / \:\ \ /:/ / |:|::/ / \:\ \:\__\ \:\ \:\__\ +# \:\/:/ / \:\ \ \/__/ |:|\/__/ \:\ \/__/ \:\ \/__/ +# \::/ / \:\__\ |:| | \:\__\ \:\__\ +# \/__/ \/__/ \|__| \/__/ \/__/ +# +# +# +# .----------------.----------------. +# /| /| /| +# / | / | / | +# / | 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 TensorMesh import TensorMesh, BaseTensorMesh +import time + +MAX_BITS = 20 + +class TreeMesh(BaseTensorMesh, InnerProducts): + + _meshType = 'TREE' + + 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." + + BaseTensorMesh.__init__(self, 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 + + 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.__dirtyCells__ or + self.__dirtyHanging__ or + self.__dirtySets__) + + @__dirty__.setter + def __dirty__(self, val): + assert val is True + self.__dirtyFaces__ = True + self.__dirtyEdges__ = True + self.__dirtyNodes__ = True + self.__dirtyCells__ = True + self.__dirtyHanging__ = True + self.__dirtySets__ = True + + deleteThese = [ + '__sortedCells', + '_gridCC', '_gridN', '_gridFx', '_gridFy', '_gridFz', '_gridEx', '_gridEy', '_gridEz', + '_area', '_edge', '_vol', + '_faceDiv', '_edgeCurl', '_nodalGrad', + '_aveFx2CC', '_aveFy2CC', '_aveFz2CC', '_aveF2CC', '_aveF2CCV', + '_aveEx2CC', '_aveEy2CC', '_aveEz2CC', '_aveE2CC', '_aveE2CCV', + '_aveN2CC', + ] + for p in deleteThese: + if hasattr(self, p): delattr(self, p) + + @property + def levels(self): return self._levels + + @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) + 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 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 vntF(self): + return [self.ntFx, self.ntFy] + ([] 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 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 + 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 type(function) in [int, long]: + level = function + function = lambda cell: level + + 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) + 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 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, 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 + + def _refineCell(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) + children = self._childPointers(pointer, returnAll=True) + for child in children: + self._cells.add(self._asIndex(child)) + self._cells.remove(ind) + return [self._asIndex(child) for child in children] + + 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] + + 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): + if pointer[-1] == 0: return None + 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) + self.x0 + return self._gridCC + + @property + def gridN(self): + self.number() + R = self._deflationMatrix('N', withHanging=False) + 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 + 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 + 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 + 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 + 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 + 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 + np.repeat([self.x0],self.nEz,axis=0) + + @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 _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() -def SortByX0(): + for ind in self._cells: + p = self._asPointer(ind) + w = self._levelWidth(p[-1]) + if self.dim == 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: + 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 _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) + 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._createNumberingSets(force=force) + + for ind in self._cells: + p = self._asPointer(ind) + w = self._levelWidth(p[-1]) + + 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._createNumberingSets(force=force) + + 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._numberCells(force=force) + 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]]) + + 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._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._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._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._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._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: + 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]]) + + 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._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._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._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._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._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 + 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]]) + + 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._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._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._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._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._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 + + 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','E','Ex','Ey'] + (['Fz','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) + 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) + 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): + 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): + 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: + 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 + + @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: + 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: + 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 + + @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 = [], [], [] + 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 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): + + # 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, 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') + 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 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', 'alpha':0.5}): + + 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 + 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): + """ + 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 +2235,124 @@ 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 TreeException(Exception): + pass +class NotBalancedException(TreeException): + pass +class CellLookUpException(TreeException): + pass if __name__ == '__main__': - M = TreeMesh([np.ones(x) for x in [4,10]]) - def function(xc): - r = xc - np.r_[2.,6.] + 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)) - if dist < 1.0: + # 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 5 + if dist < 0.2: + return 4 + if dist < 0.4: return 3 - if dist < 1.5: - return 2 - else: - return 1 + return 2 - M.refine(function) + # T = TreeMesh([[(1,128)],[(1,128)],[(1,128)]],levels=7) + # T = TreeMesh([128,128,128]) + # T = TreeMesh([64,64],levels=6) + 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]) + # 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.plotSlice(np.log(T.vol))#np.random.rand(T.nC)) + plt.show() + blah + + # T.plotImage(np.arange(len(T.vol)),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/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/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 diff --git a/SimPEG/Mesh/View.py b/SimPEG/Mesh/View.py index 38432d3c..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} ): """ @@ -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): diff --git a/SimPEG/Survey.py b/SimPEG/Survey.py index 0fdb0cd1..88355df1 100644 --- a/SimPEG/Survey.py +++ b/SimPEG/Survey.py @@ -367,7 +367,7 @@ 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) diff --git a/SimPEG/Tests/TestUtils.py b/SimPEG/Tests.py similarity index 91% rename from SimPEG/Tests/TestUtils.py rename to SimPEG/Tests.py index c6aa5bc4..6d414441 100644 --- a/SimPEG/Tests/TestUtils.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.TreeMesh import TreeMesh as Tree import numpy as np import scipy.sparse as sp import unittest @@ -132,6 +133,34 @@ 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 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 + 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(cell): + if 'notatree' in self._meshType: + return levels - 1 + r = cell.center - np.array([0.5]*len(cell.center)) + dist = np.sqrt(r.dot(r)) + if dist < 0.2: + 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/SimPEG/Tests/test_TreeMesh.py b/SimPEG/Tests/test_TreeMesh.py deleted file mode 100644 index 977392cb..00000000 --- a/SimPEG/Tests/test_TreeMesh.py +++ /dev/null @@ -1,505 +0,0 @@ -from SimPEG.Mesh import TensorMesh -from SimPEG.Mesh.TreeMesh import TreeMesh, TreeFace, TreeCell -import numpy as np -import unittest -import matplotlib.pyplot as plt - -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 - - 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 - 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) - - -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) - - 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() diff --git a/SimPEG/Utils/SolverUtils.py b/SimPEG/Utils/SolverUtils.py index 9c2f73ac..279d2b06 100644 --- a/SimPEG/Utils/SolverUtils.py +++ b/SimPEG/Utils/SolverUtils.py @@ -110,9 +110,10 @@ def SolverWrapI(fun, checkAccuracy=True, accuracyTol=1e-5): return type(fun.__name__+'_Wrapped', (object,), {"__init__": __init__, "clean": clean, "__mul__": __mul__}) -Solver = SolverWrapD(sp.linalg.spsolve, factorize=False) -SolverLU = SolverWrapD(sp.linalg.splu, factorize=True) -SolverCG = SolverWrapI(sp.linalg.cg) +from scipy.sparse import linalg +Solver = SolverWrapD(linalg.spsolve, factorize=False) +SolverLU = SolverWrapD(linalg.splu, factorize=True) +SolverCG = SolverWrapI(linalg.cg) class SolverDiag(object): diff --git a/SimPEG/Utils/__init__.py b/SimPEG/Utils/__init__.py index 6637a138..5280ae79 100644 --- a/SimPEG/Utils/__init__.py +++ b/SimPEG/Utils/__init__.py @@ -7,4 +7,4 @@ from ipythonutils import easyAnimate as animate from CounterUtils import * import ModelBuilder import SolverUtils - +from coordutils import * diff --git a/SimPEG/Utils/codeutils.py b/SimPEG/Utils/codeutils.py index 0ba57b2e..4a9a28a7 100644 --- a/SimPEG/Utils/codeutils.py +++ b/SimPEG/Utils/codeutils.py @@ -3,10 +3,7 @@ import time import numpy as np from functools import wraps - -class SimPEGMetaClass(type): - def __new__(cls, name, bases, attrs): - return super(SimPEGMetaClass, cls).__new__(cls, name, bases, attrs) +SimPEGMetaClass = type def memProfileWrapper(towrap, *funNames): """ diff --git a/SimPEG/Utils/coordutils.py b/SimPEG/Utils/coordutils.py new file mode 100644 index 00000000..260e1a3b --- /dev/null +++ b/SimPEG/Utils/coordutils.py @@ -0,0 +1,62 @@ +import numpy as np +from SimPEG.Utils import mkvc + +def rotationMatrixFromNormals(v0,v1,tol=1e-20): + """ + Performs the minimum number of rotations to define a rotation from the direction indicated by the vector n0 to the direction indicated by n1. + The axis of rotation is n0 x n1 + https://en.wikipedia.org/wiki/Rodrigues%27_rotation_formula + + :param numpy.array v0: vector of length 3 + :param numpy.array v1: vector of length 3 + :param tol = 1e-20: tolerance. If the norm of the cross product between the two vectors is below this, no rotation is performed + :rtype: numpy.array, 3x3 + :return: rotation matrix which rotates the frame so that n0 is aligned with n1 + + """ + + # ensure both n0, n1 are vectors of length 1 + assert len(v0) == 3, "Length of n0 should be 3" + assert len(v1) == 3, "Length of n1 should be 3" + + # ensure both are true normals + n0 = v0*1./np.linalg.norm(v0) + n1 = v1*1./np.linalg.norm(v1) + + n0dotn1 = n0.dot(n1) + + # define the rotation axis, which is the cross product of the two vectors + rotAx = np.cross(n0,n1) + + if np.linalg.norm(rotAx) < tol: + return np.eye(3,dtype=float) + + rotAx *= 1./np.linalg.norm(rotAx) + + cosT = n0dotn1/(np.linalg.norm(n0)*np.linalg.norm(n1)) + sinT = np.sqrt(1.-n0dotn1**2) + + ux = np.array([[0., -rotAx[2], rotAx[1]], [rotAx[2], 0., -rotAx[0]], [-rotAx[1], rotAx[0], 0.]],dtype=float) + + return np.eye(3,dtype=float) + sinT*ux + (1.-cosT)*(ux.dot(ux)) + + +def rotatePointsFromNormals(XYZ,n0,n1,x0=np.r_[0.,0.,0.]): + """ + rotates a grid so that the vector n0 is aligned with the vector n1 + + :param numpy.array n0: vector of length 3, should have norm 1 + :param numpy.array n1: vector of length 3, should have norm 1 + :param numpy.array x0: vector of length 3, point about which we perform the rotation + :rtype: numpy.array, 3x3 + :return: rotation matrix which rotates the frame so that n0 is aligned with n1 + """ + + R = rotationMatrixFromNormals(n0, n1) + + assert XYZ.shape[1] == 3, "Grid XYZ should be 3 wide" + assert len(x0) == 3, "x0 should have length 3" + + X0 = np.ones([XYZ.shape[0],1])*mkvc(x0) + + return (XYZ - X0).dot(R.T) + X0 # equivalent to (R*(XYZ - X0)).T + X0 \ No newline at end of file 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 new file mode 100644 index 00000000..d03d682c --- /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_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); + __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_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;} + __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_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_y1), + * ( ind_x1, ind_y2), # <<<<<<<<<<<<<< + * ( 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_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_y1), + * ( ind_x1, ind_y2), + * ( 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_y2), + * ( ind_x2, ind_y1), + * ( ind_x2, ind_y2)] # <<<<<<<<<<<<<< + * + * 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); + __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_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;} + __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*wy1, wx1*wy2, wx2*wy1, wx2*wy2] # <<<<<<<<<<<<<< + * + * return inds, vals + */ + __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_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); + __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*wy1, wx1*wy2, 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_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); + __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_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;} + __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_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_y1, ind_z1), + * ( ind_x1, ind_y2, 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_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_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), + */ + __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_y2, 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*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); + __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_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;} + __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*wy1*wz1, # <<<<<<<<<<<<<< + * wx1*wy2*wz1, + * wx2*wy1*wz1, + */ + __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); + __Pyx_DECREF(__pyx_t_19); __pyx_t_19 = 0; + + /* "SimPEG/Utils/interputils_cython.pyx":111 + * + * vals += [wx1*wy1*wz1, + * wx1*wy2*wz1, # <<<<<<<<<<<<<< + * wx2*wy1*wz1, + * wx2*wy2*wz1, + */ + __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*wy1*wz1, + * wx1*wy2*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*wy2*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*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;} + __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/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/SimPEG/Utils/matutils.py b/SimPEG/Utils/matutils.py index e4ab5700..ee58bf86 100644 --- a/SimPEG/Utils/matutils.py +++ b/SimPEG/Utils/matutils.py @@ -342,10 +342,10 @@ def invPropertyTensor(M, tensor, returnMatrix=False): def diagEst(matFun, n, k=None, approach='Probing'): - """ + """ Estimate the diagonal of a matrix, A. Note that the matrix may be a function which returns A times a vector. - Three different approaches have been implemented, + Three different approaches have been implemented, 1. Probing : uses cyclic permutations of vectors with ones and zeros (default) 2. Ones : random +/- 1 entries 3. Random : random vectors @@ -362,7 +362,7 @@ def diagEst(matFun, n, k=None, approach='Probing'): if type(matFun).__name__=='ndarray': A = matFun - matFun = lambda v: A.dot(v) + matFun = lambda v: A.dot(v) if k is None: k = np.floor(n/10.) @@ -396,11 +396,60 @@ def diagEst(matFun, n, k=None, approach='Probing'): return d +class Zero(object): + def __add__(self, v):return v + def __radd__(self, v):return v + def __sub__(self, v):return -v + def __rsub__(self, v):return v + def __mul__(self, v):return self + def __rmul__(self, v):return self + def __div__(self, v): return self + def __truediv__(self, v): return self + def __rdiv__(self, v): raise ZeroDivisionError('Cannot divide by zero.') + def __pos__(self):return self + def __neg__(self):return self + def __lt__(self, v):return 0 < v + def __le__(self, v):return 0 <= v + def __eq__(self, v):return v == 0 + def __ne__(self, v):return not (0 == v) + def __ge__(self, v):return 0 >= v + def __gt__(self, v):return 0 > v + +class Identity(object): + _positive = True + def __init__(self, positive=True): + self._positive = positive is True + + def __pos__(self):return self + def __neg__(self):return Identity(not self._positive) + + def __add__(self, v): + if sp.issparse(v): + return v + speye(v.shape[0]) if self._positive else v - speye(v.shape[0]) + return v + 1 if self._positive else v - 1 + def __radd__(self, v): + return self.__add__(v) + + def __sub__(self, v): return self+-v + def __rsub__(self, v):return -self+v + + def __mul__(self, v): return v if self._positive else -v + def __rmul__(self, v):return v if self._positive else -v + + def __div__(self, v): + if sp.issparse(v): raise NotImplementedError('Sparse arrays not divisibile.') + return 1/v if self._positive else -1/v + def __truediv__(self, v): + if sp.issparse(v): raise NotImplementedError('Sparse arrays not divisibile.') + return 1.0/v if self._positive else -1.0/v + def __rdiv__(self, v): + return v if self._positive else -v + + def __lt__(self, v):return 1 < v if self._positive else -1 < v + def __le__(self, v):return 1 <= v if self._positive else -1 <= v + def __eq__(self, v):return v == 1 if self._positive else v == -1 + def __ne__(self, v):return (not (1 == v))if self._positive else (not (-1 == v)) + def __ge__(self, v):return 1 >= v if self._positive else -1 >= v + def __gt__(self, v):return 1 > v if self._positive else -1 > v -from scipy.sparse.linalg import LinearOperator -class SimPEGLinearOperator(LinearOperator): - """Extends scipy.sparse.linalg.LinearOperator to have a .T function.""" - @property - def T(self): - return self.__class__((self.shape[1],self.shape[0]),self.rmatvec,rmatvec=self.matvec,matmat=self.matmat) 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] 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' + +cython_files = [ + "SimPEG/Utils/interputils_cython", + "SimPEG/Mesh/TreeUtils" + ] +extensions = [Extension(f, [f+ext]) for f in cython_files] + +if USE_CYTHON and "cleanall" not in args: + from Cython.Build import cythonize + extensions = cythonize(extensions) + import os, os.path with open("README.rst") as f: @@ -36,7 +79,8 @@ setup( version = "0.1.3", packages = find_packages(), install_requires = ['numpy>=1.7', - 'scipy>=0.13' + 'scipy>=0.13', + 'Cython' ], author = "Rowan Cockett", author_email = "rowan@3ptscience.com", @@ -50,5 +94,6 @@ 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 = extensions, + **cythonKwargs ) diff --git a/SimPEG/Tests/__init__.py b/tests/__init__.py similarity index 83% rename from SimPEG/Tests/__init__.py rename to tests/__init__.py index 32112042..38d84328 100644 --- a/SimPEG/Tests/__init__.py +++ b/tests/__init__.py @@ -1,6 +1,3 @@ -from TestUtils import checkDerivative, Rosenbrock, OrderTest, getQuadratic - - if __name__ == '__main__': import os import glob diff --git a/tests/base/__init__.py b/tests/base/__init__.py new file mode 100644 index 00000000..38d84328 --- /dev/null +++ b/tests/base/__init__.py @@ -0,0 +1,11 @@ +if __name__ == '__main__': + import os + import glob + import unittest + test_file_strings = glob.glob('test_*.py') + module_strings = [str[0:len(str)-3] for str in test_file_strings] + suites = [unittest.defaultTestLoader.loadTestsFromName(str) for str + in module_strings] + testSuite = unittest.TestSuite(suites) + + unittest.TextTestRunner(verbosity=2).run(testSuite) diff --git a/SimPEG/Tests/test_Fields.py b/tests/base/test_Fields.py similarity index 100% rename from SimPEG/Tests/test_Fields.py rename to tests/base/test_Fields.py diff --git a/SimPEG/Tests/test_PropMaps.py b/tests/base/test_PropMaps.py similarity index 94% rename from SimPEG/Tests/test_PropMaps.py rename to tests/base/test_PropMaps.py index b4c0eb8d..ef22aaad 100644 --- a/SimPEG/Tests/test_PropMaps.py +++ b/tests/base/test_PropMaps.py @@ -8,9 +8,9 @@ class MyPropMap(Maps.PropMap): mu = Maps.Property("Mu", defaultVal=mu_0) class MyReciprocalPropMap(Maps.PropMap): - sigma = Maps.Property("Electrical Conductivity", defaultInvProp=True, propertyLink=('rho', Maps.ReciprocalMap)) - rho = Maps.Property("Electrical Resistivity", propertyLink=('sigma', Maps.ReciprocalMap)) - mu = Maps.Property("Mu", defaultVal=mu_0, propertyLink=('mui', Maps.ReciprocalMap)) + sigma = Maps.Property("Electrical Conductivity", defaultInvProp=True, propertyLink=('rho', Maps.ReciprocalMap)) + rho = Maps.Property("Electrical Resistivity", propertyLink=('sigma', Maps.ReciprocalMap)) + mu = Maps.Property("Mu", defaultVal=mu_0, propertyLink=('mui', Maps.ReciprocalMap)) mui = Maps.Property("Mu", defaultVal=1./mu_0, propertyLink=('mu', Maps.ReciprocalMap)) diff --git a/SimPEG/Tests/test_Solver.py b/tests/base/test_Solver.py similarity index 100% rename from SimPEG/Tests/test_Solver.py rename to tests/base/test_Solver.py diff --git a/SimPEG/Tests/test_SurveyAndData.py b/tests/base/test_SurveyAndData.py similarity index 100% rename from SimPEG/Tests/test_SurveyAndData.py rename to tests/base/test_SurveyAndData.py diff --git a/SimPEG/Tests/test_maps.py b/tests/base/test_maps.py similarity index 99% rename from SimPEG/Tests/test_maps.py rename to tests/base/test_maps.py index a4ebd80c..623f8715 100644 --- a/SimPEG/Tests/test_maps.py +++ b/tests/base/test_maps.py @@ -1,7 +1,6 @@ import numpy as np import unittest from SimPEG import * -from TestUtils import checkDerivative from scipy.sparse.linalg import dsolve TOL = 1e-14 diff --git a/SimPEG/Tests/test_optimizers.py b/tests/base/test_optimizers.py similarity index 100% rename from SimPEG/Tests/test_optimizers.py rename to tests/base/test_optimizers.py diff --git a/SimPEG/Tests/test_problem.py b/tests/base/test_problem.py similarity index 100% rename from SimPEG/Tests/test_problem.py rename to tests/base/test_problem.py diff --git a/SimPEG/Tests/test_regularization.py b/tests/base/test_regularization.py similarity index 74% rename from SimPEG/Tests/test_regularization.py rename to tests/base/test_regularization.py index 48846d2f..af7da692 100644 --- a/SimPEG/Tests/test_regularization.py +++ b/tests/base/test_regularization.py @@ -1,7 +1,6 @@ import numpy as np import unittest from SimPEG import * -from TestUtils import checkDerivative from scipy.sparse.linalg import dsolve import inspect @@ -18,12 +17,16 @@ class RegularizationTests(unittest.TestCase): if not issubclass(r, Regularization.BaseRegularization): continue # if 'Regularization' not in R: continue - print 'Check:', R mapping = r.mapPair(self.mesh2) reg = r(self.mesh2, mapping=mapping) m = np.random.rand(mapping.nP) reg.mref = m[:]*np.mean(m) - passed = checkDerivative(lambda m : [reg.eval(m), reg.evalDeriv(m)], m, plotIt=False) + + print 'Check:', R + passed = Tests.checkDerivative(lambda m : [reg.eval(m), reg.evalDeriv(m)], m, plotIt=False) + self.assertTrue(passed) + print 'Check 2 Deriv:', R + passed = Tests.checkDerivative(lambda m : [reg.evalDeriv(m), reg.eval2Deriv(m)], m, plotIt=False) self.assertTrue(passed) diff --git a/tests/em/examples/__init__.py b/tests/em/examples/__init__.py new file mode 100644 index 00000000..38d84328 --- /dev/null +++ b/tests/em/examples/__init__.py @@ -0,0 +1,11 @@ +if __name__ == '__main__': + import os + import glob + import unittest + test_file_strings = glob.glob('test_*.py') + module_strings = [str[0:len(str)-3] for str in test_file_strings] + suites = [unittest.defaultTestLoader.loadTestsFromName(str) for str + in module_strings] + testSuite = unittest.TestSuite(suites) + + unittest.TextTestRunner(verbosity=2).run(testSuite) diff --git a/tests/em/examples/test_Examples.py b/tests/em/examples/test_Examples.py new file mode 100644 index 00000000..5a601d3b --- /dev/null +++ b/tests/em/examples/test_Examples.py @@ -0,0 +1,10 @@ +import unittest, os +from SimPEG.EM import Examples + +class EM_ExamplesRunning(unittest.TestCase): + + def test_CylInversion(self): + Examples.CylInversion.run(plotIt=False) + +if __name__ == '__main__': + unittest.main() diff --git a/tests/em/fdem/forward/__init__.py b/tests/em/fdem/forward/__init__.py new file mode 100644 index 00000000..38d84328 --- /dev/null +++ b/tests/em/fdem/forward/__init__.py @@ -0,0 +1,11 @@ +if __name__ == '__main__': + import os + import glob + import unittest + test_file_strings = glob.glob('test_*.py') + module_strings = [str[0:len(str)-3] for str in test_file_strings] + suites = [unittest.defaultTestLoader.loadTestsFromName(str) for str + in module_strings] + testSuite = unittest.TestSuite(suites) + + unittest.TextTestRunner(verbosity=2).run(testSuite) diff --git a/tests/em/fdem/forward/test_FDEM_analytics.py b/tests/em/fdem/forward/test_FDEM_analytics.py new file mode 100644 index 00000000..9786e7c8 --- /dev/null +++ b/tests/em/fdem/forward/test_FDEM_analytics.py @@ -0,0 +1,243 @@ +import unittest +from SimPEG import * +from SimPEG import EM +from scipy.constants import mu_0 + +plotIt = False +tol_EBdipole = 1e-2 + +if plotIt: + import matplotlib.pylab + + +class FDEM_analyticTests(unittest.TestCase): + + def setUp(self): + + cs = 10. + ncx, ncy, ncz = 10, 10, 10 + npad = 4 + freq = 1e2 + + hx = [(cs,npad,-1.3), (cs,ncx), (cs,npad,1.3)] + hy = [(cs,npad,-1.3), (cs,ncy), (cs,npad,1.3)] + hz = [(cs,npad,-1.3), (cs,ncz), (cs,npad,1.3)] + mesh = Mesh.TensorMesh([hx,hy,hz], 'CCC') + + mapping = Maps.ExpMap(mesh) + + x = np.linspace(-10,10,5) + XYZ = Utils.ndgrid(x,np.r_[0],np.r_[0]) + rxList = EM.FDEM.Rx(XYZ, 'exi') + Src0 = EM.FDEM.Src.MagDipole([rxList],loc=np.r_[0.,0.,0.], freq=freq) + + survey = EM.FDEM.Survey([Src0]) + + prb = EM.FDEM.Problem_b(mesh, mapping=mapping) + prb.pair(survey) + + try: + from pymatsolver import MumpsSolver + prb.Solver = MumpsSolver + except ImportError, e: + prb.Solver = SolverLU + + sig = 1e-1 + sigma = np.ones(mesh.nC)*sig + sigma[mesh.gridCC[:,2] > 0] = 1e-8 + m = np.log(sigma) + + self.prb = prb + self.mesh = mesh + self.m = m + self.Src0 = Src0 + self.sig = sig + + def test_Transect(self): + print 'Testing Transect for analytic' + + u = self.prb.fields(self.m) + + bfz = self.mesh.r(u[self.Src0, 'b'],'F','Fz','M') + x = np.linspace(-55,55,12) + XYZ = Utils.ndgrid(x,np.r_[0],np.r_[0]) + + P = self.mesh.getInterpolationMat(XYZ, 'Fz') + + an = EM.Analytics.FDEM.hzAnalyticDipoleF(x, self.Src0.freq, self.sig) + + diff = np.log10(np.abs(P*np.imag(u[self.Src0, 'b']) - mu_0*np.imag(an))) + + if plotIt: + import matplotlib.pyplot as plt + plt.plot(x,np.log10(np.abs(P*np.imag(u[self.Src0, 'b'])))) + plt.plot(x,np.log10(np.abs(mu_0*np.imag(an))), 'r') + plt.plot(x,diff,'g') + plt.show() + + # We want the difference to be an orderMag less + # than the analytic solution. Note that right at + # the source, both the analytic and the numerical + # solution will be poor. Use plotIt up top to see that... + orderMag = 1.6 + passed = np.abs(np.mean(diff - np.log10(np.abs(mu_0*np.imag(an))))) > orderMag + self.assertTrue(passed) + + + def test_CylMeshEBDipoles(self): + print 'Testing CylMesh Electric and Magnetic Dipoles in a wholespace- Analytic: J-formulation' + sigmaback = 1. + mur = 2. + freq = 1. + skdpth = 500./np.sqrt(sigmaback*freq) + + csx, ncx, npadx = 5, 50, 25 + csz, ncz, npadz = 5, 50, 25 + hx = Utils.meshTensor([(csx,ncx), (csx,npadx,1.3)]) + hz = Utils.meshTensor([(csz,npadz,-1.3), (csz,ncz), (csz,npadz,1.3)]) + mesh = Mesh.CylMesh([hx,1,hz], [0.,0.,-hz.sum()/2]) # define the cylindrical mesh + + if plotIt: + mesh.plotGrid() + + # make sure mesh is big enough + self.assertTrue(mesh.hz.sum() > skdpth*2.) + self.assertTrue(mesh.hx.sum() > skdpth*2.) + + SigmaBack = sigmaback*np.ones((mesh.nC)) + MuBack = mur*mu_0*np.ones((mesh.nC)) + + # set up source + # test electric dipole + src_loc = np.r_[0.,0.,0.] + s_ind = Utils.closestPoints(mesh,src_loc,'Fz') + mesh.nFx + + de = np.zeros(mesh.nF,dtype=complex) + de[s_ind] = 1./csz + de_p = [EM.FDEM.Src.RawVec_e([],freq,de/mesh.area)] + + dm_p = [EM.FDEM.Src.MagDipole([],freq,src_loc)] + + + # Pair the problem and survey + surveye = EM.FDEM.Survey(de_p) + surveym = EM.FDEM.Survey(dm_p) + + mapping = [('sigma', Maps.IdentityMap(mesh)),('mu', Maps.IdentityMap(mesh))] + + prbe = EM.FDEM.Problem_h(mesh, mapping=mapping) + prbm = EM.FDEM.Problem_e(mesh, mapping=mapping) + + prbe.pair(surveye) # pair problem and survey + prbm.pair(surveym) + + # solve + fieldsBackE = prbe.fields(np.r_[SigmaBack, MuBack]) # Done + fieldsBackM = prbm.fields(np.r_[SigmaBack, MuBack]) # Done + + + rlim = [20.,500.] + lookAtTx = de_p + r = mesh.vectorCCx[np.argmin(np.abs(mesh.vectorCCx-rlim[0])):np.argmin(np.abs(mesh.vectorCCx-rlim[1]))] + z = 100. + + # where we choose to measure + XYZ = Utils.ndgrid(r, np.r_[0.], np.r_[z]) + + Pf = mesh.getInterpolationMat(XYZ, 'CC') + Zero = sp.csr_matrix(Pf.shape) + Pfx,Pfz = sp.hstack([Pf,Zero]),sp.hstack([Zero,Pf]) + + jn = fieldsBackE[de_p,'j'] + bn = fieldsBackM[dm_p,'b'] + + Rho = Utils.sdiag(1./SigmaBack) + Rho = sp.block_diag([Rho,Rho]) + + en = Rho*mesh.aveF2CCV*jn + bn = mesh.aveF2CCV*bn + + ex,ez = Pfx*en, Pfz*en + bx,bz = Pfx*bn, Pfz*bn + + # get analytic solution + exa, eya, eza = EM.Analytics.FDEM.ElectricDipoleWholeSpace(XYZ, src_loc, sigmaback, freq,orientation='Z',mu= mur*mu_0) + exa, eya, eza = Utils.mkvc(exa,2), Utils.mkvc(eya,2), Utils.mkvc(eza,2) + + bxa, bya, bza = EM.Analytics.FDEM.MagneticDipoleWholeSpace(XYZ, src_loc, sigmaback, freq,orientation='Z',mu= mur*mu_0) + bxa, bya, bza = Utils.mkvc(bxa,2), Utils.mkvc(bya,2), Utils.mkvc(bza,2) + + print ' comp, anayltic, numeric, num - ana, (num - ana)/ana' + print ' ex:', np.linalg.norm(exa), np.linalg.norm(ex), np.linalg.norm(exa-ex), np.linalg.norm(exa-ex)/np.linalg.norm(exa) + print ' ez:', np.linalg.norm(eza), np.linalg.norm(ez), np.linalg.norm(eza-ez), np.linalg.norm(eza-ez)/np.linalg.norm(eza) + + print ' bx:', np.linalg.norm(bxa), np.linalg.norm(bx), np.linalg.norm(bxa-bx), np.linalg.norm(bxa-bx)/np.linalg.norm(bxa) + print ' bz:', np.linalg.norm(bza), np.linalg.norm(bz), np.linalg.norm(bza-bz), np.linalg.norm(bza-bz)/np.linalg.norm(bza) + + if plotIt: + # Edipole + plt.subplot(221) + plt.plot(r,ex.real,'o',r,exa.real,linewidth=2) + plt.grid(which='both') + plt.title('Ex Real') + plt.xlabel('r (m)') + + plt.subplot(222) + plt.plot(r,ex.imag,'o',r,exa.imag,linewidth=2) + plt.grid(which='both') + plt.title('Ex Imag') + plt.legend(['Num','Ana'],bbox_to_anchor=(1.5,0.5)) + plt.xlabel('r (m)') + + plt.subplot(223) + plt.plot(r,ez.real,'o',r,eza.real,linewidth=2) + plt.grid(which='both') + plt.title('Ez Real') + plt.xlabel('r (m)') + + plt.subplot(224) + plt.plot(r,ez.imag,'o',r,eza.imag,linewidth=2) + plt.grid(which='both') + plt.title('Ez Imag') + plt.xlabel('r (m)') + + plt.tight_layout() + + # Bdipole + plt.subplot(221) + plt.plot(r,bx.real,'o',r,bxa.real,linewidth=2) + plt.grid(which='both') + plt.title('Bx Real') + plt.xlabel('r (m)') + + plt.subplot(222) + plt.plot(r,bx.imag,'o',r,bxa.imag,linewidth=2) + plt.grid(which='both') + plt.title('Bx Imag') + plt.legend(['Num','Ana'],bbox_to_anchor=(1.5,0.5)) + plt.xlabel('r (m)') + + plt.subplot(223) + plt.plot(r,bz.real,'o',r,bza.real,linewidth=2) + plt.grid(which='both') + plt.title('Bz Real') + plt.xlabel('r (m)') + + plt.subplot(224) + plt.plot(r,bz.imag,'o',r,bza.imag,linewidth=2) + plt.grid(which='both') + plt.title('Bz Imag') + plt.xlabel('r (m)') + + plt.tight_layout() + + self.assertTrue(np.linalg.norm(exa-ex)/np.linalg.norm(exa) < tol_EBdipole) + self.assertTrue(np.linalg.norm(eza-ez)/np.linalg.norm(eza) < tol_EBdipole) + + self.assertTrue(np.linalg.norm(bxa-bx)/np.linalg.norm(bxa) < tol_EBdipole) + self.assertTrue(np.linalg.norm(bza-bz)/np.linalg.norm(bza) < tol_EBdipole) + + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/em/fdem/forward/test_FDEM_casing.py b/tests/em/fdem/forward/test_FDEM_casing.py new file mode 100644 index 00000000..c30e4ac8 --- /dev/null +++ b/tests/em/fdem/forward/test_FDEM_casing.py @@ -0,0 +1,62 @@ +from SimPEG import Tests, Utils, np +import SimPEG.EM.Analytics.FDEMcasing as Casing +import unittest +from scipy.constants import mu_0 + + +n = 50. +freq = 1. +a = 5e-2 +b = a + 1e-2 +sigma = np.r_[10., 5.5e6, 1e-1] +mu = mu_0*np.r_[1.,100.,1.] +srcloc = np.r_[0., 0., 0.] +xobs = np.random.rand(n)+10. +yobs = np.zeros(n) +zobs = np.random.randn(n) +plotit = False + +def CasingMagDipoleDeriv_r(x): + obsloc = np.vstack([x, yobs, zobs]).T + + f = Casing._getCasingHertzMagDipole(srcloc,obsloc,freq,sigma,a,b,mu) + g = Utils.sdiag(Casing._getCasingHertzMagDipoleDeriv_r(srcloc,obsloc,freq,sigma,a,b,mu)) + + return f,g + +def CasingMagDipoleDeriv_z(z): + obsloc = np.vstack([xobs, yobs, z]).T + + f = Casing._getCasingHertzMagDipole(srcloc,obsloc,freq,sigma,a,b,mu) + g = Utils.sdiag(Casing._getCasingHertzMagDipoleDeriv_z(srcloc,obsloc,freq,sigma,a,b,mu)) + + return f,g + +def CasingMagDipole2Deriv_z_r(x): + obsloc = np.vstack([x, yobs, zobs]).T + + f = Casing._getCasingHertzMagDipoleDeriv_z(srcloc,obsloc,freq,sigma,a,b,mu) + g = Utils.sdiag(Casing._getCasingHertzMagDipole2Deriv_z_r(srcloc,obsloc,freq,sigma,a,b,mu)) + + return f,g + +def CasingMagDipole2Deriv_z_z(z): + obsloc = np.vstack([xobs, yobs, z]).T + + f = Casing._getCasingHertzMagDipoleDeriv_z(srcloc,obsloc,freq,sigma,a,b,mu) + g = Utils.sdiag(Casing._getCasingHertzMagDipole2Deriv_z_z(srcloc,obsloc,freq,sigma,a,b,mu)) + + return f,g + + + +class Casing_DerivTest(unittest.TestCase): + def test_derivs(self): + Tests.checkDerivative(CasingMagDipoleDeriv_r,np.ones(n)*10+np.random.randn(n),plotIt=False) + Tests.checkDerivative(CasingMagDipoleDeriv_z,np.random.randn(n),plotIt=False) + Tests.checkDerivative(CasingMagDipole2Deriv_z_r,np.ones(n)*10+np.random.randn(n),plotIt=False) + Tests.checkDerivative(CasingMagDipole2Deriv_z_z,np.random.randn(n),plotIt=False) + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/em/fdem/forward/test_FDEM_forward.py b/tests/em/fdem/forward/test_FDEM_forward.py new file mode 100644 index 00000000..437f3708 --- /dev/null +++ b/tests/em/fdem/forward/test_FDEM_forward.py @@ -0,0 +1,127 @@ +import unittest +from SimPEG import * +from SimPEG import EM +import sys +from scipy.constants import mu_0 +from SimPEG.EM.Utils.testingUtils import getFDEMProblem + +testEB = True +testHJ = True + +verbose = False + +TOL = 1e-5 +FLR = 1e-20 # "zero", so if residual below this --> pass regardless of order +CONDUCTIVITY = 1e1 +MU = mu_0 +freq = 1e-1 +addrandoms = True + +SrcList = ['RawVec', 'MagDipole_Bfield', 'MagDipole', 'CircularLoop'] + + +def crossCheckTest(fdemType, comp): + + l2norm = lambda r: np.sqrt(r.dot(r)) + + prb1 = getFDEMProblem(fdemType, comp, SrcList, freq, verbose) + mesh = prb1.mesh + print 'Cross Checking Forward: %s formulation - %s' % (fdemType, comp) + m = np.log(np.ones(mesh.nC)*CONDUCTIVITY) + mu = np.log(np.ones(mesh.nC)*MU) + + if addrandoms is True: + m = m + np.random.randn(mesh.nC)*np.log(CONDUCTIVITY)*1e-1 + mu = mu + np.random.randn(mesh.nC)*MU*1e-1 + + # prb1.PropMap.PropModel.mu = mu + # prb1.PropMap.PropModel.mui = 1./mu + survey1 = prb1.survey + d1 = survey1.dpred(m) + + if verbose: + print ' Problem 1 solved' + + if fdemType == 'e': + prb2 = getFDEMProblem('b', comp, SrcList, freq, verbose) + elif fdemType == 'b': + prb2 = getFDEMProblem('e', comp, SrcList, freq, verbose) + elif fdemType == 'j': + prb2 = getFDEMProblem('h', comp, SrcList, freq, verbose) + elif fdemType == 'h': + prb2 = getFDEMProblem('j', comp, SrcList, freq, verbose) + else: + raise NotImplementedError() + + # prb2.mu = mu + survey2 = prb2.survey + d2 = survey2.dpred(m) + + if verbose: + print ' Problem 2 solved' + + r = d2-d1 + l2r = l2norm(r) + + tol = np.max([TOL*(10**int(np.log10(l2norm(d1)))),FLR]) + print l2norm(d1), l2norm(d2), l2r , tol, l2r < tol + return l2r < tol + + +class FDEM_CrossCheck(unittest.TestCase): + if testEB: + def test_EB_CrossCheck_exr_Eform(self): + self.assertTrue(crossCheckTest('e', 'exr')) + def test_EB_CrossCheck_eyr_Eform(self): + self.assertTrue(crossCheckTest('e', 'eyr')) + def test_EB_CrossCheck_ezr_Eform(self): + self.assertTrue(crossCheckTest('e', 'ezr')) + def test_EB_CrossCheck_exi_Eform(self): + self.assertTrue(crossCheckTest('e', 'exi')) + def test_EB_CrossCheck_eyi_Eform(self): + self.assertTrue(crossCheckTest('e', 'eyi')) + def test_EB_CrossCheck_ezi_Eform(self): + self.assertTrue(crossCheckTest('e', 'ezi')) + + def test_EB_CrossCheck_bxr_Eform(self): + self.assertTrue(crossCheckTest('e', 'bxr')) + def test_EB_CrossCheck_byr_Eform(self): + self.assertTrue(crossCheckTest('e', 'byr')) + def test_EB_CrossCheck_bzr_Eform(self): + self.assertTrue(crossCheckTest('e', 'bzr')) + def test_EB_CrossCheck_bxi_Eform(self): + self.assertTrue(crossCheckTest('e', 'bxi')) + def test_EB_CrossCheck_byi_Eform(self): + self.assertTrue(crossCheckTest('e', 'byi')) + def test_EB_CrossCheck_bzi_Eform(self): + self.assertTrue(crossCheckTest('e', 'bzi')) + + if testHJ: + def test_HJ_CrossCheck_jxr_Jform(self): + self.assertTrue(crossCheckTest('j', 'jxr')) + def test_HJ_CrossCheck_jyr_Jform(self): + self.assertTrue(crossCheckTest('j', 'jyr')) + def test_HJ_CrossCheck_jzr_Jform(self): + self.assertTrue(crossCheckTest('j', 'jzr')) + def test_HJ_CrossCheck_jxi_Jform(self): + self.assertTrue(crossCheckTest('j', 'jxi')) + def test_HJ_CrossCheck_jyi_Jform(self): + self.assertTrue(crossCheckTest('j', 'jyi')) + def test_HJ_CrossCheck_jzi_Jform(self): + self.assertTrue(crossCheckTest('j', 'jzi')) + + def test_HJ_CrossCheck_hxr_Jform(self): + self.assertTrue(crossCheckTest('j', 'hxr')) + def test_HJ_CrossCheck_hyr_Jform(self): + self.assertTrue(crossCheckTest('j', 'hyr')) + def test_HJ_CrossCheck_hzr_Jform(self): + self.assertTrue(crossCheckTest('j', 'hzr')) + def test_HJ_CrossCheck_hxi_Jform(self): + self.assertTrue(crossCheckTest('j', 'hxi')) + def test_HJ_CrossCheck_hyi_Jform(self): + self.assertTrue(crossCheckTest('j', 'hyi')) + def test_HJ_CrossCheck_hzi_Jform(self): + self.assertTrue(crossCheckTest('j', 'hzi')) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/tests/em/fdem/inverse/adjoint/__init__.py b/tests/em/fdem/inverse/adjoint/__init__.py new file mode 100644 index 00000000..38d84328 --- /dev/null +++ b/tests/em/fdem/inverse/adjoint/__init__.py @@ -0,0 +1,11 @@ +if __name__ == '__main__': + import os + import glob + import unittest + test_file_strings = glob.glob('test_*.py') + module_strings = [str[0:len(str)-3] for str in test_file_strings] + suites = [unittest.defaultTestLoader.loadTestsFromName(str) for str + in module_strings] + testSuite = unittest.TestSuite(suites) + + unittest.TextTestRunner(verbosity=2).run(testSuite) diff --git a/tests/em/fdem/inverse/adjoint/test_FDEM_adjoint.py b/tests/em/fdem/inverse/adjoint/test_FDEM_adjoint.py new file mode 100644 index 00000000..f77f2131 --- /dev/null +++ b/tests/em/fdem/inverse/adjoint/test_FDEM_adjoint.py @@ -0,0 +1,156 @@ +import unittest +from SimPEG import * +from SimPEG import EM +import sys +from scipy.constants import mu_0 +from SimPEG.EM.Utils.testingUtils import getFDEMProblem + +testEB = True +testHJ = True + +verbose = False + +TOL = 1e-5 +FLR = 1e-20 # "zero", so if residual below this --> pass regardless of order +CONDUCTIVITY = 1e1 +MU = mu_0 +freq = 1e-1 +addrandoms = True + +SrcType = 'RawVec' #or 'MAgDipole_Bfield', 'CircularLoop', 'RawVec' + +def adjointTest(fdemType, comp): + prb = getFDEMProblem(fdemType, comp, [SrcType], freq) + print 'Adjoint %s formulation - %s' % (fdemType, comp) + + m = np.log(np.ones(prb.mapping.nP)*CONDUCTIVITY) + mu = np.ones(prb.mesh.nC)*MU + + if addrandoms is True: + m = m + np.random.randn(prb.mapping.nP)*np.log(CONDUCTIVITY)*1e-1 + mu = mu + np.random.randn(prb.mesh.nC)*MU*1e-1 + + survey = prb.survey + # prb.PropMap.PropModel.mu = mu + # prb.PropMap.PropModel.mui = 1./mu + u = prb.fields(m) + + v = np.random.rand(survey.nD) + w = np.random.rand(prb.mesh.nC) + + vJw = v.dot(prb.Jvec(m, w, u)) + wJtv = w.dot(prb.Jtvec(m, v, u)) + tol = np.max([TOL*(10**int(np.log10(np.abs(vJw)))),FLR]) + print vJw, wJtv, vJw - wJtv, tol, np.abs(vJw - wJtv) < tol + return np.abs(vJw - wJtv) < tol + +class FDEM_AdjointTests(unittest.TestCase): + if testEB: + def test_Jtvec_adjointTest_exr_Eform(self): + self.assertTrue(adjointTest('e', 'exr')) + def test_Jtvec_adjointTest_eyr_Eform(self): + self.assertTrue(adjointTest('e', 'eyr')) + def test_Jtvec_adjointTest_ezr_Eform(self): + self.assertTrue(adjointTest('e', 'ezr')) + def test_Jtvec_adjointTest_exi_Eform(self): + self.assertTrue(adjointTest('e', 'exi')) + def test_Jtvec_adjointTest_eyi_Eform(self): + self.assertTrue(adjointTest('e', 'eyi')) + def test_Jtvec_adjointTest_ezi_Eform(self): + self.assertTrue(adjointTest('e', 'ezi')) + + def test_Jtvec_adjointTest_bxr_Eform(self): + self.assertTrue(adjointTest('e', 'bxr')) + def test_Jtvec_adjointTest_byr_Eform(self): + self.assertTrue(adjointTest('e', 'byr')) + def test_Jtvec_adjointTest_bzr_Eform(self): + self.assertTrue(adjointTest('e', 'bzr')) + def test_Jtvec_adjointTest_bxi_Eform(self): + self.assertTrue(adjointTest('e', 'bxi')) + def test_Jtvec_adjointTest_byi_Eform(self): + self.assertTrue(adjointTest('e', 'byi')) + def test_Jtvec_adjointTest_bzi_Eform(self): + self.assertTrue(adjointTest('e', 'bzi')) + + def test_Jtvec_adjointTest_exr_Bform(self): + self.assertTrue(adjointTest('b', 'exr')) + def test_Jtvec_adjointTest_eyr_Bform(self): + self.assertTrue(adjointTest('b', 'eyr')) + def test_Jtvec_adjointTest_ezr_Bform(self): + self.assertTrue(adjointTest('b', 'ezr')) + def test_Jtvec_adjointTest_exi_Bform(self): + self.assertTrue(adjointTest('b', 'exi')) + def test_Jtvec_adjointTest_eyi_Bform(self): + self.assertTrue(adjointTest('b', 'eyi')) + def test_Jtvec_adjointTest_ezi_Bform(self): + self.assertTrue(adjointTest('b', 'ezi')) + def test_Jtvec_adjointTest_bxr_Bform(self): + self.assertTrue(adjointTest('b', 'bxr')) + def test_Jtvec_adjointTest_byr_Bform(self): + self.assertTrue(adjointTest('b', 'byr')) + def test_Jtvec_adjointTest_bzr_Bform(self): + self.assertTrue(adjointTest('b', 'bzr')) + def test_Jtvec_adjointTest_bxi_Bform(self): + self.assertTrue(adjointTest('b', 'bxi')) + def test_Jtvec_adjointTest_byi_Bform(self): + self.assertTrue(adjointTest('b', 'byi')) + def test_Jtvec_adjointTest_bzi_Bform(self): + self.assertTrue(adjointTest('b', 'bzi')) + + + if testHJ: + def test_Jtvec_adjointTest_jxr_Jform(self): + self.assertTrue(adjointTest('j', 'jxr')) + def test_Jtvec_adjointTest_jyr_Jform(self): + self.assertTrue(adjointTest('j', 'jyr')) + def test_Jtvec_adjointTest_jzr_Jform(self): + self.assertTrue(adjointTest('j', 'jzr')) + def test_Jtvec_adjointTest_jxi_Jform(self): + self.assertTrue(adjointTest('j', 'jxi')) + def test_Jtvec_adjointTest_jyi_Jform(self): + self.assertTrue(adjointTest('j', 'jyi')) + def test_Jtvec_adjointTest_jzi_Jform(self): + self.assertTrue(adjointTest('j', 'jzi')) + + def test_Jtvec_adjointTest_hxr_Jform(self): + self.assertTrue(adjointTest('j', 'hxr')) + def test_Jtvec_adjointTest_hyr_Jform(self): + self.assertTrue(adjointTest('j', 'hyr')) + def test_Jtvec_adjointTest_hzr_Jform(self): + self.assertTrue(adjointTest('j', 'hzr')) + def test_Jtvec_adjointTest_hxi_Jform(self): + self.assertTrue(adjointTest('j', 'hxi')) + def test_Jtvec_adjointTest_hyi_Jform(self): + self.assertTrue(adjointTest('j', 'hyi')) + def test_Jtvec_adjointTest_hzi_Jform(self): + self.assertTrue(adjointTest('j', 'hzi')) + + def test_Jtvec_adjointTest_hxr_Hform(self): + self.assertTrue(adjointTest('h', 'hxr')) + def test_Jtvec_adjointTest_hyr_Hform(self): + self.assertTrue(adjointTest('h', 'hyr')) + def test_Jtvec_adjointTest_hzr_Hform(self): + self.assertTrue(adjointTest('h', 'hzr')) + def test_Jtvec_adjointTest_hxi_Hform(self): + self.assertTrue(adjointTest('h', 'hxi')) + def test_Jtvec_adjointTest_hyi_Hform(self): + self.assertTrue(adjointTest('h', 'hyi')) + def test_Jtvec_adjointTest_hzi_Hform(self): + self.assertTrue(adjointTest('h', 'hzi')) + + def test_Jtvec_adjointTest_hxr_Hform(self): + self.assertTrue(adjointTest('h', 'jxr')) + def test_Jtvec_adjointTest_hyr_Hform(self): + self.assertTrue(adjointTest('h', 'jyr')) + def test_Jtvec_adjointTest_hzr_Hform(self): + self.assertTrue(adjointTest('h', 'jzr')) + def test_Jtvec_adjointTest_hxi_Hform(self): + self.assertTrue(adjointTest('h', 'jxi')) + def test_Jtvec_adjointTest_hyi_Hform(self): + self.assertTrue(adjointTest('h', 'jyi')) + def test_Jtvec_adjointTest_hzi_Hform(self): + self.assertTrue(adjointTest('h', 'jzi')) + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/em/fdem/inverse/derivs/__init__.py b/tests/em/fdem/inverse/derivs/__init__.py new file mode 100644 index 00000000..38d84328 --- /dev/null +++ b/tests/em/fdem/inverse/derivs/__init__.py @@ -0,0 +1,11 @@ +if __name__ == '__main__': + import os + import glob + import unittest + test_file_strings = glob.glob('test_*.py') + module_strings = [str[0:len(str)-3] for str in test_file_strings] + suites = [unittest.defaultTestLoader.loadTestsFromName(str) for str + in module_strings] + testSuite = unittest.TestSuite(suites) + + unittest.TextTestRunner(verbosity=2).run(testSuite) diff --git a/tests/em/fdem/inverse/derivs/test_FDEM_derivs.py b/tests/em/fdem/inverse/derivs/test_FDEM_derivs.py new file mode 100644 index 00000000..52108c4e --- /dev/null +++ b/tests/em/fdem/inverse/derivs/test_FDEM_derivs.py @@ -0,0 +1,154 @@ +import unittest +from SimPEG import * +from SimPEG import EM +import sys +from scipy.constants import mu_0 +from SimPEG.EM.Utils.testingUtils import getFDEMProblem + +testDerivs = True +testEB = True +testHJ = True + +verbose = False + +TOL = 1e-5 +FLR = 1e-20 # "zero", so if residual below this --> pass regardless of order +CONDUCTIVITY = 1e1 +MU = mu_0 +freq = 1e-1 +addrandoms = True + +SrcType = 'RawVec' #or 'MAgDipole_Bfield', 'CircularLoop', 'RawVec' + + +def derivTest(fdemType, comp): + + prb = getFDEMProblem(fdemType, comp, [SrcType], freq) + print '%s formulation - %s' % (fdemType, comp) + x0 = np.log(np.ones(prb.mapping.nP)*CONDUCTIVITY) + mu = np.log(np.ones(prb.mesh.nC)*MU) + + if addrandoms is True: + x0 = x0 + np.random.randn(prb.mapping.nP)*np.log(CONDUCTIVITY)*1e-1 + mu = mu + np.random.randn(prb.mapping.nP)*MU*1e-1 + + # prb.PropMap.PropModel.mu = mu + # prb.PropMap.PropModel.mui = 1./mu + + survey = prb.survey + def fun(x): + return survey.dpred(x), lambda x: prb.Jvec(x0, x) + return Tests.checkDerivative(fun, x0, num=3, plotIt=False, eps=FLR) + + +class FDEM_DerivTests(unittest.TestCase): + + if testEB: + def test_Jvec_exr_Eform(self): + self.assertTrue(derivTest('e', 'exr')) + def test_Jvec_eyr_Eform(self): + self.assertTrue(derivTest('e', 'eyr')) + def test_Jvec_ezr_Eform(self): + self.assertTrue(derivTest('e', 'ezr')) + def test_Jvec_exi_Eform(self): + self.assertTrue(derivTest('e', 'exi')) + def test_Jvec_eyi_Eform(self): + self.assertTrue(derivTest('e', 'eyi')) + def test_Jvec_ezi_Eform(self): + self.assertTrue(derivTest('e', 'ezi')) + + def test_Jvec_bxr_Eform(self): + self.assertTrue(derivTest('e', 'bxr')) + def test_Jvec_byr_Eform(self): + self.assertTrue(derivTest('e', 'byr')) + def test_Jvec_bzr_Eform(self): + self.assertTrue(derivTest('e', 'bzr')) + def test_Jvec_bxi_Eform(self): + self.assertTrue(derivTest('e', 'bxi')) + def test_Jvec_byi_Eform(self): + self.assertTrue(derivTest('e', 'byi')) + def test_Jvec_bzi_Eform(self): + self.assertTrue(derivTest('e', 'bzi')) + + def test_Jvec_exr_Bform(self): + self.assertTrue(derivTest('b', 'exr')) + def test_Jvec_eyr_Bform(self): + self.assertTrue(derivTest('b', 'eyr')) + def test_Jvec_ezr_Bform(self): + self.assertTrue(derivTest('b', 'ezr')) + def test_Jvec_exi_Bform(self): + self.assertTrue(derivTest('b', 'exi')) + def test_Jvec_eyi_Bform(self): + self.assertTrue(derivTest('b', 'eyi')) + def test_Jvec_ezi_Bform(self): + self.assertTrue(derivTest('b', 'ezi')) + + def test_Jvec_bxr_Bform(self): + self.assertTrue(derivTest('b', 'bxr')) + def test_Jvec_byr_Bform(self): + self.assertTrue(derivTest('b', 'byr')) + def test_Jvec_bzr_Bform(self): + self.assertTrue(derivTest('b', 'bzr')) + def test_Jvec_bxi_Bform(self): + self.assertTrue(derivTest('b', 'bxi')) + def test_Jvec_byi_Bform(self): + self.assertTrue(derivTest('b', 'byi')) + def test_Jvec_bzi_Bform(self): + self.assertTrue(derivTest('b', 'bzi')) + + if testHJ: + def test_Jvec_jxr_Jform(self): + self.assertTrue(derivTest('j', 'jxr')) + def test_Jvec_jyr_Jform(self): + self.assertTrue(derivTest('j', 'jyr')) + def test_Jvec_jzr_Jform(self): + self.assertTrue(derivTest('j', 'jzr')) + def test_Jvec_jxi_Jform(self): + self.assertTrue(derivTest('j', 'jxi')) + def test_Jvec_jyi_Jform(self): + self.assertTrue(derivTest('j', 'jyi')) + def test_Jvec_jzi_Jform(self): + self.assertTrue(derivTest('j', 'jzi')) + + def test_Jvec_hxr_Jform(self): + self.assertTrue(derivTest('j', 'hxr')) + def test_Jvec_hyr_Jform(self): + self.assertTrue(derivTest('j', 'hyr')) + def test_Jvec_hzr_Jform(self): + self.assertTrue(derivTest('j', 'hzr')) + def test_Jvec_hxi_Jform(self): + self.assertTrue(derivTest('j', 'hxi')) + def test_Jvec_hyi_Jform(self): + self.assertTrue(derivTest('j', 'hyi')) + def test_Jvec_hzi_Jform(self): + self.assertTrue(derivTest('j', 'hzi')) + + def test_Jvec_hxr_Hform(self): + self.assertTrue(derivTest('h', 'hxr')) + def test_Jvec_hyr_Hform(self): + self.assertTrue(derivTest('h', 'hyr')) + def test_Jvec_hzr_Hform(self): + self.assertTrue(derivTest('h', 'hzr')) + def test_Jvec_hxi_Hform(self): + self.assertTrue(derivTest('h', 'hxi')) + def test_Jvec_hyi_Hform(self): + self.assertTrue(derivTest('h', 'hyi')) + def test_Jvec_hzi_Hform(self): + self.assertTrue(derivTest('h', 'hzi')) + + def test_Jvec_hxr_Hform(self): + self.assertTrue(derivTest('h', 'jxr')) + def test_Jvec_hyr_Hform(self): + self.assertTrue(derivTest('h', 'jyr')) + def test_Jvec_hzr_Hform(self): + self.assertTrue(derivTest('h', 'jzr')) + def test_Jvec_hxi_Hform(self): + self.assertTrue(derivTest('h', 'jxi')) + def test_Jvec_hyi_Hform(self): + self.assertTrue(derivTest('h', 'jyi')) + def test_Jvec_hzi_Hform(self): + self.assertTrue(derivTest('h', 'jzi')) + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/em/tdem/__init__.py b/tests/em/tdem/__init__.py new file mode 100644 index 00000000..38d84328 --- /dev/null +++ b/tests/em/tdem/__init__.py @@ -0,0 +1,11 @@ +if __name__ == '__main__': + import os + import glob + import unittest + test_file_strings = glob.glob('test_*.py') + module_strings = [str[0:len(str)-3] for str in test_file_strings] + suites = [unittest.defaultTestLoader.loadTestsFromName(str) for str + in module_strings] + testSuite = unittest.TestSuite(suites) + + unittest.TextTestRunner(verbosity=2).run(testSuite) diff --git a/tests/em/tdem/test_TDEM_b_DerivAdjoint.py b/tests/em/tdem/test_TDEM_b_DerivAdjoint.py new file mode 100644 index 00000000..570c808b --- /dev/null +++ b/tests/em/tdem/test_TDEM_b_DerivAdjoint.py @@ -0,0 +1,314 @@ +import unittest +from SimPEG import * +from SimPEG import EM + +plotIt = False +tol = 1e-6 + +class TDEM_bDerivTests(unittest.TestCase): + + def setUp(self): + + cs = 5. + ncx = 20 + ncy = 6 + npad = 20 + hx = [(cs,ncx), (cs,npad,1.3)] + hy = [(cs,npad,-1.3), (cs,ncy), (cs,npad,1.3)] + mesh = Mesh.CylMesh([hx,1,hy], '00C') + + active = mesh.vectorCCz<0. + activeMap = Maps.ActiveCells(mesh, active, np.log(1e-8), nC=mesh.nCz) + mapping = Maps.ExpMap(mesh) * Maps.Vertical1DMap(mesh) * activeMap + + rxOffset = 40. + rx = EM.TDEM.RxTDEM(np.array([[rxOffset, 0., 0.]]), np.logspace(-4,-3, 20), 'bz') + src = EM.TDEM.SrcTDEM_VMD_MVP([rx], loc=np.array([0., 0., 0.])) + + survey = EM.TDEM.SurveyTDEM([src]) + + self.prb = EM.TDEM.ProblemTDEM_b(mesh, mapping=mapping) + # self.prb.timeSteps = [1e-5] + self.prb.timeSteps = [(1e-05, 10), (5e-05, 10), (2.5e-4, 10)] + # self.prb.timeSteps = [(1e-05, 100)] + + try: + from pymatsolver import MumpsSolver + self.prb.Solver = MumpsSolver + except ImportError, e: + self.prb.Solver = SolverLU + + self.sigma = np.ones(mesh.nCz)*1e-8 + self.sigma[mesh.vectorCCz<0] = 1e-1 + self.sigma = np.log(self.sigma[active]) + + self.prb.pair(survey) + self.mesh = mesh + + def test_AhVec(self): + """ + Test that fields and AhVec produce consistent results + """ + + prb = self.prb + sigma = self.sigma + + u = prb.fields(sigma) + Ahu = prb._AhVec(sigma, u) + + V1 = Ahu[:,'b',1] + V2 = 1./prb.timeSteps[0]*prb.MfMui*u[:,'b',0] + self.assertLess(np.linalg.norm(V1-V2)/np.linalg.norm(V2), 1.e-6) + + V1 = Ahu[:,'e',1] + return np.linalg.norm(V1) < 1.e-6 + + for i in range(2,prb.nT): + + dt = prb.timeSteps[i] + + V1 = Ahu[:,'b',i] + V2 = 1.0/dt*prb.MfMui*u[:,'b', i-1] + # print np.linalg.norm(V1), np.linalg.norm(V2) + self.assertLess(np.linalg.norm(V1)/np.linalg.norm(V2), 1.e-6) + + V1 = Ahu[:,'e',i] + V2 = prb.MeSigma*u[:,'e',i] + # print np.linalg.norm(V1), np.linalg.norm(V2) + return np.linalg.norm(V1)/np.linalg.norm(V2), 1.e-6 + + def test_AhVecVSMat_OneTS(self): + + prb = self.prb + prb.timeSteps = [1e-05] + sigma = self.sigma + prb.curModel = sigma + + dt = prb.timeSteps[0] + a11 = 1/dt*prb.MfMui*sp.identity(prb.mesh.nF) + a12 = prb.MfMui*prb.mesh.edgeCurl + a21 = prb.mesh.edgeCurl.T*prb.MfMui + a22 = -prb.MeSigma + A = sp.bmat([[a11,a12],[a21,a22]]) + + f = prb.fields(sigma) + u1 = A*f.tovec() + u2 = prb._AhVec(sigma,f).tovec() + + self.assertTrue(np.linalg.norm(u1-u2)/np.linalg.norm(u1)<1e-12) + + def test_solveAhVSMat_OneTS(self): + prb = self.prb + + prb.timeSteps = [1e-05] + + sigma = self.sigma + prb.curModel = sigma + + dt = prb.timeSteps[0] + a11 = 1.0/dt*prb.MfMui*sp.identity(prb.mesh.nF) + a12 = prb.MfMui*prb.mesh.edgeCurl + a21 = prb.mesh.edgeCurl.T*prb.MfMui + a22 = -prb.MeSigma + A = sp.bmat([[a11,a12],[a21,a22]]) + + f = prb.fields(sigma) + f[:,:,0] = {'b':0} + f[:,'b',1] = 0 + + self.assertTrue(np.all(np.r_[f[:,'b',1],f[:,'e',1]] == f.tovec())) + + u1 = prb.solveAh(sigma,f).tovec().flatten() + u2 = sp.linalg.spsolve(A.tocsr(),f.tovec()) + + self.assertTrue(np.linalg.norm(u1-u2)<1e-8) + + def test_solveAhVsAhVec(self): + + prb = self.prb + mesh = self.prb.mesh + sigma = self.sigma + self.prb.curModel = sigma + + f = EM.TDEM.FieldsTDEM(prb.mesh, prb.survey) + f[:,'b',:] = 0.0 + for i in range(prb.nT): + f[:,'e', i] = np.random.rand(mesh.nE, 1) + + Ahf = prb._AhVec(sigma, f) + f_test = prb.solveAh(sigma, Ahf) + + u1 = f.tovec() + u2 = f_test.tovec() + self.assertTrue(np.linalg.norm(u1-u2)<1e-8) + + def test_DerivG(self): + """ + Test the derivative of c with respect to sigma + """ + + # Random model and perturbation + sigma = np.random.rand(self.prb.mapping.nP) + + f = self.prb.fields(sigma) + dm = 1000*np.random.rand(self.prb.mapping.nP) + h = 0.01 + + derChk = lambda m: [self.prb._AhVec(m, f).tovec(), lambda mx: self.prb.Gvec(sigma, mx, u=f).tovec()] + print '\ntest_DerivG' + passed = Tests.checkDerivative(derChk, sigma, plotIt=False, dx=dm, num=4, eps=1e-20) + return passed + + def test_Deriv_dUdM(self): + + prb = self.prb + prb.timeSteps = [(1e-05, 10), (0.0001, 10), (0.001, 10)] + mesh = self.mesh + sigma = self.sigma + + dm = 10*np.random.rand(prb.mapping.nP) + f = prb.fields(sigma) + + derChk = lambda m: [self.prb.fields(m).tovec(), lambda mx: -prb.solveAh(sigma, prb.Gvec(sigma, mx, u=f)).tovec()] + print '\n' + print 'test_Deriv_dUdM' + Tests.checkDerivative(derChk, sigma, plotIt=False, dx=dm, num=4, eps=1e-20) + + def test_Deriv_J(self): + + prb = self.prb + prb.timeSteps = [(1e-05, 10), (0.0001, 10), (0.001, 10)] + mesh = self.mesh + sigma = self.sigma + + # d_sig = 0.8*sigma #np.random.rand(mesh.nCz) + d_sig = 10*np.random.rand(prb.mapping.nP) + + + derChk = lambda m: [prb.survey.dpred(m), lambda mx: prb.Jvec(sigma, mx)] + print '\n' + print 'test_Deriv_J' + Tests.checkDerivative(derChk, sigma, plotIt=False, dx=d_sig, num=4, eps=1e-20) + + def test_projectAdjoint(self): + prb = self.prb + survey = prb.survey + mesh = self.mesh + + # Generate random fields and data + f = EM.TDEM.FieldsTDEM(prb.mesh, prb.survey) + for i in range(prb.nT): + f[:,'b',i] = np.random.rand(mesh.nF, 1) + f[:,'e',i] = np.random.rand(mesh.nE, 1) + d_vec = np.random.rand(survey.nD) + d = Survey.Data(survey,v=d_vec) + + # Check that d.T*Q*f = f.T*Q.T*d + V1 = d_vec.dot(survey.projectFieldsDeriv(None, v=f).tovec()) + V2 = f.tovec().dot(survey.projectFieldsDeriv(None, v=d, adjoint=True).tovec()) + + self.assertTrue((V1-V2)/np.abs(V1) < tol) + + def test_adjointAhVsAht(self): + prb = self.prb + mesh = self.mesh + sigma = self.sigma + + f1 = EM.TDEM.FieldsTDEM(prb.mesh, prb.survey) + for i in range(1,prb.nT+1): + f1[:,'b',i] = np.random.rand(mesh.nF, 1) + f1[:,'e',i] = np.random.rand(mesh.nE, 1) + + f2 = EM.TDEM.FieldsTDEM(prb.mesh, prb.survey) + for i in range(1,prb.nT+1): + f2[:,'b',i] = np.random.rand(mesh.nF, 1) + f2[:,'e',i] = np.random.rand(mesh.nE, 1) + + V1 = f2.tovec().dot(prb._AhVec(sigma, f1).tovec()) + V2 = f1.tovec().dot(prb._AhtVec(sigma, f2).tovec()) + self.assertTrue(np.abs(V1-V2)/np.abs(V1) < tol) + + # def test_solveAhtVsAhtVec(self): + # prb = self.prb + # mesh = self.mesh + # sigma = np.random.rand(prb.mapping.nP) + + # f1 = EM.TDEM.FieldsTDEM(mesh,prb.survey) + # for i in range(1,prb.nT+1): + # f1[:,'b',i] = np.random.rand(mesh.nF, 1) + # f1[:,'e',i] = np.random.rand(mesh.nE, 1) + + # f2 = prb.solveAht(sigma, f1) + # f3 = prb._AhtVec(sigma, f2) + + # if True: + # import matplotlib.pyplot as plt + # plt.plot(f3.tovec(),'b') + # plt.plot(f1.tovec(),'r') + # plt.show() + # V1 = np.linalg.norm(f3.tovec()-f1.tovec()) + # V2 = np.linalg.norm(f1.tovec()) + # print 'AhtVsAhtVec', V1, V2, f1.tovec() + # print 'I am gunna fail this one: boo. :(' + # self.assertLess(V1/V2, 1e-6) + + # def test_adjointsolveAhVssolveAht(self): + # prb = self.prb + # mesh = self.mesh + # sigma = self.sigma + + # f1 = EM.TDEM.FieldsTDEM(prb.mesh, prb.survey) + # for i in range(1,prb.nT+1): + # f1[:,'b',i] = np.random.rand(mesh.nF, 1) + # f1[:,'e',i] = np.random.rand(mesh.nE, 1) + + # f2 = EM.TDEM.FieldsTDEM(prb.mesh, prb.survey) + # for i in range(1,prb.nT+1): + # f2[:,'b',i] = np.random.rand(mesh.nF, 1) + # f2[:,'e',i] = np.random.rand(mesh.nE, 1) + + # V1 = f2.tovec().dot(prb.solveAh(sigma, f1).tovec()) + # V2 = f1.tovec().dot(prb.solveAht(sigma, f2).tovec()) + # print V1, V2 + # self.assertLess(np.abs(V1-V2)/np.abs(V1), 1e-6) + + def test_adjointGvecVsGtvec(self): + mesh = self.mesh + prb = self.prb + + m = np.random.rand(prb.mapping.nP) + sigma = np.random.rand(prb.mapping.nP) + + u = EM.TDEM.FieldsTDEM(prb.mesh, prb.survey) + for i in range(1,prb.nT+1): + u[:,'b',i] = np.random.rand(mesh.nF, 1) + u[:,'e',i] = np.random.rand(mesh.nE, 1) + + v = EM.TDEM.FieldsTDEM(prb.mesh, prb.survey) + for i in range(1,prb.nT+1): + v[:,'b',i] = np.random.rand(mesh.nF, 1) + v[:,'e',i] = np.random.rand(mesh.nE, 1) + + V1 = m.dot(prb.Gtvec(sigma, v, u)) + V2 = v.tovec().dot(prb.Gvec(sigma, m, u).tovec()) + self.assertTrue(np.abs(V1-V2)/np.abs(V1) < tol) + + def test_adjointJvecVsJtvec(self): + mesh = self.mesh + prb = self.prb + sigma = self.sigma + + m = np.random.rand(prb.mapping.nP) + d = np.random.rand(prb.survey.nD) + + V1 = d.dot(prb.Jvec(sigma, m)) + V2 = m.dot(prb.Jtvec(sigma, d)) + passed = np.abs(V1-V2)/np.abs(V1) < tol + print 'AdjointTest', V1, V2, passed + self.assertTrue(passed) + + + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/em/tdem/test_TDEM_b_MultiSrc_DerivAdjoint.py b/tests/em/tdem/test_TDEM_b_MultiSrc_DerivAdjoint.py new file mode 100644 index 00000000..de261a10 --- /dev/null +++ b/tests/em/tdem/test_TDEM_b_MultiSrc_DerivAdjoint.py @@ -0,0 +1,153 @@ +import unittest +from SimPEG import * +from SimPEG import EM + +plotIt = False + +class TDEM_bDerivTests(unittest.TestCase): + + def setUp(self): + + cs = 5. + ncx = 20 + ncy = 6 + npad = 20 + hx = [(cs,ncx), (cs,npad,1.3)] + hy = [(cs,npad,-1.3), (cs,ncy), (cs,npad,1.3)] + mesh = Mesh.CylMesh([hx,1,hy], '00C') + + active = mesh.vectorCCz<0. + activeMap = Maps.ActiveCells(mesh, active, np.log(1e-8), nC=mesh.nCz) + mapping = Maps.ExpMap(mesh) * Maps.Vertical1DMap(mesh) * activeMap + + rxOffset = 40. + rx = EM.TDEM.RxTDEM(np.array([[rxOffset, 0., 0.]]), np.logspace(-4,-3, 20), 'bz') + src = EM.TDEM.SrcTDEM_VMD_MVP( [rx], loc=np.array([0., 0., 0.])) + rx2 = EM.TDEM.RxTDEM(np.array([[rxOffset-10, 0., 0.]]), np.logspace(-5,-4, 25), 'bz') + src2 = EM.TDEM.SrcTDEM_VMD_MVP( [rx2], loc=np.array([0., 0., 0.])) + + survey = EM.TDEM.SurveyTDEM([src,src2]) + + self.prb = EM.TDEM.ProblemTDEM_b(mesh, mapping=mapping) + # self.prb.timeSteps = [1e-5] + self.prb.timeSteps = [(1e-05, 10), (5e-05, 10), (2.5e-4, 10)] + # self.prb.timeSteps = [(1e-05, 100)] + + try: + from pymatsolver import MumpsSolver + self.prb.Solver = MumpsSolver + except ImportError, e: + self.prb.Solver = SolverLU + + self.sigma = np.ones(mesh.nCz)*1e-8 + self.sigma[mesh.vectorCCz<0] = 1e-1 + self.sigma = np.log(self.sigma[active]) + + self.prb.pair(survey) + self.mesh = mesh + + def test_DerivG(self): + """ + Test the derivative of c with respect to sigma + """ + + # Random model and perturbation + sigma = np.random.rand(self.prb.mapping.nP) + + f = self.prb.fields(sigma) + dm = 1000*np.random.rand(self.prb.mapping.nP) + h = 0.01 + + derChk = lambda m: [self.prb._AhVec(m, f).tovec(), lambda mx: self.prb.Gvec(sigma, mx, u=f).tovec()] + print '\ntest_DerivG' + Tests.checkDerivative(derChk, sigma, plotIt=False, dx=dm, num=4, eps=1e-20) + + def test_Deriv_dUdM(self): + + prb = self.prb + prb.timeSteps = [(1e-05, 10), (0.0001, 10), (0.001, 10)] + mesh = self.mesh + sigma = self.sigma + + dm = 10*np.random.rand(prb.mapping.nP) + f = prb.fields(sigma) + + derChk = lambda m: [self.prb.fields(m).tovec(), lambda mx: -prb.solveAh(sigma, prb.Gvec(sigma, mx, u=f)).tovec()] + print '\n' + print 'test_Deriv_dUdM' + Tests.checkDerivative(derChk, sigma, plotIt=False, dx=dm, num=4, eps=1e-20) + + def test_Deriv_J(self): + + prb = self.prb + prb.timeSteps = [(1e-05, 10), (0.0001, 10), (0.001, 10)] + mesh = self.mesh + sigma = self.sigma + + # d_sig = 0.8*sigma #np.random.rand(mesh.nCz) + d_sig = 10*np.random.rand(prb.mapping.nP) + + + derChk = lambda m: [prb.survey.dpred(m), lambda mx: prb.Jvec(sigma, mx)] + print '\n' + print 'test_Deriv_J' + Tests.checkDerivative(derChk, sigma, plotIt=False, dx=d_sig, num=4, eps=1e-20) + + def test_projectAdjoint(self): + prb = self.prb + survey = prb.survey + nSrc = survey.nSrc + mesh = self.mesh + + # Generate random fields and data + f = EM.TDEM.FieldsTDEM(prb.mesh, prb.survey) + for i in range(prb.nT): + f[:,'b',i] = np.random.rand(mesh.nF, nSrc) + f[:,'e',i] = np.random.rand(mesh.nE, nSrc) + d_vec = np.random.rand(survey.nD) + d = Survey.Data(survey,v=d_vec) + + # Check that d.T*Q*f = f.T*Q.T*d + V1 = d_vec.dot(survey.projectFieldsDeriv(None, v=f).tovec()) + V2 = np.sum((f.tovec())*(survey.projectFieldsDeriv(None, v=d, adjoint=True).tovec())) + + self.assertTrue((V1-V2)/np.abs(V1) < 1e-6) + + def test_adjointGvecVsGtvec(self): + mesh = self.mesh + prb = self.prb + + m = np.random.rand(prb.mapping.nP) + sigma = np.random.rand(prb.mapping.nP) + + u = EM.TDEM.FieldsTDEM(prb.mesh, prb.survey) + for i in range(1,prb.nT+1): + u[:,'b',i] = np.random.rand(mesh.nF, 2) + u[:,'e',i] = np.random.rand(mesh.nE, 2) + + v = EM.TDEM.FieldsTDEM(prb.mesh, prb.survey) + for i in range(1,prb.nT+1): + v[:,'b',i] = np.random.rand(mesh.nF, 2) + v[:,'e',i] = np.random.rand(mesh.nE, 2) + + V1 = m.dot(prb.Gtvec(sigma, v, u)) + V2 = np.sum(v.tovec()*prb.Gvec(sigma, m, u).tovec()) + self.assertTrue(np.abs(V1-V2)/np.abs(V1) <1e-6) + + def test_adjointJvecVsJtvec(self): + mesh = self.mesh + prb = self.prb + sigma = self.sigma + + m = np.random.rand(prb.mapping.nP) + d = np.random.rand(prb.survey.nD) + + V1 = d.dot(prb.Jvec(sigma, m)) + V2 = m.dot(prb.Jtvec(sigma, d)) + print 'AdjointTest', V1, V2 + self.assertTrue(np.abs(V1-V2)/np.abs(V1) < 1e-6) + + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/em/tdem/test_TDEM_combos.py b/tests/em/tdem/test_TDEM_combos.py new file mode 100644 index 00000000..1f538c3c --- /dev/null +++ b/tests/em/tdem/test_TDEM_combos.py @@ -0,0 +1,94 @@ +import unittest +from SimPEG import * +from SimPEG import EM + +plotIt = False + +def getProb(meshType='CYL',rxTypes='bx,bz',nSrc=1): + cs = 5. + ncx = 20 + ncy = 6 + npad = 20 + hx = [(cs,ncx), (cs,npad,1.3)] + hy = [(cs,npad,-1.3), (cs,ncy), (cs,npad,1.3)] + mesh = Mesh.CylMesh([hx,1,hy], '00C') + + active = mesh.vectorCCz<0. + activeMap = Maps.ActiveCells(mesh, active, np.log(1e-8), nC=mesh.nCz) + mapping = Maps.ExpMap(mesh) * Maps.Vertical1DMap(mesh) * activeMap + + rxOffset = 40. + + srcs = [] + for ii in range(nSrc): + rxs = [EM.TDEM.RxTDEM(np.array([[rxOffset, 0., 0.]]), np.logspace(-4,-3, 20 + ii), rxType) for rxType in rxTypes.split(',')] + srcs += [EM.TDEM.SrcTDEM_VMD_MVP(rxs,np.array([0., 0., 0.]))] + + survey = EM.TDEM.SurveyTDEM(srcs) + + prb = EM.TDEM.ProblemTDEM_b(mesh, mapping=mapping) + # prb.timeSteps = [1e-5] + prb.timeSteps = [(1e-05, 10), (5e-05, 10), (2.5e-4, 10)] + # prb.timeSteps = [(1e-05, 100)] + + try: + from pymatsolver import MumpsSolver + prb.Solver = MumpsSolver + except ImportError, e: + prb.Solver = SolverLU + + sigma = np.ones(mesh.nCz)*1e-8 + sigma[mesh.vectorCCz<0] = 1e-1 + sigma = np.log(sigma[active]) + + prb.pair(survey) + return prb, mesh, sigma + +def dotestJvec(prb, mesh, sigma): + prb.timeSteps = [(1e-05, 10), (0.0001, 10), (0.001, 10)] + # d_sig = 0.8*sigma #np.random.rand(mesh.nCz) + d_sig = 10*np.random.rand(prb.mapping.nP) + derChk = lambda m: [prb.survey.dpred(m), lambda mx: prb.Jvec(sigma, mx)] + return Tests.checkDerivative(derChk, sigma, plotIt=False, dx=d_sig, num=2, eps=1e-20) + +def dotestAdjoint(prb, mesh, sigma): + m = np.random.rand(prb.mapping.nP) + d = np.random.rand(prb.survey.nD) + + V1 = d.dot(prb.Jvec(sigma, m)) + V2 = m.dot(prb.Jtvec(sigma, d)) + print 'AdjointTest', V1, V2 + return np.abs(V1-V2)/np.abs(V1), 1e-6 + +class TDEM_bDerivTests(unittest.TestCase): + + def test_Jvec_bx(self): self.assertTrue(dotestJvec(*getProb(rxTypes='bx'))) + def test_Adjoint_bx(self): self.assertLess(*dotestAdjoint(*getProb(rxTypes='bx'))) + + def test_Jvec_bxbz(self): self.assertTrue(dotestJvec(*getProb(rxTypes='bx,bz'))) + def test_Adjoint_bxbz(self): self.assertLess(*dotestAdjoint(*getProb(rxTypes='bx,bz'))) + + def test_Jvec_bxbz_2src(self): self.assertTrue(dotestJvec(*getProb(rxTypes='bx,bz',nSrc=2))) + def test_Adjoint_bxbz_2src(self): self.assertLess(*dotestAdjoint(*getProb(rxTypes='bx,bz',nSrc=2))) + + def test_Jvec_bxbzbz(self): self.assertTrue(dotestJvec(*getProb(rxTypes='bx,bz,bz'))) + def test_Adjoint_bxbzbz(self): self.assertLess(*dotestAdjoint(*getProb(rxTypes='bx,bz,bz'))) + + def test_Jvec_dbxdt(self): self.assertTrue(dotestJvec(*getProb(rxTypes='dbxdt'))) + def test_Adjoint_dbxdt(self): self.assertLess(*dotestAdjoint(*getProb(rxTypes='dbxdt'))) + + def test_Jvec_dbzdt(self): self.assertTrue(dotestJvec(*getProb(rxTypes='dbzdt'))) + def test_Adjoint_dbzdt(self): self.assertLess(*dotestAdjoint(*getProb(rxTypes='dbzdt'))) + + def test_Jvec_dbxdtbz(self): self.assertTrue(dotestJvec(*getProb(rxTypes='dbxdt,bz'))) + def test_Adjoint_dbxdtbz(self): self.assertLess(*dotestAdjoint(*getProb(rxTypes='dbxdt,bz'))) + + def test_Jvec_ey(self): self.assertTrue(dotestJvec(*getProb(rxTypes='ey'))) + def test_Adjoint_ey(self): self.assertLess(*dotestAdjoint(*getProb(rxTypes='ey'))) + + def test_Jvec_eybzdbxdt(self): self.assertTrue(dotestJvec(*getProb(rxTypes='ey,bz,dbxdt'))) + def test_Adjoint_eybzdbxdt(self): self.assertLess(*dotestAdjoint(*getProb(rxTypes='ey,bz,dbxdt'))) + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/em/tdem/test_TDEM_forward_Analytic.py b/tests/em/tdem/test_TDEM_forward_Analytic.py new file mode 100644 index 00000000..06890541 --- /dev/null +++ b/tests/em/tdem/test_TDEM_forward_Analytic.py @@ -0,0 +1,89 @@ +import unittest +from SimPEG import * +from SimPEG import EM +from scipy.constants import mu_0 +import matplotlib.pyplot as plt + +try: + from pymatsolver import MumpsSolver +except ImportError, e: + MumpsSolver = SolverLU + + +def halfSpaceProblemAnaDiff(meshType, sig_half=1e-2, rxOffset=50., bounds=[1e-5,1e-3], showIt=False): + if meshType == 'CYL': + cs, ncx, ncz, npad = 5., 30, 10, 15 + hx = [(cs,ncx), (cs,npad,1.3)] + hz = [(cs,npad,-1.3), (cs,ncz), (cs,npad,1.3)] + mesh = Mesh.CylMesh([hx,1,hz], '00C') + elif meshType == 'TENSOR': + cs, nc, npad = 20., 13, 5 + hx = [(cs,npad,-1.3), (cs,nc), (cs,npad,1.3)] + hy = [(cs,npad,-1.3), (cs,nc), (cs,npad,1.3)] + hz = [(cs,npad,-1.3), (cs,nc), (cs,npad,1.3)] + mesh = Mesh.TensorMesh([hx,hy,hz], 'CCC') + + active = mesh.vectorCCz<0. + actMap = Maps.ActiveCells(mesh, active, np.log(1e-8), nC=mesh.nCz) + mapping = Maps.ExpMap(mesh) * Maps.Vertical1DMap(mesh) * actMap + + rx = EM.TDEM.RxTDEM(np.array([[rxOffset, 0., 0.]]), np.logspace(-5,-4, 21), 'bz') + src = EM.TDEM.SrcTDEM_VMD_MVP([rx], loc=np.array([0., 0., 0.])) + # src = EM.TDEM.SrcTDEM([rx], loc=np.array([0., 0., 0.])) + + survey = EM.TDEM.SurveyTDEM([src]) + prb = EM.TDEM.ProblemTDEM_b(mesh, mapping=mapping) + prb.Solver = MumpsSolver + + prb.timeSteps = [(1e-06, 40), (5e-06, 40), (1e-05, 40), (5e-05, 40), (0.0001, 40), (0.0005, 40)] + + sigma = np.ones(mesh.nCz)*1e-8 + sigma[active] = sig_half + sigma = np.log(sigma[active]) + prb.pair(survey) + + bz_ana = mu_0*EM.Analytics.hzAnalyticDipoleT(rx.locs[0][0]+1e-3, rx.times, sig_half) + + bz_calc = survey.dpred(sigma) + + ind = np.logical_and(rx.times > bounds[0],rx.times < bounds[1]) + log10diff = np.linalg.norm(np.log10(np.abs(bz_calc[ind])) - np.log10(np.abs(bz_ana[ind])))/np.linalg.norm(np.log10(np.abs(bz_ana[ind]))) + print 'Difference: ', log10diff + + if showIt == True: + plt.loglog(rx.times[bz_calc>0], bz_calc[bz_calc>0], 'r', rx.times[bz_calc<0], -bz_calc[bz_calc<0], 'r--') + plt.loglog(rx.times, abs(bz_ana), 'b*') + plt.title('sig_half = %e'%sig_half) + plt.show() + + return log10diff + + +class TDEM_bTests(unittest.TestCase): + + def test_analytic_p2_CYL_50m(self): + self.assertTrue(halfSpaceProblemAnaDiff('CYL', rxOffset=50., sig_half=1e+2) < 0.01) + def test_analytic_p1_CYL_50m(self): + self.assertTrue(halfSpaceProblemAnaDiff('CYL', rxOffset=50., sig_half=1e+1) < 0.01) + def test_analytic_p0_CYL_50m(self): + self.assertTrue(halfSpaceProblemAnaDiff('CYL', rxOffset=50., sig_half=1e+0) < 0.01) + def test_analytic_m1_CYL_50m(self): + self.assertTrue(halfSpaceProblemAnaDiff('CYL', rxOffset=50., sig_half=1e-1) < 0.01) + def test_analytic_m2_CYL_50m(self): + self.assertTrue(halfSpaceProblemAnaDiff('CYL', rxOffset=50., sig_half=1e-2) < 0.01) + def test_analytic_m3_CYL_50m(self): + self.assertTrue(halfSpaceProblemAnaDiff('CYL', rxOffset=50., sig_half=1e-3) < 0.02) + + def test_analytic_p0_CYL_1m(self): + self.assertTrue(halfSpaceProblemAnaDiff('CYL', rxOffset=1.0, sig_half=1e+0) < 0.01) + def test_analytic_m1_CYL_1m(self): + self.assertTrue(halfSpaceProblemAnaDiff('CYL', rxOffset=1.0, sig_half=1e-1) < 0.01) + def test_analytic_m2_CYL_1m(self): + self.assertTrue(halfSpaceProblemAnaDiff('CYL', rxOffset=1.0, sig_half=1e-2) < 0.01) + def test_analytic_m3_CYL_1m(self): + self.assertTrue(halfSpaceProblemAnaDiff('CYL', rxOffset=1.0, sig_half=1e-3) < 0.02) + + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/examples/__init__.py b/tests/examples/__init__.py new file mode 100644 index 00000000..38d84328 --- /dev/null +++ b/tests/examples/__init__.py @@ -0,0 +1,11 @@ +if __name__ == '__main__': + import os + import glob + import unittest + test_file_strings = glob.glob('test_*.py') + module_strings = [str[0:len(str)-3] for str in test_file_strings] + suites = [unittest.defaultTestLoader.loadTestsFromName(str) for str + in module_strings] + testSuite = unittest.TestSuite(suites) + + unittest.TextTestRunner(verbosity=2).run(testSuite) diff --git a/SimPEG/Tests/test_example_linear.py b/tests/examples/test_examples.py similarity index 57% rename from SimPEG/Tests/test_example_linear.py rename to tests/examples/test_examples.py index b42d8a70..1fcf05f5 100644 --- a/SimPEG/Tests/test_example_linear.py +++ b/tests/examples/test_examples.py @@ -1,13 +1,17 @@ import unittest import sys -from SimPEG.Examples import Linear +from SimPEG.Examples import Linear, DCfwd import numpy as np class TestLinear(unittest.TestCase): - def test_running(self): Linear.run(100, plotIt=False) self.assertTrue(True) +class TestDCfwd(unittest.TestCase): + def test_running(self): + DCfwd.run(plotIt=False) + self.assertTrue(True) + if __name__ == '__main__': unittest.main() diff --git a/tests/flow/__init__.py b/tests/flow/__init__.py new file mode 100644 index 00000000..38d84328 --- /dev/null +++ b/tests/flow/__init__.py @@ -0,0 +1,11 @@ +if __name__ == '__main__': + import os + import glob + import unittest + test_file_strings = glob.glob('test_*.py') + module_strings = [str[0:len(str)-3] for str in test_file_strings] + suites = [unittest.defaultTestLoader.loadTestsFromName(str) for str + in module_strings] + testSuite = unittest.TestSuite(suites) + + unittest.TextTestRunner(verbosity=2).run(testSuite) diff --git a/tests/flow/test_Richards.py b/tests/flow/test_Richards.py new file mode 100644 index 00000000..d63a6210 --- /dev/null +++ b/tests/flow/test_Richards.py @@ -0,0 +1,288 @@ +import unittest +from SimPEG import * +from SimPEG.Tests import OrderTest, checkDerivative +from scipy.sparse.linalg import dsolve +from SimPEG.FLOW import Richards +try: + from pymatsolver import MumpsSolver + Solver = MumpsSolver +except Exception, e: + pass + + +TOL = 1E-8 + +np.random.seed(0) + +class TestModels(unittest.TestCase): + + def test_BaseHaverkamp_Theta(self): + mesh = Mesh.TensorMesh([50]) + hav = Richards.Empirical._haverkamp_theta(mesh) + m = np.random.randn(50) + def wrapper(u): + return hav.transform(u, m), hav.transformDerivU(u, m) + passed = checkDerivative(wrapper, np.random.randn(50), plotIt=False) + self.assertTrue(passed,True) + + def test_vangenuchten_theta(self): + mesh = Mesh.TensorMesh([50]) + hav = Richards.Empirical._vangenuchten_theta(mesh) + m = np.random.randn(50) + def wrapper(u): + return hav.transform(u, m), hav.transformDerivU(u, m) + passed = checkDerivative(wrapper, np.random.randn(50), plotIt=False) + self.assertTrue(passed,True) + + def test_BaseHaverkamp_k(self): + mesh = Mesh.TensorMesh([50]) + hav = Richards.Empirical._haverkamp_k(mesh) + m = np.random.randn(50) + def wrapper(u): + return hav.transform(u, m), hav.transformDerivU(u, m) + passed = checkDerivative(wrapper, np.random.randn(50), plotIt=False) + self.assertTrue(passed,True) + + hav = Richards.Empirical._haverkamp_k(mesh) + u = np.random.randn(50) + def wrapper(m): + return hav.transform(u, m), hav.transformDerivM(u, m) + passed = checkDerivative(wrapper, np.random.randn(50), plotIt=False) + self.assertTrue(passed,True) + + def test_vangenuchten_k(self): + mesh = Mesh.TensorMesh([50]) + hav = Richards.Empirical._vangenuchten_k(mesh) + m = np.random.randn(50) + def wrapper(u): + return hav.transform(u, m), hav.transformDerivU(u, m) + passed = checkDerivative(wrapper, np.random.randn(50), plotIt=False) + self.assertTrue(passed,True) + + hav = Richards.Empirical._vangenuchten_k(mesh) + u = np.random.randn(50) + def wrapper(m): + return hav.transform(u, m), hav.transformDerivM(u, m) + passed = checkDerivative(wrapper, np.random.randn(50), plotIt=False) + self.assertTrue(passed,True) + + + +class RichardsTests1D(unittest.TestCase): + + def setUp(self): + M = Mesh.TensorMesh([np.ones(20)]) + M.setCellGradBC('dirichlet') + + params = Richards.Empirical.HaverkampParams().celia1990 + params['Ks'] = np.log(params['Ks']) + E = Richards.Empirical.Haverkamp(M, **params) + + bc = np.array([-61.5,-20.7]) + h = np.zeros(M.nC) + bc[0] + + prob = Richards.RichardsProblem(M, mapping=E, timeSteps=[(40,3),(60,3)], tolRootFinder=1e-6, debug=False, + boundaryConditions=bc, initialConditions=h, + doNewton=False, method='mixed') + prob.Solver = Solver + + locs = np.r_[5.,10,15] + times = prob.times[3:5] + rxSat = Richards.RichardsRx(locs, times, 'saturation') + rxPre = Richards.RichardsRx(locs, times, 'pressureHead') + survey = Richards.RichardsSurvey([rxSat, rxPre]) + + prob.pair(survey) + + self.h0 = h + self.M = M + self.Ks = params['Ks'] + self.prob = prob + self.survey = survey + + def test_Richards_getResidual_Newton(self): + self.prob.doNewton = True + m = self.Ks + passed = checkDerivative(lambda hn1: self.prob.getResidual(m, self.h0, hn1, self.prob.timeSteps[0], self.prob.boundaryConditions), self.h0, plotIt=False) + self.assertTrue(passed,True) + + def test_Richards_getResidual_Picard(self): + self.prob.doNewton = False + m = self.Ks + passed = checkDerivative(lambda hn1: self.prob.getResidual(m, self.h0, hn1, self.prob.timeSteps[0], self.prob.boundaryConditions), self.h0, plotIt=False, expectedOrder=1) + self.assertTrue(passed,True) + + def test_Adjoint(self): + v = np.random.rand(self.survey.nD) + z = np.random.rand(self.M.nC) + Hs = self.prob.fields(self.Ks) + vJz = v.dot(self.prob.Jvec(self.Ks,z,u=Hs)) + zJv = z.dot(self.prob.Jtvec(self.Ks,v,u=Hs)) + tol = TOL*(10**int(np.log10(np.abs(zJv)))) + passed = np.abs(vJz - zJv) < tol + print 'Richards Adjoint Test - PressureHead' + print '%4.4e === %4.4e, diff=%4.4e < %4.e'%(vJz, zJv,np.abs(vJz - zJv),tol) + self.assertTrue(passed,True) + + def test_Sensitivity(self): + mTrue = self.Ks*np.ones(self.M.nC) + derChk = lambda m: [self.survey.dpred(m), lambda v: self.prob.Jvec(m, v)] + print 'Testing Richards Derivative' + passed = checkDerivative(derChk, mTrue, num=4, plotIt=False) + self.assertTrue(passed,True) + + + def test_Sensitivity_full(self): + mTrue = self.Ks*np.ones(self.M.nC) + J = self.prob.Jfull(mTrue) + derChk = lambda m: [self.survey.dpred(m), J] + print 'Testing Richards Derivative FULL' + passed = checkDerivative(derChk, mTrue, num=4, plotIt=False) + self.assertTrue(passed,True) + + +class RichardsTests2D(unittest.TestCase): + + def setUp(self): + M = Mesh.TensorMesh([np.ones(8),np.ones(30)]) + + M.setCellGradBC(['neumann','dirichlet']) + + params = Richards.Empirical.HaverkampParams().celia1990 + params['Ks'] = np.log(params['Ks']) + E = Richards.Empirical.Haverkamp(M, **params) + + bc = np.array([-61.5,-20.7]) + bc = np.r_[np.zeros(M.nCy*2),np.ones(M.nCx)*bc[0],np.ones(M.nCx)*bc[1]] + h = np.zeros(M.nC) + bc[0] + prob = Richards.RichardsProblem(M,E, timeSteps=[(40,3),(60,3)], boundaryConditions=bc, initialConditions=h, doNewton=False, method='mixed', tolRootFinder=1e-6, debug=False) + prob.Solver = Solver + + locs = Utils.ndgrid(np.array([5,7.]),np.array([5,15,25.])) + times = prob.times[3:5] + rxSat = Richards.RichardsRx(locs, times, 'saturation') + rxPre = Richards.RichardsRx(locs, times, 'pressureHead') + survey = Richards.RichardsSurvey([rxSat, rxPre]) + + prob.pair(survey) + + self.h0 = h + self.M = M + self.Ks = params['Ks'] + self.prob = prob + self.survey = survey + + def test_Richards_getResidual_Newton(self): + self.prob.doNewton = True + m = self.Ks + passed = checkDerivative(lambda hn1: self.prob.getResidual(m, self.h0, hn1, self.prob.timeSteps[0], self.prob.boundaryConditions), self.h0, plotIt=False) + self.assertTrue(passed,True) + + def test_Richards_getResidual_Picard(self): + self.prob.doNewton = False + m = self.Ks + passed = checkDerivative(lambda hn1: self.prob.getResidual(m, self.h0, hn1, self.prob.timeSteps[0], self.prob.boundaryConditions), self.h0, plotIt=False, expectedOrder=1) + self.assertTrue(passed,True) + + def test_Adjoint(self): + v = np.random.rand(self.survey.nD) + z = np.random.rand(self.M.nC) + Hs = self.prob.fields(self.Ks) + vJz = v.dot(self.prob.Jvec(self.Ks,z,u=Hs)) + zJv = z.dot(self.prob.Jtvec(self.Ks,v,u=Hs)) + tol = TOL*(10**int(np.log10(np.abs(zJv)))) + passed = np.abs(vJz - zJv) < tol + print '2D: Richards Adjoint Test - PressureHead' + print '%4.4e === %4.4e, diff=%4.4e < %4.e'%(vJz, zJv,np.abs(vJz - zJv),tol) + self.assertTrue(passed,True) + + def test_Sensitivity(self): + mTrue = self.Ks*np.ones(self.M.nC) + derChk = lambda m: [self.survey.dpred(m), lambda v: self.prob.Jvec(m, v)] + print '2D: Testing Richards Derivative' + passed = checkDerivative(derChk, mTrue, num=3, plotIt=False) + self.assertTrue(passed,True) + + def test_Sensitivity_full(self): + mTrue = self.Ks*np.ones(self.M.nC) + J = self.prob.Jfull(mTrue) + derChk = lambda m: [self.survey.dpred(m), J] + print '2D: Testing Richards Derivative FULL' + passed = checkDerivative(derChk, mTrue, num=4, plotIt=False) + self.assertTrue(passed,True) + + + +class RichardsTests3D(unittest.TestCase): + + def setUp(self): + M = Mesh.TensorMesh([np.ones(8),np.ones(20),np.ones(10)]) + + M.setCellGradBC(['neumann','neumann','dirichlet']) + + params = Richards.Empirical.HaverkampParams().celia1990 + params['Ks'] = np.log(params['Ks']) + E = Richards.Empirical.Haverkamp(M, **params) + + bc = np.array([-61.5,-20.7]) + bc = np.r_[np.zeros(M.nCy*M.nCz*2),np.zeros(M.nCx*M.nCz*2),np.ones(M.nCx*M.nCy)*bc[0],np.ones(M.nCx*M.nCy)*bc[1]] + h = np.zeros(M.nC) + bc[0] + prob = Richards.RichardsProblem(M,E, timeSteps=[(40,3),(60,3)], boundaryConditions=bc, initialConditions=h, doNewton=False, method='mixed', tolRootFinder=1e-6, debug=False) + prob.Solver = Solver + + locs = Utils.ndgrid(np.r_[5,7.],np.r_[5,15.],np.r_[6,8.]) + times = prob.times[3:5] + rxSat = Richards.RichardsRx(locs, times, 'saturation') + rxPre = Richards.RichardsRx(locs, times, 'pressureHead') + survey = Richards.RichardsSurvey([rxSat, rxPre]) + + prob.pair(survey) + + self.h0 = h + self.M = M + self.Ks = params['Ks'] + self.prob = prob + self.survey = survey + + def test_Richards_getResidual_Newton(self): + self.prob.doNewton = True + m = self.Ks + passed = checkDerivative(lambda hn1: self.prob.getResidual(m, self.h0, hn1, self.prob.timeSteps[0], self.prob.boundaryConditions), self.h0, plotIt=False) + self.assertTrue(passed,True) + + def test_Richards_getResidual_Picard(self): + self.prob.doNewton = False + m = self.Ks + passed = checkDerivative(lambda hn1: self.prob.getResidual(m, self.h0, hn1, self.prob.timeSteps[0], self.prob.boundaryConditions), self.h0, plotIt=False, expectedOrder=1) + self.assertTrue(passed,True) + + def test_Adjoint(self): + v = np.random.rand(self.survey.nD) + z = np.random.rand(self.M.nC) + Hs = self.prob.fields(self.Ks) + vJz = v.dot(self.prob.Jvec(self.Ks,z,u=Hs)) + zJv = z.dot(self.prob.Jtvec(self.Ks,v,u=Hs)) + tol = TOL*(10**int(np.log10(np.abs(zJv)))) + passed = np.abs(vJz - zJv) < tol + print '3D: Richards Adjoint Test - PressureHead' + print '%4.4e === %4.4e, diff=%4.4e < %4.e'%(vJz, zJv,np.abs(vJz - zJv),tol) + self.assertTrue(passed,True) + + def test_Sensitivity(self): + mTrue = self.Ks*np.ones(self.M.nC) + derChk = lambda m: [self.survey.dpred(m), lambda v: self.prob.Jvec(m, v)] + print '3D: Testing Richards Derivative' + passed = checkDerivative(derChk, mTrue, num=4, plotIt=False) + self.assertTrue(passed,True) + + # def test_Sensitivity_full(self): + # mTrue = self.Ks*np.ones(self.M.nC) + # J = self.prob.Jfull(mTrue) + # derChk = lambda m: [self.survey.dpred(m), J] + # print '3D: Testing Richards Derivative FULL' + # passed = checkDerivative(derChk, mTrue, num=4, plotIt=False) + # self.assertTrue(passed,True) + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/flow/test_examples.py b/tests/flow/test_examples.py new file mode 100644 index 00000000..bc519e6d --- /dev/null +++ b/tests/flow/test_examples.py @@ -0,0 +1,12 @@ +import unittest +import sys +from SimPEG.FLOW.Examples import Celia1990 +import numpy as np + +class TestCelia1990(unittest.TestCase): + def test_running(self): + Celia1990.run(plotIt=False) + self.assertTrue(True) + +if __name__ == '__main__': + unittest.main() diff --git a/tests/mesh/__init__.py b/tests/mesh/__init__.py new file mode 100644 index 00000000..38d84328 --- /dev/null +++ b/tests/mesh/__init__.py @@ -0,0 +1,11 @@ +if __name__ == '__main__': + import os + import glob + import unittest + test_file_strings = glob.glob('test_*.py') + module_strings = [str[0:len(str)-3] for str in test_file_strings] + suites = [unittest.defaultTestLoader.loadTestsFromName(str) for str + in module_strings] + testSuite = unittest.TestSuite(suites) + + unittest.TextTestRunner(verbosity=2).run(testSuite) diff --git a/SimPEG/Tests/test_CurvilinearMesh.py b/tests/mesh/test_CurvilinearMesh.py similarity index 100% rename from SimPEG/Tests/test_CurvilinearMesh.py rename to tests/mesh/test_CurvilinearMesh.py 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 new file mode 100644 index 00000000..e624ce87 --- /dev/null +++ b/tests/mesh/test_TreeMesh.py @@ -0,0 +1,306 @@ +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): + 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) + print M + 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_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): + + 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): + + 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 + +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__': + unittest.main() diff --git a/tests/mesh/test_TreeOperators.py b/tests/mesh/test_TreeOperators.py new file mode 100644 index 00000000..c16f6b23 --- /dev/null +++ b/tests/mesh/test_TreeOperators.py @@ -0,0 +1,675 @@ +import numpy as np +import unittest +from SimPEG import Utils, Tests +import matplotlib.pyplot as plt + +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 + +class TestFaceDiv2D(Tests.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(Tests.OrderTest): + name = "Face Divergence 3D" + meshTypes = MESHTYPES + meshSizes = [8, 16] + + def getError(self): + 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(Tests.OrderTest): + name = "Curl" + meshTypes = ['notatreeTree', 'uniformTree'] #, 'randomTree']#, 'uniformTree'] + meshSizes = [8, 16]#, 32] + 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)) + # 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) + # err = np.linalg.norm((curlE - curlE_ana)*self.M.area, 2) + + return err + + def test_order(self): + 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.""" + + meshTypes = ['uniformTree', 'notatreeTree'] #['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'] + 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() + + +class TestTreeAveraging2D(Tests.OrderTest): + """Integrate an function over a unit cube domain using edgeInnerProducts and faceInnerProducts.""" + + meshTypes = ['notatreeTree', 'uniformTree']#, 'randomTree'] + meshDimension = 2 + 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) + + 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_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)) + 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 + +class TestAveraging3D(Tests.OrderTest): + name = "Averaging 3D" + meshTypes = ['notatreeTree', 'uniformTree']#, 'randomTree'] + meshDimension = 3 + meshSizes = [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 + + 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_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)) + 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_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)) + 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() diff --git a/SimPEG/Tests/test_basemesh.py b/tests/mesh/test_basemesh.py similarity index 100% rename from SimPEG/Tests/test_basemesh.py rename to tests/mesh/test_basemesh.py diff --git a/SimPEG/Tests/test_boundaryPoisson.py b/tests/mesh/test_boundaryPoisson.py similarity index 98% rename from SimPEG/Tests/test_boundaryPoisson.py rename to tests/mesh/test_boundaryPoisson.py index 6e10b827..1accb578 100644 --- a/SimPEG/Tests/test_boundaryPoisson.py +++ b/tests/mesh/test_boundaryPoisson.py @@ -1,13 +1,12 @@ import numpy as np import scipy.sparse as sp import unittest -from TestUtils import OrderTest import matplotlib.pyplot as plt from SimPEG import * MESHTYPES = ['uniformTensorMesh'] -class Test1D_InhomogeneousDirichlet(OrderTest): +class Test1D_InhomogeneousDirichlet(Tests.OrderTest): name = "1D - Dirichlet" meshTypes = MESHTYPES meshDimension = 1 @@ -88,7 +87,7 @@ class Test1D_InhomogeneousDirichlet(OrderTest): self.orderTest() -class Test2D_InhomogeneousDirichlet(OrderTest): +class Test2D_InhomogeneousDirichlet(Tests.OrderTest): name = "2D - Dirichlet" meshTypes = MESHTYPES meshDimension = 2 @@ -169,7 +168,7 @@ class Test2D_InhomogeneousDirichlet(OrderTest): self.myTest = 'xcJ' self.orderTest() -class Test1D_InhomogeneousNeumann(OrderTest): +class Test1D_InhomogeneousNeumann(Tests.OrderTest): name = "1D - Neumann" meshTypes = MESHTYPES meshDimension = 1 @@ -246,7 +245,7 @@ class Test1D_InhomogeneousNeumann(OrderTest): self.myTest = 'xcJ' self.orderTest() -class Test2D_InhomogeneousNeumann(OrderTest): +class Test2D_InhomogeneousNeumann(Tests.OrderTest): name = "2D - Neumann" meshTypes = MESHTYPES meshDimension = 2 @@ -333,7 +332,7 @@ class Test2D_InhomogeneousNeumann(OrderTest): self.myTest = 'xcJ' self.orderTest() -class Test1D_InhomogeneousMixed(OrderTest): +class Test1D_InhomogeneousMixed(Tests.OrderTest): name = "1D - Mixed" meshTypes = MESHTYPES meshDimension = 1 @@ -410,7 +409,7 @@ class Test1D_InhomogeneousMixed(OrderTest): self.myTest = 'xcJ' self.orderTest() -class Test2D_InhomogeneousMixed(OrderTest): +class Test2D_InhomogeneousMixed(Tests.OrderTest): name = "2D - Mixed" meshTypes = MESHTYPES meshDimension = 2 diff --git a/SimPEG/Tests/test_cylMesh.py b/tests/mesh/test_cylMesh.py similarity index 99% rename from SimPEG/Tests/test_cylMesh.py rename to tests/mesh/test_cylMesh.py index 6bb6cbd3..5a963398 100644 --- a/SimPEG/Tests/test_cylMesh.py +++ b/tests/mesh/test_cylMesh.py @@ -1,7 +1,6 @@ import unittest import sys from SimPEG import * -from TestUtils import OrderTest class TestCyl2DMesh(unittest.TestCase): @@ -217,7 +216,7 @@ cyl_row3 = lambda g, xfun, yfun, zfun: np.c_[call3(xfun, g), call3(yfun, g), cal cylF2 = lambda M, fx, fy: np.vstack((cyl_row2(M.gridFx, fx, fy), cyl_row2(M.gridFz, fx, fy))) -class TestFaceDiv2D(OrderTest): +class TestFaceDiv2D(Tests.OrderTest): name = "FaceDiv" meshTypes = MESHTYPES meshDimension = 2 @@ -242,7 +241,7 @@ class TestFaceDiv2D(OrderTest): def test_order(self): self.orderTest() -class TestEdgeCurl2D(OrderTest): +class TestEdgeCurl2D(Tests.OrderTest): name = "EdgeCurl" meshTypes = MESHTYPES meshDimension = 2 @@ -281,7 +280,7 @@ class TestEdgeCurl2D(OrderTest): self.orderTest() -# class TestInnerProducts2D(OrderTest): +# class TestInnerProducts2D(Tests.OrderTest): # """Integrate an function over a unit cube domain using edgeInnerProducts and faceInnerProducts.""" # meshTypes = MESHTYPES diff --git a/SimPEG/Tests/test_innerProduct.py b/tests/mesh/test_innerProduct.py similarity index 98% rename from SimPEG/Tests/test_innerProduct.py rename to tests/mesh/test_innerProduct.py index 0a5ff809..cebecf2b 100644 --- a/SimPEG/Tests/test_innerProduct.py +++ b/tests/mesh/test_innerProduct.py @@ -1,10 +1,9 @@ import numpy as np import unittest -from TestUtils import OrderTest -from SimPEG import Utils +from SimPEG import Utils, Tests -class TestInnerProducts(OrderTest): +class TestInnerProducts(Tests.OrderTest): """Integrate an function over a unit cube domain using edgeInnerProducts and faceInnerProducts.""" meshTypes = ['uniformTensorMesh', 'uniformCurv', 'rotateCurv'] @@ -151,7 +150,7 @@ class TestInnerProducts(OrderTest): self.orderTest() -class TestInnerProducts2D(OrderTest): +class TestInnerProducts2D(Tests.OrderTest): """Integrate an function over a unit cube domain using edgeInnerProducts and faceInnerProducts.""" meshTypes = ['uniformTensorMesh', 'uniformCurv', 'rotateCurv'] @@ -293,7 +292,7 @@ class TestInnerProducts2D(OrderTest): -class TestInnerProducts1D(OrderTest): +class TestInnerProducts1D(Tests.OrderTest): """Integrate an function over a unit cube domain using edgeInnerProducts and faceInnerProducts.""" meshTypes = ['uniformTensorMesh'] diff --git a/SimPEG/Tests/test_innerProductDerivs.py b/tests/mesh/test_innerProductDerivs.py similarity index 81% rename from SimPEG/Tests/test_innerProductDerivs.py rename to tests/mesh/test_innerProductDerivs.py index 6eb561c1..41ba5dcd 100644 --- a/SimPEG/Tests/test_innerProductDerivs.py +++ b/tests/mesh/test_innerProductDerivs.py @@ -1,7 +1,6 @@ import numpy as np import unittest from SimPEG import * -from TestUtils import checkDerivative class TestInnerProductsDerivs(unittest.TestCase): @@ -11,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) @@ -21,14 +22,16 @@ class TestInnerProductsDerivs(unittest.TestCase): Md = mesh.getFaceInnerProductDeriv(sig, invProp=invProp, invMat=invMat, doFast=fast) return M*v, Md(v) print meshType, 'Face', h, rep, fast, ('harmonic' if invProp and invMat else 'standard') - return checkDerivative(fun, sig, num=5, plotIt=False) + return Tests.checkDerivative(fun, sig, num=5, plotIt=False) def doTestEdge(self, h, rep, fast, meshType, invProp=False, invMat=False): if meshType == 'Curv': 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) @@ -38,7 +41,7 @@ class TestInnerProductsDerivs(unittest.TestCase): Md = mesh.getEdgeInnerProductDeriv(sig, invProp=invProp, invMat=invMat, doFast=fast) return M*v, Md(v) print meshType, 'Edge', h, rep, fast, ('harmonic' if invProp and invMat else 'standard') - return checkDerivative(fun, sig, num=5, plotIt=False) + return Tests.checkDerivative(fun, sig, num=5, plotIt=False) def test_FaceIP_1D_float(self): self.assertTrue(self.doTestFace([10],0, False, 'Tensor')) @@ -198,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')) + self.assertTrue(self.doTestFace([8, 8],0, True, 'Tree')) def test_FaceIP_3D_float_fast_Tree(self): - self.assertTrue(self.doTestFace([10, 4, 5],0, True, 'Tree')) + self.assertTrue(self.doTestFace([8, 8, 8],0, True, 'Tree')) def test_FaceIP_2D_isotropic_fast_Tree(self): - self.assertTrue(self.doTestFace([10, 4],1, True, 'Tree')) + self.assertTrue(self.doTestFace([8, 8],1, True, 'Tree')) def test_FaceIP_3D_isotropic_fast_Tree(self): - self.assertTrue(self.doTestFace([10, 4, 5],1, True, 'Tree')) + self.assertTrue(self.doTestFace([8, 8, 8],1, True, 'Tree')) def test_FaceIP_2D_anisotropic_fast_Tree(self): - self.assertTrue(self.doTestFace([10, 4],2, True, 'Tree')) + self.assertTrue(self.doTestFace([8, 8],2, True, 'Tree')) def test_FaceIP_3D_anisotropic_fast_Tree(self): - self.assertTrue(self.doTestFace([10, 4, 5],3, True, 'Tree')) + 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_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([10, 4, 5],0, True, 'Tree')) - def test_EdgeIP_2D_isotropic_fast_Tree(self): - self.assertTrue(self.doTestEdge([10, 4],1, True, 'Tree')) + 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([10, 4, 5],1, True, 'Tree')) - def test_EdgeIP_2D_anisotropic_fast_Tree(self): - self.assertTrue(self.doTestEdge([10, 4],2, True, 'Tree')) + 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([10, 4, 5],3, True, 'Tree')) + self.assertTrue(self.doTestEdge([8, 8, 8],3, True, 'Tree')) if __name__ == '__main__': unittest.main() diff --git a/SimPEG/Tests/test_interpolation.py b/tests/mesh/test_interpolation.py similarity index 97% rename from SimPEG/Tests/test_interpolation.py rename to tests/mesh/test_interpolation.py index e3c0176d..a6804950 100644 --- a/SimPEG/Tests/test_interpolation.py +++ b/tests/mesh/test_interpolation.py @@ -1,8 +1,7 @@ import numpy as np import unittest -from TestUtils import OrderTest from SimPEG.Utils import mkvc -from SimPEG import Mesh +from SimPEG import Mesh, Tests import unittest @@ -23,7 +22,7 @@ cartE3 = lambda M, ex, ey, ez: np.vstack((cart_row3(M.gridEx, ex, ey, ez), cart_ TOL = 1e-7 -class TestInterpolation1D(OrderTest): +class TestInterpolation1D(Tests.OrderTest): LOCS = np.random.rand(50)*0.6+0.2 name = "Interpolation 1D" meshTypes = MESHTYPES @@ -69,7 +68,7 @@ class TestOutliersInterp1D(unittest.TestCase): Q = M.getInterpolationMat(np.array([[-1],[0.126],[0.127]]),'CC',zerosOutside=True) self.assertTrue(np.linalg.norm(Q*x - np.r_[0,1.004,1.008]) < TOL) -class TestInterpolation2d(OrderTest): +class TestInterpolation2d(Tests.OrderTest): name = "Interpolation 2D" LOCS = np.random.rand(50,2)*0.6+0.2 meshTypes = MESHTYPES @@ -152,7 +151,7 @@ class TestInterpolation2dCyl_Simple(unittest.TestCase): self.assertRaises(Exception,lambda:M.getInterpolationMat(locs, 'Ez')) -class TestInterpolation2dCyl(OrderTest): +class TestInterpolation2dCyl(Tests.OrderTest): name = "Interpolation 2D" LOCS = np.c_[np.random.rand(4)*0.6+0.2, np.zeros(4), np.random.rand(4)*0.6+0.2] meshTypes = ['uniformCylMesh'] # MESHTYPES + @@ -220,7 +219,7 @@ class TestInterpolation2dCyl(OrderTest): self.name = 'Interpolation 2D CYLMESH: Ey' self.orderTest() -class TestInterpolation3D(OrderTest): +class TestInterpolation3D(Tests.OrderTest): name = "Interpolation" LOCS = np.random.rand(50,3)*0.6+0.2 meshTypes = MESHTYPES diff --git a/SimPEG/Tests/test_operators.py b/tests/mesh/test_operators.py similarity index 99% rename from SimPEG/Tests/test_operators.py rename to tests/mesh/test_operators.py index 416689bc..3b99345c 100644 --- a/SimPEG/Tests/test_operators.py +++ b/tests/mesh/test_operators.py @@ -1,6 +1,6 @@ import numpy as np import unittest -from TestUtils import OrderTest +from SimPEG.Tests import OrderTest import matplotlib.pyplot as plt #TODO: 'randomTensorMesh' diff --git a/SimPEG/Tests/test_tensorMesh.py b/tests/mesh/test_tensorMesh.py similarity index 97% rename from SimPEG/Tests/test_tensorMesh.py rename to tests/mesh/test_tensorMesh.py index b9335164..dd5f461c 100644 --- a/SimPEG/Tests/test_tensorMesh.py +++ b/tests/mesh/test_tensorMesh.py @@ -1,8 +1,7 @@ import numpy as np import unittest from SimPEG.Mesh import TensorMesh -from TestUtils import OrderTest -from SimPEG import Solver +from SimPEG import Solver, Tests TOL = 1e-10 @@ -91,7 +90,7 @@ class BasicTensorMeshTests(unittest.TestCase): M = TensorMesh([[(10.,2)]]) self.assertLess(np.abs(M.hx - np.r_[10.,10.]).sum(), TOL) -class TestPoissonEqn(OrderTest): +class TestPoissonEqn(Tests.OrderTest): name = "Poisson Equation" meshSizes = [10, 16, 20] diff --git a/tests/utils/__init__.py b/tests/utils/__init__.py new file mode 100644 index 00000000..38d84328 --- /dev/null +++ b/tests/utils/__init__.py @@ -0,0 +1,11 @@ +if __name__ == '__main__': + import os + import glob + import unittest + test_file_strings = glob.glob('test_*.py') + module_strings = [str[0:len(str)-3] for str in test_file_strings] + suites = [unittest.defaultTestLoader.loadTestsFromName(str) for str + in module_strings] + testSuite = unittest.TestSuite(suites) + + unittest.TextTestRunner(verbosity=2).run(testSuite) diff --git a/tests/utils/test_Zero.py b/tests/utils/test_Zero.py new file mode 100644 index 00000000..be7c9bbe --- /dev/null +++ b/tests/utils/test_Zero.py @@ -0,0 +1,129 @@ +import unittest +from SimPEG.Utils import Zero, Identity, sdiag +from SimPEG import np, sp + +class Tests(unittest.TestCase): + + def test_zero(self): + z = Zero() + assert z == 0 + assert not (z < 0) + assert z <= 0 + assert not (z > 0) + assert z >= 0 + assert +z == z + assert -z == z + assert z + 1 == 1 + assert z + 3 +z == 3 + assert z - 3 == -3 + assert z - 3 -z == -3 + assert 3*z == 0 + assert z*3 == 0 + assert z/3 == 0 + self.assertRaises(ZeroDivisionError, lambda:3/z) + + def test_mat_zero(self): + z = Zero() + S = sdiag(np.r_[2,3]) + assert S*z == 0 + + def test_one(self): + o = Identity() + assert o == 1 + assert not (o < 1) + assert o <= 1 + assert not (o > 1) + assert o >= 1 + o = -o + assert o == -1 + assert not (o < -1) + assert o <= -1 + assert not (o > -1) + assert o >= -1 + assert -(-o)*o == -o + o = Identity() + assert +o == o + assert -o == -o + assert o*3 == 3 + assert -o*3 == -3 + assert -o*o == -1 + assert -o*o*-o == 1 + assert -o + 3 == 2 + assert 3 + -o == 2 + + assert -o - 3 == -4 + assert o - 3 == -2 + assert 3 - -o == 4 + assert 3 - o == 2 + + assert o/2 == 0 + assert o/2. == 0.5 + assert -o/2 == -1 + assert -o/2. == -0.5 + assert 2/o == 2 + assert 2/-o == -2 + + + def test_mat_one(self): + + o = Identity() + S = sdiag(np.r_[2,3]) + def check(exp,ans): + assert np.all((exp).todense() == ans) + + check(S * o, [[2,0],[0,3]]) + check(o * S, [[2,0],[0,3]]) + check(S * -o, [[-2,0],[0,-3]]) + check(-o * S, [[-2,0],[0,-3]]) + check(S/o, [[2,0],[0,3]]) + check(S/-o, [[-2,0],[0,-3]]) + self.assertRaises(NotImplementedError, lambda:o/S) + + check(S + o, [[3,0],[0,4]]) + check(o + S, [[3,0],[0,4]]) + + check(S + - o, [[1,0],[0,2]]) + check(S - o, [[1,0],[0,2]]) + check(- o + S, [[1,0],[0,2]]) + + def test_mat_shape(self): + o = Identity() + S = sdiag(np.r_[2,3])[:1,:] + self.assertRaises(ValueError, lambda:S + o) + def check(exp,ans): + assert np.all((exp).todense() == ans) + check(S * o, [[2,0]]) + check(S * -o, [[-2,0]]) + + def test_numpy_one(self): + o = Identity() + n = np.r_[2.,3] + assert np.all(n+1 == n+o) + assert np.all(1+n == o+n) + assert np.all(n-1 == n-o) + assert np.all(1-n == o-n) + assert np.all(n/1 == n/o) + assert np.all(n/-1 == n/-o) + assert np.all(1/n == o/n) + assert np.all(-1/n == -o/n) + assert np.all(n*1 == n*o) + assert np.all(n*-1 == n*-o) + assert np.all(1*n == o*n) + assert np.all(-1*n == -o*n) + + def test_both(self): + z = Zero() + o = Identity() + assert o*z == 0 + assert o*z + o == 1 + assert o-z == 1 + + + +if __name__ == '__main__': + unittest.main() + + + + + diff --git a/tests/utils/test_coordutils.py b/tests/utils/test_coordutils.py new file mode 100644 index 00000000..24f8451c --- /dev/null +++ b/tests/utils/test_coordutils.py @@ -0,0 +1,56 @@ +import unittest, os +import numpy as np +from SimPEG import Utils + +tol = 1e-15 + +class coorUtilsTest(unittest.TestCase): + + def test_rotationMatrixFromNormals(self): + np.random.seed(0) + v0 = np.random.rand(3) + v0 *= 1./np.linalg.norm(v0) + + np.random.seed(5) + v1 = np.random.rand(3) + v1 *= 1./np.linalg.norm(v1) + + Rf = Utils.coordutils.rotationMatrixFromNormals(v0,v1) + Ri = Utils.coordutils.rotationMatrixFromNormals(v1,v0) + + self.assertTrue(np.linalg.norm(Utils.mkvc(Rf.dot(v0) - v1)) < tol) + self.assertTrue(np.linalg.norm(Utils.mkvc(Ri.dot(v1) - v0)) < tol) + + def test_rotatePointsFromNormals(self): + np.random.seed(10) + v0 = np.random.rand(3) + v0*= 1./np.linalg.norm(v0) + + np.random.seed(15) + v1 = np.random.rand(3) + v1*= 1./np.linalg.norm(v1) + + v2 = Utils.mkvc(Utils.coordutils.rotatePointsFromNormals(Utils.mkvc(v0,2).T,v0,v1)) + + self.assertTrue(np.linalg.norm(v2-v1) < tol) + + def test_rotateMatrixFromNormals(self): + np.random.seed(20) + n0 = np.random.rand(3) + n0 *= 1./np.linalg.norm(n0) + + np.random.seed(25) + n1 = np.random.rand(3) + n1 *= 1./np.linalg.norm(n1) + + np.random.seed(30) + scale = np.random.rand(100,1) + XYZ0 = scale * n0 + XYZ1 = scale * n1 + + XYZ2 = Utils.coordutils.rotatePointsFromNormals(XYZ0,n0,n1) + self.assertTrue(np.linalg.norm(Utils.mkvc(XYZ1) - Utils.mkvc(XYZ2))/np.linalg.norm(Utils.mkvc(XYZ1)) < tol) + +if __name__ == '__main__': + unittest.main() + diff --git a/SimPEG/Tests/test_utils.py b/tests/utils/test_utils.py similarity index 100% rename from SimPEG/Tests/test_utils.py rename to tests/utils/test_utils.py