xref: /petsc/src/binding/petsc4py/test/test_dmplex.py (revision 439f958df26b8d52c8c1eafe28238aff6c160a8c)
15808f684SSatish Balayfrom petsc4py import PETSc
25808f684SSatish Balayimport unittest
35808f684SSatish Balayimport numpy as np
45808f684SSatish Balay
55808f684SSatish Balay# --------------------------------------------------------------------
65808f684SSatish Balay
75808f684SSatish BalayERR_SUP = 56
85808f684SSatish Balay
95808f684SSatish Balayclass BaseTestPlex(object):
105808f684SSatish Balay
115808f684SSatish Balay    COMM = PETSc.COMM_WORLD
125808f684SSatish Balay    DIM = 1
135808f684SSatish Balay    CELLS = [[0, 1], [1, 2]]
145808f684SSatish Balay    COORDS = [[0.], [0.5], [1.]]
155808f684SSatish Balay    COMP = 1
165808f684SSatish Balay    DOFS = [1, 0]
175808f684SSatish Balay
185808f684SSatish Balay    def setUp(self):
195808f684SSatish Balay        self.plex = PETSc.DMPlex().createFromCellList(self.DIM,
205808f684SSatish Balay                                                      self.CELLS,
215808f684SSatish Balay                                                      self.COORDS,
225808f684SSatish Balay                                                      comm=self.COMM)
235808f684SSatish Balay
245808f684SSatish Balay    def tearDown(self):
255808f684SSatish Balay        self.plex.destroy()
265808f684SSatish Balay        self.plex = None
275808f684SSatish Balay
285808f684SSatish Balay    def testTopology(self):
295808f684SSatish Balay        dim = self.plex.getDimension()
305808f684SSatish Balay        pStart, pEnd = self.plex.getChart()
315808f684SSatish Balay        cStart, cEnd = self.plex.getHeightStratum(0)
325808f684SSatish Balay        vStart, vEnd = self.plex.getDepthStratum(0)
335808f684SSatish Balay        numDepths = self.plex.getLabelSize("depth")
345808f684SSatish Balay        coords_raw = self.plex.getCoordinates().getArray()
355808f684SSatish Balay        coords = np.reshape(coords_raw, (vEnd - vStart, dim))
365808f684SSatish Balay        self.assertEqual(dim, self.DIM)
375808f684SSatish Balay        self.assertEqual(numDepths, self.DIM+1)
385808f684SSatish Balay        if self.CELLS is not None:
395808f684SSatish Balay            self.assertEqual(cEnd-cStart, len(self.CELLS))
405808f684SSatish Balay        if self.COORDS is not None:
415808f684SSatish Balay            self.assertEqual(vEnd-vStart, len(self.COORDS))
425808f684SSatish Balay            self.assertTrue((coords == self.COORDS).all())
435808f684SSatish Balay
445808f684SSatish Balay    def testClosure(self):
455808f684SSatish Balay        pStart, pEnd = self.plex.getChart()
465808f684SSatish Balay        for p in range(pStart, pEnd):
475808f684SSatish Balay            closure = self.plex.getTransitiveClosure(p)[0]
485808f684SSatish Balay            for c in closure:
495808f684SSatish Balay                cone = self.plex.getCone(c)
505808f684SSatish Balay                self.assertEqual(self.plex.getConeSize(c), len(cone))
515808f684SSatish Balay                for i in cone:
525808f684SSatish Balay                    self.assertIn(i, closure)
535808f684SSatish Balay            star = self.plex.getTransitiveClosure(p, useCone=False)[0]
545808f684SSatish Balay            for s in star:
555808f684SSatish Balay                support = self.plex.getSupport(s)
565808f684SSatish Balay                self.assertEqual(self.plex.getSupportSize(s), len(support))
575808f684SSatish Balay                for i in support:
585808f684SSatish Balay                    self.assertIn(i, star)
595808f684SSatish Balay
605808f684SSatish Balay    def testAdjacency(self):
615808f684SSatish Balay        PETSc.DMPlex.setAdjacencyUseAnchors(self.plex, False)
625808f684SSatish Balay        flag = PETSc.DMPlex.getAdjacencyUseAnchors(self.plex)
635808f684SSatish Balay        self.assertFalse(flag)
645808f684SSatish Balay        PETSc.DMPlex.setAdjacencyUseAnchors(self.plex, True)
655808f684SSatish Balay        flag = PETSc.DMPlex.getAdjacencyUseAnchors(self.plex)
665808f684SSatish Balay        self.assertTrue(flag)
675808f684SSatish Balay        PETSc.DMPlex.setBasicAdjacency(self.plex, False, False)
685808f684SSatish Balay        flagA, flagB = PETSc.DMPlex.getBasicAdjacency(self.plex)
695808f684SSatish Balay        self.assertFalse(flagA)
705808f684SSatish Balay        self.assertFalse(flagB)
715808f684SSatish Balay        PETSc.DMPlex.setBasicAdjacency(self.plex, True, True)
725808f684SSatish Balay        flagA, flagB = PETSc.DMPlex.getBasicAdjacency(self.plex)
735808f684SSatish Balay        self.assertTrue(flagA)
745808f684SSatish Balay        self.assertTrue(flagB)
755808f684SSatish Balay        pStart, pEnd = self.plex.getChart()
765808f684SSatish Balay        for p in range(pStart, pEnd):
775808f684SSatish Balay            adjacency = self.plex.getAdjacency(p)
785808f684SSatish Balay            self.assertTrue(p in adjacency)
795808f684SSatish Balay            self.assertTrue(len(adjacency) > 1)
805808f684SSatish Balay
815808f684SSatish Balay    def testSectionDofs(self):
825808f684SSatish Balay        self.plex.setNumFields(1)
835808f684SSatish Balay        section = self.plex.createSection([self.COMP], [self.DOFS])
845808f684SSatish Balay        size = section.getStorageSize()
855808f684SSatish Balay        entity_dofs = [self.plex.getStratumSize("depth", d) *
865808f684SSatish Balay                       self.DOFS[d] for d in range(self.DIM+1)]
875808f684SSatish Balay        self.assertEqual(sum(entity_dofs), size)
885808f684SSatish Balay
895808f684SSatish Balay    def testSectionClosure(self):
905808f684SSatish Balay        section = self.plex.createSection([self.COMP], [self.DOFS])
915808f684SSatish Balay        self.plex.setSection(section)
925808f684SSatish Balay        vec = self.plex.createLocalVec()
935808f684SSatish Balay        pStart, pEnd = self.plex.getChart()
945808f684SSatish Balay        for p in range(pStart, pEnd):
955808f684SSatish Balay            for i in range(section.getDof(p)):
965808f684SSatish Balay                off = section.getOffset(p)
975808f684SSatish Balay                vec.setValue(off+i, p)
985808f684SSatish Balay
995808f684SSatish Balay        for p in range(pStart, pEnd):
1005808f684SSatish Balay            point_closure = self.plex.getTransitiveClosure(p)[0]
1015808f684SSatish Balay            dof_closure = self.plex.vecGetClosure(section, vec, p)
1025808f684SSatish Balay            for p in dof_closure:
1035808f684SSatish Balay                self.assertIn(p, point_closure)
1045808f684SSatish Balay
1055808f684SSatish Balay    def testBoundaryLabel(self):
106*439f958dSVaclav Hapla        pStart, pEnd = self.plex.getChart()
107*439f958dSVaclav Hapla        if (pEnd - pStart == 0): return
108*439f958dSVaclav Hapla
1095808f684SSatish Balay        self.assertFalse(self.plex.hasLabel("boundary"))
1105808f684SSatish Balay        self.plex.markBoundaryFaces("boundary")
1115808f684SSatish Balay        self.assertTrue(self.plex.hasLabel("boundary"))
1125808f684SSatish Balay
1135808f684SSatish Balay        faces = self.plex.getStratumIS("boundary", 1)
1145808f684SSatish Balay        for f in faces.getIndices():
1155808f684SSatish Balay            points, orient = self.plex.getTransitiveClosure(f, useCone=True)
1165808f684SSatish Balay            for p in points:
1175808f684SSatish Balay                self.plex.setLabelValue("boundary", p, 1)
1185808f684SSatish Balay
1195808f684SSatish Balay        for p in range(pStart, pEnd):
1205808f684SSatish Balay            if self.plex.getLabelValue("boundary", p) != 1:
1215808f684SSatish Balay                self.plex.setLabelValue("boundary", p, 2)
1225808f684SSatish Balay
1235808f684SSatish Balay        numBoundary = self.plex.getStratumSize("boundary", 1)
1245808f684SSatish Balay        numInterior = self.plex.getStratumSize("boundary", 2)
1255808f684SSatish Balay        self.assertNotEqual(numBoundary, pEnd - pStart)
1265808f684SSatish Balay        self.assertNotEqual(numInterior, pEnd - pStart)
1275808f684SSatish Balay        self.assertEqual(numBoundary + numInterior, pEnd - pStart)
1285808f684SSatish Balay
1295808f684SSatish Balay
1305808f684SSatish Balay    def testAdapt(self):
1315808f684SSatish Balay        dim = self.plex.getDimension()
1325808f684SSatish Balay        if dim == 1: return
1335808f684SSatish Balay        vStart, vEnd = self.plex.getDepthStratum(0)
1345808f684SSatish Balay        numVertices = vEnd-vStart
1355808f684SSatish Balay        metric_array = np.zeros([numVertices,dim,dim])
1365808f684SSatish Balay        for met in metric_array:
1375808f684SSatish Balay            met[:,:] = np.diag([9]*dim)
1385808f684SSatish Balay        metric = PETSc.Vec().createWithArray(metric_array)
1395808f684SSatish Balay        try:
1405808f684SSatish Balay            newplex = self.plex.adaptMetric(metric,"")
1415808f684SSatish Balay        except PETSc.Error as exc:
1425808f684SSatish Balay            if exc.ierr != ERR_SUP: raise
1435808f684SSatish Balay
1445808f684SSatish Balay
1455808f684SSatish Balay# --------------------------------------------------------------------
1465808f684SSatish Balay
1475808f684SSatish Balayclass BaseTestPlex_2D(BaseTestPlex):
1485808f684SSatish Balay    DIM = 2
1495808f684SSatish Balay    CELLS = [[0, 1, 3], [1, 3, 4], [1, 2, 4], [2, 4, 5],
1505808f684SSatish Balay             [3, 4, 6], [4, 6, 7], [4, 5, 7], [5, 7, 8]]
1515808f684SSatish Balay    COORDS = [[0.0, 0.0], [0.5, 0.0], [1.0, 0.0],
1525808f684SSatish Balay              [0.0, 0.5], [0.5, 0.5], [1.0, 0.5],
1535808f684SSatish Balay              [0.0, 1.0], [0.5, 1.0], [1.0, 1.0]]
1545808f684SSatish Balay    DOFS = [1, 0, 0]
1555808f684SSatish Balay
1565808f684SSatish Balayclass BaseTestPlex_3D(BaseTestPlex):
1575808f684SSatish Balay    DIM = 3
1585808f684SSatish Balay    CELLS = [[0, 2, 3, 7], [0, 2, 6, 7], [0, 4, 6, 7],
1595808f684SSatish Balay             [0, 1, 3, 7], [0, 1, 5, 7], [0, 4, 5, 7]]
1605808f684SSatish Balay    COORDS = [[0., 0., 0.], [1., 0., 0.], [0., 1., 0.], [1., 1., 0.],
1615808f684SSatish Balay              [0., 0., 1.], [1., 0., 1.], [0., 1., 1.], [1., 1., 1.]]
1625808f684SSatish Balay    DOFS = [1, 0, 0, 0]
1635808f684SSatish Balay
1645808f684SSatish Balay# --------------------------------------------------------------------
1655808f684SSatish Balay
1665808f684SSatish Balayclass TestPlex_1D(BaseTestPlex, unittest.TestCase):
1675808f684SSatish Balay    pass
1685808f684SSatish Balay
1695808f684SSatish Balayclass TestPlex_2D(BaseTestPlex_2D, unittest.TestCase):
1705808f684SSatish Balay    pass
1715808f684SSatish Balay
1725808f684SSatish Balayclass TestPlex_3D(BaseTestPlex_3D, unittest.TestCase):
1735808f684SSatish Balay    pass
1745808f684SSatish Balay
1755808f684SSatish Balayclass TestPlex_2D_P3(BaseTestPlex_2D, unittest.TestCase):
1765808f684SSatish Balay    DOFS = [1, 2, 1]
1775808f684SSatish Balay
1785808f684SSatish Balayclass TestPlex_3D_P3(BaseTestPlex_3D, unittest.TestCase):
1795808f684SSatish Balay    DOFS = [1, 2, 1, 0]
1805808f684SSatish Balay
1815808f684SSatish Balayclass TestPlex_3D_P4(BaseTestPlex_3D, unittest.TestCase):
1825808f684SSatish Balay    DOFS = [1, 3, 3, 1]
1835808f684SSatish Balay
1845808f684SSatish Balayclass TestPlex_2D_BoxTensor(BaseTestPlex_2D, unittest.TestCase):
1855808f684SSatish Balay    CELLS = None
1865808f684SSatish Balay    COORDS = None
1875808f684SSatish Balay    def setUp(self):
1885808f684SSatish Balay        self.plex = PETSc.DMPlex().createBoxMesh([3,3], simplex=False)
1895808f684SSatish Balay
1905808f684SSatish Balayclass TestPlex_3D_BoxTensor(BaseTestPlex_3D, unittest.TestCase):
1915808f684SSatish Balay    CELLS = None
1925808f684SSatish Balay    COORDS = None
1935808f684SSatish Balay    def setUp(self):
1945808f684SSatish Balay        self.plex = PETSc.DMPlex().createBoxMesh([3,3,3], simplex=False)
1955808f684SSatish Balay
1965808f684SSatish Balayimport sys
1975808f684SSatish Balaytry:
1985808f684SSatish Balay    raise PETSc.Error
1995808f684SSatish Balay    PETSc.DMPlex().createBoxMesh([2,2], simplex=True, comm=PETSc.COMM_SELF).destroy()
2005808f684SSatish Balayexcept PETSc.Error:
2015808f684SSatish Balay    pass
2025808f684SSatish Balayelse:
2035808f684SSatish Balay    class TestPlex_2D_Box(BaseTestPlex_2D, unittest.TestCase):
2045808f684SSatish Balay        CELLS = None
2055808f684SSatish Balay        COORDS = None
2065808f684SSatish Balay        def setUp(self):
2075808f684SSatish Balay            self.plex = PETSc.DMPlex().createBoxMesh([1,1], simplex=True)
2085808f684SSatish Balay
2095808f684SSatish Balay    class TestPlex_2D_Boundary(BaseTestPlex_2D, unittest.TestCase):
2105808f684SSatish Balay        CELLS = None
2115808f684SSatish Balay        COORDS = None
2125808f684SSatish Balay        def setUp(self):
2135808f684SSatish Balay            boundary = PETSc.DMPlex().create(self.COMM)
2145808f684SSatish Balay            boundary.createSquareBoundary([0., 0.], [1., 1.], [2, 2])
2155808f684SSatish Balay            boundary.setDimension(self.DIM-1)
2165808f684SSatish Balay            self.plex = PETSc.DMPlex().generate(boundary)
2175808f684SSatish Balay
2185808f684SSatish Balay    class TestPlex_3D_Box(BaseTestPlex_3D, unittest.TestCase):
2195808f684SSatish Balay        CELLS = None
2205808f684SSatish Balay        COORDS = None
2215808f684SSatish Balay        def setUp(self):
2225808f684SSatish Balay            self.plex = PETSc.DMPlex().createBoxMesh([1,1,1], simplex=True)
2235808f684SSatish Balay
2245808f684SSatish Balay    class TestPlex_3D_Boundary(BaseTestPlex_3D, unittest.TestCase):
2255808f684SSatish Balay        CELLS = None
2265808f684SSatish Balay        COORDS = None
2275808f684SSatish Balay        def setUp(self):
2285808f684SSatish Balay            boundary = PETSc.DMPlex().create(self.COMM)
2295808f684SSatish Balay            boundary.createCubeBoundary([0., 0., 0.], [1., 1., 1.], [1, 1, 1])
2305808f684SSatish Balay            boundary.setDimension(self.DIM-1)
2315808f684SSatish Balay            self.plex = PETSc.DMPlex().generate(boundary)
2325808f684SSatish Balay
2335808f684SSatish Balay# --------------------------------------------------------------------
2345808f684SSatish Balay
2355808f684SSatish Balayif __name__ == '__main__':
2365808f684SSatish Balay    unittest.main()
237