xref: /petsc/src/binding/petsc4py/test/test_ts_py.py (revision b69d2765e9c8cde17308f61ee677dcd992b8a9cf)
15808f684SSatish Balayimport unittest
25808f684SSatish Balayfrom petsc4py import PETSc
35808f684SSatish Balayfrom sys import getrefcount
45808f684SSatish Balay
55808f684SSatish Balay# --------------------------------------------------------------------
65808f684SSatish Balay
76f336411SStefano 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()
316f336411SStefano Zampini        if J != P:
326f336411SStefano Zampini            J.assemble()
335808f684SSatish Balay        return False  # same_nz
345808f684SSatish Balay
35ebead697SStefano Zampini
366f336411SStefano 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)
77*39933f97SStefano Zampini        self.assertEqual(getrefcount(self._getCtx()), 2)
78*39933f97SStefano Zampini        self.assertEqual(self._getCtx().log['create'], 1)
795808f684SSatish Balay        self.nsolve = 0
805808f684SSatish Balay
815808f684SSatish Balay    def tearDown(self):
82*39933f97SStefano Zampini        self.assertEqual(getrefcount(self._getCtx()), 2)
83*39933f97SStefano Zampini        self.assertTrue('destroy' not in self._getCtx().log)
84*39933f97SStefano Zampini        ctx = self._getCtx()
85*39933f97SStefano Zampini        self.ts.destroy()
865808f684SSatish Balay        self.ts = None
8762e5d2d2SJDBetteridge        PETSc.garbage_cleanup()
885808f684SSatish Balay        self.assertEqual(ctx.log['destroy'], 1)
895808f684SSatish Balay
90ebead697SStefano Zampini    def testGetType(self):
91ebead697SStefano Zampini        ctx = self.ts.getPythonContext()
926f336411SStefano Zampini        pytype = f'{ctx.__module__}.{type(ctx).__name__}'
93ebead697SStefano Zampini        self.assertTrue(self.ts.getPythonType() == pytype)
94ebead697SStefano Zampini
955808f684SSatish Balay    def testSolve(self):
965808f684SSatish Balay        ts = self.ts
975808f684SSatish Balay        ts.setProblemType(ts.ProblemType.NONLINEAR)
985808f684SSatish Balay        ode = MyODE()
995808f684SSatish Balay        J = PETSc.Mat().create(ts.comm)
1006f336411SStefano Zampini        J.setSizes(3)
1015808f684SSatish Balay        J.setFromOptions()
1025808f684SSatish Balay        J.setUp()
1035808f684SSatish Balay        u, f = J.createVecs()
1045808f684SSatish Balay
1055808f684SSatish Balay        ts.setAppCtx(ode)
1065808f684SSatish Balay        ts.setIFunction(ode.function, f)
1075808f684SSatish Balay        ts.setIJacobian(ode.jacobian, J, J)
1085808f684SSatish Balay        ts.snes.ksp.pc.setType('none')
1095808f684SSatish Balay
1105808f684SSatish Balay        T0, dT, nT = 0.0, 0.1, 10
1115808f684SSatish Balay        T = T0 + nT * dT
1125808f684SSatish Balay        ts.setTime(T0)
1135808f684SSatish Balay        ts.setTimeStep(dT)
1145808f684SSatish Balay        ts.setMaxTime(T)
1155808f684SSatish Balay        ts.setMaxSteps(nT)
1165808f684SSatish Balay        ts.setFromOptions()
1175808f684SSatish Balay        u[0], u[1], u[2] = 1, 2, 3
1185808f684SSatish Balay        ts.solve(u)
1195808f684SSatish Balay        self.nsolve += 1
1205808f684SSatish Balay
1215808f684SSatish Balay        self.assertTrue(ode.function_calls > 0)
1225808f684SSatish Balay        self.assertTrue(ode.jacobian_calls > 0)
1235808f684SSatish Balay
1245808f684SSatish Balay        ctx = self.ts.getPythonContext()
1255808f684SSatish Balay        ncalls = self.nsolve * ts.step_number
1265808f684SSatish Balay        self.assertTrue(ctx.log['solveStep'] == ncalls)
1275808f684SSatish Balay        self.assertTrue(ctx.log['adaptStep'] == ncalls)
1285808f684SSatish Balay        del ctx
1295808f684SSatish Balay
1305808f684SSatish Balay        dct = self.ts.getDict()
1315808f684SSatish Balay        self.assertTrue('__appctx__' in dct)
1325808f684SSatish Balay        self.assertTrue('__ifunction__' in dct)
1335808f684SSatish Balay        self.assertTrue('__ijacobian__' in dct)
1345808f684SSatish Balay
1355808f684SSatish Balay    def testFDColor(self):
1365808f684SSatish Balay        #
1375808f684SSatish Balay        ts = self.ts
1385808f684SSatish Balay        ts.setProblemType(ts.ProblemType.NONLINEAR)
1395808f684SSatish Balay        ode = MyODE()
1405808f684SSatish Balay        J = PETSc.Mat().create(ts.comm)
1416f336411SStefano Zampini        J.setSizes(5)
1426f336411SStefano Zampini        J.setType('aij')
1435808f684SSatish Balay        J.setPreallocationNNZ(1)
1445808f684SSatish Balay        J.setFromOptions()
1455808f684SSatish Balay        u, f = J.createVecs()
1465808f684SSatish Balay
1475808f684SSatish Balay        ts.setAppCtx(ode)
1485808f684SSatish Balay        ts.setIFunction(ode.function, f)
1495808f684SSatish Balay        ts.setIJacobian(ode.jacobian, J, J)
1505808f684SSatish Balay
1515808f684SSatish Balay        T0, dT, nT = 0.00, 0.1, 10
1525808f684SSatish Balay        T = T0 + nT * dT
1535808f684SSatish Balay        ts.setTime(T0)
1545808f684SSatish Balay        ts.setTimeStep(dT)
1555808f684SSatish Balay        ts.setMaxTime(T)
1565808f684SSatish Balay        ts.setMaxSteps(nT)
1575808f684SSatish Balay        ts.setFromOptions()
1585808f684SSatish Balay        u[:] = 1, 2, 3, 4, 5
1595808f684SSatish Balay
1605808f684SSatish Balay        ts.setSolution(u)
1615808f684SSatish Balay        ode.jacobian(ts, 0.0, u, u, 1.0, J, J)
1625808f684SSatish Balay        ts.snes.setUseFD(True)
1635808f684SSatish Balay        ts.solve(u)
1645808f684SSatish Balay        self.nsolve += 1
1655808f684SSatish Balay
1665808f684SSatish Balay    def testResetAndSolve(self):
1675808f684SSatish Balay        self.ts.reset()
1685808f684SSatish Balay        self.ts.setStepNumber(0)
1695808f684SSatish Balay        self.testSolve()
1705808f684SSatish Balay        self.ts.reset()
1715808f684SSatish Balay        self.ts.setStepNumber(0)
1725808f684SSatish Balay        self.testFDColor()
1735808f684SSatish Balay        self.ts.reset()
1745808f684SSatish Balay        self.ts.setStepNumber(0)
1755808f684SSatish Balay        self.testSolve()
1765808f684SSatish Balay        self.ts.reset()
1775808f684SSatish Balay
1784af29056SMoritz Huck    def testSetAdaptLimits(self):
1794af29056SMoritz Huck        self.ts.setStepLimits(1.0, 2.0)
1804af29056SMoritz Huck        hmin, hmax = self.ts.getStepLimits()
1814af29056SMoritz Huck        self.assertEqual(1.0, hmin)
1824af29056SMoritz Huck        self.assertEqual(2.0, hmax)
1834af29056SMoritz Huck
184*39933f97SStefano Zampini    def _getCtx(self):
185*39933f97SStefano Zampini        return self.ts.getPythonContext()
186*39933f97SStefano Zampini
1876f336411SStefano Zampini
1885808f684SSatish Balay# --------------------------------------------------------------------
1895808f684SSatish Balay
1905808f684SSatish Balayif __name__ == '__main__':
1915808f684SSatish Balay    unittest.main()
1925808f684SSatish Balay
1935808f684SSatish Balay# --------------------------------------------------------------------
194