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