xref: /petsc/src/binding/petsc4py/test/test_pc_py.py (revision 62e5d2d2208a68fdbd23dac44110783534664de8)
15808f684SSatish Balay# --------------------------------------------------------------------
25808f684SSatish Balay
35808f684SSatish Balayfrom petsc4py import PETSc
45808f684SSatish Balayimport unittest
55808f684SSatish Balayfrom sys import getrefcount
65808f684SSatish Balay
75808f684SSatish Balay# --------------------------------------------------------------------
85808f684SSatish Balay
95808f684SSatish Balayclass BaseMyPC(object):
105808f684SSatish Balay    def setup(self, pc):
115808f684SSatish Balay        pass
125808f684SSatish Balay    def reset(self, pc):
135808f684SSatish Balay        pass
145808f684SSatish Balay    def apply(self, pc, x, y):
155808f684SSatish Balay        raise NotImplementedError
165808f684SSatish Balay    def applyT(self, pc, x, y):
175808f684SSatish Balay        self.apply(pc, x, y)
185808f684SSatish Balay    def applyS(self, pc, x, y):
195808f684SSatish Balay        self.apply(pc, x, y)
205808f684SSatish Balay    def applySL(self, pc, x, y):
215808f684SSatish Balay        self.applyS(pc, x, y)
225808f684SSatish Balay    def applySR(self, pc, x, y):
235808f684SSatish Balay        self.applyS(pc, x, y)
245808f684SSatish Balay    def applyRich(self, pc, x, y, w, tols):
255808f684SSatish Balay        self.apply(pc, x, y)
26bda5c5f8SStefano Zampini    def applyM(self, pc, x, y):
27bda5c5f8SStefano Zampini        raise NotImplementedError
285808f684SSatish Balay
295808f684SSatish Balayclass MyPCNone(BaseMyPC):
305808f684SSatish Balay    def apply(self, pc, x, y):
315808f684SSatish Balay        x.copy(y)
32bda5c5f8SStefano Zampini    def applyM(self, pc, x, y):
33bda5c5f8SStefano Zampini        x.copy(y)
345808f684SSatish Balay
355808f684SSatish Balayclass MyPCJacobi(BaseMyPC):
365808f684SSatish Balay    def setup(self, pc):
375808f684SSatish Balay        A, P = pc.getOperators()
385808f684SSatish Balay        self.diag = P.getDiagonal()
395808f684SSatish Balay        self.diag.reciprocal()
405808f684SSatish Balay    def reset(self, pc):
415808f684SSatish Balay        self.diag.destroy()
425808f684SSatish Balay        del self.diag
435808f684SSatish Balay    def apply(self, pc, x, y):
445808f684SSatish Balay        y.pointwiseMult(self.diag, x)
455808f684SSatish Balay    def applyS(self, pc, x, y):
465808f684SSatish Balay        self.diag.copy(y)
475808f684SSatish Balay        y.sqrtabs()
485808f684SSatish Balay        y.pointwiseMult(y, x)
49bda5c5f8SStefano Zampini    def applyM(self, pc, x, y):
50bda5c5f8SStefano Zampini        x.copy(y)
51bda5c5f8SStefano Zampini        y.diagonalScale(L=self.diag)
525808f684SSatish Balay
535808f684SSatish Balayclass PC_PYTHON_CLASS(object):
545808f684SSatish Balay
555808f684SSatish Balay    def __init__(self):
565808f684SSatish Balay        self.impl = None
575808f684SSatish Balay        self.log = {}
585808f684SSatish Balay    def _log(self, method, *args):
595808f684SSatish Balay        self.log.setdefault(method, 0)
605808f684SSatish Balay        self.log[method] += 1
615808f684SSatish Balay    def create(self, pc):
625808f684SSatish Balay        self._log('create', pc)
635808f684SSatish Balay    def destroy(self, pc):
645808f684SSatish Balay        self._log('destroy')
655808f684SSatish Balay        self.impl = None
665808f684SSatish Balay    def reset(self, pc):
675808f684SSatish Balay        self._log('reset', pc)
685808f684SSatish Balay    def view(self, pc, vw):
695808f684SSatish Balay        self._log('view', pc, vw)
705808f684SSatish Balay        assert isinstance(pc, PETSc.PC)
715808f684SSatish Balay        assert isinstance(vw, PETSc.Viewer)
725808f684SSatish Balay        pass
735808f684SSatish Balay    def setFromOptions(self, pc):
745808f684SSatish Balay        self._log('setFromOptions', pc)
755808f684SSatish Balay        assert isinstance(pc, PETSc.PC)
765808f684SSatish Balay        OptDB = PETSc.Options(pc)
775808f684SSatish Balay        impl =  OptDB.getString('impl','MyPCNone')
785808f684SSatish Balay        klass = globals()[impl]
795808f684SSatish Balay        self.impl = klass()
805808f684SSatish Balay    def setUp(self, pc):
815808f684SSatish Balay        self._log('setUp', pc)
825808f684SSatish Balay        assert isinstance(pc, PETSc.PC)
835808f684SSatish Balay        self.impl.setup(pc)
845808f684SSatish Balay    def preSolve(self, pc, ksp, b, x):
855808f684SSatish Balay        self._log('preSolve', pc, ksp, b, x)
865808f684SSatish Balay    def postSolve(self, pc, ksp, b, x):
875808f684SSatish Balay        self._log('postSolve', pc, ksp, b, x)
885808f684SSatish Balay    def apply(self, pc, x, y):
895808f684SSatish Balay        self._log('apply', pc, x, y)
905808f684SSatish Balay        assert isinstance(pc, PETSc.PC)
915808f684SSatish Balay        assert isinstance(x,  PETSc.Vec)
925808f684SSatish Balay        assert isinstance(y,  PETSc.Vec)
935808f684SSatish Balay        self.impl.apply(pc, x, y)
945808f684SSatish Balay    def applySymmetricLeft(self, pc, x, y):
955808f684SSatish Balay        self._log('applySymmetricLeft', pc, x, y)
965808f684SSatish Balay        assert isinstance(pc, PETSc.PC)
975808f684SSatish Balay        assert isinstance(x,  PETSc.Vec)
985808f684SSatish Balay        assert isinstance(y,  PETSc.Vec)
995808f684SSatish Balay        self.impl.applySL(pc, x, y)
1005808f684SSatish Balay    def applySymmetricRight(self, pc, x, y):
1015808f684SSatish Balay        self._log('applySymmetricRight', pc, x, y)
1025808f684SSatish Balay        assert isinstance(pc, PETSc.PC)
1035808f684SSatish Balay        assert isinstance(x,  PETSc.Vec)
1045808f684SSatish Balay        assert isinstance(y,  PETSc.Vec)
1055808f684SSatish Balay        self.impl.applySR(pc, x, y)
1065808f684SSatish Balay    def applyTranspose(self, pc, x, y):
1075808f684SSatish Balay        self._log('applyTranspose', pc, x, y)
1085808f684SSatish Balay        assert isinstance(pc, PETSc.PC)
1095808f684SSatish Balay        assert isinstance(x,  PETSc.Vec)
1105808f684SSatish Balay        assert isinstance(y,  PETSc.Vec)
1115808f684SSatish Balay        self.impl.applyT(pc, x, y)
112bda5c5f8SStefano Zampini    def matApply(self, pc, x, y):
113bda5c5f8SStefano Zampini        self._log('matApply', pc, x, y)
114bda5c5f8SStefano Zampini        assert isinstance(pc, PETSc.PC)
115bda5c5f8SStefano Zampini        assert isinstance(x,  PETSc.Mat)
116bda5c5f8SStefano Zampini        assert isinstance(y,  PETSc.Mat)
117bda5c5f8SStefano Zampini        self.impl.applyM(pc, x, y)
1185808f684SSatish Balay    def applyRichardson(self, pc, x, y, w, tols):
1195808f684SSatish Balay        self._log('applyRichardson', pc, x, y, w, tols)
1205808f684SSatish Balay        assert isinstance(pc, PETSc.PC)
1215808f684SSatish Balay        assert isinstance(x,  PETSc.Vec)
1225808f684SSatish Balay        assert isinstance(y,  PETSc.Vec)
1235808f684SSatish Balay        assert isinstance(w,  PETSc.Vec)
1245808f684SSatish Balay        assert isinstance(tols,  tuple)
1255808f684SSatish Balay        assert len(tols) == 4
1265808f684SSatish Balay        self.impl.applyRich(pc, x, y, w, tols)
1275808f684SSatish Balay
1285808f684SSatish Balay
1295808f684SSatish Balayclass TestPCPYTHON(unittest.TestCase):
1305808f684SSatish Balay
1315808f684SSatish Balay    PC_TYPE = PETSc.PC.Type.PYTHON
1325808f684SSatish Balay    PC_PREFIX = 'test-'
1335808f684SSatish Balay
1345808f684SSatish Balay    def setUp(self):
1355808f684SSatish Balay        pc = self.pc = PETSc.PC()
1365808f684SSatish Balay        pc.create(PETSc.COMM_SELF)
1375808f684SSatish Balay        pc.setType(self.PC_TYPE)
1385808f684SSatish Balay        module = __name__
1395808f684SSatish Balay        factory = 'PC_PYTHON_CLASS'
1405808f684SSatish Balay        self.pc.prefix = self.PC_PREFIX
1415808f684SSatish Balay        OptDB = PETSc.Options(self.pc)
1425808f684SSatish Balay        assert OptDB.prefix == self.pc.prefix
1435808f684SSatish Balay        OptDB['pc_python_type'] = '%s.%s' % (module, factory)
1445808f684SSatish Balay        self.pc.setFromOptions()
1455808f684SSatish Balay        del OptDB['pc_python_type']
1465808f684SSatish Balay        assert self._getCtx().log['create'] == 1
1475808f684SSatish Balay        assert self._getCtx().log['setFromOptions'] == 1
1485808f684SSatish Balay        ctx = self._getCtx()
1495808f684SSatish Balay        self.assertEqual(getrefcount(ctx), 3)
1505808f684SSatish Balay
151ebead697SStefano Zampini    def testGetType(self):
152ebead697SStefano Zampini        ctx = self.pc.getPythonContext()
153ebead697SStefano Zampini        pytype = "{0}.{1}".format(ctx.__module__, type(ctx).__name__)
154ebead697SStefano Zampini        self.assertTrue(self.pc.getPythonType() == pytype)
155ebead697SStefano Zampini
1565808f684SSatish Balay    def tearDown(self):
1575808f684SSatish Balay        ctx = self._getCtx()
1585808f684SSatish Balay        self.pc.destroy() # XXX
1595808f684SSatish Balay        self.pc = None
160*62e5d2d2SJDBetteridge        PETSc.garbage_cleanup()
1615808f684SSatish Balay        assert ctx.log['destroy'] == 1
1625808f684SSatish Balay        self.assertEqual(getrefcount(ctx), 2)
1635808f684SSatish Balay
1645808f684SSatish Balay    def _prepare(self):
1655808f684SSatish Balay        A = PETSc.Mat().createAIJ([3,3], comm=PETSc.COMM_SELF)
1665808f684SSatish Balay        A.setUp()
1675808f684SSatish Balay        A.assemble()
1685808f684SSatish Balay        A.shift(10)
1695808f684SSatish Balay        x, y = A.createVecs()
1705808f684SSatish Balay        x.setRandom()
1715808f684SSatish Balay        self.pc.setOperators(A, A)
172bda5c5f8SStefano Zampini        X = PETSc.Mat().createDense([3,5], comm=PETSc.COMM_SELF).setUp()
173bda5c5f8SStefano Zampini        X.assemble()
174bda5c5f8SStefano Zampini        Y = PETSc.Mat().createDense([3,5], comm=PETSc.COMM_SELF).setUp()
175bda5c5f8SStefano Zampini        Y.assemble()
1765808f684SSatish Balay        assert (A,A) == self.pc.getOperators()
177bda5c5f8SStefano Zampini        return A, x, y, X, Y
1785808f684SSatish Balay
1795808f684SSatish Balay    def _getCtx(self):
1805808f684SSatish Balay        return self.pc.getPythonContext()
1815808f684SSatish Balay
1825808f684SSatish Balay    def _applyMeth(self, meth):
183bda5c5f8SStefano Zampini        A, x, y, X, Y = self._prepare()
184bda5c5f8SStefano Zampini        if meth == 'matApply':
185bda5c5f8SStefano Zampini            getattr(self.pc, meth)(X,Y)
186bda5c5f8SStefano Zampini            x.copy(y)
187bda5c5f8SStefano Zampini        else:
1885808f684SSatish Balay            getattr(self.pc, meth)(x,y)
189bda5c5f8SStefano Zampini            X.copy(Y)
1905808f684SSatish Balay        if 'reset' not in self._getCtx().log:
1915808f684SSatish Balay            assert self._getCtx().log['setUp'] == 1
1925808f684SSatish Balay            assert self._getCtx().log[meth] == 1
1935808f684SSatish Balay        else:
1945808f684SSatish Balay            nreset = self._getCtx().log['reset']
1955808f684SSatish Balay            nsetup = self._getCtx().log['setUp']
1965808f684SSatish Balay            nmeth  = self._getCtx().log[meth]
1975808f684SSatish Balay            assert (nreset == nsetup)
1985808f684SSatish Balay            assert (nreset == nmeth)
1995808f684SSatish Balay        if isinstance(self._getCtx().impl, MyPCNone):
2005808f684SSatish Balay            self.assertTrue(y.equal(x))
201bda5c5f8SStefano Zampini            self.assertTrue(Y.equal(X))
2025808f684SSatish Balay    def testApply(self):
2035808f684SSatish Balay        self._applyMeth('apply')
2045808f684SSatish Balay    def testApplySymmetricLeft(self):
2055808f684SSatish Balay        self._applyMeth('applySymmetricLeft')
2065808f684SSatish Balay    def testApplySymmetricRight(self):
2075808f684SSatish Balay        self._applyMeth('applySymmetricRight')
2085808f684SSatish Balay    def testApplyTranspose(self):
2095808f684SSatish Balay        self._applyMeth('applyTranspose')
210bda5c5f8SStefano Zampini    def testApplyMat(self):
211bda5c5f8SStefano Zampini        self._applyMeth('matApply')
2125808f684SSatish Balay    ## def testApplyRichardson(self):
2135808f684SSatish Balay    ##     x, y = self._prepare()
2145808f684SSatish Balay    ##     w = x.duplicate()
2155808f684SSatish Balay    ##     tols = 0,0,0,0
2165808f684SSatish Balay    ##     self.pc.applyRichardson(x,y,w,tols)
2175808f684SSatish Balay    ##     assert self._getCtx().log['setUp'] == 1
2185808f684SSatish Balay    ##     assert self._getCtx().log['applyRichardson'] == 1
2195808f684SSatish Balay
2205808f684SSatish Balay    ## def testView(self):
2215808f684SSatish Balay    ##     vw = PETSc.ViewerString(100, self.pc.comm)
2225808f684SSatish Balay    ##     self.pc.view(vw)
2235808f684SSatish Balay    ##     s = vw.getString()
2245808f684SSatish Balay    ##     assert 'python' in s
2255808f684SSatish Balay    ##     module = __name__
2265808f684SSatish Balay    ##     factory = 'self._getCtx()'
2275808f684SSatish Balay    ##     assert '.'.join([module, factory]) in s
2285808f684SSatish Balay
2295808f684SSatish Balay    def testResetAndApply(self):
2305808f684SSatish Balay        self.pc.reset()
2315808f684SSatish Balay        self.testApply()
2325808f684SSatish Balay        self.pc.reset()
2335808f684SSatish Balay        self.testApply()
2345808f684SSatish Balay        self.pc.reset()
2355808f684SSatish Balay
2365808f684SSatish Balay    def testKSPSolve(self):
237bda5c5f8SStefano Zampini        A, x, y, _, _ = self._prepare()
2385808f684SSatish Balay        ksp = PETSc.KSP().create(self.pc.comm)
2395808f684SSatish Balay        ksp.setType(PETSc.KSP.Type.PREONLY)
2405808f684SSatish Balay        assert self.pc.getRefCount() == 1
2415808f684SSatish Balay        ksp.setPC(self.pc)
2425808f684SSatish Balay        assert self.pc.getRefCount() == 2
2435808f684SSatish Balay        # normal ksp solve, twice
2445808f684SSatish Balay        ksp.solve(x,y)
2455808f684SSatish Balay        assert self._getCtx().log['setUp'    ] == 1
2465808f684SSatish Balay        assert self._getCtx().log['apply'    ] == 1
2475808f684SSatish Balay        assert self._getCtx().log['preSolve' ] == 1
2485808f684SSatish Balay        assert self._getCtx().log['postSolve'] == 1
2495808f684SSatish Balay        ksp.solve(x,y)
2505808f684SSatish Balay        assert self._getCtx().log['setUp'    ] == 1
2515808f684SSatish Balay        assert self._getCtx().log['apply'    ] == 2
2525808f684SSatish Balay        assert self._getCtx().log['preSolve' ] == 2
2535808f684SSatish Balay        assert self._getCtx().log['postSolve'] == 2
2545808f684SSatish Balay        # transpose ksp solve, twice
2555808f684SSatish Balay        ksp.solveTranspose(x,y)
2565808f684SSatish Balay        assert self._getCtx().log['setUp'         ] == 1
2575808f684SSatish Balay        assert self._getCtx().log['applyTranspose'] == 1
2585808f684SSatish Balay        ksp.solveTranspose(x,y)
2595808f684SSatish Balay        assert self._getCtx().log['setUp'         ] == 1
2605808f684SSatish Balay        assert self._getCtx().log['applyTranspose'] == 2
2615808f684SSatish Balay        del ksp # ksp.destroy()
262*62e5d2d2SJDBetteridge        PETSc.garbage_cleanup()
263*62e5d2d2SJDBetteridge        self.assertEqual(self.pc.getRefCount(), 1)
2645808f684SSatish Balay
2655808f684SSatish Balay    def testGetSetContext(self):
2665808f684SSatish Balay        ctx = self.pc.getPythonContext()
2675808f684SSatish Balay        self.pc.setPythonContext(ctx)
2685808f684SSatish Balay        self.assertEqual(getrefcount(ctx), 3)
2695808f684SSatish Balay        del ctx
2705808f684SSatish Balay
2715808f684SSatish Balay
2725808f684SSatish Balayclass TestPCPYTHON2(TestPCPYTHON):
2735808f684SSatish Balay    def setUp(self):
2745808f684SSatish Balay        OptDB = PETSc.Options(self.PC_PREFIX)
2755808f684SSatish Balay        OptDB['impl'] = 'MyPCJacobi'
2765808f684SSatish Balay        super(TestPCPYTHON2, self).setUp()
2775808f684SSatish Balay        clsname = type(self._getCtx().impl).__name__
2785808f684SSatish Balay        assert clsname == OptDB['impl']
2795808f684SSatish Balay        del OptDB['impl']
2805808f684SSatish Balay
2815808f684SSatish Balayclass TestPCPYTHON3(TestPCPYTHON):
2825808f684SSatish Balay    def setUp(self):
2835808f684SSatish Balay        pc = self.pc = PETSc.PC()
2845808f684SSatish Balay        ctx = PC_PYTHON_CLASS()
2855808f684SSatish Balay        pc.createPython(ctx, comm=PETSc.COMM_SELF)
2865808f684SSatish Balay        self.pc.prefix = self.PC_PREFIX
2875808f684SSatish Balay        self.pc.setFromOptions()
2885808f684SSatish Balay        assert self._getCtx().log['create'] == 1
2895808f684SSatish Balay        assert self._getCtx().log['setFromOptions'] == 1
2905808f684SSatish Balay
2915808f684SSatish Balayclass TestPCPYTHON4(TestPCPYTHON3):
2925808f684SSatish Balay    def setUp(self):
2935808f684SSatish Balay        OptDB = PETSc.Options(self.PC_PREFIX)
2945808f684SSatish Balay        OptDB['impl'] = 'MyPCJacobi'
2955808f684SSatish Balay        super(TestPCPYTHON4, self).setUp()
2965808f684SSatish Balay        clsname = type(self._getCtx().impl).__name__
2975808f684SSatish Balay        assert clsname == OptDB['impl']
2985808f684SSatish Balay        del OptDB['impl']
2995808f684SSatish Balay
3005808f684SSatish Balay# --------------------------------------------------------------------
3015808f684SSatish Balay
3025808f684SSatish Balayif __name__ == '__main__':
3035808f684SSatish Balay    unittest.main()
304