xref: /petsc/src/binding/petsc4py/test/test_ksp_py.py (revision 5808f68492579297331054bd8ff190489c3b8c20)
1*5808f684SSatish Balay# --------------------------------------------------------------------
2*5808f684SSatish Balay
3*5808f684SSatish Balayfrom petsc4py import PETSc
4*5808f684SSatish Balayimport unittest
5*5808f684SSatish Balayfrom sys import getrefcount
6*5808f684SSatish Balay
7*5808f684SSatish Balay# --------------------------------------------------------------------
8*5808f684SSatish Balay
9*5808f684SSatish Balayclass MyKSP(object):
10*5808f684SSatish Balay
11*5808f684SSatish Balay    def __init__(self):
12*5808f684SSatish Balay        pass
13*5808f684SSatish Balay
14*5808f684SSatish Balay    def create(self, ksp):
15*5808f684SSatish Balay        self.work = []
16*5808f684SSatish Balay
17*5808f684SSatish Balay    def destroy(self, ksp):
18*5808f684SSatish Balay        for v in self.work:
19*5808f684SSatish Balay            v.destroy()
20*5808f684SSatish Balay
21*5808f684SSatish Balay    def setUp(self, ksp):
22*5808f684SSatish Balay        self.work[:] = ksp.getWorkVecs(right=2, left=None)
23*5808f684SSatish Balay
24*5808f684SSatish Balay    def reset(self, ksp):
25*5808f684SSatish Balay        for v in self.work:
26*5808f684SSatish Balay            v.destroy()
27*5808f684SSatish Balay        del self.work[:]
28*5808f684SSatish Balay
29*5808f684SSatish Balay    def loop(self, ksp, r):
30*5808f684SSatish Balay        its = ksp.getIterationNumber()
31*5808f684SSatish Balay        rnorm = r.norm()
32*5808f684SSatish Balay        ksp.setResidualNorm(rnorm)
33*5808f684SSatish Balay        ksp.logConvergenceHistory(rnorm)
34*5808f684SSatish Balay        ksp.monitor(its, rnorm)
35*5808f684SSatish Balay        reason = ksp.callConvergenceTest(its, rnorm)
36*5808f684SSatish Balay        if not reason:
37*5808f684SSatish Balay            ksp.setIterationNumber(its+1)
38*5808f684SSatish Balay        else:
39*5808f684SSatish Balay            ksp.setConvergedReason(reason)
40*5808f684SSatish Balay        return reason
41*5808f684SSatish Balay
42*5808f684SSatish Balayclass MyRichardson(MyKSP):
43*5808f684SSatish Balay
44*5808f684SSatish Balay    def solve(self, ksp, b, x):
45*5808f684SSatish Balay        A, B = ksp.getOperators()
46*5808f684SSatish Balay        P = ksp.getPC()
47*5808f684SSatish Balay        r, z = self.work
48*5808f684SSatish Balay        #
49*5808f684SSatish Balay        A.mult(x, r)
50*5808f684SSatish Balay        r.aypx(-1, b)
51*5808f684SSatish Balay        P.apply(r, z)
52*5808f684SSatish Balay        x.axpy(1, z)
53*5808f684SSatish Balay        while not self.loop(ksp, z):
54*5808f684SSatish Balay            A.mult(x, r)
55*5808f684SSatish Balay            r.aypx(-1, b)
56*5808f684SSatish Balay            P.apply(r, z)
57*5808f684SSatish Balay            x.axpy(1, z)
58*5808f684SSatish Balay
59*5808f684SSatish Balayclass MyCG(MyKSP):
60*5808f684SSatish Balay
61*5808f684SSatish Balay    def setUp(self, ksp):
62*5808f684SSatish Balay        super(MyCG, self).setUp(ksp)
63*5808f684SSatish Balay        d = self.work[0].duplicate()
64*5808f684SSatish Balay        q = d.duplicate()
65*5808f684SSatish Balay        self.work += [d, q]
66*5808f684SSatish Balay
67*5808f684SSatish Balay    def solve(self, ksp, b, x):
68*5808f684SSatish Balay        A, B = ksp.getOperators()
69*5808f684SSatish Balay        P = ksp.getPC()
70*5808f684SSatish Balay        r, z, d, q = self.work
71*5808f684SSatish Balay        #
72*5808f684SSatish Balay        A.mult(x, r)
73*5808f684SSatish Balay        r.aypx(-1, b)
74*5808f684SSatish Balay        r.copy(d)
75*5808f684SSatish Balay        delta_0 = r.dot(r)
76*5808f684SSatish Balay        delta = delta_0
77*5808f684SSatish Balay        while not self.loop(ksp, r):
78*5808f684SSatish Balay            A.mult(d, q)
79*5808f684SSatish Balay            alpha = delta / d.dot(q)
80*5808f684SSatish Balay            x.axpy(+alpha, d)
81*5808f684SSatish Balay            r.axpy(-alpha, q)
82*5808f684SSatish Balay            delta_old = delta
83*5808f684SSatish Balay            delta = r.dot(r)
84*5808f684SSatish Balay            beta = delta / delta_old
85*5808f684SSatish Balay            d.aypx(beta, r)
86*5808f684SSatish Balay
87*5808f684SSatish Balay# --------------------------------------------------------------------
88*5808f684SSatish Balay
89*5808f684SSatish Balayfrom test_ksp import BaseTestKSP
90*5808f684SSatish Balay
91*5808f684SSatish Balayclass BaseTestKSPPYTHON(BaseTestKSP):
92*5808f684SSatish Balay
93*5808f684SSatish Balay    KSP_TYPE = PETSc.KSP.Type.PYTHON
94*5808f684SSatish Balay    ContextClass = None
95*5808f684SSatish Balay
96*5808f684SSatish Balay    def setUp(self):
97*5808f684SSatish Balay        super(BaseTestKSPPYTHON, self).setUp()
98*5808f684SSatish Balay        ctx = self.ContextClass()
99*5808f684SSatish Balay        self.ksp.setPythonContext(ctx)
100*5808f684SSatish Balay
101*5808f684SSatish Balayclass TestKSPPYTHON_RICH(BaseTestKSPPYTHON, unittest.TestCase):
102*5808f684SSatish Balay    PC_TYPE  = PETSc.PC.Type.JACOBI
103*5808f684SSatish Balay    ContextClass = MyRichardson
104*5808f684SSatish Balay
105*5808f684SSatish Balayclass TestKSPPYTHON_CG(BaseTestKSPPYTHON, unittest.TestCase):
106*5808f684SSatish Balay    PC_TYPE  = PETSc.PC.Type.NONE
107*5808f684SSatish Balay    ContextClass = MyCG
108*5808f684SSatish Balay
109*5808f684SSatish Balay# --------------------------------------------------------------------
110*5808f684SSatish Balay
111*5808f684SSatish Balayif __name__ == '__main__':
112*5808f684SSatish Balay    unittest.main()
113