def vol(self): """ Construct cell volumes of the 3D model as 1d array """ if getattr(self, '_vol', None) is None: if self.dim == 2: A, B, C, D = utils.indexCube('ABCD', self.vnC+1) normal, area = utils.faceInfo(np.c_[self.gridN, np.zeros( (self.nN, 1))], A, B, C, D) self._vol = area elif self.dim == 3: # Each polyhedron can be decomposed into 5 tetrahedrons # However, this presents a choice so we may as well divide in # two ways and average. A, B, C, D, E, F, G, H = utils.indexCube('ABCDEFGH', self.vnC + 1) vol1 = (utils.volTetra(self.gridN, A, B, D, E) + # cutted edge top utils.volTetra(self.gridN, B, E, F, G) + # cutted edge top utils.volTetra(self.gridN, B, D, E, G) + # middle utils.volTetra(self.gridN, B, C, D, G) + # cutted edge bottom utils.volTetra(self.gridN, D, E, G, H)) # cutted edge bottom vol2 = (utils.volTetra(self.gridN, A, F, B, C) + # cutted edge top utils.volTetra(self.gridN, A, E, F, H) + # cutted edge top utils.volTetra(self.gridN, A, H, F, C) + # middle utils.volTetra(self.gridN, C, H, D, A) + # cutted edge bottom utils.volTetra(self.gridN, C, G, H, F)) # cutted edge bottom self._vol = (vol1 + vol2)/2 return self._vol
def test_indexCube_3D(self): nN = np.array([3, 3, 3]) self.assertTrue( np.all( indexCube("A", nN) == np.array([0, 1, 3, 4, 9, 10, 12, 13]))) self.assertTrue( np.all( indexCube("B", nN) == np.array([3, 4, 6, 7, 12, 13, 15, 16]))) self.assertTrue( np.all( indexCube("C", nN) == np.array([4, 5, 7, 8, 13, 14, 16, 17]))) self.assertTrue( np.all( indexCube("D", nN) == np.array([1, 2, 4, 5, 10, 11, 13, 14]))) self.assertTrue( np.all( indexCube("E", nN) == np.array([9, 10, 12, 13, 18, 19, 21, 22 ]))) self.assertTrue( np.all( indexCube("F", nN) == np.array( [12, 13, 15, 16, 21, 22, 24, 25]))) self.assertTrue( np.all( indexCube("G", nN) == np.array( [13, 14, 16, 17, 22, 23, 25, 26]))) self.assertTrue( np.all( indexCube("H", nN) == np.array( [10, 11, 13, 14, 19, 20, 22, 23])))
def test_indexCube_3D(self): nN = np.array([3, 3, 3]) self.assertTrue( np.all( indexCube('A', nN) == np.array([0, 1, 3, 4, 9, 10, 12, 13]))) self.assertTrue( np.all( indexCube('B', nN) == np.array([3, 4, 6, 7, 12, 13, 15, 16]))) self.assertTrue( np.all( indexCube('C', nN) == np.array([4, 5, 7, 8, 13, 14, 16, 17]))) self.assertTrue( np.all( indexCube('D', nN) == np.array([1, 2, 4, 5, 10, 11, 13, 14]))) self.assertTrue( np.all( indexCube('E', nN) == np.array([9, 10, 12, 13, 18, 19, 21, 22 ]))) self.assertTrue( np.all( indexCube('F', nN) == np.array( [12, 13, 15, 16, 21, 22, 24, 25]))) self.assertTrue( np.all( indexCube('G', nN) == np.array( [13, 14, 16, 17, 22, 23, 25, 26]))) self.assertTrue( np.all( indexCube('H', nN) == np.array( [10, 11, 13, 14, 19, 20, 22, 23])))
def area(self): if (getattr(self, '_area', None) is None or getattr(self, '_normals', None) is None): # Compute areas of cell faces if(self.dim == 2): xy = self.gridN A, B = utils.indexCube('AB', self.vnC+1, np.array([self.nNx, self.nCy])) edge1 = xy[B, :] - xy[A, :] normal1 = np.c_[edge1[:, 1], -edge1[:, 0]] area1 = length2D(edge1) A, D = utils.indexCube('AD', self.vnC+1, np.array([self.nCx, self.nNy])) # Note that we are doing A-D to make sure the normal points the # right way. # Think about it. Look at the picture. Normal points towards C # iff you do this. edge2 = xy[A, :] - xy[D, :] normal2 = np.c_[edge2[:, 1], -edge2[:, 0]] area2 = length2D(edge2) self._area = np.r_[utils.mkvc(area1), utils.mkvc(area2)] self._normals = [normalize2D(normal1), normalize2D(normal2)] elif(self.dim == 3): A, E, F, B = utils.indexCube('AEFB', self.vnC+1, np.array( [self.nNx, self.nCy, self.nCz])) normal1, area1 = utils.faceInfo(self.gridN, A, E, F, B, average=False, normalizeNormals=False) A, D, H, E = utils.indexCube('ADHE', self.vnC+1, np.array( [self.nCx, self.nNy, self.nCz])) normal2, area2 = utils.faceInfo(self.gridN, A, D, H, E, average=False, normalizeNormals=False) A, B, C, D = utils.indexCube('ABCD', self.vnC+1, np.array( [self.nCx, self.nCy, self.nNz])) normal3, area3 = utils.faceInfo(self.gridN, A, B, C, D, average=False, normalizeNormals=False) self._area = np.r_[utils.mkvc(area1), utils.mkvc(area2), utils.mkvc(area3)] self._normals = [normal1, normal2, normal3] return self._area
def edge(self): """Edge lengths""" if getattr(self, '_edge', None) is None: if (self.dim == 2): xy = self.gridN A, D = utils.indexCube('AD', self.vnC + 1, np.array([self.nCx, self.nNy])) edge1 = xy[D, :] - xy[A, :] A, B = utils.indexCube('AB', self.vnC + 1, np.array([self.nNx, self.nCy])) edge2 = xy[B, :] - xy[A, :] self._edge = np.r_[utils.mkvc(length2D(edge1)), utils.mkvc(length2D(edge2))] self._tangents = np.r_[edge1, edge2] / np.c_[self._edge, self._edge] elif (self.dim == 3): xyz = self.gridN A, D = utils.indexCube( 'AD', self.vnC + 1, np.array([self.nCx, self.nNy, self.nNz])) edge1 = xyz[D, :] - xyz[A, :] A, B = utils.indexCube( 'AB', self.vnC + 1, np.array([self.nNx, self.nCy, self.nNz])) edge2 = xyz[B, :] - xyz[A, :] A, E = utils.indexCube( 'AE', self.vnC + 1, np.array([self.nNx, self.nNy, self.nCz])) edge3 = xyz[E, :] - xyz[A, :] self._edge = np.r_[utils.mkvc(length3D(edge1)), utils.mkvc(length3D(edge2)), utils.mkvc(length3D(edge3))] self._tangents = (np.r_[edge1, edge2, edge3] / np.c_[self._edge, self._edge, self._edge]) return self._edge return self._edge
def test_indexCube_2D(self): nN = np.array([3, 3]) self.assertTrue(np.all(indexCube("A", nN) == np.array([0, 1, 3, 4]))) self.assertTrue(np.all(indexCube("B", nN) == np.array([3, 4, 6, 7]))) self.assertTrue(np.all(indexCube("C", nN) == np.array([4, 5, 7, 8]))) self.assertTrue(np.all(indexCube("D", nN) == np.array([1, 2, 4, 5])))
def test_indexCube_2D(self): nN = np.array([3, 3]) self.assertTrue(np.all(indexCube('A', nN) == np.array([0, 1, 3, 4]))) self.assertTrue(np.all(indexCube('B', nN) == np.array([3, 4, 6, 7]))) self.assertTrue(np.all(indexCube('C', nN) == np.array([4, 5, 7, 8]))) self.assertTrue(np.all(indexCube('D', nN) == np.array([1, 2, 4, 5])))