1dc97da86SPierre Jolivet# This script demonstrates solving a symmetric positive definite linear system using PETSc and HPDDM preconditioner 2dc97da86SPierre Jolivet# It must be run with exactly 4 MPI processes 3dc97da86SPierre Jolivet# Example run: 4*a8cf87e0SJunchao Zhang# mpiexec -n 4 python3 hpddm.py -pc_hpddm_levels_1_sub_pc_type lu -pc_hpddm_levels_1_eps_nev 20 -pc_hpddm_levels_1_eps_threshold_absolute 0.1 -ksp_monitor 5dc97da86SPierre Jolivet# For more options, see ${PETSC_DIR}/src/ksp/ksp/tutorials/ex76.c 6dc97da86SPierre Jolivet 7dc97da86SPierre Jolivetimport sys 8dc97da86SPierre Jolivetimport petsc4py 9dc97da86SPierre Jolivet# Initialize PETSc with command-line arguments 10dc97da86SPierre Jolivetpetsc4py.init(sys.argv) 11dc97da86SPierre Jolivetfrom petsc4py import PETSc 12dc97da86SPierre Jolivet 13dc97da86SPierre Jolivet# Get the rank of the current process 14dc97da86SPierre Jolivetrank = PETSc.COMM_WORLD.getRank() 15dc97da86SPierre Jolivet# Ensure that the script is run with exactly 4 processes 16dc97da86SPierre Jolivetif PETSc.COMM_WORLD.getSize() != 4: 17dc97da86SPierre Jolivet if rank == 0: 18dc97da86SPierre Jolivet print("This example requires 4 processes") 19dc97da86SPierre Jolivet quit() 20dc97da86SPierre Jolivet 21dc97da86SPierre Jolivet# Load directory for input data 22dc97da86SPierre Jolivetload_dir = PETSc.Options().getString("load_dir", "${DATAFILESPATH}/matrices/hpddm/GENEO") 23dc97da86SPierre Jolivet 24dc97da86SPierre Jolivet# Load an index set (IS) from binary file 25dc97da86SPierre Jolivetsizes = PETSc.IS().load(PETSc.Viewer().createBinary(f"{load_dir}/sizes_{rank}_4.dat", "r", comm = PETSc.COMM_SELF)) 26dc97da86SPierre Jolivet# Get indices from the loaded IS 27dc97da86SPierre Jolivetidx = sizes.getIndices() 28dc97da86SPierre Jolivet 29dc97da86SPierre Jolivet# Create a PETSc matrix object 30dc97da86SPierre JolivetA = PETSc.Mat().create() 31dc97da86SPierre Jolivet# Set the local and global sizes of the matrix 32dc97da86SPierre JolivetA.setSizes([[idx[0], idx[2]], [idx[1], idx[3]]]) 33dc97da86SPierre Jolivet# Configure matrix using runtime options 34dc97da86SPierre JolivetA.setFromOptions() 35dc97da86SPierre Jolivet# Load matrix A from binary file 36dc97da86SPierre JolivetA = A.load(PETSc.Viewer().createBinary(f"{load_dir}/A.dat", "r", comm = PETSc.COMM_WORLD)) 37dc97da86SPierre Jolivet 38dc97da86SPierre Jolivet# Load an index set (IS) from binary file 39dc97da86SPierre Jolivetaux_IS = PETSc.IS().load(PETSc.Viewer().createBinary(f"{load_dir}/is_{rank}_4.dat", "r", comm = PETSc.COMM_SELF)) 40dc97da86SPierre Jolivet# Set the block size of the index set 416d61d5b2SPierre Jolivetaux_IS.setBlockSize(A.getBlockSize()) 42dc97da86SPierre Jolivet# Load the Neumann matrix of the current process 43dc97da86SPierre Jolivetaux_Mat = PETSc.Mat().load(PETSc.Viewer().createBinary(f"{load_dir}/Neumann_{rank}_4.dat", "r", comm = PETSc.COMM_SELF)) 44dc97da86SPierre Jolivet 45dc97da86SPierre Jolivet# Create and configure the linear solver (KSP) and preconditioner (PC) 46dc97da86SPierre Jolivetksp = PETSc.KSP(PETSc.COMM_WORLD).create() 47dc97da86SPierre Jolivetpc = ksp.getPC() 48dc97da86SPierre Jolivet# Use HPDDM as the preconditioner 49dc97da86SPierre Jolivetpc.setType(PETSc.PC.Type.HPDDM) 50bd6c8f9dSPierre Jolivet# Set the index set (local-to-global numbering) and auxiliary matrix 51dc97da86SPierre Jolivetpc.setHPDDMAuxiliaryMat(aux_IS, aux_Mat) 52dc97da86SPierre Jolivet# Inform HPDDM that the auxiliary matrix is the local Neumann matrix 53dc97da86SPierre Jolivetpc.setHPDDMHasNeumannMat(True) 54dc97da86SPierre Jolivet# Apply any command-line options (which may override options from the source file) 55dc97da86SPierre Jolivetksp.setFromOptions() 56dc97da86SPierre Jolivet# Set the system matrix (Amat = Pmat) 57dc97da86SPierre Jolivetksp.setOperators(A) 58dc97da86SPierre Jolivet 59dc97da86SPierre Jolivet# Create RHS (b) and solution (x) vectors, set random values to b, and solve the system 60dc97da86SPierre Jolivetb, x = A.createVecs() 61dc97da86SPierre Jolivetb.setRandom() 62dc97da86SPierre Jolivetksp.solve(b, x) 63dc97da86SPierre Jolivet 64dc97da86SPierre Jolivet# Output grid and operator complexities on rank 0 65dc97da86SPierre Jolivetgc, oc = pc.getHPDDMComplexities() 66dc97da86SPierre Jolivetif rank == 0: 67dc97da86SPierre Jolivet print("grid complexity = ", gc, ", operator complexity = ", oc, sep = "") 68