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 _fastInnerProductDeriv(self, projType, prop, invProp=False, invMat=False): """ :param str projType: 'E' or 'F' :param TensorType tensorType: type of the tensor :param bool invProp: inverts the material property :param bool invMat: inverts the matrix :rtype: function :return: dMdmu, the derivative of the inner product matrix """ assert projType in ['F', 'E'], "projType must be 'F' for faces or 'E' for edges" tensorType = Utils.TensorType(self, prop) dMdprop = None if invMat: MI = self._fastInnerProduct(projType, prop, invProp=invProp, invMat=invMat) if tensorType == 0: Av = getattr(self, 'ave'+projType+'2CC') V = Utils.sdiag(self.vol) ones = sp.csr_matrix((np.ones(self.nC), (range(self.nC), np.zeros(self.nC))), shape=(self.nC,1)) if not invMat and not invProp: dMdprop = self.dim * Av.T * V * ones elif invMat and invProp: dMdprop = self.dim * Utils.sdiag(MI.diagonal()**2) * Av.T * V * ones * Utils.sdiag(1./prop**2) if tensorType == 1: Av = getattr(self, 'ave'+projType+'2CC') V = Utils.sdiag(self.vol) if not invMat and not invProp: dMdprop = self.dim * Av.T * V elif invMat and invProp: dMdprop = self.dim * Utils.sdiag(MI.diagonal()**2) * Av.T * V * Utils.sdiag(1./prop**2) if tensorType == 2: # anisotropic Av = getattr(self, 'ave'+projType+'2CCV') V = sp.kron(sp.identity(self.dim), Utils.sdiag(self.vol)) if not invMat and not invProp: dMdprop = Av.T * V elif invMat and invProp: dMdprop = Utils.sdiag(MI.diagonal()**2) * Av.T * V * Utils.sdiag(1./prop**2) if dMdprop is not None: def innerProductDeriv(v=None): if v is None: print 'Depreciation Warning: TensorMesh.innerProductDeriv. You should be supplying a vector. Use: sdiag(u)*dMdprop' return dMdprop return Utils.sdiag(v) * dMdprop return innerProductDeriv else: return None
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 faceDiv(self): if getattr(self, '_faceDiv', None) is None: self.number() # TODO: Preallocate! I, J, V = [], [], [] for cell in self.sortedCells: faces = cell.faceDict for face in faces: j = faces[face].index I += [cell.num]*len(j) J += j V += [-1 if 'm' in face else 1]*len(j) VOL = self.vol D = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.nF)) S = self.area self._faceDiv = Utils.sdiag(1/VOL)*D*Utils.sdiag(S) return self._faceDiv
def edgeCurl(self): """Construct the 3D curl operator.""" assert self.dim > 2, "Edge Curl only programed for 3D." if getattr(self, '_edgeCurl', None) is None: self.number() # TODO: Preallocate! I, J, V = [], [], [] for face in self.faces: for ii, edge in enumerate([face.edge0, face.edge1, face.edge2, face.edge3]): j = edge.index I += [face.num]*len(j) J += j isNeg = [True, False, True, False] V += [-1 if isNeg[ii] else 1]*len(j) C = sp.csr_matrix((V,(I,J)), shape=(self.nF, self.nE)) S = self.area L = self.edge self._edgeCurl = Utils.sdiag(1/S)*C*Utils.sdiag(L) return self._edgeCurl
def 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 _fastInnerProductDeriv(self, projType, prop, invProp=False, invMat=False): """ :param str projType: 'E' or 'F' :param TensorType tensorType: type of the tensor :param bool invProp: inverts the material property :param bool invMat: inverts the matrix :rtype: function :return: dMdmu, the derivative of the inner product matrix """ assert projType in [ 'F', 'E' ], "projType must be 'F' for faces or 'E' for edges" tensorType = Utils.TensorType(self, prop) dMdprop = None if invMat: MI = self._fastInnerProduct(projType, prop, invProp=invProp, invMat=invMat) if tensorType == 0: Av = getattr(self, 'ave' + projType + '2CC') V = Utils.sdiag(self.vol) ones = sp.csr_matrix( (np.ones(self.nC), (range(self.nC), np.zeros(self.nC))), shape=(self.nC, 1)) if not invMat and not invProp: dMdprop = self.dim * Av.T * V * ones elif invMat and invProp: dMdprop = self.dim * Utils.sdiag( MI.diagonal()**2) * Av.T * V * ones * Utils.sdiag( 1. / prop**2) if tensorType == 1: Av = getattr(self, 'ave' + projType + '2CC') V = Utils.sdiag(self.vol) if not invMat and not invProp: dMdprop = self.dim * Av.T * V elif invMat and invProp: dMdprop = self.dim * Utils.sdiag( MI.diagonal()**2) * Av.T * V * Utils.sdiag(1. / prop**2) if tensorType == 2: # anisotropic Av = getattr(self, 'ave' + projType + '2CCV') V = sp.kron(sp.identity(self.dim), Utils.sdiag(self.vol)) if not invMat and not invProp: dMdprop = Av.T * V elif invMat and invProp: dMdprop = Utils.sdiag(MI.diagonal()** 2) * Av.T * V * Utils.sdiag(1. / prop**2) if dMdprop is not None: def innerProductDeriv(v=None): if v is None: print 'Depreciation Warning: TensorMesh.innerProductDeriv. You should be supplying a vector. Use: sdiag(u)*dMdprop' return dMdprop return Utils.sdiag(v) * dMdprop return innerProductDeriv else: return None
def _fastInnerProductDeriv(self, projType, prop, invProp=False, invMat=False): """ :param str projType: 'E' or 'F' :param TensorType tensorType: type of the tensor :param bool invProp: inverts the material property :param bool invMat: inverts the matrix :rtype: function :return: dMdmu, the derivative of the inner product matrix """ assert projType in ['F', 'E'], ("projType must be 'F' for faces or 'E'" " for edges") tensorType = Utils.TensorType(self, prop) dMdprop = None if invMat or invProp: MI = self._fastInnerProduct(projType, prop, invProp=invProp, invMat=invMat) # number of elements we are averaging (equals dim for regular # meshes, but for cyl, where we use symmetry, it is 1 for edge # variables and 2 for face variables) if self._meshType == 'CYL': n_elements = np.sum(getattr(self, 'vn'+projType).nonzero()) else: n_elements = self.dim if tensorType == 0: # isotropic, constant Av = getattr(self, 'ave'+projType+'2CC') V = Utils.sdiag(self.vol) ones = sp.csr_matrix((np.ones(self.nC), (range(self.nC), np.zeros(self.nC))), shape=(self.nC, 1)) if not invMat and not invProp: dMdprop = n_elements * Av.T * V * ones elif invMat and invProp: dMdprop = n_elements * (Utils.sdiag(MI.diagonal()**2) * Av.T * V * ones * Utils.sdiag(1./prop**2)) elif invProp: dMdprop = n_elements * Av.T * V * Utils.sdiag(- 1./prop**2) elif invMat: dMdprop = n_elements * (Utils.sdiag(- MI.diagonal()**2) * Av.T * V) elif tensorType == 1: # isotropic, variable in space Av = getattr(self, 'ave'+projType+'2CC') V = Utils.sdiag(self.vol) if not invMat and not invProp: dMdprop = n_elements * Av.T * V elif invMat and invProp: dMdprop = n_elements * (Utils.sdiag(MI.diagonal()**2) * Av.T * V * Utils.sdiag(1./prop**2)) elif invProp: dMdprop = n_elements * Av.T * V * Utils.sdiag(-1./prop**2) elif invMat: dMdprop = n_elements * (Utils.sdiag(- MI.diagonal()**2) * Av.T * V) elif tensorType == 2: # anisotropic Av = getattr(self, 'ave'+projType+'2CCV') V = sp.kron(sp.identity(self.dim), Utils.sdiag(self.vol)) if self._meshType == 'CYL': Zero = sp.csr_matrix((self.nC, self.nC)) Eye = sp.eye(self.nC) if projType == 'E': P = sp.hstack([Zero, Eye, Zero]) # print P.todense() elif projType == 'F': P = sp.vstack([sp.hstack([Eye, Zero, Zero]), sp.hstack([Zero, Zero, Eye])]) # print P.todense() else: P = sp.eye(self.nC*self.dim) if not invMat and not invProp: dMdprop = Av.T * P * V elif invMat and invProp: dMdprop = (Utils.sdiag(MI.diagonal()**2) * Av.T * P * V * Utils.sdiag(1./prop**2)) elif invProp: dMdprop = Av.T * P * V * Utils.sdiag(-1./prop**2) elif invMat: dMdprop = Utils.sdiag(- MI.diagonal()**2) * Av.T * P * V if dMdprop is not None: def innerProductDeriv(v=None): if v is None: warnings.warn("Depreciation Warning: " "TensorMesh.innerProductDeriv." " You should be supplying a vector. " "Use: sdiag(u)*dMdprop", FutureWarning) return dMdprop return Utils.sdiag(v) * dMdprop return innerProductDeriv else: return None
def _fastInnerProductDeriv(self, projType, prop, invProp=False, invMat=False): """ :param str projType: 'E' or 'F' :param TensorType tensorType: type of the tensor :param bool invProp: inverts the material property :param bool invMat: inverts the matrix :rtype: function :return: dMdmu, the derivative of the inner product matrix """ assert projType in ["F", "E"], "projType must be 'F' for faces or 'E'" " for edges" tensorType = Utils.TensorType(self, prop) dMdprop = None if invMat or invProp: MI = self._fastInnerProduct(projType, prop, invProp=invProp, invMat=invMat) # number of elements we are averaging (equals dim for regular # meshes, but for cyl, where we use symmetry, it is 1 for edge # variables and 2 for face variables) if self._meshType == "CYL": n_elements = np.sum(getattr(self, "vn" + projType).nonzero()) else: n_elements = self.dim if tensorType == 0: # isotropic, constant Av = getattr(self, "ave" + projType + "2CC") V = Utils.sdiag(self.vol) ones = sp.csr_matrix((np.ones(self.nC), (range(self.nC), np.zeros(self.nC))), shape=(self.nC, 1)) if not invMat and not invProp: dMdprop = n_elements * Av.T * V * ones elif invMat and invProp: dMdprop = n_elements * ( Utils.sdiag(MI.diagonal() ** 2) * Av.T * V * ones * Utils.sdiag(1.0 / prop ** 2) ) elif invProp: dMdprop = n_elements * Av.T * V * Utils.sdiag(-1.0 / prop ** 2) elif invMat: dMdprop = n_elements * (Utils.sdiag(-MI.diagonal() ** 2) * Av.T * V) elif tensorType == 1: # isotropic, variable in space Av = getattr(self, "ave" + projType + "2CC") V = Utils.sdiag(self.vol) if not invMat and not invProp: dMdprop = n_elements * Av.T * V elif invMat and invProp: dMdprop = n_elements * (Utils.sdiag(MI.diagonal() ** 2) * Av.T * V * Utils.sdiag(1.0 / prop ** 2)) elif invProp: dMdprop = n_elements * Av.T * V * Utils.sdiag(-1.0 / prop ** 2) elif invMat: dMdprop = n_elements * (Utils.sdiag(-MI.diagonal() ** 2) * Av.T * V) elif tensorType == 2: # anisotropic Av = getattr(self, "ave" + projType + "2CCV") V = sp.kron(sp.identity(self.dim), Utils.sdiag(self.vol)) if self._meshType == "CYL": Zero = sp.csr_matrix((self.nC, self.nC)) Eye = sp.eye(self.nC) if projType == "E": P = sp.hstack([Zero, Eye, Zero]) # print(P.todense()) elif projType == "F": P = sp.vstack([sp.hstack([Eye, Zero, Zero]), sp.hstack([Zero, Zero, Eye])]) # print(P.todense()) else: P = sp.eye(self.nC * self.dim) if not invMat and not invProp: dMdprop = Av.T * P * V elif invMat and invProp: dMdprop = Utils.sdiag(MI.diagonal() ** 2) * Av.T * P * V * Utils.sdiag(1.0 / prop ** 2) elif invProp: dMdprop = Av.T * P * V * Utils.sdiag(-1.0 / prop ** 2) elif invMat: dMdprop = Utils.sdiag(-MI.diagonal() ** 2) * Av.T * P * V if dMdprop is not None: def innerProductDeriv(v=None): if v is None: warnings.warn( "Depreciation Warning: " "TensorMesh.innerProductDeriv." " You should be supplying a vector. " "Use: sdiag(u)*dMdprop", FutureWarning, ) return dMdprop return Utils.sdiag(v) * dMdprop return innerProductDeriv else: return None