xref: /petsc/src/binding/petsc4py/test/test_ts_py.py (revision 6f33641175f69f1db294cc9ba81c3f4ad4f81d49)
15808f684SSatish Balayimport unittest
25808f684SSatish Balayfrom petsc4py import PETSc
35808f684SSatish Balayfrom sys import getrefcount
45808f684SSatish Balay
55808f684SSatish Balay# --------------------------------------------------------------------
65808f684SSatish Balay
7*6f336411SStefano Zampini
85808f684SSatish Balayclass MyODE:
95808f684SSatish Balay    """
105808f684SSatish Balay    du/dt + u**2 = 0;
115808f684SSatish Balay    u0 = 1
125808f684SSatish Balay    """
135808f684SSatish Balay
145808f684SSatish Balay    def __init__(self):
155808f684SSatish Balay        self.function_calls = 0
165808f684SSatish Balay        self.jacobian_calls = 0
175808f684SSatish Balay
185808f684SSatish Balay    def function(self, ts, t, u, du, F):
195808f684SSatish Balay        # print 'MyODE.function()'
205808f684SSatish Balay        self.function_calls += 1
215808f684SSatish Balay        f = du + u * u
225808f684SSatish Balay        f.copy(F)
235808f684SSatish Balay
245808f684SSatish Balay    def jacobian(self, ts, t, u, du, a, J, P):
255808f684SSatish Balay        # print 'MyODE.jacobian()'
265808f684SSatish Balay        self.jacobian_calls += 1
275808f684SSatish Balay        P.zeroEntries()
285808f684SSatish Balay        diag = a + 2 * u
295808f684SSatish Balay        P.setDiagonal(diag)
305808f684SSatish Balay        P.assemble()
31*6f336411SStefano Zampini        if J != P:
32*6f336411SStefano Zampini            J.assemble()
335808f684SSatish Balay        return False  # same_nz
345808f684SSatish Balay
35ebead697SStefano Zampini
36*6f336411SStefano Zampiniclass MyTS:
375808f684SSatish Balay    def __init__(self):
385808f684SSatish Balay        self.log = {}
39a82e8c82SStefano Zampini
405808f684SSatish Balay    def _log(self, method, *args):
415808f684SSatish Balay        self.log.setdefault(method, 0)
425808f684SSatish Balay        self.log[method] += 1
435808f684SSatish Balay
445808f684SSatish Balay    def create(self, ts, *args):
455808f684SSatish Balay        self._log('create', *args)
465808f684SSatish Balay        self.vec_update = PETSc.Vec()
475808f684SSatish Balay
485808f684SSatish Balay    def destroy(self, ts, *args):
495808f684SSatish Balay        self._log('destroy', *args)
505808f684SSatish Balay        self.vec_update.destroy()
515808f684SSatish Balay
525808f684SSatish Balay    def setFromOptions(self, ts, *args):
535808f684SSatish Balay        self._log('setFromOptions', *args)
545808f684SSatish Balay
555808f684SSatish Balay    def setUp(self, ts, *args):
565808f684SSatish Balay        self._log('setUp', ts, *args)
575808f684SSatish Balay        self.vec_update = ts.getSolution().duplicate()
585808f684SSatish Balay
595808f684SSatish Balay    def reset(self, ts, *args):
605808f684SSatish Balay        self._log('reset', ts, *args)
615808f684SSatish Balay
625808f684SSatish Balay    def solveStep(self, ts, t, u, *args):
635808f684SSatish Balay        self._log('solveStep', ts, t, u, *args)
645808f684SSatish Balay        ts.snes.solve(None, u)
655808f684SSatish Balay
665808f684SSatish Balay    def adaptStep(self, ts, t, u, *args):
675808f684SSatish Balay        self._log('adaptStep', ts, t, u, *args)
685808f684SSatish Balay        return (ts.getTimeStep(), True)
695808f684SSatish Balay
705808f684SSatish Balay
715808f684SSatish Balayclass TestTSPython(unittest.TestCase):
725808f684SSatish Balay    def setUp(self):
735808f684SSatish Balay        self.ts = PETSc.TS()
745808f684SSatish Balay        self.ts.createPython(MyTS(), comm=PETSc.COMM_SELF)
755808f684SSatish Balay        eft = PETSc.TS.ExactFinalTime.STEPOVER
765808f684SSatish Balay        self.ts.setExactFinalTime(eft)
775808f684SSatish Balay        ctx = self.ts.getPythonContext()
785808f684SSatish Balay        self.assertEqual(getrefcount(ctx), 3)
795808f684SSatish Balay        self.assertEqual(ctx.log['create'], 1)
805808f684SSatish Balay        self.nsolve = 0
815808f684SSatish Balay
825808f684SSatish Balay    def tearDown(self):
835808f684SSatish Balay        ctx = self.ts.getPythonContext()
845808f684SSatish Balay        self.assertEqual(getrefcount(ctx), 3)
855808f684SSatish Balay        self.assertTrue('destroy' not in ctx.log)
865808f684SSatish Balay        self.ts.destroy()  # XXX
875808f684SSatish Balay        self.ts = None
8862e5d2d2SJDBetteridge        PETSc.garbage_cleanup()
895808f684SSatish Balay        self.assertEqual(ctx.log['destroy'], 1)
905808f684SSatish Balay        self.assertEqual(getrefcount(ctx), 2)
915808f684SSatish Balay
92ebead697SStefano Zampini    def testGetType(self):
93ebead697SStefano Zampini        ctx = self.ts.getPythonContext()
94*6f336411SStefano Zampini        pytype = f'{ctx.__module__}.{type(ctx).__name__}'
95ebead697SStefano Zampini        self.assertTrue(self.ts.getPythonType() == pytype)
96ebead697SStefano Zampini
975808f684SSatish Balay    def testSolve(self):
985808f684SSatish Balay        ts = self.ts
995808f684SSatish Balay        ts.setProblemType(ts.ProblemType.NONLINEAR)
1005808f684SSatish Balay        ode = MyODE()
1015808f684SSatish Balay        J = PETSc.Mat().create(ts.comm)
102*6f336411SStefano Zampini        J.setSizes(3)
1035808f684SSatish Balay        J.setFromOptions()
1045808f684SSatish Balay        J.setUp()
1055808f684SSatish Balay        u, f = J.createVecs()
1065808f684SSatish Balay
1075808f684SSatish Balay        ts.setAppCtx(ode)
1085808f684SSatish Balay        ts.setIFunction(ode.function, f)
1095808f684SSatish Balay        ts.setIJacobian(ode.jacobian, J, J)
1105808f684SSatish Balay        ts.snes.ksp.pc.setType('none')
1115808f684SSatish Balay
1125808f684SSatish Balay        T0, dT, nT = 0.0, 0.1, 10
1135808f684SSatish Balay        T = T0 + nT * dT
1145808f684SSatish Balay        ts.setTime(T0)
1155808f684SSatish Balay        ts.setTimeStep(dT)
1165808f684SSatish Balay        ts.setMaxTime(T)
1175808f684SSatish Balay        ts.setMaxSteps(nT)
1185808f684SSatish Balay        ts.setFromOptions()
1195808f684SSatish Balay        u[0], u[1], u[2] = 1, 2, 3
1205808f684SSatish Balay        ts.solve(u)
1215808f684SSatish Balay        self.nsolve += 1
1225808f684SSatish Balay
1235808f684SSatish Balay        self.assertTrue(ode.function_calls > 0)
1245808f684SSatish Balay        self.assertTrue(ode.jacobian_calls > 0)
1255808f684SSatish Balay
1265808f684SSatish Balay        ctx = self.ts.getPythonContext()
1275808f684SSatish Balay        ncalls = self.nsolve * ts.step_number
1285808f684SSatish Balay        self.assertTrue(ctx.log['solveStep'] == ncalls)
1295808f684SSatish Balay        self.assertTrue(ctx.log['adaptStep'] == ncalls)
1305808f684SSatish Balay        del ctx
1315808f684SSatish Balay
1325808f684SSatish Balay        dct = self.ts.getDict()
1335808f684SSatish Balay        self.assertTrue('__appctx__' in dct)
1345808f684SSatish Balay        self.assertTrue('__ifunction__' in dct)
1355808f684SSatish Balay        self.assertTrue('__ijacobian__' in dct)
1365808f684SSatish Balay
1375808f684SSatish Balay    def testFDColor(self):
1385808f684SSatish Balay        #
1395808f684SSatish Balay        ts = self.ts
1405808f684SSatish Balay        ts.setProblemType(ts.ProblemType.NONLINEAR)
1415808f684SSatish Balay        ode = MyODE()
1425808f684SSatish Balay        J = PETSc.Mat().create(ts.comm)
143*6f336411SStefano Zampini        J.setSizes(5)
144*6f336411SStefano Zampini        J.setType('aij')
1455808f684SSatish Balay        J.setPreallocationNNZ(1)
1465808f684SSatish Balay        J.setFromOptions()
1475808f684SSatish Balay        u, f = J.createVecs()
1485808f684SSatish Balay
1495808f684SSatish Balay        ts.setAppCtx(ode)
1505808f684SSatish Balay        ts.setIFunction(ode.function, f)
1515808f684SSatish Balay        ts.setIJacobian(ode.jacobian, J, J)
1525808f684SSatish Balay
1535808f684SSatish Balay        T0, dT, nT = 0.00, 0.1, 10
1545808f684SSatish Balay        T = T0 + nT * dT
1555808f684SSatish Balay        ts.setTime(T0)
1565808f684SSatish Balay        ts.setTimeStep(dT)
1575808f684SSatish Balay        ts.setMaxTime(T)
1585808f684SSatish Balay        ts.setMaxSteps(nT)
1595808f684SSatish Balay        ts.setFromOptions()
1605808f684SSatish Balay        u[:] = 1, 2, 3, 4, 5
1615808f684SSatish Balay
1625808f684SSatish Balay        ts.setSolution(u)
1635808f684SSatish Balay        ode.jacobian(ts, 0.0, u, u, 1.0, J, J)
1645808f684SSatish Balay        ts.snes.setUseFD(True)
1655808f684SSatish Balay        ts.solve(u)
1665808f684SSatish Balay        self.nsolve += 1
1675808f684SSatish Balay
1685808f684SSatish Balay    def testResetAndSolve(self):
1695808f684SSatish Balay        self.ts.reset()
1705808f684SSatish Balay        self.ts.setStepNumber(0)
1715808f684SSatish Balay        self.testSolve()
1725808f684SSatish Balay        self.ts.reset()
1735808f684SSatish Balay        self.ts.setStepNumber(0)
1745808f684SSatish Balay        self.testFDColor()
1755808f684SSatish Balay        self.ts.reset()
1765808f684SSatish Balay        self.ts.setStepNumber(0)
1775808f684SSatish Balay        self.testSolve()
1785808f684SSatish Balay        self.ts.reset()
1795808f684SSatish Balay
1804af29056SMoritz Huck    def testSetAdaptLimits(self):
1814af29056SMoritz Huck        self.ts.setStepLimits(1.0, 2.0)
1824af29056SMoritz Huck        hmin, hmax = self.ts.getStepLimits()
1834af29056SMoritz Huck        self.assertEqual(1.0, hmin)
1844af29056SMoritz Huck        self.assertEqual(2.0, hmax)
1854af29056SMoritz Huck
186*6f336411SStefano Zampini
1875808f684SSatish Balay# --------------------------------------------------------------------
1885808f684SSatish Balay
1895808f684SSatish Balayif __name__ == '__main__':
1905808f684SSatish Balay    unittest.main()
1915808f684SSatish Balay
1925808f684SSatish Balay# --------------------------------------------------------------------
193