15808f684SSatish Balay# -------------------------------------------------------------------- 25808f684SSatish Balay 35808f684SSatish Balayfrom petsc4py import PETSc 45808f684SSatish Balayimport unittest 55808f684SSatish Balayfrom sys import getrefcount 65808f684SSatish Balay 75808f684SSatish Balay# -------------------------------------------------------------------- 85808f684SSatish Balay 96f336411SStefano Zampini 106f336411SStefano Zampiniclass BaseMyPC: 115808f684SSatish Balay def setup(self, pc): 125808f684SSatish Balay pass 136f336411SStefano Zampini 145808f684SSatish Balay def reset(self, pc): 155808f684SSatish Balay pass 166f336411SStefano Zampini 175808f684SSatish Balay def apply(self, pc, x, y): 185808f684SSatish Balay raise NotImplementedError 196f336411SStefano Zampini 205808f684SSatish Balay def applyT(self, pc, x, y): 215808f684SSatish Balay self.apply(pc, x, y) 226f336411SStefano Zampini 235808f684SSatish Balay def applyS(self, pc, x, y): 245808f684SSatish Balay self.apply(pc, x, y) 256f336411SStefano Zampini 265808f684SSatish Balay def applySL(self, pc, x, y): 275808f684SSatish Balay self.applyS(pc, x, y) 286f336411SStefano Zampini 295808f684SSatish Balay def applySR(self, pc, x, y): 305808f684SSatish Balay self.applyS(pc, x, y) 316f336411SStefano Zampini 325808f684SSatish Balay def applyRich(self, pc, x, y, w, tols): 335808f684SSatish Balay self.apply(pc, x, y) 346f336411SStefano Zampini 35bda5c5f8SStefano Zampini def applyM(self, pc, x, y): 36bda5c5f8SStefano Zampini raise NotImplementedError 375808f684SSatish Balay 386f336411SStefano Zampini 395808f684SSatish Balayclass MyPCNone(BaseMyPC): 405808f684SSatish Balay def apply(self, pc, x, y): 415808f684SSatish Balay x.copy(y) 426f336411SStefano Zampini 43bda5c5f8SStefano Zampini def applyM(self, pc, x, y): 44bda5c5f8SStefano Zampini x.copy(y) 455808f684SSatish Balay 466f336411SStefano Zampini 475808f684SSatish Balayclass MyPCJacobi(BaseMyPC): 485808f684SSatish Balay def setup(self, pc): 495808f684SSatish Balay A, P = pc.getOperators() 505808f684SSatish Balay self.diag = P.getDiagonal() 515808f684SSatish Balay self.diag.reciprocal() 526f336411SStefano Zampini 535808f684SSatish Balay def reset(self, pc): 545808f684SSatish Balay self.diag.destroy() 555808f684SSatish Balay del self.diag 566f336411SStefano Zampini 575808f684SSatish Balay def apply(self, pc, x, y): 585808f684SSatish Balay y.pointwiseMult(self.diag, x) 596f336411SStefano Zampini 605808f684SSatish Balay def applyS(self, pc, x, y): 615808f684SSatish Balay self.diag.copy(y) 625808f684SSatish Balay y.sqrtabs() 635808f684SSatish Balay y.pointwiseMult(y, x) 646f336411SStefano Zampini 65bda5c5f8SStefano Zampini def applyM(self, pc, x, y): 66bda5c5f8SStefano Zampini x.copy(y) 67bda5c5f8SStefano Zampini y.diagonalScale(L=self.diag) 685808f684SSatish Balay 695808f684SSatish Balay 706f336411SStefano Zampiniclass PC_PYTHON_CLASS: 715808f684SSatish Balay def __init__(self): 725808f684SSatish Balay self.impl = None 735808f684SSatish Balay self.log = {} 746f336411SStefano Zampini 755808f684SSatish Balay def _log(self, method, *args): 765808f684SSatish Balay self.log.setdefault(method, 0) 775808f684SSatish Balay self.log[method] += 1 786f336411SStefano Zampini 795808f684SSatish Balay def create(self, pc): 805808f684SSatish Balay self._log('create', pc) 816f336411SStefano Zampini 825808f684SSatish Balay def destroy(self, pc): 835808f684SSatish Balay self._log('destroy') 845808f684SSatish Balay self.impl = None 856f336411SStefano Zampini 865808f684SSatish Balay def reset(self, pc): 875808f684SSatish Balay self._log('reset', pc) 886f336411SStefano Zampini 895808f684SSatish Balay def view(self, pc, vw): 905808f684SSatish Balay self._log('view', pc, vw) 916f336411SStefano Zampini 925808f684SSatish Balay def setFromOptions(self, pc): 935808f684SSatish Balay self._log('setFromOptions', pc) 945808f684SSatish Balay OptDB = PETSc.Options(pc) 955808f684SSatish Balay impl = OptDB.getString('impl', 'MyPCNone') 965808f684SSatish Balay klass = globals()[impl] 975808f684SSatish Balay self.impl = klass() 986f336411SStefano Zampini 995808f684SSatish Balay def setUp(self, pc): 1005808f684SSatish Balay self._log('setUp', pc) 1015808f684SSatish Balay self.impl.setup(pc) 1026f336411SStefano Zampini 1035808f684SSatish Balay def preSolve(self, pc, ksp, b, x): 1045808f684SSatish Balay self._log('preSolve', pc, ksp, b, x) 1056f336411SStefano Zampini 1065808f684SSatish Balay def postSolve(self, pc, ksp, b, x): 1075808f684SSatish Balay self._log('postSolve', pc, ksp, b, x) 1086f336411SStefano Zampini 1095808f684SSatish Balay def apply(self, pc, x, y): 1105808f684SSatish Balay self._log('apply', pc, x, y) 1115808f684SSatish Balay self.impl.apply(pc, x, y) 1126f336411SStefano Zampini 1135808f684SSatish Balay def applySymmetricLeft(self, pc, x, y): 1145808f684SSatish Balay self._log('applySymmetricLeft', pc, x, y) 1155808f684SSatish Balay self.impl.applySL(pc, x, y) 1166f336411SStefano Zampini 1175808f684SSatish Balay def applySymmetricRight(self, pc, x, y): 1185808f684SSatish Balay self._log('applySymmetricRight', pc, x, y) 1195808f684SSatish Balay self.impl.applySR(pc, x, y) 1206f336411SStefano Zampini 1215808f684SSatish Balay def applyTranspose(self, pc, x, y): 1225808f684SSatish Balay self._log('applyTranspose', pc, x, y) 1235808f684SSatish Balay self.impl.applyT(pc, x, y) 1246f336411SStefano Zampini 125bda5c5f8SStefano Zampini def matApply(self, pc, x, y): 126bda5c5f8SStefano Zampini self._log('matApply', pc, x, y) 127bda5c5f8SStefano Zampini self.impl.applyM(pc, x, y) 1286f336411SStefano Zampini 1295808f684SSatish Balay def applyRichardson(self, pc, x, y, w, tols): 1305808f684SSatish Balay self._log('applyRichardson', pc, x, y, w, tols) 1315808f684SSatish Balay self.impl.applyRich(pc, x, y, w, tols) 1325808f684SSatish Balay 1335808f684SSatish Balay 1345808f684SSatish Balayclass TestPCPYTHON(unittest.TestCase): 1355808f684SSatish Balay PC_TYPE = PETSc.PC.Type.PYTHON 1365808f684SSatish Balay PC_PREFIX = 'test-' 1375808f684SSatish Balay 1385808f684SSatish Balay def setUp(self): 1395808f684SSatish Balay pc = self.pc = PETSc.PC() 1405808f684SSatish Balay pc.create(PETSc.COMM_SELF) 1415808f684SSatish Balay pc.setType(self.PC_TYPE) 1425808f684SSatish Balay module = __name__ 1435808f684SSatish Balay factory = 'PC_PYTHON_CLASS' 1445808f684SSatish Balay self.pc.prefix = self.PC_PREFIX 1455808f684SSatish Balay OptDB = PETSc.Options(self.pc) 1466f336411SStefano Zampini self.assertTrue(OptDB.prefix == self.pc.prefix) 1476f336411SStefano Zampini OptDB['pc_python_type'] = f'{module}.{factory}' 1485808f684SSatish Balay self.pc.setFromOptions() 1495808f684SSatish Balay del OptDB['pc_python_type'] 1506f336411SStefano Zampini self.assertTrue(self._getCtx().log['create'] == 1) 1516f336411SStefano Zampini self.assertTrue(self._getCtx().log['setFromOptions'] == 1) 152*39933f97SStefano Zampini self.assertEqual(getrefcount(self._getCtx()), 2) 1535808f684SSatish Balay 154ebead697SStefano Zampini def testGetType(self): 155ebead697SStefano Zampini ctx = self.pc.getPythonContext() 1566f336411SStefano Zampini pytype = f'{ctx.__module__}.{type(ctx).__name__}' 157ebead697SStefano Zampini self.assertTrue(self.pc.getPythonType() == pytype) 158ebead697SStefano Zampini 1595808f684SSatish Balay def tearDown(self): 1605808f684SSatish Balay ctx = self._getCtx() 1615808f684SSatish Balay self.pc.destroy() # XXX 1625808f684SSatish Balay self.pc = None 16362e5d2d2SJDBetteridge PETSc.garbage_cleanup() 1646f336411SStefano Zampini self.assertTrue(ctx.log['destroy'] == 1) 1655808f684SSatish Balay 1665808f684SSatish Balay def _prepare(self): 1675808f684SSatish Balay A = PETSc.Mat().createAIJ([3, 3], comm=PETSc.COMM_SELF) 1685808f684SSatish Balay A.setUp() 1695808f684SSatish Balay A.assemble() 1705808f684SSatish Balay A.shift(10) 1715808f684SSatish Balay x, y = A.createVecs() 1725808f684SSatish Balay x.setRandom() 1735808f684SSatish Balay self.pc.setOperators(A, A) 174bda5c5f8SStefano Zampini X = PETSc.Mat().createDense([3, 5], comm=PETSc.COMM_SELF).setUp() 175bda5c5f8SStefano Zampini X.assemble() 176bda5c5f8SStefano Zampini Y = PETSc.Mat().createDense([3, 5], comm=PETSc.COMM_SELF).setUp() 177bda5c5f8SStefano Zampini Y.assemble() 1786f336411SStefano Zampini self.assertTrue((A, A) == self.pc.getOperators()) 179bda5c5f8SStefano Zampini return A, x, y, X, Y 1805808f684SSatish Balay 1815808f684SSatish Balay def _getCtx(self): 1825808f684SSatish Balay return self.pc.getPythonContext() 1835808f684SSatish Balay 1845808f684SSatish Balay def _applyMeth(self, meth): 185bda5c5f8SStefano Zampini A, x, y, X, Y = self._prepare() 186bda5c5f8SStefano Zampini if meth == 'matApply': 187bda5c5f8SStefano Zampini getattr(self.pc, meth)(X, Y) 188bda5c5f8SStefano Zampini x.copy(y) 189bda5c5f8SStefano Zampini else: 1905808f684SSatish Balay getattr(self.pc, meth)(x, y) 191bda5c5f8SStefano Zampini X.copy(Y) 1925808f684SSatish Balay if 'reset' not in self._getCtx().log: 1936f336411SStefano Zampini self.assertTrue(self._getCtx().log['setUp'] == 1) 1946f336411SStefano Zampini self.assertTrue(self._getCtx().log[meth] == 1) 1955808f684SSatish Balay else: 1965808f684SSatish Balay nreset = self._getCtx().log['reset'] 1975808f684SSatish Balay nsetup = self._getCtx().log['setUp'] 1985808f684SSatish Balay nmeth = self._getCtx().log[meth] 1996f336411SStefano Zampini self.assertTrue(nreset == nsetup) 2006f336411SStefano Zampini self.assertTrue(nreset == nmeth) 2015808f684SSatish Balay if isinstance(self._getCtx().impl, MyPCNone): 2025808f684SSatish Balay self.assertTrue(y.equal(x)) 203bda5c5f8SStefano Zampini self.assertTrue(Y.equal(X)) 2046f336411SStefano Zampini 2055808f684SSatish Balay def testApply(self): 2065808f684SSatish Balay self._applyMeth('apply') 2076f336411SStefano Zampini 2085808f684SSatish Balay def testApplySymmetricLeft(self): 2095808f684SSatish Balay self._applyMeth('applySymmetricLeft') 2106f336411SStefano Zampini 2115808f684SSatish Balay def testApplySymmetricRight(self): 2125808f684SSatish Balay self._applyMeth('applySymmetricRight') 2136f336411SStefano Zampini 2145808f684SSatish Balay def testApplyTranspose(self): 2155808f684SSatish Balay self._applyMeth('applyTranspose') 2166f336411SStefano Zampini 217bda5c5f8SStefano Zampini def testApplyMat(self): 218bda5c5f8SStefano Zampini self._applyMeth('matApply') 2196f336411SStefano Zampini 2205808f684SSatish Balay ## def testApplyRichardson(self): 2215808f684SSatish Balay ## x, y = self._prepare() 2225808f684SSatish Balay ## w = x.duplicate() 2235808f684SSatish Balay ## tols = 0,0,0,0 2245808f684SSatish Balay ## self.pc.applyRichardson(x,y,w,tols) 2255808f684SSatish Balay ## assert self._getCtx().log['setUp'] == 1 2265808f684SSatish Balay ## assert self._getCtx().log['applyRichardson'] == 1 2275808f684SSatish Balay 2285808f684SSatish Balay ## def testView(self): 2295808f684SSatish Balay ## vw = PETSc.ViewerString(100, self.pc.comm) 2305808f684SSatish Balay ## self.pc.view(vw) 2315808f684SSatish Balay ## s = vw.getString() 2325808f684SSatish Balay ## assert 'python' in s 2335808f684SSatish Balay ## module = __name__ 2345808f684SSatish Balay ## factory = 'self._getCtx()' 2355808f684SSatish Balay ## assert '.'.join([module, factory]) in s 2365808f684SSatish Balay 2375808f684SSatish Balay def testResetAndApply(self): 2385808f684SSatish Balay self.pc.reset() 2395808f684SSatish Balay self.testApply() 2405808f684SSatish Balay self.pc.reset() 2415808f684SSatish Balay self.testApply() 2425808f684SSatish Balay self.pc.reset() 2435808f684SSatish Balay 2445808f684SSatish Balay def testKSPSolve(self): 245bda5c5f8SStefano Zampini A, x, y, _, _ = self._prepare() 2465808f684SSatish Balay ksp = PETSc.KSP().create(self.pc.comm) 2475808f684SSatish Balay ksp.setType(PETSc.KSP.Type.PREONLY) 2486f336411SStefano Zampini self.assertTrue(self.pc.getRefCount() == 1) 2495808f684SSatish Balay ksp.setPC(self.pc) 2506f336411SStefano Zampini self.assertTrue(self.pc.getRefCount() == 2) 2515808f684SSatish Balay # normal ksp solve, twice 2525808f684SSatish Balay ksp.solve(x, y) 2536f336411SStefano Zampini self.assertTrue(self._getCtx().log['setUp'] == 1) 2546f336411SStefano Zampini self.assertTrue(self._getCtx().log['apply'] == 1) 2556f336411SStefano Zampini self.assertTrue(self._getCtx().log['preSolve'] == 1) 2566f336411SStefano Zampini self.assertTrue(self._getCtx().log['postSolve'] == 1) 2575808f684SSatish Balay ksp.solve(x, y) 2586f336411SStefano Zampini self.assertTrue(self._getCtx().log['setUp'] == 1) 2596f336411SStefano Zampini self.assertTrue(self._getCtx().log['apply'] == 2) 2606f336411SStefano Zampini self.assertTrue(self._getCtx().log['preSolve'] == 2) 2616f336411SStefano Zampini self.assertTrue(self._getCtx().log['postSolve'] == 2) 2625808f684SSatish Balay # transpose ksp solve, twice 2635808f684SSatish Balay ksp.solveTranspose(x, y) 2646f336411SStefano Zampini self.assertTrue(self._getCtx().log['setUp'] == 1) 2656f336411SStefano Zampini self.assertTrue(self._getCtx().log['applyTranspose'] == 1) 2665808f684SSatish Balay ksp.solveTranspose(x, y) 2676f336411SStefano Zampini self.assertTrue(self._getCtx().log['setUp'] == 1) 2686f336411SStefano Zampini self.assertTrue(self._getCtx().log['applyTranspose'] == 2) 2695808f684SSatish Balay del ksp # ksp.destroy() 27062e5d2d2SJDBetteridge PETSc.garbage_cleanup() 27162e5d2d2SJDBetteridge self.assertEqual(self.pc.getRefCount(), 1) 2725808f684SSatish Balay 2735808f684SSatish Balay def testGetSetContext(self): 274*39933f97SStefano Zampini self.pc.setPythonContext(self._getCtx()) 275*39933f97SStefano Zampini self.assertEqual(getrefcount(self.pc.getPythonContext()), 2) 2765808f684SSatish Balay 2775808f684SSatish Balay 2785808f684SSatish Balayclass TestPCPYTHON2(TestPCPYTHON): 2795808f684SSatish Balay def setUp(self): 2805808f684SSatish Balay OptDB = PETSc.Options(self.PC_PREFIX) 2815808f684SSatish Balay OptDB['impl'] = 'MyPCJacobi' 2826f336411SStefano Zampini super().setUp() 2835808f684SSatish Balay clsname = type(self._getCtx().impl).__name__ 2846f336411SStefano Zampini self.assertTrue(clsname == OptDB['impl']) 2855808f684SSatish Balay del OptDB['impl'] 2865808f684SSatish Balay 2876f336411SStefano Zampini 2885808f684SSatish Balayclass TestPCPYTHON3(TestPCPYTHON): 2895808f684SSatish Balay def setUp(self): 2905808f684SSatish Balay pc = self.pc = PETSc.PC() 2915808f684SSatish Balay ctx = PC_PYTHON_CLASS() 2925808f684SSatish Balay pc.createPython(ctx, comm=PETSc.COMM_SELF) 2935808f684SSatish Balay self.pc.prefix = self.PC_PREFIX 2945808f684SSatish Balay self.pc.setFromOptions() 2956f336411SStefano Zampini self.assertTrue(self._getCtx().log['create'] == 1) 2966f336411SStefano Zampini self.assertTrue(self._getCtx().log['setFromOptions'] == 1) 2976f336411SStefano Zampini 2985808f684SSatish Balay 2995808f684SSatish Balayclass TestPCPYTHON4(TestPCPYTHON3): 3005808f684SSatish Balay def setUp(self): 3015808f684SSatish Balay OptDB = PETSc.Options(self.PC_PREFIX) 3025808f684SSatish Balay OptDB['impl'] = 'MyPCJacobi' 3036f336411SStefano Zampini super().setUp() 3045808f684SSatish Balay clsname = type(self._getCtx().impl).__name__ 3056f336411SStefano Zampini self.assertTrue(clsname == OptDB['impl']) 3065808f684SSatish Balay del OptDB['impl'] 3075808f684SSatish Balay 3086f336411SStefano Zampini 3095808f684SSatish Balay# -------------------------------------------------------------------- 3105808f684SSatish Balay 3115808f684SSatish Balayif __name__ == '__main__': 3125808f684SSatish Balay unittest.main() 313