xref: /petsc/src/binding/petsc4py/test/test_ts_py.py (revision 5808f68492579297331054bd8ff190489c3b8c20)
1*5808f684SSatish Balayimport unittest
2*5808f684SSatish Balayfrom petsc4py import PETSc
3*5808f684SSatish Balayfrom sys import getrefcount
4*5808f684SSatish Balayimport gc
5*5808f684SSatish Balay
6*5808f684SSatish Balay# --------------------------------------------------------------------
7*5808f684SSatish Balay
8*5808f684SSatish Balayclass MyODE:
9*5808f684SSatish Balay    """
10*5808f684SSatish Balay    du/dt + u**2 = 0;
11*5808f684SSatish Balay    u0 = 1
12*5808f684SSatish Balay    """
13*5808f684SSatish Balay
14*5808f684SSatish Balay    def __init__(self):
15*5808f684SSatish Balay        self.function_calls = 0
16*5808f684SSatish Balay        self.jacobian_calls = 0
17*5808f684SSatish Balay
18*5808f684SSatish Balay    def function(self,ts,t,u,du,F):
19*5808f684SSatish Balay        #print 'MyODE.function()'
20*5808f684SSatish Balay        self.function_calls += 1
21*5808f684SSatish Balay        f = du + u * u
22*5808f684SSatish Balay        f.copy(F)
23*5808f684SSatish Balay
24*5808f684SSatish Balay    def jacobian(self,ts,t,u,du,a,J,P):
25*5808f684SSatish Balay        #print 'MyODE.jacobian()'
26*5808f684SSatish Balay        self.jacobian_calls += 1
27*5808f684SSatish Balay        P.zeroEntries()
28*5808f684SSatish Balay        diag = a + 2 * u
29*5808f684SSatish Balay        P.setDiagonal(diag)
30*5808f684SSatish Balay        P.assemble()
31*5808f684SSatish Balay        if J != P: J.assemble()
32*5808f684SSatish Balay        return False # same_nz
33*5808f684SSatish Balay
34*5808f684SSatish Balayclass MyTS:
35*5808f684SSatish Balay    def __init__(self):
36*5808f684SSatish Balay        self.log = {}
37*5808f684SSatish Balay    def _log(self, method, *args):
38*5808f684SSatish Balay        self.log.setdefault(method, 0)
39*5808f684SSatish Balay        self.log[method] += 1
40*5808f684SSatish Balay
41*5808f684SSatish Balay    def create(self, ts, *args):
42*5808f684SSatish Balay        self._log('create', *args)
43*5808f684SSatish Balay        self.vec_update = PETSc.Vec()
44*5808f684SSatish Balay
45*5808f684SSatish Balay    def destroy(self, ts, *args):
46*5808f684SSatish Balay        self._log('destroy', *args)
47*5808f684SSatish Balay        self.vec_update.destroy()
48*5808f684SSatish Balay
49*5808f684SSatish Balay    def setFromOptions(self, ts, *args):
50*5808f684SSatish Balay        self._log('setFromOptions', *args)
51*5808f684SSatish Balay
52*5808f684SSatish Balay    def setUp(self, ts, *args):
53*5808f684SSatish Balay        self._log('setUp', ts, *args)
54*5808f684SSatish Balay        self.vec_update = ts.getSolution().duplicate()
55*5808f684SSatish Balay
56*5808f684SSatish Balay    def reset(self, ts, *args):
57*5808f684SSatish Balay        self._log('reset', ts, *args)
58*5808f684SSatish Balay
59*5808f684SSatish Balay    def solveStep(self, ts, t, u, *args):
60*5808f684SSatish Balay        self._log('solveStep', ts, t, u, *args)
61*5808f684SSatish Balay        ts.snes.solve(None, u)
62*5808f684SSatish Balay
63*5808f684SSatish Balay    def adaptStep(self, ts, t, u, *args):
64*5808f684SSatish Balay        self._log('adaptStep', ts, t, u, *args)
65*5808f684SSatish Balay        return (ts.getTimeStep(), True)
66*5808f684SSatish Balay
67*5808f684SSatish Balay
68*5808f684SSatish Balayclass TestTSPython(unittest.TestCase):
69*5808f684SSatish Balay
70*5808f684SSatish Balay    def setUp(self):
71*5808f684SSatish Balay        self.ts = PETSc.TS()
72*5808f684SSatish Balay        self.ts.createPython(MyTS(), comm=PETSc.COMM_SELF)
73*5808f684SSatish Balay        eft = PETSc.TS.ExactFinalTime.STEPOVER
74*5808f684SSatish Balay        self.ts.setExactFinalTime(eft)
75*5808f684SSatish Balay        ctx = self.ts.getPythonContext()
76*5808f684SSatish Balay        self.assertEqual(getrefcount(ctx),  3)
77*5808f684SSatish Balay        self.assertEqual(ctx.log['create'], 1)
78*5808f684SSatish Balay        self.nsolve = 0
79*5808f684SSatish Balay
80*5808f684SSatish Balay    def tearDown(self):
81*5808f684SSatish Balay        ctx = self.ts.getPythonContext()
82*5808f684SSatish Balay        self.assertEqual(getrefcount(ctx), 3)
83*5808f684SSatish Balay        self.assertTrue('destroy' not in ctx.log)
84*5808f684SSatish Balay        self.ts.destroy() # XXX
85*5808f684SSatish Balay        self.ts = None
86*5808f684SSatish Balay        self.assertEqual(ctx.log['destroy'], 1)
87*5808f684SSatish Balay        self.assertEqual(getrefcount(ctx),   2)
88*5808f684SSatish Balay
89*5808f684SSatish Balay    def testSolve(self):
90*5808f684SSatish Balay        ts = self.ts
91*5808f684SSatish Balay        ts.setProblemType(ts.ProblemType.NONLINEAR)
92*5808f684SSatish Balay        ode = MyODE()
93*5808f684SSatish Balay        J = PETSc.Mat().create(ts.comm)
94*5808f684SSatish Balay        J.setSizes(3);
95*5808f684SSatish Balay        J.setFromOptions()
96*5808f684SSatish Balay        J.setUp()
97*5808f684SSatish Balay        u, f = J.createVecs()
98*5808f684SSatish Balay
99*5808f684SSatish Balay        ts.setAppCtx(ode)
100*5808f684SSatish Balay        ts.setIFunction(ode.function, f)
101*5808f684SSatish Balay        ts.setIJacobian(ode.jacobian, J, J)
102*5808f684SSatish Balay        ts.snes.ksp.pc.setType('none')
103*5808f684SSatish Balay
104*5808f684SSatish Balay        T0, dT, nT = 0.0, 0.1, 10
105*5808f684SSatish Balay        T = T0 + nT*dT
106*5808f684SSatish Balay        ts.setTime(T0)
107*5808f684SSatish Balay        ts.setTimeStep(dT)
108*5808f684SSatish Balay        ts.setMaxTime(T)
109*5808f684SSatish Balay        ts.setMaxSteps(nT)
110*5808f684SSatish Balay        ts.setFromOptions()
111*5808f684SSatish Balay        u[0], u[1], u[2] = 1, 2, 3
112*5808f684SSatish Balay        ts.solve(u)
113*5808f684SSatish Balay        self.nsolve +=1
114*5808f684SSatish Balay
115*5808f684SSatish Balay        self.assertTrue(ode.function_calls > 0)
116*5808f684SSatish Balay        self.assertTrue(ode.jacobian_calls > 0)
117*5808f684SSatish Balay
118*5808f684SSatish Balay        ctx = self.ts.getPythonContext()
119*5808f684SSatish Balay        ncalls = self.nsolve * ts.step_number
120*5808f684SSatish Balay        self.assertTrue(ctx.log['solveStep'] == ncalls)
121*5808f684SSatish Balay        self.assertTrue(ctx.log['adaptStep'] == ncalls)
122*5808f684SSatish Balay        del ctx
123*5808f684SSatish Balay
124*5808f684SSatish Balay        dct = self.ts.getDict()
125*5808f684SSatish Balay        self.assertTrue('__appctx__'    in dct)
126*5808f684SSatish Balay        self.assertTrue('__ifunction__' in dct)
127*5808f684SSatish Balay        self.assertTrue('__ijacobian__' in dct)
128*5808f684SSatish Balay
129*5808f684SSatish Balay    def testFDColor(self):
130*5808f684SSatish Balay        #
131*5808f684SSatish Balay        ts = self.ts
132*5808f684SSatish Balay        ts.setProblemType(ts.ProblemType.NONLINEAR)
133*5808f684SSatish Balay        ode = MyODE()
134*5808f684SSatish Balay        J = PETSc.Mat().create(ts.comm)
135*5808f684SSatish Balay        J.setSizes(5); J.setType('aij');
136*5808f684SSatish Balay        J.setPreallocationNNZ(1)
137*5808f684SSatish Balay        J.setFromOptions()
138*5808f684SSatish Balay        u, f = J.createVecs()
139*5808f684SSatish Balay
140*5808f684SSatish Balay        ts.setAppCtx(ode)
141*5808f684SSatish Balay        ts.setIFunction(ode.function, f)
142*5808f684SSatish Balay        ts.setIJacobian(ode.jacobian, J, J)
143*5808f684SSatish Balay
144*5808f684SSatish Balay        T0, dT, nT = 0.00, 0.1, 10
145*5808f684SSatish Balay        T = T0 + nT*dT
146*5808f684SSatish Balay        ts.setTime(T0)
147*5808f684SSatish Balay        ts.setTimeStep(dT)
148*5808f684SSatish Balay        ts.setMaxTime(T)
149*5808f684SSatish Balay        ts.setMaxSteps(nT)
150*5808f684SSatish Balay        ts.setFromOptions()
151*5808f684SSatish Balay        u[:] = 1, 2, 3, 4, 5
152*5808f684SSatish Balay
153*5808f684SSatish Balay        ts.setSolution(u)
154*5808f684SSatish Balay        ode.jacobian(ts,0.0,u,u,1.0,J,J)
155*5808f684SSatish Balay        ts.snes.setUseFD(True)
156*5808f684SSatish Balay        ts.solve(u)
157*5808f684SSatish Balay        self.nsolve +=1
158*5808f684SSatish Balay
159*5808f684SSatish Balay    def testResetAndSolve(self):
160*5808f684SSatish Balay        self.ts.reset()
161*5808f684SSatish Balay        self.ts.setStepNumber(0)
162*5808f684SSatish Balay        self.testSolve()
163*5808f684SSatish Balay        self.ts.reset()
164*5808f684SSatish Balay        self.ts.setStepNumber(0)
165*5808f684SSatish Balay        self.testFDColor()
166*5808f684SSatish Balay        self.ts.reset()
167*5808f684SSatish Balay        self.ts.setStepNumber(0)
168*5808f684SSatish Balay        self.testSolve()
169*5808f684SSatish Balay        self.ts.reset()
170*5808f684SSatish Balay
171*5808f684SSatish Balay# --------------------------------------------------------------------
172*5808f684SSatish Balay
173*5808f684SSatish Balayif __name__ == '__main__':
174*5808f684SSatish Balay    unittest.main()
175*5808f684SSatish Balay
176*5808f684SSatish Balay# --------------------------------------------------------------------
177