1*5808f684SSatish Balay# ------------------------------------------------------------------------ 2*5808f684SSatish Balay# 3*5808f684SSatish Balay# Poisson problem. This problem is modeled by the partial 4*5808f684SSatish Balay# differential equation 5*5808f684SSatish Balay# 6*5808f684SSatish Balay# -Laplacian(u) = 1, 0 < x,y < 1, 7*5808f684SSatish Balay# 8*5808f684SSatish Balay# with boundary conditions 9*5808f684SSatish Balay# 10*5808f684SSatish Balay# u = 0 for x = 0, x = 1, y = 0, y = 1 11*5808f684SSatish Balay# 12*5808f684SSatish Balay# A finite difference approximation with the usual 7-point stencil 13*5808f684SSatish Balay# is used to discretize the boundary value problem to obtain a 14*5808f684SSatish Balay# nonlinear system of equations. The problem is solved in a 2D 15*5808f684SSatish Balay# rectangular domain, using distributed arrays (DAs) to partition 16*5808f684SSatish Balay# the parallel grid. 17*5808f684SSatish Balay# 18*5808f684SSatish Balay# ------------------------------------------------------------------------ 19*5808f684SSatish Balay 20*5808f684SSatish Balaytry: range = xrange 21*5808f684SSatish Balayexcept: pass 22*5808f684SSatish Balay 23*5808f684SSatish Balayimport sys, petsc4py 24*5808f684SSatish Balaypetsc4py.init(sys.argv) 25*5808f684SSatish Balay 26*5808f684SSatish Balayfrom petsc4py import PETSc 27*5808f684SSatish Balay 28*5808f684SSatish Balayclass Poisson2D(object): 29*5808f684SSatish Balay 30*5808f684SSatish Balay def __init__(self, da): 31*5808f684SSatish Balay assert da.getDim() == 2 32*5808f684SSatish Balay self.da = da 33*5808f684SSatish Balay self.localX = da.createLocalVec() 34*5808f684SSatish Balay 35*5808f684SSatish Balay def formRHS(self, B): 36*5808f684SSatish Balay b = self.da.getVecArray(B) 37*5808f684SSatish Balay mx, my = self.da.getSizes() 38*5808f684SSatish Balay hx, hy = [1.0/m for m in [mx, my]] 39*5808f684SSatish Balay (xs, xe), (ys, ye) = self.da.getRanges() 40*5808f684SSatish Balay for j in range(ys, ye): 41*5808f684SSatish Balay for i in range(xs, xe): 42*5808f684SSatish Balay b[i, j] = 1*hx*hy 43*5808f684SSatish Balay 44*5808f684SSatish Balay def mult(self, mat, X, Y): 45*5808f684SSatish Balay # 46*5808f684SSatish Balay self.da.globalToLocal(X, self.localX) 47*5808f684SSatish Balay x = self.da.getVecArray(self.localX) 48*5808f684SSatish Balay y = self.da.getVecArray(Y) 49*5808f684SSatish Balay # 50*5808f684SSatish Balay mx, my = self.da.getSizes() 51*5808f684SSatish Balay hx, hy = [1.0/m for m in [mx, my]] 52*5808f684SSatish Balay (xs, xe), (ys, ye) = self.da.getRanges() 53*5808f684SSatish Balay for j in range(ys, ye): 54*5808f684SSatish Balay for i in range(xs, xe): 55*5808f684SSatish Balay u = x[i, j] # center 56*5808f684SSatish Balay u_e = u_w = u_n = u_s = 0 57*5808f684SSatish Balay if i > 0: u_w = x[i-1, j] # west 58*5808f684SSatish Balay if i < mx-1: u_e = x[i+1, j] # east 59*5808f684SSatish Balay if j > 0: u_s = x[i, j-1] # south 60*5808f684SSatish Balay if j < ny-1: u_n = x[i, j+1] # north 61*5808f684SSatish Balay u_xx = (-u_e + 2*u - u_w)*hy/hx 62*5808f684SSatish Balay u_yy = (-u_n + 2*u - u_s)*hx/hy 63*5808f684SSatish Balay y[i, j] = u_xx + u_yy 64*5808f684SSatish Balay 65*5808f684SSatish BalayOptDB = PETSc.Options() 66*5808f684SSatish Balay 67*5808f684SSatish Balayn = OptDB.getInt('n', 16) 68*5808f684SSatish Balaynx = OptDB.getInt('nx', n) 69*5808f684SSatish Balayny = OptDB.getInt('ny', n) 70*5808f684SSatish Balay 71*5808f684SSatish Balayda = PETSc.DMDA().create([nx, ny], stencil_width=1) 72*5808f684SSatish Balaypde = Poisson2D(da) 73*5808f684SSatish Balay 74*5808f684SSatish Balayx = da.createGlobalVec() 75*5808f684SSatish Balayb = da.createGlobalVec() 76*5808f684SSatish Balay# A = da.createMat('python') 77*5808f684SSatish BalayA = PETSc.Mat().createPython( 78*5808f684SSatish Balay [x.getSizes(), b.getSizes()], comm=da.comm) 79*5808f684SSatish BalayA.setPythonContext(pde) 80*5808f684SSatish BalayA.setUp() 81*5808f684SSatish Balay 82*5808f684SSatish Balayksp = PETSc.KSP().create() 83*5808f684SSatish Balayksp.setOperators(A) 84*5808f684SSatish Balayksp.setType('cg') 85*5808f684SSatish Balaypc = ksp.getPC() 86*5808f684SSatish Balaypc.setType('none') 87*5808f684SSatish Balayksp.setFromOptions() 88*5808f684SSatish Balay 89*5808f684SSatish Balaypde.formRHS(b) 90*5808f684SSatish Balayksp.solve(b, x) 91*5808f684SSatish Balay 92*5808f684SSatish Balayu = da.createNaturalVec() 93*5808f684SSatish Balayda.globalToNatural(x, u) 94*5808f684SSatish Balay 95*5808f684SSatish Balayif OptDB.getBool('plot', True): 96*5808f684SSatish Balay draw = PETSc.Viewer.DRAW(x.comm) 97*5808f684SSatish Balay OptDB['draw_pause'] = 1 98*5808f684SSatish Balay draw(x) 99