xref: /petsc/src/binding/petsc4py/test/test_dmplex.py (revision 5808f68492579297331054bd8ff190489c3b8c20)
1*5808f684SSatish Balayfrom petsc4py import PETSc
2*5808f684SSatish Balayimport unittest
3*5808f684SSatish Balayimport numpy as np
4*5808f684SSatish Balay
5*5808f684SSatish Balay# --------------------------------------------------------------------
6*5808f684SSatish Balay
7*5808f684SSatish BalayERR_SUP = 56
8*5808f684SSatish Balay
9*5808f684SSatish Balayclass BaseTestPlex(object):
10*5808f684SSatish Balay
11*5808f684SSatish Balay    COMM = PETSc.COMM_WORLD
12*5808f684SSatish Balay    DIM = 1
13*5808f684SSatish Balay    CELLS = [[0, 1], [1, 2]]
14*5808f684SSatish Balay    COORDS = [[0.], [0.5], [1.]]
15*5808f684SSatish Balay    COMP = 1
16*5808f684SSatish Balay    DOFS = [1, 0]
17*5808f684SSatish Balay
18*5808f684SSatish Balay    def setUp(self):
19*5808f684SSatish Balay        self.plex = PETSc.DMPlex().createFromCellList(self.DIM,
20*5808f684SSatish Balay                                                      self.CELLS,
21*5808f684SSatish Balay                                                      self.COORDS,
22*5808f684SSatish Balay                                                      comm=self.COMM)
23*5808f684SSatish Balay
24*5808f684SSatish Balay    def tearDown(self):
25*5808f684SSatish Balay        self.plex.destroy()
26*5808f684SSatish Balay        self.plex = None
27*5808f684SSatish Balay
28*5808f684SSatish Balay    def testTopology(self):
29*5808f684SSatish Balay        dim = self.plex.getDimension()
30*5808f684SSatish Balay        pStart, pEnd = self.plex.getChart()
31*5808f684SSatish Balay        cStart, cEnd = self.plex.getHeightStratum(0)
32*5808f684SSatish Balay        vStart, vEnd = self.plex.getDepthStratum(0)
33*5808f684SSatish Balay        numDepths = self.plex.getLabelSize("depth")
34*5808f684SSatish Balay        coords_raw = self.plex.getCoordinates().getArray()
35*5808f684SSatish Balay        coords = np.reshape(coords_raw, (vEnd - vStart, dim))
36*5808f684SSatish Balay        self.assertEqual(dim, self.DIM)
37*5808f684SSatish Balay        self.assertEqual(numDepths, self.DIM+1)
38*5808f684SSatish Balay        if self.CELLS is not None:
39*5808f684SSatish Balay            self.assertEqual(cEnd-cStart, len(self.CELLS))
40*5808f684SSatish Balay        if self.COORDS is not None:
41*5808f684SSatish Balay            self.assertEqual(vEnd-vStart, len(self.COORDS))
42*5808f684SSatish Balay            self.assertTrue((coords == self.COORDS).all())
43*5808f684SSatish Balay
44*5808f684SSatish Balay    def testClosure(self):
45*5808f684SSatish Balay        pStart, pEnd = self.plex.getChart()
46*5808f684SSatish Balay        for p in range(pStart, pEnd):
47*5808f684SSatish Balay            closure = self.plex.getTransitiveClosure(p)[0]
48*5808f684SSatish Balay            for c in closure:
49*5808f684SSatish Balay                cone = self.plex.getCone(c)
50*5808f684SSatish Balay                self.assertEqual(self.plex.getConeSize(c), len(cone))
51*5808f684SSatish Balay                for i in cone:
52*5808f684SSatish Balay                    self.assertIn(i, closure)
53*5808f684SSatish Balay            star = self.plex.getTransitiveClosure(p, useCone=False)[0]
54*5808f684SSatish Balay            for s in star:
55*5808f684SSatish Balay                support = self.plex.getSupport(s)
56*5808f684SSatish Balay                self.assertEqual(self.plex.getSupportSize(s), len(support))
57*5808f684SSatish Balay                for i in support:
58*5808f684SSatish Balay                    self.assertIn(i, star)
59*5808f684SSatish Balay
60*5808f684SSatish Balay    def testAdjacency(self):
61*5808f684SSatish Balay        PETSc.DMPlex.setAdjacencyUseAnchors(self.plex, False)
62*5808f684SSatish Balay        flag = PETSc.DMPlex.getAdjacencyUseAnchors(self.plex)
63*5808f684SSatish Balay        self.assertFalse(flag)
64*5808f684SSatish Balay        PETSc.DMPlex.setAdjacencyUseAnchors(self.plex, True)
65*5808f684SSatish Balay        flag = PETSc.DMPlex.getAdjacencyUseAnchors(self.plex)
66*5808f684SSatish Balay        self.assertTrue(flag)
67*5808f684SSatish Balay        PETSc.DMPlex.setBasicAdjacency(self.plex, False, False)
68*5808f684SSatish Balay        flagA, flagB = PETSc.DMPlex.getBasicAdjacency(self.plex)
69*5808f684SSatish Balay        self.assertFalse(flagA)
70*5808f684SSatish Balay        self.assertFalse(flagB)
71*5808f684SSatish Balay        PETSc.DMPlex.setBasicAdjacency(self.plex, True, True)
72*5808f684SSatish Balay        flagA, flagB = PETSc.DMPlex.getBasicAdjacency(self.plex)
73*5808f684SSatish Balay        self.assertTrue(flagA)
74*5808f684SSatish Balay        self.assertTrue(flagB)
75*5808f684SSatish Balay        pStart, pEnd = self.plex.getChart()
76*5808f684SSatish Balay        for p in range(pStart, pEnd):
77*5808f684SSatish Balay            adjacency = self.plex.getAdjacency(p)
78*5808f684SSatish Balay            self.assertTrue(p in adjacency)
79*5808f684SSatish Balay            self.assertTrue(len(adjacency) > 1)
80*5808f684SSatish Balay
81*5808f684SSatish Balay    def testSectionDofs(self):
82*5808f684SSatish Balay        self.plex.setNumFields(1)
83*5808f684SSatish Balay        section = self.plex.createSection([self.COMP], [self.DOFS])
84*5808f684SSatish Balay        size = section.getStorageSize()
85*5808f684SSatish Balay        entity_dofs = [self.plex.getStratumSize("depth", d) *
86*5808f684SSatish Balay                       self.DOFS[d] for d in range(self.DIM+1)]
87*5808f684SSatish Balay        self.assertEqual(sum(entity_dofs), size)
88*5808f684SSatish Balay
89*5808f684SSatish Balay    def testSectionClosure(self):
90*5808f684SSatish Balay        section = self.plex.createSection([self.COMP], [self.DOFS])
91*5808f684SSatish Balay        self.plex.setSection(section)
92*5808f684SSatish Balay        vec = self.plex.createLocalVec()
93*5808f684SSatish Balay        pStart, pEnd = self.plex.getChart()
94*5808f684SSatish Balay        for p in range(pStart, pEnd):
95*5808f684SSatish Balay            for i in range(section.getDof(p)):
96*5808f684SSatish Balay                off = section.getOffset(p)
97*5808f684SSatish Balay                vec.setValue(off+i, p)
98*5808f684SSatish Balay
99*5808f684SSatish Balay        for p in range(pStart, pEnd):
100*5808f684SSatish Balay            point_closure = self.plex.getTransitiveClosure(p)[0]
101*5808f684SSatish Balay            dof_closure = self.plex.vecGetClosure(section, vec, p)
102*5808f684SSatish Balay            for p in dof_closure:
103*5808f684SSatish Balay                self.assertIn(p, point_closure)
104*5808f684SSatish Balay
105*5808f684SSatish Balay    def testBoundaryLabel(self):
106*5808f684SSatish Balay        self.assertFalse(self.plex.hasLabel("boundary"))
107*5808f684SSatish Balay        self.plex.markBoundaryFaces("boundary")
108*5808f684SSatish Balay        self.assertTrue(self.plex.hasLabel("boundary"))
109*5808f684SSatish Balay
110*5808f684SSatish Balay        faces = self.plex.getStratumIS("boundary", 1)
111*5808f684SSatish Balay        for f in faces.getIndices():
112*5808f684SSatish Balay            points, orient = self.plex.getTransitiveClosure(f, useCone=True)
113*5808f684SSatish Balay            for p in points:
114*5808f684SSatish Balay                self.plex.setLabelValue("boundary", p, 1)
115*5808f684SSatish Balay
116*5808f684SSatish Balay        pStart, pEnd = self.plex.getChart()
117*5808f684SSatish Balay        for p in range(pStart, pEnd):
118*5808f684SSatish Balay            if self.plex.getLabelValue("boundary", p) != 1:
119*5808f684SSatish Balay                self.plex.setLabelValue("boundary", p, 2)
120*5808f684SSatish Balay
121*5808f684SSatish Balay        numBoundary = self.plex.getStratumSize("boundary", 1)
122*5808f684SSatish Balay        numInterior = self.plex.getStratumSize("boundary", 2)
123*5808f684SSatish Balay        self.assertNotEqual(numBoundary, pEnd - pStart)
124*5808f684SSatish Balay        self.assertNotEqual(numInterior, pEnd - pStart)
125*5808f684SSatish Balay        self.assertEqual(numBoundary + numInterior, pEnd - pStart)
126*5808f684SSatish Balay
127*5808f684SSatish Balay
128*5808f684SSatish Balay    def testAdapt(self):
129*5808f684SSatish Balay        dim = self.plex.getDimension()
130*5808f684SSatish Balay        if dim == 1: return
131*5808f684SSatish Balay        vStart, vEnd = self.plex.getDepthStratum(0)
132*5808f684SSatish Balay        numVertices = vEnd-vStart
133*5808f684SSatish Balay        metric_array = np.zeros([numVertices,dim,dim])
134*5808f684SSatish Balay        for met in metric_array:
135*5808f684SSatish Balay            met[:,:] = np.diag([9]*dim)
136*5808f684SSatish Balay        metric = PETSc.Vec().createWithArray(metric_array)
137*5808f684SSatish Balay        try:
138*5808f684SSatish Balay            newplex = self.plex.adaptMetric(metric,"")
139*5808f684SSatish Balay        except PETSc.Error as exc:
140*5808f684SSatish Balay            if exc.ierr != ERR_SUP: raise
141*5808f684SSatish Balay
142*5808f684SSatish Balay
143*5808f684SSatish Balay# --------------------------------------------------------------------
144*5808f684SSatish Balay
145*5808f684SSatish Balayclass BaseTestPlex_2D(BaseTestPlex):
146*5808f684SSatish Balay    DIM = 2
147*5808f684SSatish Balay    CELLS = [[0, 1, 3], [1, 3, 4], [1, 2, 4], [2, 4, 5],
148*5808f684SSatish Balay             [3, 4, 6], [4, 6, 7], [4, 5, 7], [5, 7, 8]]
149*5808f684SSatish Balay    COORDS = [[0.0, 0.0], [0.5, 0.0], [1.0, 0.0],
150*5808f684SSatish Balay              [0.0, 0.5], [0.5, 0.5], [1.0, 0.5],
151*5808f684SSatish Balay              [0.0, 1.0], [0.5, 1.0], [1.0, 1.0]]
152*5808f684SSatish Balay    DOFS = [1, 0, 0]
153*5808f684SSatish Balay
154*5808f684SSatish Balayclass BaseTestPlex_3D(BaseTestPlex):
155*5808f684SSatish Balay    DIM = 3
156*5808f684SSatish Balay    CELLS = [[0, 2, 3, 7], [0, 2, 6, 7], [0, 4, 6, 7],
157*5808f684SSatish Balay             [0, 1, 3, 7], [0, 1, 5, 7], [0, 4, 5, 7]]
158*5808f684SSatish Balay    COORDS = [[0., 0., 0.], [1., 0., 0.], [0., 1., 0.], [1., 1., 0.],
159*5808f684SSatish Balay              [0., 0., 1.], [1., 0., 1.], [0., 1., 1.], [1., 1., 1.]]
160*5808f684SSatish Balay    DOFS = [1, 0, 0, 0]
161*5808f684SSatish Balay
162*5808f684SSatish Balay# --------------------------------------------------------------------
163*5808f684SSatish Balay
164*5808f684SSatish Balayclass TestPlex_1D(BaseTestPlex, unittest.TestCase):
165*5808f684SSatish Balay    pass
166*5808f684SSatish Balay
167*5808f684SSatish Balayclass TestPlex_2D(BaseTestPlex_2D, unittest.TestCase):
168*5808f684SSatish Balay    pass
169*5808f684SSatish Balay
170*5808f684SSatish Balayclass TestPlex_3D(BaseTestPlex_3D, unittest.TestCase):
171*5808f684SSatish Balay    pass
172*5808f684SSatish Balay
173*5808f684SSatish Balayclass TestPlex_2D_P3(BaseTestPlex_2D, unittest.TestCase):
174*5808f684SSatish Balay    DOFS = [1, 2, 1]
175*5808f684SSatish Balay
176*5808f684SSatish Balayclass TestPlex_3D_P3(BaseTestPlex_3D, unittest.TestCase):
177*5808f684SSatish Balay    DOFS = [1, 2, 1, 0]
178*5808f684SSatish Balay
179*5808f684SSatish Balayclass TestPlex_3D_P4(BaseTestPlex_3D, unittest.TestCase):
180*5808f684SSatish Balay    DOFS = [1, 3, 3, 1]
181*5808f684SSatish Balay
182*5808f684SSatish Balayclass TestPlex_2D_BoxTensor(BaseTestPlex_2D, unittest.TestCase):
183*5808f684SSatish Balay    CELLS = None
184*5808f684SSatish Balay    COORDS = None
185*5808f684SSatish Balay    def setUp(self):
186*5808f684SSatish Balay        self.plex = PETSc.DMPlex().createBoxMesh([3,3], simplex=False)
187*5808f684SSatish Balay
188*5808f684SSatish Balayclass TestPlex_3D_BoxTensor(BaseTestPlex_3D, unittest.TestCase):
189*5808f684SSatish Balay    CELLS = None
190*5808f684SSatish Balay    COORDS = None
191*5808f684SSatish Balay    def setUp(self):
192*5808f684SSatish Balay        self.plex = PETSc.DMPlex().createBoxMesh([3,3,3], simplex=False)
193*5808f684SSatish Balay
194*5808f684SSatish Balayimport sys
195*5808f684SSatish Balaytry:
196*5808f684SSatish Balay    raise PETSc.Error
197*5808f684SSatish Balay    PETSc.DMPlex().createBoxMesh([2,2], simplex=True, comm=PETSc.COMM_SELF).destroy()
198*5808f684SSatish Balayexcept PETSc.Error:
199*5808f684SSatish Balay    pass
200*5808f684SSatish Balayelse:
201*5808f684SSatish Balay    class TestPlex_2D_Box(BaseTestPlex_2D, unittest.TestCase):
202*5808f684SSatish Balay        CELLS = None
203*5808f684SSatish Balay        COORDS = None
204*5808f684SSatish Balay        def setUp(self):
205*5808f684SSatish Balay            self.plex = PETSc.DMPlex().createBoxMesh([1,1], simplex=True)
206*5808f684SSatish Balay
207*5808f684SSatish Balay    class TestPlex_2D_Boundary(BaseTestPlex_2D, unittest.TestCase):
208*5808f684SSatish Balay        CELLS = None
209*5808f684SSatish Balay        COORDS = None
210*5808f684SSatish Balay        def setUp(self):
211*5808f684SSatish Balay            boundary = PETSc.DMPlex().create(self.COMM)
212*5808f684SSatish Balay            boundary.createSquareBoundary([0., 0.], [1., 1.], [2, 2])
213*5808f684SSatish Balay            boundary.setDimension(self.DIM-1)
214*5808f684SSatish Balay            self.plex = PETSc.DMPlex().generate(boundary)
215*5808f684SSatish Balay
216*5808f684SSatish Balay    class TestPlex_3D_Box(BaseTestPlex_3D, unittest.TestCase):
217*5808f684SSatish Balay        CELLS = None
218*5808f684SSatish Balay        COORDS = None
219*5808f684SSatish Balay        def setUp(self):
220*5808f684SSatish Balay            self.plex = PETSc.DMPlex().createBoxMesh([1,1,1], simplex=True)
221*5808f684SSatish Balay
222*5808f684SSatish Balay    class TestPlex_3D_Boundary(BaseTestPlex_3D, unittest.TestCase):
223*5808f684SSatish Balay        CELLS = None
224*5808f684SSatish Balay        COORDS = None
225*5808f684SSatish Balay        def setUp(self):
226*5808f684SSatish Balay            boundary = PETSc.DMPlex().create(self.COMM)
227*5808f684SSatish Balay            boundary.createCubeBoundary([0., 0., 0.], [1., 1., 1.], [1, 1, 1])
228*5808f684SSatish Balay            boundary.setDimension(self.DIM-1)
229*5808f684SSatish Balay            self.plex = PETSc.DMPlex().generate(boundary)
230*5808f684SSatish Balay
231*5808f684SSatish Balay# --------------------------------------------------------------------
232*5808f684SSatish Balay
233*5808f684SSatish Balayif __name__ == '__main__':
234*5808f684SSatish Balay    unittest.main()
235