def getP(self, mesh, Gloc): if mesh in self._Ps: return self._Ps[mesh] # Find indices for pole receivers inds_dipole = (np.linalg.norm(self.locs[0] - self.locs[1], axis=1) > self.threshold) P0 = mesh.getInterpolationMat(self.locs[0][inds_dipole], Gloc) P1 = mesh.getInterpolationMat(self.locs[1][inds_dipole], Gloc) P = P0 - P1 # Generate interpolation matrix for pole receivers if ~np.alltrue(inds_dipole): P0_pole = mesh.getInterpolationMat(self.locs[0][~inds_dipole], Gloc) P = sp.vstack((P, P0_pole)) if self.data_type == 'apparent_resistivity': P = sdiag(1. / self.geometric_factor) * P elif self.data_type == 'apparent_chargeability': P = sdiag(1. / self.dc_voltage) * P if self.storeProjections: self._Ps[mesh] = P return P
def edgeCurl(self): """The edgeCurl property.""" if self.nCy > 1: raise NotImplementedError( 'Edge curl not yet implemented for nCy > 1') if getattr(self, '_edgeCurl', None) is None: #1D Difference matricies dr = sp.spdiags((np.ones((self.nCx + 1, 1)) * [-1, 1]).T, [-1, 0], self.nCx, self.nCx, format="csr") dz = sp.spdiags((np.ones((self.nCz + 1, 1)) * [-1, 1]).T, [0, 1], self.nCz, self.nCz + 1, format="csr") #2D Difference matricies Dr = sp.kron(sp.identity(self.nNz), dr) Dz = -sp.kron(dz, sp.identity(self.nCx)) A = self.area E = self.edge #Edge curl operator self._edgeCurl = sdiag(1 / A) * sp.vstack((Dz, Dr)) * sdiag(E) return self._edgeCurl
def faceDivx(self): """Construct divergence operator in the x component (face-stg to cell-centres).""" if getattr(self, '_faceDivx', None) is None: D1 = kron3(speye(self.nCz), speye(self.nCy), ddx(self.nCx)[:, 1:]) S = self.r(self.area, 'F', 'Fx', 'V') V = self.vol self._faceDivx = sdiag(1 / V) * D1 * sdiag(S) return self._faceDivx
def faceDivz(self): """Construct divergence operator in the z component (face-stg to cell-centres).""" if getattr(self, '_faceDivz', None) is None: D3 = kron3(ddx(self.nCz), speye(self.nCy), speye(self.nCx)) S = self.r(self.area, 'F', 'Fz', 'V') V = self.vol self._faceDivz = sdiag(1 / V) * D3 * sdiag(S) return self._faceDivz
def faceDivx(self): """Construct divergence operator in the x component (face-stg to cell-centres).""" if getattr(self, '_faceDivx', None) is None: D1 = kron3(speye(self.nCz), speye(self.nCy), ddx(self.nCx)[:,1:]) S = self.r(self.area, 'F', 'Fx', 'V') V = self.vol self._faceDivx = sdiag(1/V)*D1*sdiag(S) return self._faceDivx
def faceDivz(self): """Construct divergence operator in the z component (face-stg to cell-centres).""" if getattr(self, '_faceDivz', None) is None: D3 = kron3(ddx(self.nCz), speye(self.nCy), speye(self.nCx)) S = self.r(self.area, 'F', 'Fz', 'V') V = self.vol self._faceDivz = sdiag(1/V)*D3*sdiag(S) return self._faceDivz
def faceDivy(self): """Construct divergence operator in the y component (face-stg to cell-centres).""" raise NotImplementedError('Wrapping the ddx is not yet implemented.') if getattr(self, '_faceDivy', None) is None: # TODO: this needs to wrap to join up faces which are connected in the cylinder D2 = kron3(speye(self.nCz), ddx(self.nCy), speye(self.nCx)) S = self.r(self.area, 'F', 'Fy', 'V') V = self.vol self._faceDivy = sdiag(1 / V) * D2 * sdiag(S) return self._faceDivy
def faceDivy(self): """Construct divergence operator in the y component (face-stg to cell-centres).""" raise NotImplementedError('Wrapping the ddx is not yet implemented.') if getattr(self, '_faceDivy', None) is None: # TODO: this needs to wrap to join up faces which are connected in the cylinder D2 = kron3(speye(self.nCz), ddx(self.nCy), speye(self.nCx)) S = self.r(self.area, 'F', 'Fy', 'V') V = self.vol self._faceDivy = sdiag(1/V)*D2*sdiag(S) return self._faceDivy
def fget(self): if(self.dim < 3): return None if(self._faceDivz is None): # The number of cell centers in each direction n = self.vnC # Compute faceDivergence operator on faces D3 = kron3(ddx(n[2]), speye(n[1]), speye(n[0])) # Compute areas of cell faces & volumes S = self.r(self.area, 'F', 'Fz', 'V') V = self.vol self._faceDivz = sdiag(1/V)*D3*sdiag(S) return self._faceDivz
def getP(self, mesh, Gloc): if mesh in self._Ps: return self._Ps[mesh] P = mesh.getInterpolationMat(self.locs, Gloc) if self.data_type == 'apparent_resistivity': P = sdiag(1. / self.geometric_factor) * P elif self.data_type == 'apparent_chargeability': P = sdiag(1. / self.dc_voltage) * P if self.storeProjections: self._Ps[mesh] = P return P
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 a = 1 a += z assert a == 1 a = 1 a += z assert a == 1 self.assertRaises(ZeroDivisionError, lambda:3/z) assert mkvc(z) == 0 assert sdiag(z)*a == 0 assert z.T == 0 assert z.transpose == 0
def faceDivy(self): if (self.dim < 2): return None if getattr(self, '_faceDivy', None) is None: # The number of cell centers in each direction n = self.vnC # Compute faceDivergence operator on faces if (self.dim == 2): D2 = sp.kron(ddx(n[1]), speye(n[0])) elif (self.dim == 3): D2 = kron3(speye(n[2]), ddx(n[1]), speye(n[0])) # Compute areas of cell faces & volumes S = self.r(self.area, 'F', 'Fy', 'V') V = self.vol self._faceDivy = sdiag(1 / V) * D2 * sdiag(S) return self._faceDivy
def makeMassMatrices(self, m): mu = self.muMap * m self._MfMui = self.mesh.getFaceInnerProduct(1. / mu) / self.mesh.dim # self._MfMui = self.mesh.getFaceInnerProduct(1./mu) # TODO: this will break if tensor mu self._MfMuI = sdiag(1. / self._MfMui.diagonal()) self._MfMu0 = self.mesh.getFaceInnerProduct(1. / mu_0) / self.mesh.dim
def cellGradBC(self): """ The cell centered Gradient boundary condition matrix """ if getattr(self, '_cellGradBC', None) is None: BC = self.setCellGradBC(self._cellGradBC_list) n = self.vnC if (self.dim == 1): G = ddxCellGradBC(n[0], BC[0]) elif (self.dim == 2): G1 = sp.kron(speye(n[1]), ddxCellGradBC(n[0], BC[0])) G2 = sp.kron(ddxCellGradBC(n[1], BC[1]), speye(n[0])) G = sp.block_diag((G1, G2), format="csr") elif (self.dim == 3): G1 = kron3(speye(n[2]), speye(n[1]), ddxCellGradBC(n[0], BC[0])) G2 = kron3(speye(n[2]), ddxCellGradBC(n[1], BC[1]), speye(n[0])) G3 = kron3(ddxCellGradBC(n[2], BC[2]), speye(n[1]), speye(n[0])) G = sp.block_diag((G1, G2, G3), format="csr") # Compute areas of cell faces & volumes S = self.area V = self.aveCC2F * self.vol # Average volume between adjacent cells self._cellGradBC = sdiag(S / V) * G return self._cellGradBC
def getq(self, mesh): srcind = Utils.closestPoints(mesh, self.loc, gridLoc='CC') q = sdiag(1 / mesh.vol) * np.zeros(mesh.nC) q[srcind] = 1. return q
def getq(self, mesh): srcind = Utils.closestPoints(mesh, self.loc, gridLoc='CC') q = sdiag(1/mesh.vol)*np.zeros(mesh.nC) q[srcind] = 1. return q
def getJtJdiag(self, m, W=None): """ Return the diagonal of JtJ """ dmudm = self.chiMap.deriv(m) self._dSdm = None self._dfdm = None self.model = m if (self.gtgdiag is None) and (self.modelType != 'amplitude'): if W is None: w = np.ones(self.G.shape[1]) else: w = W.diagonal() self.gtgdiag = np.zeros(dmudm.shape[1]) for ii in range(self.G.shape[0]): self.gtgdiag += (w[ii]*self.G[ii, :]*dmudm)**2. if self.coordinate_system == 'cartesian': if self.modelType == 'amplitude': return np.sum((W * self.dfdm * self.G * dmudm)**2., axis=0) else: return self.gtgdiag else: # spherical if self.modelType == 'amplitude': return np.sum(((W * self.dfdm) * self.G * (self.dSdm * dmudm))**2., axis=0) else: Japprox = sdiag(mkvc(self.gtgdiag)**0.5*dmudm.T) * (self.dSdm * dmudm) return mkvc(np.sum(Japprox.power(2), axis=0))
def fget(self): if(self.dim < 2): return None if(self._faceDivy is None): # The number of cell centers in each direction n = self.vnC # Compute faceDivergence operator on faces if(self.dim == 2): D2 = sp.kron(ddx(n[1]), speye(n[0])) elif(self.dim == 3): D2 = kron3(speye(n[2]), ddx(n[1]), speye(n[0])) # Compute areas of cell faces & volumes S = self.r(self.area, 'F', 'Fy', 'V') V = self.vol self._faceDivy = sdiag(1/V)*D2*sdiag(S) return self._faceDivy
def getInterpolationMatCartMesh(self, Mrect, locType='CC'): """ Takes a cartesian mesh and returns a projection to translate onto the cartesian grid. """ assert self.isSymmetric, "Currently we have not taken into account other projections for more complicated CylMeshes" if locType == 'F': # do this three times for each component X = self.getInterpolationMatCartMesh(Mrect, locType='Fx') Y = self.getInterpolationMatCartMesh(Mrect, locType='Fy') Z = self.getInterpolationMatCartMesh(Mrect, locType='Fz') return sp.vstack((X, Y, Z)) if locType == 'E': X = self.getInterpolationMatCartMesh(Mrect, locType='Ex') Y = self.getInterpolationMatCartMesh(Mrect, locType='Ey') Z = spzeros(Mrect.nEz, self.nE) return sp.vstack((X, Y, Z)) grid = getattr(Mrect, 'grid' + locType) # This is unit circle stuff, 0 to 2*pi, starting at x-axis, rotating counter clockwise in an x-y slice theta = -np.arctan2(grid[:, 0] - self.cartesianOrigin[0], grid[:, 1] - self.cartesianOrigin[1]) + np.pi / 2 theta[theta < 0] += np.pi * 2.0 r = ((grid[:, 0] - self.cartesianOrigin[0])**2 + (grid[:, 1] - self.cartesianOrigin[1])**2)**0.5 if locType in ['CC', 'N', 'Fz', 'Ez']: G, proj = np.c_[r, theta, grid[:, 2]], np.ones(r.size) else: dotMe = { 'Fx': Mrect.normals[:Mrect.nFx, :], 'Fy': Mrect.normals[Mrect.nFx:(Mrect.nFx + Mrect.nFy), :], 'Fz': Mrect.normals[-Mrect.nFz:, :], 'Ex': Mrect.tangents[:Mrect.nEx, :], 'Ey': Mrect.tangents[Mrect.nEx:(Mrect.nEx + Mrect.nEy), :], 'Ez': Mrect.tangents[-Mrect.nEz:, :], }[locType] if 'F' in locType: normals = np.c_[np.cos(theta), np.sin(theta), np.zeros(theta.size)] proj = (normals * dotMe).sum(axis=1) if 'E' in locType: tangents = np.c_[-np.sin(theta), np.cos(theta), np.zeros(theta.size)] proj = (tangents * dotMe).sum(axis=1) G = np.c_[r, theta, grid[:, 2]] interpType = locType if interpType == 'Fy': interpType = 'Fx' elif interpType == 'Ex': interpType = 'Ey' Pc2r = self.getInterpolationMat(G, interpType) Proj = sdiag(proj) return Proj * Pc2r
def faceDivz(self): """ Construct divergence operator in the z component (face-stg to cell-centers). """ if (self.dim < 3): return None if getattr(self, '_faceDivz', None) is None: # The number of cell centers in each direction n = self.vnC # Compute faceDivergence operator on faces D3 = kron3(ddx(n[2]), speye(n[1]), speye(n[0])) # Compute areas of cell faces & volumes S = self.r(self.area, 'F', 'Fz', 'V') V = self.vol self._faceDivz = sdiag(1 / V) * D3 * sdiag(S) return self._faceDivz
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 faceDivz(self): """ Construct divergence operator in the z component (face-stg to cell-centres). """ if(self.dim < 3): return None if getattr(self, '_faceDivz', None) is None: # The number of cell centers in each direction n = self.vnC # Compute faceDivergence operator on faces D3 = kron3(ddx(n[2]), speye(n[1]), speye(n[0])) # Compute areas of cell faces & volumes S = self.r(self.area, 'F', 'Fz', 'V') V = self.vol self._faceDivz = sdiag(1/V)*D3*sdiag(S) return self._faceDivz
def fget(self): if(self._faceDivx is None): # The number of cell centers in each direction n = self.vnC # Compute faceDivergence operator on faces if(self.dim == 1): D1 = ddx(n[0]) elif(self.dim == 2): D1 = sp.kron(speye(n[1]), ddx(n[0])) elif(self.dim == 3): D1 = kron3(speye(n[2]), speye(n[1]), ddx(n[0])) # Compute areas of cell faces & volumes S = self.r(self.area, 'F', 'Fx', 'V') V = self.vol self._faceDivx = sdiag(1/V)*D1*sdiag(S) return self._faceDivx
def edgeCurl(self): """The edgeCurl property.""" if self.nCy > 1: raise NotImplementedError('Edge curl not yet implemented for nCy > 1') if getattr(self, '_edgeCurl', None) is None: #1D Difference matricies dr = sp.spdiags((np.ones((self.nCx+1, 1))*[-1, 1]).T, [-1,0], self.nCx, self.nCx, format="csr") dz = sp.spdiags((np.ones((self.nCz+1, 1))*[-1, 1]).T, [0,1], self.nCz, self.nCz+1, format="csr") #2D Difference matricies Dr = sp.kron(sp.identity(self.nNz), dr) Dz = -sp.kron(dz, sp.identity(self.nCx)) A = self.area E = self.edge #Edge curl operator self._edgeCurl = sdiag(1/A)*sp.vstack((Dz, Dr))*sdiag(E) return self._edgeCurl
def test_NewtonRoot(self): fun = lambda x, return_g=True: np.sin(x) if not return_g else ( np.sin(x), sdiag( np.cos(x) ) ) x = np.array([np.pi-0.3, np.pi+0.1, 0]) xopt = Optimization.NewtonRoot(comments=False).root(fun,x) x_true = np.array([np.pi,np.pi,0]) print('Newton Root Finding') print('xopt: ', xopt) print('x_true: ', x_true) self.assertTrue(np.linalg.norm(xopt-x_true,2) < TOL, True)
def __init__(self, mesh, **kwargs): Problem.BaseProblem.__init__(self, mesh, **kwargs) Pbc, Pin, self._Pout = \ self.mesh.getBCProjWF('neumann', discretization='CC') Dface = self.mesh.faceDiv Mc = sdiag(self.mesh.vol) self._Div = Mc * Dface * Pin.T * Pin
def getInterpolationMatCartMesh(self, Mrect, locType='CC', locTypeTo=None): """ Takes a cartesian mesh and returns a projection to translate onto the cartesian grid. """ assert self.isSymmetric, "Currently we have not taken into account other projections for more complicated CylMeshes" if locTypeTo is None: locTypeTo = locType if locType == 'F': # do this three times for each component X = self.getInterpolationMatCartMesh(Mrect, locType='Fx', locTypeTo=locTypeTo+'x') Y = self.getInterpolationMatCartMesh(Mrect, locType='Fy', locTypeTo=locTypeTo+'y') Z = self.getInterpolationMatCartMesh(Mrect, locType='Fz', locTypeTo=locTypeTo+'z') return sp.vstack((X,Y,Z)) if locType == 'E': X = self.getInterpolationMatCartMesh(Mrect, locType='Ex', locTypeTo=locTypeTo+'x') Y = self.getInterpolationMatCartMesh(Mrect, locType='Ey', locTypeTo=locTypeTo+'y') Z = spzeros(getattr(Mrect, 'n' + locTypeTo + 'z'), self.nE) return sp.vstack((X,Y,Z)) grid = getattr(Mrect, 'grid' + locTypeTo) # This is unit circle stuff, 0 to 2*pi, starting at x-axis, rotating counter clockwise in an x-y slice theta = - np.arctan2(grid[:,0] - self.cartesianOrigin[0], grid[:,1] - self.cartesianOrigin[1]) + np.pi/2 theta[theta < 0] += np.pi*2.0 r = ((grid[:,0] - self.cartesianOrigin[0])**2 + (grid[:,1] - self.cartesianOrigin[1])**2)**0.5 if locType in ['CC', 'N', 'Fz', 'Ez']: G, proj = np.c_[r, theta, grid[:,2]], np.ones(r.size) else: dotMe = { 'Fx': Mrect.normals[:Mrect.nFx,:], 'Fy': Mrect.normals[Mrect.nFx:(Mrect.nFx+Mrect.nFy),:], 'Fz': Mrect.normals[-Mrect.nFz:,:], 'Ex': Mrect.tangents[:Mrect.nEx,:], 'Ey': Mrect.tangents[Mrect.nEx:(Mrect.nEx+Mrect.nEy),:], 'Ez': Mrect.tangents[-Mrect.nEz:,:], }[locTypeTo] if 'F' in locType: normals = np.c_[np.cos(theta), np.sin(theta), np.zeros(theta.size)] proj = ( normals * dotMe ).sum(axis=1) if 'E' in locType: tangents = np.c_[-np.sin(theta), np.cos(theta), np.zeros(theta.size)] proj = ( tangents * dotMe ).sum(axis=1) G = np.c_[r, theta, grid[:,2]] interpType = locType if interpType == 'Fy': interpType = 'Fx' elif interpType == 'Ex': interpType = 'Ey' Pc2r = self.getInterpolationMat(G, interpType) Proj = sdiag(proj) return Proj * Pc2r
def cellGrady(self): if self.dim < 2: return None if getattr(self, '_cellGrady', None) is None: G2 = self._cellGradyStencil() # Compute areas of cell faces & volumes V = self.aveCC2F*self.vol L = self.r(self.area/V, 'F', 'Fy', 'V') self._cellGrady = sdiag(L)*G2 return self._cellGrady
def cellGrady(self): if self.dim < 2: return None if getattr(self, '_cellGrady', None) is None: G2 = self._cellGradyStencil() # Compute areas of cell faces & volumes V = self.aveCC2F * self.vol L = self.r(self.area / V, 'F', 'Fy', 'V') self._cellGrady = sdiag(L) * G2 return self._cellGrady
def cellGrad(self): """ The cell centered Gradient, takes you to cell faces. """ if getattr(self, '_cellGrad', None) is None: G = self._cellGradStencil() S = self.area # Compute areas of cell faces & volumes V = self.aveCC2F * self.vol # Average volume between adjacent cells self._cellGrad = sdiag(S / V) * G return self._cellGrad
def cellGrad(self): """ The cell centered Gradient, takes you to cell faces. """ if getattr(self, '_cellGrad', None) is None: G = self._cellGradStencil() S = self.area # Compute areas of cell faces & volumes V = self.aveCC2F*self.vol # Average volume between adjacent cells self._cellGrad = sdiag(S/V)*G return self._cellGrad
def fget(self): if self.dim < 3: return None if getattr(self, '_cellGradz', None) is None: BC = ['neumann', 'neumann'] n = self.vnC G3 = kron3(ddxCellGrad(n[2], BC), speye(n[1]), speye(n[0])) # Compute areas of cell faces & volumes V = self.aveCC2F*self.vol L = self.r(self.area/V, 'F','Fz', 'V') self._cellGradz = sdiag(L)*G3 return self._cellGradz
def _h(self, bSolution, srcList): """ Magnetic field from bSolution :param numpy.ndarray bSolution: field we solved for :param list srcList: list of sources :rtype: numpy.ndarray :return: magnetic field """ n = int(self._aveF2CCV.shape[0] / self._nC) #number of components VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol)) return VI * (self._aveF2CCV * (self._MfMui * self._b(bSolution, srcList)))
def cellGradx(self): """ Cell centered Gradient in the x dimension. Has neumann boundary conditions. """ if getattr(self, '_cellGradx', None) is None: G1 = self._cellGradxStencil() # Compute areas of cell faces & volumes V = self.aveCC2F * self.vol L = self.r(self.area / V, 'F', 'Fx', 'V') self._cellGradx = sdiag(L) * G1 return self._cellGradx
def cellGradx(self): """ Cell centered Gradient in the x dimension. Has neumann boundary conditions. """ if getattr(self, '_cellGradx', None) is None: G1 = self._cellGradxStencil() # Compute areas of cell faces & volumes V = self.aveCC2F*self.vol L = self.r(self.area/V, 'F','Fx', 'V') self._cellGradx = sdiag(L)*G1 return self._cellGradx
def _e(self, jSolution, srcList): """ Electric field from jSolution :param numpy.ndarray hSolution: field we solved for :param list srcList: list of sources :rtype: numpy.ndarray :return: electric field """ n = int(self._aveF2CCV.shape[0] / self._nC) # number of components VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol)) return VI * (self._aveF2CCV * (self._MfRho * self._j(jSolution, srcList)))
def faceDivx(self): """ Construct divergence operator in the x component (face-stg to cell-centres). """ if getattr(self, '_faceDivx', None) is None: # The number of cell centers in each direction n = self.vnC # Compute faceDivergence operator on faces if (self.dim == 1): D1 = ddx(n[0]) elif (self.dim == 2): D1 = sp.kron(speye(n[1]), ddx(n[0])) elif (self.dim == 3): D1 = kron3(speye(n[2]), speye(n[1]), ddx(n[0])) # Compute areas of cell faces & volumes S = self.r(self.area, 'F', 'Fx', 'V') V = self.vol self._faceDivx = sdiag(1 / V) * D1 * sdiag(S) return self._faceDivx
def faceDivx(self): """ Construct divergence operator in the x component (face-stg to cell-centres). """ if getattr(self, '_faceDivx', None) is None: # The number of cell centers in each direction n = self.vnC # Compute faceDivergence operator on faces if(self.dim == 1): D1 = ddx(n[0]) elif(self.dim == 2): D1 = sp.kron(speye(n[1]), ddx(n[0])) elif(self.dim == 3): D1 = kron3(speye(n[2]), speye(n[1]), ddx(n[0])) # Compute areas of cell faces & volumes S = self.r(self.area, 'F', 'Fx', 'V') V = self.vol self._faceDivx = sdiag(1/V)*D1*sdiag(S) return self._faceDivx
def fget(self): if(self._edgeCurl is None): assert self.dim > 1, "Edge Curl only programed for 2 or 3D." # The number of cell centers in each direction n = self.vnC # Compute lengths of cell edges L = self.edge # Compute areas of cell faces S = self.area # Compute divergence operator on faces if self.dim == 2: D21 = sp.kron(ddx(n[1]), speye(n[0])) D12 = sp.kron(speye(n[1]), ddx(n[0])) C = sp.hstack((-D21, D12), format="csr") self._edgeCurl = C*sdiag(1/S) elif self.dim == 3: D32 = kron3(ddx(n[2]), speye(n[1]), speye(n[0]+1)) D23 = kron3(speye(n[2]), ddx(n[1]), speye(n[0]+1)) D31 = kron3(ddx(n[2]), speye(n[1]+1), speye(n[0])) D13 = kron3(speye(n[2]), speye(n[1]+1), ddx(n[0])) D21 = kron3(speye(n[2]+1), ddx(n[1]), speye(n[0])) D12 = kron3(speye(n[2]+1), speye(n[1]), ddx(n[0])) O1 = spzeros(np.shape(D32)[0], np.shape(D31)[1]) O2 = spzeros(np.shape(D31)[0], np.shape(D32)[1]) O3 = spzeros(np.shape(D21)[0], np.shape(D13)[1]) C = sp.vstack((sp.hstack((O1, -D32, D23)), sp.hstack((D31, O2, -D13)), sp.hstack((-D21, D12, O3))), format="csr") self._edgeCurl = sdiag(1/S)*(C*sdiag(L)) return self._edgeCurl
def nodalLaplacian(self): """ Construct laplacian operator (nodes to edges). """ if getattr(self, '_nodalLaplacian', None) is None: print('Warning: Laplacian has not been tested rigorously.') # The number of cell centers in each direction n = self.vnC # Compute divergence operator on faces if (self.dim == 1): D1 = sdiag(1. / self.hx) * ddx(self.nCx) L = -D1.T * D1 elif (self.dim == 2): D1 = sdiag(1. / self.hx) * ddx(n[0]) D2 = sdiag(1. / self.hy) * ddx(n[1]) L1 = sp.kron(speye(n[1] + 1), -D1.T * D1) L2 = sp.kron(-D2.T * D2, speye(n[0] + 1)) L = L1 + L2 elif (self.dim == 3): D1 = sdiag(1. / self.hx) * ddx(n[0]) D2 = sdiag(1. / self.hy) * ddx(n[1]) D3 = sdiag(1. / self.hz) * ddx(n[2]) L1 = kron3(speye(n[2] + 1), speye(n[1] + 1), -D1.T * D1) L2 = kron3(speye(n[2] + 1), -D2.T * D2, speye(n[0] + 1)) L3 = kron3(-D3.T * D3, speye(n[1] + 1), speye(n[0] + 1)) L = L1 + L2 + L3 self._nodalLaplacian = L return self._nodalLaplacian
def fget(self): if(self._nodalLaplacian is None): print 'Warning: Laplacian has not been tested rigorously.' # The number of cell centers in each direction n = self.vnC # Compute divergence operator on faces if(self.dim == 1): D1 = sdiag(1./self.hx) * ddx(mesh.nCx) L = - D1.T*D1 elif(self.dim == 2): D1 = sdiag(1./self.hx) * ddx(n[0]) D2 = sdiag(1./self.hy) * ddx(n[1]) L1 = sp.kron(speye(n[1]+1), - D1.T * D1) L2 = sp.kron(- D2.T * D2, speye(n[0]+1)) L = L1 + L2 elif(self.dim == 3): D1 = sdiag(1./self.hx) * ddx(n[0]) D2 = sdiag(1./self.hy) * ddx(n[1]) D3 = sdiag(1./self.hz) * ddx(n[2]) L1 = kron3(speye(n[2]+1), speye(n[1]+1), - D1.T * D1) L2 = kron3(speye(n[2]+1), - D2.T * D2, speye(n[0]+1)) L3 = kron3(- D3.T * D3, speye(n[1]+1), speye(n[0]+1)) L = L1 + L2 + L3 self._nodalLaplacian = L return self._nodalLaplacian
def _b(self, jSolution, srcList): """ Secondary magnetic flux density from jSolution :param numpy.ndarray hSolution: field we solved for :param list srcList: list of sources :rtype: numpy.ndarray :return: secondary magnetic flux density """ n = int(self._aveE2CCV.shape[0] / self._nC) # number of components VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol)) return VI * (self._aveE2CCV * ( self._MeMu * self._h(jSolution,srcList)) )
def _j(self, eSolution, srcList): """ Current density from eSolution :param numpy.ndarray eSolution: field we solved for :param list srcList: list of sources :rtype: numpy.ndarray :return: current density """ aveE2CCV = self._aveE2CCV n = int(aveE2CCV.shape[0] / self._nC) # number of components (instead of checking if cyl or not) VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol)) return VI * (aveE2CCV * (self._MeSigma * self._e(eSolution,srcList) ) )
def fget(self): if(self._faceDiv is None): # The number of cell centers in each direction n = self.vnC # Compute faceDivergence operator on faces if(self.dim == 1): D = ddx(n[0]) elif(self.dim == 2): D1 = sp.kron(speye(n[1]), ddx(n[0])) D2 = sp.kron(ddx(n[1]), speye(n[0])) D = sp.hstack((D1, D2), format="csr") elif(self.dim == 3): D1 = kron3(speye(n[2]), speye(n[1]), ddx(n[0])) D2 = kron3(speye(n[2]), ddx(n[1]), speye(n[0])) D3 = kron3(ddx(n[2]), speye(n[1]), speye(n[0])) D = sp.hstack((D1, D2, D3), format="csr") # Compute areas of cell faces & volumes S = self.area V = self.vol self._faceDiv = sdiag(1/V)*D*sdiag(S) return self._faceDiv
def faceDiv(self): """ Construct divergence operator (face-stg to cell-centres). """ if getattr(self, '_faceDiv', None) is None: n = self.vnC # Compute faceDivergence operator on faces if (self.dim == 1): D = ddx(n[0]) elif (self.dim == 2): D1 = sp.kron(speye(n[1]), ddx(n[0])) D2 = sp.kron(ddx(n[1]), speye(n[0])) D = sp.hstack((D1, D2), format="csr") elif (self.dim == 3): D1 = kron3(speye(n[2]), speye(n[1]), ddx(n[0])) D2 = kron3(speye(n[2]), ddx(n[1]), speye(n[0])) D3 = kron3(ddx(n[2]), speye(n[1]), speye(n[0])) D = sp.hstack((D1, D2, D3), format="csr") # Compute areas of cell faces & volumes S = self.area V = self.vol self._faceDiv = sdiag(1 / V) * D * sdiag(S) return self._faceDiv
def fget(self): if self.dim < 2: return None if getattr(self, '_cellGrady', None) is None: BC = ['neumann', 'neumann'] n = self.vnC if(self.dim == 2): G2 = sp.kron(ddxCellGrad(n[1], BC), speye(n[0])) elif(self.dim == 3): G2 = kron3(speye(n[2]), ddxCellGrad(n[1], BC), speye(n[0])) # Compute areas of cell faces & volumes V = self.aveCC2F*self.vol L = self.r(self.area/V, 'F','Fy', 'V') self._cellGrady = sdiag(L)*G2 return self._cellGrady
def faceDiv(self): """ Construct divergence operator (face-stg to cell-centres). """ if getattr(self, '_faceDiv', None) is None: n = self.vnC # Compute faceDivergence operator on faces if(self.dim == 1): D = ddx(n[0]) elif(self.dim == 2): D1 = sp.kron(speye(n[1]), ddx(n[0])) D2 = sp.kron(ddx(n[1]), speye(n[0])) D = sp.hstack((D1, D2), format="csr") elif(self.dim == 3): D1 = kron3(speye(n[2]), speye(n[1]), ddx(n[0])) D2 = kron3(speye(n[2]), ddx(n[1]), speye(n[0])) D3 = kron3(ddx(n[2]), speye(n[1]), speye(n[0])) D = sp.hstack((D1, D2, D3), format="csr") # Compute areas of cell faces & volumes S = self.area V = self.vol self._faceDiv = sdiag(1/V)*D*sdiag(S) return self._faceDiv
def _j(self, bSolution, srcList): """ Secondary current density from bSolution :param numpy.ndarray bSolution: field we solved for :param list srcList: list of sources :rtype: numpy.ndarray :return: primary current density """ n = int(self._aveE2CCV.shape[0] / self._nC) # number of components VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol)) return VI * (self._aveE2CCV * ( self._MeSigma * self._e(bSolution,srcList ) ) )