hpddm.optionParseArgs(opt, args, 2, ctypes.cast(val, ctypes.POINTER(ctypes.c_char_p)), ctypes.cast(desc, ctypes.POINTER(ctypes.c_char_p))) val = None desc = None appArgs() o, connectivity, dof, Mat, MatNeumann, d, f, sol, mu = generate(rankWorld, sizeWorld) status = 0 if sizeWorld > 1: A = hpddm.schwarzCreate(Mat, o, connectivity) hpddm.schwarzMultiplicityScaling(A, d) hpddm.schwarzInitialize(A, d) if mu != 0: hpddm.schwarzScaledExchange(A, f) else: mu = 1 if hpddm.optionSet(opt, b'schwarz_coarse_correction'): nu = ctypes.c_ushort(int(hpddm.optionVal(opt, b'geneo_nu'))) if nu.value > 0: if hpddm.optionApp(opt, b'nonuniform'): nu.value += max(int(-hpddm.optionVal(opt, b'geneo_nu') + 1), (-1)**rankWorld * rankWorld) threshold = hpddm.underlying(max(0, hpddm.optionVal(opt, b'geneo_threshold'))) hpddm.schwarzSolveGEVP(A, MatNeumann, ctypes.byref(nu), threshold) addr = hpddm.optionAddr(opt, b'geneo_nu') addr.contents.value = nu.value else: nu = 1 deflation = numpy.ones((dof, nu), order = 'F', dtype = hpddm.scalar) hpddm.setVectors(hpddm.schwarzPreconditioner(A), nu, deflation) hpddm.initializeCoarseOperator(hpddm.schwarzPreconditioner(A), nu) hpddm.schwarzBuildCoarseOperator(A, hpddm.MPI_Comm.from_address(MPI._addressof(MPI.COMM_WORLD))) hpddm.schwarzCallNumfact(A) if rankWorld != 0:
if sizeWorld > 1: A = hpddm.schwarzCreate(Mat, o, connectivity) hpddm.schwarzMultiplicityScaling(A, d) hpddm.schwarzInitialize(A, d) if mu != 0: hpddm.schwarzScaledExchange(A, f) else: mu = 1 if hpddm.optionSet(opt, b'schwarz_coarse_correction'): addr = hpddm.optionAddr(opt, b'geneo_nu') nu = ctypes.c_ushort(int(addr.contents.value)) if nu.value > 0: if hpddm.optionApp(opt, b'nonuniform'): addr.contents.value += max(int(-addr.contents.value + 1), (-1)**rankWorld * rankWorld) hpddm.schwarzSolveGEVP(A, MatNeumann) nu = int(hpddm.optionVal(opt, b'geneo_nu')) else: nu = 1 deflation = numpy.ones((dof, nu), order = 'F', dtype = hpddm.scalar) hpddm.setVectors(hpddm.schwarzPreconditioner(A), nu, deflation) hpddm.initializeCoarseOperator(hpddm.schwarzPreconditioner(A), nu) hpddm.schwarzBuildCoarseOperator(A, hpddm.MPI_Comm.from_address(MPI._addressof(MPI.COMM_WORLD))) hpddm.schwarzCallNumfact(A) if rankWorld != 0: hpddm.optionRemove(opt, b'verbosity') comm = hpddm.getCommunicator(hpddm.schwarzPreconditioner(A)) it = hpddm.solve(A, f, sol, comm) storage = numpy.empty(2 * mu, order = 'F', dtype = hpddm.underlying) hpddm.schwarzComputeResidual(A, sol, f, storage) if rankWorld == 0: for nu in xrange(mu):
lu = scipy.sparse.linalg.spilu(csr.tocsc(), drop_tol = hpddm.optionApp(opt, b'drop_tol'), fill_factor = hpddm.optionApp(opt, b'fill_factor')) @hpddm.precondFunc def precond(y, x, n, m): if m == 1: x._shape_ = (n,) y._shape_ = (n,) x = numpy.ctypeslib.as_array(x, (n,)) y = numpy.ctypeslib.as_array(y, (n,)) else: x._shape_ = (m, n) y._shape_ = (m, n) x = numpy.ctypeslib.as_array(x, (m, n)).transpose() y = numpy.ctypeslib.as_array(y, (m, n)).transpose() x[:] = lu.solve(y[:]) if hpddm.optionVal(opt, b'krylov_method') == 1: hpddm.BGMRES(Mat, precond, f, sol) else: hpddm.GMRES(Mat, precond, f, sol) status = 0 nrmb = numpy.linalg.norm(f, axis = 0) tmp = numpy.empty_like(f) hpddm.csrmv(Mat, sol, tmp) tmp -= f nrmAx = numpy.linalg.norm(tmp, axis = 0) if mu == 1: nrmb = [ nrmb ] nrmAx = [ nrmAx ] for nu in xrange(mu): if nu == 0:
def generate(rankWorld, sizeWorld): opt = hpddm.optionGet() Nx = int(hpddm.optionApp(opt, b'Nx')) Ny = int(hpddm.optionApp(opt, b'Ny')) overlap = int(hpddm.optionApp(opt, b'overlap')) mu = int(hpddm.optionApp(opt, b'generate_random_rhs')) sym = bool(hpddm.optionApp(opt, b'symmetric_csr')) xGrid = int(math.sqrt(sizeWorld)) while sizeWorld % xGrid != 0: --xGrid yGrid = int(sizeWorld / xGrid) y = int(rankWorld / xGrid) x = rankWorld - xGrid * y iStart = max(x * int(Nx / xGrid) - overlap, 0) iEnd = min((x + 1) * int(Nx / xGrid) + overlap, Nx) jStart = max(y * int(Ny / yGrid) - overlap, 0) jEnd = min((y + 1) * int(Ny / yGrid) + overlap, Ny) ndof = (iEnd - iStart) * (jEnd - jStart) nnz = ndof * 3 - (iEnd - iStart) - (jEnd - jStart) if not(sym): nnz = 2 * nnz - ndof sol = numpy.zeros(ndof if mu == 0 else (ndof, mu), order = 'F', dtype = hpddm.scalar) f = numpy.empty_like(sol) xdim = [ 0.0, 10.0 ] ydim = [ 0.0, 10.0 ] dx = (xdim[1] - xdim[0]) / float(Nx) dy = (ydim[1] - ydim[0]) / float(Ny) if mu == 0: Nf = 3 xsc = [ 6.5, 2.0, 7.0 ] ysc = [ 8.0, 7.0, 3.0 ] rsc = [ 0.3, 0.3, 0.4 ] asc = [ 0.3, 0.2, -0.1 ] k = 0 for j in xrange(jStart, jEnd): for i in xrange(iStart, iEnd): frs = 1.0 for n in xrange(Nf): (xdist, ydist) = [ xdim[0] + dx * (i + 0.5) - xsc[n], ydim[0] + dy * (j + 0.5) - ysc[n] ] if math.sqrt(xdist * xdist + ydist * ydist) <= rsc[n]: frs -= asc[n] * math.cos(0.5 * math.pi * xdist / rsc[n]) * math.cos(0.5 * math.pi * ydist / rsc[n]) f[k] = frs k += 1 else: f[:] = numpy.random.random_sample((ndof, mu)) if hpddm.scalar == numpy.complex64 or hpddm.scalar == numpy.complex128: f[:] += numpy.random.random_sample((ndof, mu)) * 1j d = numpy.ones(ndof, dtype = hpddm.underlying) o = [] connectivity = [] if jStart != 0: if iStart != 0: o.append(rankWorld - xGrid - 1) connectivity.append([None] * 4 * overlap * overlap) k = 0 for j in xrange(2 * overlap): for i in xrange(iStart, iStart + 2 * overlap): connectivity[-1][k] = i - iStart + (iEnd - iStart) * j k += 1 for j in xrange(overlap): for i in xrange(overlap - j): d[i + j + j * (iEnd - iStart)] = j / float(overlap) for i in xrange(j): d[i + j * (iEnd - iStart)] = i / float(overlap) else: for j in xrange(overlap): for i in xrange(overlap): d[i + j * (iEnd - iStart)] = j / float(overlap) o.append(rankWorld - xGrid) connectivity.append([None] * 2 * overlap * (iEnd - iStart)) k = 0 for j in xrange(2 * overlap): for i in xrange(iStart, iEnd): connectivity[-1][k] = i - iStart + (iEnd - iStart) * j k += 1 for j in xrange(overlap): for i in xrange(iStart + overlap, iEnd - overlap): d[i - iStart + (iEnd - iStart) * j] = j / float(overlap) if iEnd != Nx: o.append(rankWorld - xGrid + 1) connectivity.append([None] * 4 * overlap * overlap) k = 0 for i in xrange(2 * overlap): for j in xrange(2 * overlap): connectivity[-1][k] = (iEnd - iStart) * (i + 1) - 2 * overlap + j k += 1 for j in xrange(0, overlap): for i in xrange(overlap - j): d[(iEnd - iStart) * (j + 1) - overlap + i] = j / float(overlap) for i in xrange(j): d[(iEnd - iStart) * (j + 1) - i - 1] = i / float(overlap) else: for j in xrange(overlap): for i in xrange(overlap): d[(iEnd - iStart) * (j + 1) - overlap + i] = j / float(overlap) if iStart != 0: o.append(rankWorld - 1) connectivity.append([None] * 2 * overlap * (jEnd - jStart)) k = 0 for i in xrange(jStart, jEnd): for j in xrange(2 * overlap): connectivity[-1][k] = j + (i - jStart) * (iEnd - iStart) k += 1 for i in xrange(jStart + (jStart != 0) * overlap, jEnd - (jEnd != Ny) * overlap): for j in xrange(overlap): d[j + (i - jStart) * (iEnd - iStart)] = j / float(overlap) if iEnd != Nx: o.append(rankWorld + 1) connectivity.append([None] * 2 * overlap * (jEnd - jStart)) k = 0 for i in xrange(jStart, jEnd): for j in xrange(2 * overlap): connectivity[-1][k] = (iEnd - iStart) * (i + 1 - jStart) - 2 * overlap + j k += 1 for i in xrange(jStart + (jStart != 0) * overlap, jEnd - (jEnd != Ny) * overlap): for j in xrange(overlap): d[(iEnd - iStart) * (i + 1 - jStart) - j - 1] = j / float(overlap) if jEnd != Ny: if iStart != 0: o.append(rankWorld + xGrid - 1) connectivity.append([None] * 4 * overlap * overlap) k = 0 for j in xrange(2 * overlap): for i in xrange(iStart, iStart + 2 * overlap): connectivity[-1][k] = ndof - 2 * overlap * (iEnd - iStart) + i - iStart + (iEnd - iStart) * j k += 1 for j in xrange(overlap): for i in xrange(overlap - j): d[ndof - overlap * (iEnd - iStart) + i + (iEnd - iStart) * j] = i / float(overlap) for i in xrange(overlap - j, overlap): d[ndof - overlap * (iEnd - iStart) + i + (iEnd - iStart) * j] = (overlap - 1 - j) / float(overlap) else: for j in xrange(overlap): for i in xrange(overlap): d[ndof - overlap * (iEnd - iStart) + (iEnd - iStart) * j + i] = (overlap - j - 1) / float(overlap) o.append(rankWorld + xGrid); connectivity.append([None] * 2 * overlap * (iEnd - iStart)) k = 0 for j in xrange(2 * overlap): for i in xrange(iStart, iEnd): connectivity[-1][k] = ndof - 2 * overlap * (iEnd - iStart) + i - iStart + (iEnd - iStart) * j k += 1 for j in xrange(overlap): for i in xrange(iStart + overlap, iEnd - overlap): d[ndof - overlap * (iEnd - iStart) + i - iStart + (iEnd - iStart) * j] = (overlap - 1 - j) / float(overlap) if iEnd != Nx: o.append(rankWorld + xGrid + 1) connectivity.append([None] * 4 * overlap * overlap) k = 0 for j in xrange(2 * overlap): for i in xrange(iStart, iStart + 2 * overlap): connectivity[-1][k] = ndof - 2 * overlap * (iEnd - iStart) + i - iStart + (iEnd - iStart) * j + (iEnd - iStart - 2 * overlap) k += 1 for j in xrange(overlap): for i in xrange(j, overlap): d[ndof - overlap * (iEnd - iStart) + i + (iEnd - iStart) * (j + 1) - overlap] = (overlap - 1 - i) / float(overlap) for i in xrange(j): d[ndof - overlap * (iEnd - iStart) + i + (iEnd - iStart) * (j + 1) - overlap] = (overlap - 1 - j) / float(overlap) else: for j in xrange(overlap): for i in xrange(overlap): d[ndof - overlap * (iEnd - iStart) + i + (iEnd - iStart) * (j + 1) - overlap] = (overlap - j - 1) / float(overlap) ia = numpy.empty(ndof + 1, dtype = ctypes.c_int) ja = numpy.empty(nnz, dtype = ctypes.c_int) a = numpy.empty(nnz, dtype = hpddm.scalar) ia[0] = (hpddm.numbering.value == b'F') ia[ndof] = nnz + (hpddm.numbering.value == b'F') if sym: k = 0 nnz = 0 for j in xrange(jStart, jEnd): for i in xrange(iStart, iEnd): if j > jStart: a[nnz] = -1 / (dy * dy) ja[nnz] = k - int(Nx / xGrid) + (hpddm.numbering.value == b'F') nnz += 1 if i > iStart: a[nnz] = -1 / (dx * dx) ja[nnz] = k - (hpddm.numbering.value == b'C') nnz += 1 a[nnz] = 2 / (dx * dx) + 2 / (dy * dy) ja[nnz] = k + (hpddm.numbering.value == b'F') nnz += 1 k += 1 ia[k] = nnz + (hpddm.numbering.value == b'F') else: k = 0 nnz = 0 for j in xrange(jStart, jEnd): for i in xrange(iStart, iEnd): if j > jStart: a[nnz] = -1 / (dy * dy) ja[nnz] = k - int(Nx / xGrid) + (hpddm.numbering.value == b'F') nnz += 1 if i > iStart: a[nnz] = -1 / (dx * dx) ja[nnz] = k - (hpddm.numbering.value == b'C') nnz += 1 a[nnz] = 2 / (dx * dx) + 2 / (dy * dy) ja[nnz] = k + (hpddm.numbering.value == b'F') nnz += 1 if i < iEnd - 1: a[nnz] = -1 / (dx * dx) ja[nnz] = k + 1 + (hpddm.numbering.value == b'F') nnz += 1 if j < jEnd - 1: a[nnz] = -1 / (dy * dy) ja[nnz] = k + int(Nx / xGrid) + (hpddm.numbering.value == b'F') nnz += 1 k += 1 ia[k] = nnz + (hpddm.numbering.value == b'F') if sizeWorld > 1 and hpddm.optionSet(opt, b'schwarz_coarse_correction') and hpddm.optionVal(opt, b'geneo_nu') > 0: if sym: nnzNeumann = 2 * nnz - ndof iNeumann = numpy.empty_like(ia) jNeumann = numpy.empty(nnzNeumann, dtype = ctypes.c_int) aNeumann = numpy.empty(nnzNeumann, dtype = hpddm.scalar) iNeumann[0] = (hpddm.numbering.value == b'F') iNeumann[ndof] = nnzNeumann + (hpddm.numbering.value == b'F') k = 0 nnzNeumann = 0 for j in xrange(jStart, jEnd): for i in xrange(iStart, iEnd): if j > jStart: aNeumann[nnzNeumann] = -1 / (dy * dy) + (-1 / (dx * dx) if i == iStart else 0) jNeumann[nnzNeumann] = k - int(Nx / xGrid) + (hpddm.numbering.value == b'F') nnzNeumann += 1 if i > iStart: aNeumann[nnzNeumann] = -1 / (dx * dx) + (-1 / (dy * dy) if j == jStart else 0) jNeumann[nnzNeumann] = k - (hpddm.numbering.value == b'C') nnzNeumann += 1 aNeumann[nnzNeumann] = 2 / (dx * dx) + 2 / (dy * dy) jNeumann[nnzNeumann] = k + (hpddm.numbering.value == b'F') nnzNeumann += 1 if i < iEnd - 1: aNeumann[nnzNeumann] = -1 / (dx * dx) + (-1 / (dy * dy) if j == jEnd - 1 else 0) jNeumann[nnzNeumann] = k + 1 + (hpddm.numbering.value == b'F') nnzNeumann += 1 if j < jEnd - 1: aNeumann[nnzNeumann] = -1 / (dy * dy) + (-1 / (dx * dx) if i == iEnd - 1 else 0) jNeumann[nnzNeumann] = k + int(Nx / xGrid) + (hpddm.numbering.value == b'F') nnzNeumann += 1 k += 1 iNeumann[k] = nnzNeumann + (hpddm.numbering.value == b'F') MatNeumann = hpddm.matrixCSRCreate(ndof, ndof, nnzNeumann, aNeumann, iNeumann, jNeumann, False) else: aNeumann = numpy.empty_like(a) numpy.copyto(aNeumann, a) nnzNeumann = 0 for j in xrange(jStart, jEnd): for i in xrange(iStart, iEnd): if j > jStart: if i == iStart: aNeumann[nnzNeumann] -= 1 / (dx * dx) nnzNeumann += 1 if i > iStart: if j == jStart: aNeumann[nnzNeumann] -= 1 / (dy * dy) nnzNeumann += 1 nnzNeumann += 1 if i < iEnd - 1: if j == jEnd - 1: aNeumann[nnzNeumann] -= 1 / (dy * dy) nnzNeumann += 1 if j < jEnd - 1: if i == iEnd - 1: aNeumann[nnzNeumann] -= 1 / (dx * dx) nnzNeumann += 1 MatNeumann = hpddm.matrixCSRCreate(ndof, ndof, nnzNeumann, aNeumann, ia, ja, False) else: MatNeumann = ctypes.POINTER(hpddm.MatrixCSR)() Mat = hpddm.matrixCSRCreate(ndof, ndof, nnz, a, ia, ja, sym) if sizeWorld > 1: for k in xrange(sizeWorld): if k == rankWorld: print(str(rankWorld) + ':') print(str(x) + 'x' + str(y) + ' -- [' + str(iStart) + ' ; ' + str(iEnd) + '] x [' + str(jStart) + ' ; ' + str(jEnd) + '] -- ' + str(ndof) + ', ' + str(nnz)) MPI.COMM_WORLD.Barrier() return o, connectivity, ndof, Mat, MatNeumann, d, f, sol, mu
def generate(rankWorld, sizeWorld): opt = hpddm.optionGet() Nx = int(hpddm.optionApp(opt, b'Nx')) Ny = int(hpddm.optionApp(opt, b'Ny')) overlap = int(hpddm.optionApp(opt, b'overlap')) mu = int(hpddm.optionApp(opt, b'generate_random_rhs')) sym = bool(hpddm.optionApp(opt, b'symmetric_csr')) xGrid = int(math.sqrt(sizeWorld)) while sizeWorld % xGrid != 0: --xGrid yGrid = int(sizeWorld / xGrid) y = int(rankWorld / xGrid) x = rankWorld - xGrid * y iStart = max(x * int(Nx / xGrid) - overlap, 0) iEnd = min((x + 1) * int(Nx / xGrid) + overlap, Nx) jStart = max(y * int(Ny / yGrid) - overlap, 0) jEnd = min((y + 1) * int(Ny / yGrid) + overlap, Ny) ndof = (iEnd - iStart) * (jEnd - jStart) nnz = ndof * 3 - (iEnd - iStart) - (jEnd - jStart) if not (sym): nnz = 2 * nnz - ndof sol = numpy.zeros(ndof if mu == 0 else (ndof, mu), order='F', dtype=hpddm.scalar) f = numpy.empty_like(sol) xdim = [0.0, 10.0] ydim = [0.0, 10.0] dx = (xdim[1] - xdim[0]) / float(Nx) dy = (ydim[1] - ydim[0]) / float(Ny) if mu == 0: Nf = 3 xsc = [6.5, 2.0, 7.0] ysc = [8.0, 7.0, 3.0] rsc = [0.3, 0.3, 0.4] asc = [0.3, 0.2, -0.1] k = 0 for j in xrange(jStart, jEnd): for i in xrange(iStart, iEnd): frs = 1.0 for n in xrange(Nf): (xdist, ydist) = [ xdim[0] + dx * (i + 0.5) - xsc[n], ydim[0] + dy * (j + 0.5) - ysc[n] ] if math.sqrt(xdist * xdist + ydist * ydist) <= rsc[n]: frs -= asc[n] * math.cos( 0.5 * math.pi * xdist / rsc[n]) * math.cos( 0.5 * math.pi * ydist / rsc[n]) f[k] = frs k += 1 else: f[:] = numpy.random.random_sample((ndof, mu)) if hpddm.scalar == numpy.complex64 or hpddm.scalar == numpy.complex128: f[:] += numpy.random.random_sample((ndof, mu)) * 1j d = numpy.ones(ndof, dtype=hpddm.underlying) o = [] connectivity = [] if jStart != 0: if iStart != 0: o.append(rankWorld - xGrid - 1) connectivity.append([None] * 4 * overlap * overlap) k = 0 for j in xrange(2 * overlap): for i in xrange(iStart, iStart + 2 * overlap): connectivity[-1][k] = i - iStart + (iEnd - iStart) * j k += 1 for j in xrange(overlap): for i in xrange(overlap - j): d[i + j + j * (iEnd - iStart)] = j / float(overlap) for i in xrange(j): d[i + j * (iEnd - iStart)] = i / float(overlap) else: for j in xrange(overlap): for i in xrange(overlap): d[i + j * (iEnd - iStart)] = j / float(overlap) o.append(rankWorld - xGrid) connectivity.append([None] * 2 * overlap * (iEnd - iStart)) k = 0 for j in xrange(2 * overlap): for i in xrange(iStart, iEnd): connectivity[-1][k] = i - iStart + (iEnd - iStart) * j k += 1 for j in xrange(overlap): for i in xrange(iStart + overlap, iEnd - overlap): d[i - iStart + (iEnd - iStart) * j] = j / float(overlap) if iEnd != Nx: o.append(rankWorld - xGrid + 1) connectivity.append([None] * 4 * overlap * overlap) k = 0 for i in xrange(2 * overlap): for j in xrange(2 * overlap): connectivity[-1][k] = (iEnd - iStart) * (i + 1) - 2 * overlap + j k += 1 for j in xrange(0, overlap): for i in xrange(overlap - j): d[(iEnd - iStart) * (j + 1) - overlap + i] = j / float(overlap) for i in xrange(j): d[(iEnd - iStart) * (j + 1) - i - 1] = i / float(overlap) else: for j in xrange(overlap): for i in xrange(overlap): d[(iEnd - iStart) * (j + 1) - overlap + i] = j / float(overlap) if iStart != 0: o.append(rankWorld - 1) connectivity.append([None] * 2 * overlap * (jEnd - jStart)) k = 0 for i in xrange(jStart, jEnd): for j in xrange(2 * overlap): connectivity[-1][k] = j + (i - jStart) * (iEnd - iStart) k += 1 for i in xrange(jStart + (jStart != 0) * overlap, jEnd - (jEnd != Ny) * overlap): for j in xrange(overlap): d[j + (i - jStart) * (iEnd - iStart)] = j / float(overlap) if iEnd != Nx: o.append(rankWorld + 1) connectivity.append([None] * 2 * overlap * (jEnd - jStart)) k = 0 for i in xrange(jStart, jEnd): for j in xrange(2 * overlap): connectivity[-1][k] = (iEnd - iStart) * ( i + 1 - jStart) - 2 * overlap + j k += 1 for i in xrange(jStart + (jStart != 0) * overlap, jEnd - (jEnd != Ny) * overlap): for j in xrange(overlap): d[(iEnd - iStart) * (i + 1 - jStart) - j - 1] = j / float(overlap) if jEnd != Ny: if iStart != 0: o.append(rankWorld + xGrid - 1) connectivity.append([None] * 4 * overlap * overlap) k = 0 for j in xrange(2 * overlap): for i in xrange(iStart, iStart + 2 * overlap): connectivity[-1][k] = ndof - 2 * overlap * ( iEnd - iStart) + i - iStart + (iEnd - iStart) * j k += 1 for j in xrange(overlap): for i in xrange(overlap - j): d[ndof - overlap * (iEnd - iStart) + i + (iEnd - iStart) * j] = i / float(overlap) for i in xrange(overlap - j, overlap): d[ndof - overlap * (iEnd - iStart) + i + (iEnd - iStart) * j] = (overlap - 1 - j) / float(overlap) else: for j in xrange(overlap): for i in xrange(overlap): d[ndof - overlap * (iEnd - iStart) + (iEnd - iStart) * j + i] = (overlap - j - 1) / float(overlap) o.append(rankWorld + xGrid) connectivity.append([None] * 2 * overlap * (iEnd - iStart)) k = 0 for j in xrange(2 * overlap): for i in xrange(iStart, iEnd): connectivity[-1][k] = ndof - 2 * overlap * ( iEnd - iStart) + i - iStart + (iEnd - iStart) * j k += 1 for j in xrange(overlap): for i in xrange(iStart + overlap, iEnd - overlap): d[ndof - overlap * (iEnd - iStart) + i - iStart + (iEnd - iStart) * j] = (overlap - 1 - j) / float(overlap) if iEnd != Nx: o.append(rankWorld + xGrid + 1) connectivity.append([None] * 4 * overlap * overlap) k = 0 for j in xrange(2 * overlap): for i in xrange(iStart, iStart + 2 * overlap): connectivity[-1][k] = ndof - 2 * overlap * ( iEnd - iStart) + i - iStart + (iEnd - iStart) * j + ( iEnd - iStart - 2 * overlap) k += 1 for j in xrange(overlap): for i in xrange(j, overlap): d[ndof - overlap * (iEnd - iStart) + i + (iEnd - iStart) * (j + 1) - overlap] = (overlap - 1 - i) / float(overlap) for i in xrange(j): d[ndof - overlap * (iEnd - iStart) + i + (iEnd - iStart) * (j + 1) - overlap] = (overlap - 1 - j) / float(overlap) else: for j in xrange(overlap): for i in xrange(overlap): d[ndof - overlap * (iEnd - iStart) + i + (iEnd - iStart) * (j + 1) - overlap] = (overlap - j - 1) / float(overlap) ia = numpy.empty(ndof + 1, dtype=ctypes.c_int) ja = numpy.empty(nnz, dtype=ctypes.c_int) a = numpy.empty(nnz, dtype=hpddm.scalar) ia[0] = (hpddm.numbering.value == b'F') ia[ndof] = nnz + (hpddm.numbering.value == b'F') if sym: k = 0 nnz = 0 for j in xrange(jStart, jEnd): for i in xrange(iStart, iEnd): if j > jStart: a[nnz] = -1 / (dy * dy) ja[nnz] = k - int(Nx / xGrid) + (hpddm.numbering.value == b'F') nnz += 1 if i > iStart: a[nnz] = -1 / (dx * dx) ja[nnz] = k - (hpddm.numbering.value == b'C') nnz += 1 a[nnz] = 2 / (dx * dx) + 2 / (dy * dy) ja[nnz] = k + (hpddm.numbering.value == b'F') nnz += 1 k += 1 ia[k] = nnz + (hpddm.numbering.value == b'F') else: k = 0 nnz = 0 for j in xrange(jStart, jEnd): for i in xrange(iStart, iEnd): if j > jStart: a[nnz] = -1 / (dy * dy) ja[nnz] = k - int(Nx / xGrid) + (hpddm.numbering.value == b'F') nnz += 1 if i > iStart: a[nnz] = -1 / (dx * dx) ja[nnz] = k - (hpddm.numbering.value == b'C') nnz += 1 a[nnz] = 2 / (dx * dx) + 2 / (dy * dy) ja[nnz] = k + (hpddm.numbering.value == b'F') nnz += 1 if i < iEnd - 1: a[nnz] = -1 / (dx * dx) ja[nnz] = k + 1 + (hpddm.numbering.value == b'F') nnz += 1 if j < jEnd - 1: a[nnz] = -1 / (dy * dy) ja[nnz] = k + int(Nx / xGrid) + (hpddm.numbering.value == b'F') nnz += 1 k += 1 ia[k] = nnz + (hpddm.numbering.value == b'F') if sizeWorld > 1 and hpddm.optionSet( opt, b'schwarz_coarse_correction') and hpddm.optionVal( opt, b'geneo_nu') > 0: if sym: nnzNeumann = 2 * nnz - ndof iNeumann = numpy.empty_like(ia) jNeumann = numpy.empty(nnzNeumann, dtype=ctypes.c_int) aNeumann = numpy.empty(nnzNeumann, dtype=hpddm.scalar) iNeumann[0] = (hpddm.numbering.value == b'F') iNeumann[ndof] = nnzNeumann + (hpddm.numbering.value == b'F') k = 0 nnzNeumann = 0 for j in xrange(jStart, jEnd): for i in xrange(iStart, iEnd): if j > jStart: aNeumann[nnzNeumann] = -1 / (dy * dy) + ( -1 / (dx * dx) if i == iStart else 0) jNeumann[nnzNeumann] = k - int( Nx / xGrid) + (hpddm.numbering.value == b'F') nnzNeumann += 1 if i > iStart: aNeumann[nnzNeumann] = -1 / (dx * dx) + ( -1 / (dy * dy) if j == jStart else 0) jNeumann[nnzNeumann] = k - (hpddm.numbering.value == b'C') nnzNeumann += 1 aNeumann[nnzNeumann] = 2 / (dx * dx) + 2 / (dy * dy) jNeumann[nnzNeumann] = k + (hpddm.numbering.value == b'F') nnzNeumann += 1 if i < iEnd - 1: aNeumann[nnzNeumann] = -1 / (dx * dx) + ( -1 / (dy * dy) if j == jEnd - 1 else 0) jNeumann[nnzNeumann] = k + 1 + (hpddm.numbering.value == b'F') nnzNeumann += 1 if j < jEnd - 1: aNeumann[nnzNeumann] = -1 / (dy * dy) + ( -1 / (dx * dx) if i == iEnd - 1 else 0) jNeumann[nnzNeumann] = k + int( Nx / xGrid) + (hpddm.numbering.value == b'F') nnzNeumann += 1 k += 1 iNeumann[k] = nnzNeumann + (hpddm.numbering.value == b'F') MatNeumann = hpddm.matrixCSRCreate(ndof, ndof, nnzNeumann, aNeumann, iNeumann, jNeumann, False) else: aNeumann = numpy.empty_like(a) numpy.copyto(aNeumann, a) nnzNeumann = 0 for j in xrange(jStart, jEnd): for i in xrange(iStart, iEnd): if j > jStart: if i == iStart: aNeumann[nnzNeumann] -= 1 / (dx * dx) nnzNeumann += 1 if i > iStart: if j == jStart: aNeumann[nnzNeumann] -= 1 / (dy * dy) nnzNeumann += 1 nnzNeumann += 1 if i < iEnd - 1: if j == jEnd - 1: aNeumann[nnzNeumann] -= 1 / (dy * dy) nnzNeumann += 1 if j < jEnd - 1: if i == iEnd - 1: aNeumann[nnzNeumann] -= 1 / (dx * dx) nnzNeumann += 1 MatNeumann = hpddm.matrixCSRCreate(ndof, ndof, nnzNeumann, aNeumann, ia, ja, False) else: MatNeumann = ctypes.POINTER(hpddm.MatrixCSR)() Mat = hpddm.matrixCSRCreate(ndof, ndof, nnz, a, ia, ja, sym) if sizeWorld > 1: for k in xrange(sizeWorld): if k == rankWorld: print(str(rankWorld) + ':') print( str(x) + 'x' + str(y) + ' -- [' + str(iStart) + ' ; ' + str(iEnd) + '] x [' + str(jStart) + ' ; ' + str(jEnd) + '] -- ' + str(ndof) + ', ' + str(nnz)) MPI.COMM_WORLD.Barrier() return o, connectivity, ndof, Mat, MatNeumann, d, f, sol, mu
appArgs() o, connectivity, dof, Mat, MatNeumann, d, f, sol, mu = generate( rankWorld, sizeWorld) status = 0 if sizeWorld > 1: A = hpddm.schwarzCreate(Mat, o, connectivity) hpddm.schwarzMultiplicityScaling(A, d) hpddm.schwarzInitialize(A, d) if mu != 0: hpddm.schwarzScaledExchange(A, f) else: mu = 1 if hpddm.optionSet(opt, b'schwarz_coarse_correction'): nu = ctypes.c_ushort(int(hpddm.optionVal(opt, b'geneo_nu'))) if nu.value > 0: if hpddm.optionApp(opt, b'nonuniform'): nu.value += max(int(-hpddm.optionVal(opt, b'geneo_nu') + 1), (-1)**rankWorld * rankWorld) threshold = hpddm.underlying( max(0, hpddm.optionVal(opt, b'geneo_threshold'))) hpddm.schwarzSolveGEVP(A, MatNeumann, ctypes.byref(nu), threshold) addr = hpddm.optionAddr(opt, b'geneo_nu') addr.contents.value = nu.value else: nu = 1 deflation = numpy.ones((dof, nu), order='F', dtype=hpddm.scalar) hpddm.setVectors(hpddm.schwarzPreconditioner(A), nu, deflation) hpddm.initializeCoarseOperator(hpddm.schwarzPreconditioner(A), nu) hpddm.schwarzBuildCoarseOperator(