def aveCCV2F(self): """ Construct the averaging operator on cell centers to faces as a vector. """ if getattr(self, '_aveCCV2F', None) is None: if self.dim == 1: self._aveCCV2F = self.aveCC2F elif self.dim == 2: aveCCV2Fx = sp.kron(speye(self.nCy), av_extrap(self.nCx)) aveCC2VFy = sp.kron(av_extrap(self.nCy), speye(self.nCx)) self._aveCCV2F = sp.block_diag(( aveCCV2Fx, aveCC2VFy ), format="csr") elif self.dim == 3: aveCCV2Fx = kron3( speye(self.nCz), speye(self.nCy), av_extrap(self.nCx) ) aveCC2VFy = kron3( speye(self.nCz), av_extrap(self.nCy), speye(self.nCx) ) aveCC2BFz = kron3( av_extrap(self.nCz), speye(self.nCy), speye(self.nCx) ) self._aveCCV2F = sp.block_diag(( aveCCV2Fx, aveCC2VFy, aveCC2BFz ), format="csr") return self._aveCCV2F
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 _edgeCurlStencily(self): n = self.vnC # The number of cell centers in each direction D31 = kron3(ddx(n[2]), speye(n[1] + 1), speye(n[0])) D13 = kron3(speye(n[2]), speye(n[1] + 1), ddx(n[0])) # O2 = spzeros(np.shape(D31)[0], np.shape(D32)[1]) O2 = spzeros(n[0] * (n[1] + 1) * n[2], (n[0] + 1) * n[1] * (n[2] + 1)) return sp.hstack((D31, O2, -D13))
def _edgeCurlStencilz(self): n = self.vnC # The number of cell centers in each direction D21 = kron3(speye(n[2] + 1), ddx(n[1]), speye(n[0])) D12 = kron3(speye(n[2] + 1), speye(n[1]), ddx(n[0])) # O3 = spzeros(np.shape(D21)[0], np.shape(D13)[1]) O3 = spzeros(n[0] * n[1] * (n[2] + 1), (n[0] + 1) * (n[1] + 1) * n[2]) return sp.hstack((-D21, D12, O3))
def _edgeCurlStencilx(self): n = self.vnC # The number of cell centers in each direction D32 = kron3(ddx(n[2]), speye(n[1]), speye(n[0] + 1)) D23 = kron3(speye(n[2]), ddx(n[1]), speye(n[0] + 1)) # O1 = spzeros(np.shape(D32)[0], np.shape(D31)[1]) O1 = spzeros((n[0] + 1) * n[1] * n[2], n[0] * (n[1] + 1) * (n[2] + 1)) return sp.hstack((O1, -D32, D23))
def _cellGradStencil(self): BC = self.setCellGradBC(self._cellGradBC_list) if self.dim == 1: G = ddxCellGrad(self.nCx, BC[0]) elif self.dim == 2: G1 = sp.kron(speye(self.nCy), ddxCellGrad(self.nCx, BC[0])) G2 = sp.kron(ddxCellGrad(self.nCy, BC[1]), speye(self.nCx)) G = sp.vstack((G1, G2), format="csr") elif self.dim == 3: G1 = kron3(speye(self.nCz), speye(self.nCy), ddxCellGrad(self.nCx, BC[0])) G2 = kron3(speye(self.nCz), ddxCellGrad(self.nCy, BC[1]), speye(self.nCx)) G3 = kron3(ddxCellGrad(self.nCz, BC[2]), speye(self.nCy), speye(self.nCx)) G = sp.vstack((G1, G2, G3), format="csr") return G
def _nodalLaplacianx(self): Hx = sdiag(1. / self.hx) if self.dim == 2: Hx = sp.kron(speye(self.nNy), Hx) elif self.dim == 3: Hx = kron3(speye(self.nNz), speye(self.nNy), Hx) return Hx.T * self._nodalGradStencilx * Hx
def _cellGradzStencil(self): if self.dim < 3: return None BC = ['neumann', 'neumann'] # TODO: remove this hard-coding n = self.vnC G3 = kron3(ddxCellGrad(n[2], BC), speye(n[1]), speye(n[0])) return G3
def _aveN2Fy(self): if self.dim == 1: return None elif self.dim == 2: aveN2Fy = sp.kron(speye(self.nNy), av(self.nCx)) elif self.dim == 3: aveN2Fy = kron3(av(self.nCz), speye(self.nNy), av(self.nCx)) return aveN2Fy
def _aveN2Fx(self): if self.dim == 1: aveN2Fx = av(self.nCx) elif self.dim == 2: aveN2Fx = sp.kron(av(self.nCy), speye(self.nNx)) elif self.dim == 3: aveN2Fx = kron3(av(self.nCz), av(self.nCy), speye(self.nNx)) return aveN2Fx
def _faceDivStencilz(self): """ Face divergence operator in the z-direction (z-faces to cell centers) """ if self.dim == 1 or self.dim == 2: return None elif self.dim == 3: Dz = kron3(ddx(self.nCz), speye(self.nCy), speye(self.nCx)) return Dz
def _nodalGradStencilz(self): """ Stencil for the nodal grad in the z-direction (nodes to z- edges) """ if self.dim == 1 or self.dim == 2: return None else: Gz = kron3(ddx(self.nCz), speye(self.nNy), speye(self.nNx)) return Gz
def _nodalLaplacianStencilz(self): warnings.warn('Laplacian has not been tested rigorously.') if self.dim == 1 or self.dim == 2: return None Dz = ddx(self.nCz) Lz = -Dz.T * Dz return kron3(Lz, speye(self.nNy), speye(self.nNx))
def _nodalLaplaciany(self): Hy = sdiag(1. / self.hy) if self.dim == 1: return None elif self.dim == 2: Hy = sp.kron(Hy, speye(self.nNx)) elif self.dim == 3: Hy = kron3(speye(self.nNz), Hy, speye(self.nNx)) return Hy.T * self._nodalGradStencily * Hy
def _cellGradyStencil(self): if self.dim < 2: return None BC = ['neumann', 'neumann'] # TODO: remove this hard-coding 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])) return G2
def _nodalGradStencilx(self): """ Stencil for the nodal grad in the x-direction (nodes to x-edges) """ if self.dim == 1: Gx = ddx(self.nCx) elif self.dim == 2: Gx = sp.kron(speye(self.nNy), ddx(self.nCx)) elif self.dim == 3: Gx = kron3(speye(self.nNz), speye(self.nNy), ddx(self.nCx)) return Gx
def _aveN2Ex(self): """ Averaging operator on cell nodes to x-edges """ if self.dim == 1: aveN2Ex = av(self.nCx) elif self.dim == 2: aveN2Ex = sp.kron(speye(self.nNy), av(self.nCx)) elif self.dim == 3: aveN2Ex = kron3(speye(self.nNz), speye(self.nNy), av(self.nCx)) return aveN2Ex
def _cellGradxStencil(self): # TODO: remove this hard-coding BC = ['neumann', 'neumann'] if self.dim == 1: G1 = ddxCellGrad(self.nCx, BC) elif self.dim == 2: G1 = sp.kron(speye(self.nCy), ddxCellGrad(self.nCx, BC)) elif self.dim == 3: G1 = kron3(speye(self.nCz), speye(self.nCy), ddxCellGrad(self.nCx, BC)) return G1
def _aveN2Ey(self): """ Averaging operator on cell nodes to y-edges """ if self.dim == 1: return None elif self.dim == 2: aveN2Ey = sp.kron(av(self.nCy), speye(self.nNx)) elif self.dim == 3: aveN2Ey = kron3(speye(self.nNz), av(self.nCy), speye(self.nNx)) return aveN2Ey
def _faceDivStencilx(self): """ Face divergence operator in the x-direction (x-faces to cell centers) """ if self.dim == 1: Dx = ddx(self.nCx) elif self.dim == 2: Dx = sp.kron(speye(self.nCy), ddx(self.nCx)) elif self.dim == 3: Dx = kron3(speye(self.nCz), speye(self.nCy), ddx(self.nCx)) return Dx
def _nodalLaplacianStencilx(self): warnings.warn('Laplacian has not been tested rigorously.') Dx = ddx(self.nCx) Lx = -Dx.T * Dx if self.dim == 2: Lx = sp.kron(speye(self.nNy), Lx) elif self.dim == 3: Lx = kron3(speye(self.nNz), speye(self.nNy), Lx) return Lx
def _faceDivStencily(self): """ Face divergence operator in the y-direction (y-faces to cell centers) """ if self.dim == 1: return None elif self.dim == 2: Dy = sp.kron(ddx(self.nCy), speye(self.nCx)) elif self.dim == 3: Dy = kron3(speye(self.nCz), ddx(self.nCy), speye(self.nCx)) return Dy
def _nodalGradStencily(self): """ Stencil for the nodal grad in the y-direction (nodes to y-edges) """ if self.dim == 1: return None elif self.dim == 2: Gy = sp.kron(ddx(self.nCy), speye(self.nNx)) elif self.dim == 3: Gy = kron3(speye(self.nNz), ddx(self.nCy), speye(self.nNx)) return Gy
def aveCC2F(self): "Construct the averaging operator on cell centers to faces." if getattr(self, '_aveCC2F', None) is None: if self.dim == 1: self._aveCC2F = av_extrap(self.nCx) elif self.dim == 2: self._aveCC2F = sp.vstack( (sp.kron(speye(self.nCy), av_extrap(self.nCx)), sp.kron(av_extrap(self.nCy), speye(self.nCx))), format="csr") elif self.dim == 3: self._aveCC2F = sp.vstack( (kron3(speye(self.nCz), speye(self.nCy), av_extrap( self.nCx)), kron3(speye(self.nCz), av_extrap(self.nCy), speye( self.nCx)), kron3(av_extrap(self.nCz), speye(self.nCy), speye( self.nCx))), format="csr") return self._aveCC2F
def aveN2CC(self): "Construct the averaging operator on cell nodes to cell centers." if getattr(self, '_aveN2CC', None) is None: # The number of cell centers in each direction if self.dim == 1: self._aveN2CC = av(self.nCx) elif self.dim == 2: self._aveN2CC = sp.kron(av(self.nCy), av(self.nCx)).tocsr() elif self.dim == 3: self._aveN2CC = kron3(av(self.nCz), av(self.nCy), av(self.nCx)).tocsr() return self._aveN2CC
def aveFz2CC(self): """ Construct the averaging operator on cell faces in the z direction to cell centers. """ if self.dim < 3: return None if getattr(self, '_aveFz2CC', None) is None: n = self.vnC if (self.dim == 3): self._aveFz2CC = kron3(av(n[2]), speye(n[1]), speye(n[0])) return self._aveFz2CC
def aveEz2CC(self): """ Construct the averaging operator on cell edges in the z direction to cell centers. """ if self.dim < 3: return None if getattr(self, '_aveEz2CC', None) is None: # The number of cell centers in each direction n = self.vnC if (self.dim == 3): self._aveEz2CC = kron3(speye(n[2]), av(n[1]), av(n[0])) return self._aveEz2CC
def _nodalLaplacianStencily(self): warnings.warn('Laplacian has not been tested rigorously.') if self.dim == 1: return None Dy = ddx(self.nCy) Ly = -Dy.T * Dy if self.dim == 2: Ly = sp.kron(Ly, speye(self.nNx)) elif self.dim == 3: Ly = kron3(speye(self.nNz), Ly, speye(self.nNx)) return Ly
def aveEx2CC(self): """ Construct the averaging operator on cell edges in the x direction to cell centers. """ if getattr(self, '_aveEx2CC', None) is None: # The number of cell centers in each direction n = self.vnC if self.dim == 1: self._aveEx2CC = speye(n[0]) elif self.dim == 2: self._aveEx2CC = sp.kron(av(n[1]), speye(n[0])) elif self.dim == 3: self._aveEx2CC = kron3(av(n[2]), av(n[1]), speye(n[0])) return self._aveEx2CC
def aveFx2CC(self): """ Construct the averaging operator on cell faces in the x direction to cell centers. """ if getattr(self, '_aveFx2CC', None) is None: n = self.vnC if self.dim == 1: self._aveFx2CC = av(n[0]) elif self.dim == 2: self._aveFx2CC = sp.kron(speye(n[1]), av(n[0])) elif self.dim == 3: self._aveFx2CC = kron3(speye(n[2]), speye(n[1]), av(n[0])) return self._aveFx2CC