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 151*ebead697SStefano Zampini def testGetType(self): 152*ebead697SStefano Zampini ctx = self.pc.getPythonContext() 153*ebead697SStefano Zampini pytype = "{0}.{1}".format(ctx.__module__, type(ctx).__name__) 154*ebead697SStefano Zampini self.assertTrue(self.pc.getPythonType() == pytype) 155*ebead697SStefano Zampini 1565808f684SSatish Balay def tearDown(self): 1575808f684SSatish Balay ctx = self._getCtx() 1585808f684SSatish Balay self.pc.destroy() # XXX 1595808f684SSatish Balay self.pc = None 1605808f684SSatish Balay assert ctx.log['destroy'] == 1 1615808f684SSatish Balay self.assertEqual(getrefcount(ctx), 2) 1625808f684SSatish Balay 1635808f684SSatish Balay def _prepare(self): 1645808f684SSatish Balay A = PETSc.Mat().createAIJ([3,3], comm=PETSc.COMM_SELF) 1655808f684SSatish Balay A.setUp() 1665808f684SSatish Balay A.assemble() 1675808f684SSatish Balay A.shift(10) 1685808f684SSatish Balay x, y = A.createVecs() 1695808f684SSatish Balay x.setRandom() 1705808f684SSatish Balay self.pc.setOperators(A, A) 171bda5c5f8SStefano Zampini X = PETSc.Mat().createDense([3,5], comm=PETSc.COMM_SELF).setUp() 172bda5c5f8SStefano Zampini X.assemble() 173bda5c5f8SStefano Zampini Y = PETSc.Mat().createDense([3,5], comm=PETSc.COMM_SELF).setUp() 174bda5c5f8SStefano Zampini Y.assemble() 1755808f684SSatish Balay assert (A,A) == self.pc.getOperators() 176bda5c5f8SStefano Zampini return A, x, y, X, Y 1775808f684SSatish Balay 1785808f684SSatish Balay def _getCtx(self): 1795808f684SSatish Balay return self.pc.getPythonContext() 1805808f684SSatish Balay 1815808f684SSatish Balay def _applyMeth(self, meth): 182bda5c5f8SStefano Zampini A, x, y, X, Y = self._prepare() 183bda5c5f8SStefano Zampini if meth == 'matApply': 184bda5c5f8SStefano Zampini getattr(self.pc, meth)(X,Y) 185bda5c5f8SStefano Zampini x.copy(y) 186bda5c5f8SStefano Zampini else: 1875808f684SSatish Balay getattr(self.pc, meth)(x,y) 188bda5c5f8SStefano Zampini X.copy(Y) 1895808f684SSatish Balay if 'reset' not in self._getCtx().log: 1905808f684SSatish Balay assert self._getCtx().log['setUp'] == 1 1915808f684SSatish Balay assert self._getCtx().log[meth] == 1 1925808f684SSatish Balay else: 1935808f684SSatish Balay nreset = self._getCtx().log['reset'] 1945808f684SSatish Balay nsetup = self._getCtx().log['setUp'] 1955808f684SSatish Balay nmeth = self._getCtx().log[meth] 1965808f684SSatish Balay assert (nreset == nsetup) 1975808f684SSatish Balay assert (nreset == nmeth) 1985808f684SSatish Balay if isinstance(self._getCtx().impl, MyPCNone): 1995808f684SSatish Balay self.assertTrue(y.equal(x)) 200bda5c5f8SStefano Zampini self.assertTrue(Y.equal(X)) 2015808f684SSatish Balay def testApply(self): 2025808f684SSatish Balay self._applyMeth('apply') 2035808f684SSatish Balay def testApplySymmetricLeft(self): 2045808f684SSatish Balay self._applyMeth('applySymmetricLeft') 2055808f684SSatish Balay def testApplySymmetricRight(self): 2065808f684SSatish Balay self._applyMeth('applySymmetricRight') 2075808f684SSatish Balay def testApplyTranspose(self): 2085808f684SSatish Balay self._applyMeth('applyTranspose') 209bda5c5f8SStefano Zampini def testApplyMat(self): 210bda5c5f8SStefano Zampini self._applyMeth('matApply') 2115808f684SSatish Balay ## def testApplyRichardson(self): 2125808f684SSatish Balay ## x, y = self._prepare() 2135808f684SSatish Balay ## w = x.duplicate() 2145808f684SSatish Balay ## tols = 0,0,0,0 2155808f684SSatish Balay ## self.pc.applyRichardson(x,y,w,tols) 2165808f684SSatish Balay ## assert self._getCtx().log['setUp'] == 1 2175808f684SSatish Balay ## assert self._getCtx().log['applyRichardson'] == 1 2185808f684SSatish Balay 2195808f684SSatish Balay ## def testView(self): 2205808f684SSatish Balay ## vw = PETSc.ViewerString(100, self.pc.comm) 2215808f684SSatish Balay ## self.pc.view(vw) 2225808f684SSatish Balay ## s = vw.getString() 2235808f684SSatish Balay ## assert 'python' in s 2245808f684SSatish Balay ## module = __name__ 2255808f684SSatish Balay ## factory = 'self._getCtx()' 2265808f684SSatish Balay ## assert '.'.join([module, factory]) in s 2275808f684SSatish Balay 2285808f684SSatish Balay def testResetAndApply(self): 2295808f684SSatish Balay self.pc.reset() 2305808f684SSatish Balay self.testApply() 2315808f684SSatish Balay self.pc.reset() 2325808f684SSatish Balay self.testApply() 2335808f684SSatish Balay self.pc.reset() 2345808f684SSatish Balay 2355808f684SSatish Balay def testKSPSolve(self): 236bda5c5f8SStefano Zampini A, x, y, _, _ = self._prepare() 2375808f684SSatish Balay ksp = PETSc.KSP().create(self.pc.comm) 2385808f684SSatish Balay ksp.setType(PETSc.KSP.Type.PREONLY) 2395808f684SSatish Balay assert self.pc.getRefCount() == 1 2405808f684SSatish Balay ksp.setPC(self.pc) 2415808f684SSatish Balay assert self.pc.getRefCount() == 2 2425808f684SSatish Balay # normal ksp solve, twice 2435808f684SSatish Balay ksp.solve(x,y) 2445808f684SSatish Balay assert self._getCtx().log['setUp' ] == 1 2455808f684SSatish Balay assert self._getCtx().log['apply' ] == 1 2465808f684SSatish Balay assert self._getCtx().log['preSolve' ] == 1 2475808f684SSatish Balay assert self._getCtx().log['postSolve'] == 1 2485808f684SSatish Balay ksp.solve(x,y) 2495808f684SSatish Balay assert self._getCtx().log['setUp' ] == 1 2505808f684SSatish Balay assert self._getCtx().log['apply' ] == 2 2515808f684SSatish Balay assert self._getCtx().log['preSolve' ] == 2 2525808f684SSatish Balay assert self._getCtx().log['postSolve'] == 2 2535808f684SSatish Balay # transpose ksp solve, twice 2545808f684SSatish Balay ksp.solveTranspose(x,y) 2555808f684SSatish Balay assert self._getCtx().log['setUp' ] == 1 2565808f684SSatish Balay assert self._getCtx().log['applyTranspose'] == 1 2575808f684SSatish Balay ksp.solveTranspose(x,y) 2585808f684SSatish Balay assert self._getCtx().log['setUp' ] == 1 2595808f684SSatish Balay assert self._getCtx().log['applyTranspose'] == 2 2605808f684SSatish Balay del ksp # ksp.destroy() 2615808f684SSatish Balay assert self.pc.getRefCount() == 1 2625808f684SSatish Balay 2635808f684SSatish Balay def testGetSetContext(self): 2645808f684SSatish Balay ctx = self.pc.getPythonContext() 2655808f684SSatish Balay self.pc.setPythonContext(ctx) 2665808f684SSatish Balay self.assertEqual(getrefcount(ctx), 3) 2675808f684SSatish Balay del ctx 2685808f684SSatish Balay 2695808f684SSatish Balay 2705808f684SSatish Balayclass TestPCPYTHON2(TestPCPYTHON): 2715808f684SSatish Balay def setUp(self): 2725808f684SSatish Balay OptDB = PETSc.Options(self.PC_PREFIX) 2735808f684SSatish Balay OptDB['impl'] = 'MyPCJacobi' 2745808f684SSatish Balay super(TestPCPYTHON2, self).setUp() 2755808f684SSatish Balay clsname = type(self._getCtx().impl).__name__ 2765808f684SSatish Balay assert clsname == OptDB['impl'] 2775808f684SSatish Balay del OptDB['impl'] 2785808f684SSatish Balay 2795808f684SSatish Balayclass TestPCPYTHON3(TestPCPYTHON): 2805808f684SSatish Balay def setUp(self): 2815808f684SSatish Balay pc = self.pc = PETSc.PC() 2825808f684SSatish Balay ctx = PC_PYTHON_CLASS() 2835808f684SSatish Balay pc.createPython(ctx, comm=PETSc.COMM_SELF) 2845808f684SSatish Balay self.pc.prefix = self.PC_PREFIX 2855808f684SSatish Balay self.pc.setFromOptions() 2865808f684SSatish Balay assert self._getCtx().log['create'] == 1 2875808f684SSatish Balay assert self._getCtx().log['setFromOptions'] == 1 2885808f684SSatish Balay 2895808f684SSatish Balayclass TestPCPYTHON4(TestPCPYTHON3): 2905808f684SSatish Balay def setUp(self): 2915808f684SSatish Balay OptDB = PETSc.Options(self.PC_PREFIX) 2925808f684SSatish Balay OptDB['impl'] = 'MyPCJacobi' 2935808f684SSatish Balay super(TestPCPYTHON4, self).setUp() 2945808f684SSatish Balay clsname = type(self._getCtx().impl).__name__ 2955808f684SSatish Balay assert clsname == OptDB['impl'] 2965808f684SSatish Balay del OptDB['impl'] 2975808f684SSatish Balay 2985808f684SSatish Balay# -------------------------------------------------------------------- 2995808f684SSatish Balay 3005808f684SSatish Balayif __name__ == '__main__': 3015808f684SSatish Balay unittest.main() 302