155a74a43SLisandro Dalcin# ------------------------------------------------------------------------ 255a74a43SLisandro Dalcin# 355a74a43SLisandro Dalcin# Poisson problem. This problem is modeled by the partial 455a74a43SLisandro Dalcin# differential equation 555a74a43SLisandro Dalcin# 655a74a43SLisandro Dalcin# -Laplacian(u) = 1, 0 < x,y < 1, 755a74a43SLisandro Dalcin# 855a74a43SLisandro Dalcin# with boundary conditions 955a74a43SLisandro Dalcin# 1055a74a43SLisandro Dalcin# u = 0 for x = 0, x = 1, y = 0, y = 1 1155a74a43SLisandro Dalcin# 129690009eSJose E. Roman# A finite difference approximation with the usual 5-point stencil 1355a74a43SLisandro Dalcin# is used to discretize the boundary value problem to obtain a 1455a74a43SLisandro Dalcin# nonlinear system of equations. The problem is solved in a 2D 1555a74a43SLisandro Dalcin# rectangular domain, using distributed arrays (DAs) to partition 1655a74a43SLisandro Dalcin# the parallel grid. 1755a74a43SLisandro Dalcin# 1855a74a43SLisandro Dalcin# ------------------------------------------------------------------------ 1955a74a43SLisandro Dalcin 2055a74a43SLisandro Dalcintry: range = xrange 2155a74a43SLisandro Dalcinexcept: pass 2255a74a43SLisandro Dalcin 2355a74a43SLisandro Dalcinimport sys, petsc4py 2455a74a43SLisandro Dalcinpetsc4py.init(sys.argv) 2555a74a43SLisandro Dalcin 2655a74a43SLisandro Dalcinfrom petsc4py import PETSc 2755a74a43SLisandro Dalcin 2855a74a43SLisandro Dalcinclass Poisson2D(object): 2955a74a43SLisandro Dalcin 3055a74a43SLisandro Dalcin def __init__(self, da): 3155a74a43SLisandro Dalcin assert da.getDim() == 2 3255a74a43SLisandro Dalcin self.da = da 3355a74a43SLisandro Dalcin self.localX = da.createLocalVec() 3455a74a43SLisandro Dalcin 3555a74a43SLisandro Dalcin def formRHS(self, B): 3655a74a43SLisandro Dalcin b = self.da.getVecArray(B) 3755a74a43SLisandro Dalcin mx, my = self.da.getSizes() 3855a74a43SLisandro Dalcin hx, hy = [1.0/m for m in [mx, my]] 3955a74a43SLisandro Dalcin (xs, xe), (ys, ye) = self.da.getRanges() 4055a74a43SLisandro Dalcin for j in range(ys, ye): 4155a74a43SLisandro Dalcin for i in range(xs, xe): 4255a74a43SLisandro Dalcin b[i, j] = 1*hx*hy 4355a74a43SLisandro Dalcin 4455a74a43SLisandro Dalcin def mult(self, mat, X, Y): 4555a74a43SLisandro Dalcin # 4655a74a43SLisandro Dalcin self.da.globalToLocal(X, self.localX) 4755a74a43SLisandro Dalcin x = self.da.getVecArray(self.localX) 4855a74a43SLisandro Dalcin y = self.da.getVecArray(Y) 4955a74a43SLisandro Dalcin # 5055a74a43SLisandro Dalcin mx, my = self.da.getSizes() 5155a74a43SLisandro Dalcin hx, hy = [1.0/m for m in [mx, my]] 5255a74a43SLisandro Dalcin (xs, xe), (ys, ye) = self.da.getRanges() 5355a74a43SLisandro Dalcin for j in range(ys, ye): 5455a74a43SLisandro Dalcin for i in range(xs, xe): 5555a74a43SLisandro Dalcin u = x[i, j] # center 5655a74a43SLisandro Dalcin u_e = u_w = u_n = u_s = 0 5755a74a43SLisandro Dalcin if i > 0: u_w = x[i-1, j] # west 5855a74a43SLisandro Dalcin if i < mx-1: u_e = x[i+1, j] # east 5955a74a43SLisandro Dalcin if j > 0: u_s = x[i, j-1] # south 6055a74a43SLisandro Dalcin if j < ny-1: u_n = x[i, j+1] # north 6155a74a43SLisandro Dalcin u_xx = (-u_e + 2*u - u_w)*hy/hx 6255a74a43SLisandro Dalcin u_yy = (-u_n + 2*u - u_s)*hx/hy 6355a74a43SLisandro Dalcin y[i, j] = u_xx + u_yy 6455a74a43SLisandro Dalcin 6555a74a43SLisandro DalcinOptDB = PETSc.Options() 6655a74a43SLisandro Dalcin 6755a74a43SLisandro Dalcinn = OptDB.getInt('n', 16) 6855a74a43SLisandro Dalcinnx = OptDB.getInt('nx', n) 6955a74a43SLisandro Dalcinny = OptDB.getInt('ny', n) 7055a74a43SLisandro Dalcin 71*8e704042SBarry Smithda = PETSc.DMDA().create([nx, ny], stencil_width=1, setup=False) 72*8e704042SBarry Smithda.setFromOptions() 73*8e704042SBarry Smithda.setUp() 7455a74a43SLisandro Dalcinpde = Poisson2D(da) 7555a74a43SLisandro Dalcin 7655a74a43SLisandro Dalcinx = da.createGlobalVec() 7755a74a43SLisandro Dalcinb = da.createGlobalVec() 7855a74a43SLisandro Dalcin# A = da.createMat('python') 7955a74a43SLisandro DalcinA = PETSc.Mat().createPython( 8055a74a43SLisandro Dalcin [x.getSizes(), b.getSizes()], comm=da.comm) 8155a74a43SLisandro DalcinA.setPythonContext(pde) 8255a74a43SLisandro DalcinA.setUp() 8355a74a43SLisandro Dalcin 8455a74a43SLisandro Dalcinksp = PETSc.KSP().create() 8555a74a43SLisandro Dalcinksp.setOperators(A) 8655a74a43SLisandro Dalcinksp.setType('cg') 8755a74a43SLisandro Dalcinpc = ksp.getPC() 8855a74a43SLisandro Dalcinpc.setType('none') 8955a74a43SLisandro Dalcinksp.setFromOptions() 9055a74a43SLisandro Dalcin 9155a74a43SLisandro Dalcinpde.formRHS(b) 9255a74a43SLisandro Dalcinksp.solve(b, x) 9355a74a43SLisandro Dalcin 9455a74a43SLisandro Dalcinu = da.createNaturalVec() 9555a74a43SLisandro Dalcinda.globalToNatural(x, u) 9655a74a43SLisandro Dalcin 9755a74a43SLisandro Dalcinif OptDB.getBool('plot', True): 9855a74a43SLisandro Dalcin draw = PETSc.Viewer.DRAW(x.comm) 9955a74a43SLisandro Dalcin OptDB['draw_pause'] = 1 10055a74a43SLisandro Dalcin draw(x) 101