static char help[] = "Reads a PETSc matrix and vector from a file and solves a linear system.\n\ This version first preloads and solves a small system, then loads \n\ another (larger) system and solves it as well. This example illustrates\n\ preloading of instructions with the smaller system so that more accurate\n\ performance monitoring can be done with the larger one (that actually\n\ is the system of interest). See the 'Performance Hints' chapter of the\n\ users manual for a discussion of preloading. Input parameters include\n\ -f0 : first file to load (small system)\n\ -f1 : second file to load (larger system)\n\n\ -trans : solve transpose system instead\n\n"; /* This code can be used to test PETSc interface to other packages.\n\ Examples of command line options: \n\ ex10 -f0 -ksp_type preonly \n\ -help -ksp_view \n\ -num_numfac -num_rhs \n\ -ksp_type preonly -pc_type lu -mat_type aijspooles/superlu/superlu_dist/aijmumps \n\ -ksp_type preonly -pc_type cholesky -mat_type sbaijspooles/dscpack/sbaijmumps \n\ -f0 -fB -mat_type sbaijmumps -ksp_type preonly -pc_type cholesky -test_inertia -mat_sigma \n\ mpiexec -np ex10 -f0 -ksp_type cg -pc_type asm -pc_asm_type basic -sub_pc_type icc -mat_type sbaij \n\n"; */ /*T Concepts: KSP^solving a linear system Processors: n T*/ /* Include "petscksp.h" so that we can use KSP solvers. Note that this file automatically includes: petsc.h - base PETSc routines petscvec.h - vectors petscsys.h - system routines petscmat.h - matrices petscis.h - index sets petscksp.h - Krylov subspace methods petscviewer.h - viewers petscpc.h - preconditioners */ #include "petscksp.h" #undef __FUNCT__ #define __FUNCT__ "main" int main(int argc,char **args) { KSP ksp; /* linear solver context */ Mat A,B; /* matrix */ Vec x,b,u; /* approx solution, RHS, exact solution */ PetscViewer fd; /* viewer */ char file[3][PETSC_MAX_PATH_LEN]; /* input file name */ PetscTruth table,flg,flgB=PETSC_FALSE,trans=PETSC_FALSE,partition=PETSC_FALSE; PetscErrorCode ierr; PetscInt its,num_numfac,m,n,M; PetscReal norm; PetscLogDouble tsetup,tsetup1,tsetup2,tsolve,tsolve1,tsolve2; PetscTruth preload=PETSC_TRUE,diagonalscale,isSymmetric,cknorm=PETSC_FALSE,Test_MatDuplicate=PETSC_FALSE; PetscMPIInt rank; PetscScalar sigma; PetscInitialize(&argc,&args,(char *)0,help); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = PetscOptionsHasName(PETSC_NULL,"-table",&table);CHKERRQ(ierr); ierr = PetscOptionsHasName(PETSC_NULL,"-trans",&trans);CHKERRQ(ierr); ierr = PetscOptionsHasName(PETSC_NULL,"-partition",&partition);CHKERRQ(ierr); /* Determine files from which we read the two linear systems (matrix and right-hand-side vector). */ ierr = PetscOptionsGetString(PETSC_NULL,"-f",file[0],PETSC_MAX_PATH_LEN-1,&flg);CHKERRQ(ierr); if (flg) { ierr = PetscStrcpy(file[1],file[0]);CHKERRQ(ierr); preload = PETSC_FALSE; } else { ierr = PetscOptionsGetString(PETSC_NULL,"-f0",file[0],PETSC_MAX_PATH_LEN-1,&flg);CHKERRQ(ierr); if (!flg) SETERRQ(1,"Must indicate binary file with the -f0 or -f option"); ierr = PetscOptionsGetString(PETSC_NULL,"-f1",file[1],PETSC_MAX_PATH_LEN-1,&flg);CHKERRQ(ierr); if (!flg) {preload = PETSC_FALSE;} /* don't bother with second system */ } /* ----------------------------------------------------------- Beginning of linear solver loop ----------------------------------------------------------- */ /* Loop through the linear solve 2 times. - The intention here is to preload and solve a small system; then load another (larger) system and solve it as well. This process preloads the instructions with the smaller system so that more accurate performance monitoring (via -log_summary) can be done with the larger one (that actually is the system of interest). */ PreLoadBegin(preload,"Load system"); /* - - - - - - - - - - - New Stage - - - - - - - - - - - - - Load system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Open binary file. Note that we use FILE_MODE_READ to indicate reading from this file. */ ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,file[PreLoadIt],FILE_MODE_READ,&fd);CHKERRQ(ierr); /* Load the matrix and vector; then destroy the viewer. */ ierr = MatLoad(fd,MATAIJ,&A);CHKERRQ(ierr); if (!preload){ flg = PETSC_FALSE; ierr = PetscOptionsGetString(PETSC_NULL,"-rhs",file[2],PETSC_MAX_PATH_LEN-1,&flg);CHKERRQ(ierr); if (flg){ /* rhs is stored in a separate file */ ierr = PetscViewerDestroy(fd);CHKERRQ(ierr); ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,file[2],FILE_MODE_READ,&fd);CHKERRQ(ierr); } } if (rank){ ierr = PetscExceptionTry1(VecLoad(fd,PETSC_NULL,&b),PETSC_ERR_FILE_UNEXPECTED); } else { ierr = PetscExceptionTry1(VecLoad(fd,PETSC_NULL,&b),PETSC_ERR_FILE_READ); } if (PetscExceptionCaught(ierr,PETSC_ERR_FILE_UNEXPECTED) || PetscExceptionCaught(ierr,PETSC_ERR_FILE_READ)) { /* if file contains no RHS, then use a vector of all ones */ PetscInt m; PetscScalar one = 1.0; ierr = PetscInfo(0,"Using vector of ones for RHS\n");CHKERRQ(ierr); ierr = MatGetLocalSize(A,&m,PETSC_NULL);CHKERRQ(ierr); ierr = VecCreate(PETSC_COMM_WORLD,&b);CHKERRQ(ierr); ierr = VecSetSizes(b,m,PETSC_DECIDE);CHKERRQ(ierr); ierr = VecSetFromOptions(b);CHKERRQ(ierr); ierr = VecSet(b,one);CHKERRQ(ierr); } else CHKERRQ(ierr); ierr = PetscViewerDestroy(fd);CHKERRQ(ierr); /* Test MatDuplicate() */ if (Test_MatDuplicate){ ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); ierr = MatEqual(A,B,&flg);CHKERRQ(ierr); if (!flg){ PetscPrintf(PETSC_COMM_WORLD," A != B \n");CHKERRQ(ierr); } ierr = MatDestroy(B);CHKERRQ(ierr); } /* Add a shift to A */ ierr = PetscOptionsGetScalar(PETSC_NULL,"-mat_sigma",&sigma,&flg);CHKERRQ(ierr); if (flg) { ierr = PetscOptionsGetString(PETSC_NULL,"-fB",file[2],PETSC_MAX_PATH_LEN-1,&flgB);CHKERRQ(ierr); if (flgB){ /* load B to get A = A + sigma*B */ ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,file[2],FILE_MODE_READ,&fd);CHKERRQ(ierr); ierr = MatLoad(fd,MATAIJ,&B);CHKERRQ(ierr); ierr = PetscViewerDestroy(fd);CHKERRQ(ierr); ierr = MatAXPY(A,sigma,B,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); /* A <- sigma*B + A */ } else { ierr = MatShift(A,sigma);CHKERRQ(ierr); } } /* Make A singular for testing zero-pivot of ilu factorization */ /* Example: ./ex10 -f0 -test_zeropivot -set_row_zero -pc_factor_shift_nonzero */ ierr = PetscOptionsHasName(PETSC_NULL, "-test_zeropivot", &flg);CHKERRQ(ierr); if (flg) { PetscInt row,ncols; const PetscInt *cols; const PetscScalar *vals; PetscTruth flg1=PETSC_FALSE; PetscScalar *zeros; row = 0; ierr = MatGetRow(A,row,&ncols,&cols,&vals);CHKERRQ(ierr); ierr = PetscMalloc(sizeof(PetscScalar)*(ncols+1),&zeros); ierr = PetscMemzero(zeros,(ncols+1)*sizeof(PetscScalar));CHKERRQ(ierr); ierr = PetscOptionsHasName(PETSC_NULL, "-set_row_zero", &flg1);CHKERRQ(ierr); if (flg1){ /* set entire row as zero */ ierr = MatSetValues(A,1,&row,ncols,cols,zeros,INSERT_VALUES);CHKERRQ(ierr); } else { /* only set (row,row) entry as zero */ ierr = MatSetValues(A,1,&row,1,&row,zeros,INSERT_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); } /* Check whether A is symmetric */ ierr = PetscOptionsHasName(PETSC_NULL, "-check_symmetry", &flg);CHKERRQ(ierr); if (flg) { Mat Atrans; ierr = MatTranspose(A, &Atrans); ierr = MatEqual(A, Atrans, &isSymmetric); if (isSymmetric) { PetscPrintf(PETSC_COMM_WORLD,"A is symmetric \n");CHKERRQ(ierr); } else { PetscPrintf(PETSC_COMM_WORLD,"A is non-symmetric \n");CHKERRQ(ierr); } ierr = MatDestroy(Atrans);CHKERRQ(ierr); } /* If the loaded matrix is larger than the vector (due to being padded to match the block size of the system), then create a new padded vector. */ ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); if (m != n) { SETERRQ2(PETSC_ERR_ARG_SIZ, "This example is not intended for rectangular matrices (%d, %d)", m, n); } ierr = MatGetSize(A,&M,PETSC_NULL);CHKERRQ(ierr); ierr = VecGetSize(b,&m);CHKERRQ(ierr); if (M != m) { /* Create a new vector b by padding the old one */ PetscInt j,mvec,start,end,indx; Vec tmp; PetscScalar *bold; ierr = VecCreate(PETSC_COMM_WORLD,&tmp);CHKERRQ(ierr); ierr = VecSetSizes(tmp,n,PETSC_DECIDE);CHKERRQ(ierr); ierr = VecSetFromOptions(tmp);CHKERRQ(ierr); ierr = VecGetOwnershipRange(b,&start,&end);CHKERRQ(ierr); ierr = VecGetLocalSize(b,&mvec);CHKERRQ(ierr); ierr = VecGetArray(b,&bold);CHKERRQ(ierr); for (j=0; j -ksp_type preonly -pc_type cholesky -mat_type seqsbaij -test_inertia -mat_sigma */ ierr = PetscOptionsHasName(PETSC_NULL,"-test_inertia",&flg);CHKERRQ(ierr); if (flg){ PC pc; PetscInt nneg, nzero, npos; Mat F; ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); ierr = PCGetFactoredMatrix(pc,&F);CHKERRQ(ierr); ierr = MatGetInertia(F,&nneg,&nzero,&npos);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF," MatInertia: nneg: %D, nzero: %D, npos: %D\n",nneg,nzero,npos); } /* Tests "diagonal-scaling of preconditioned residual norm" as used by many ODE integrator codes including SUNDIALS. Note this is different than diagonally scaling the matrix before computing the preconditioner */ ierr = PetscOptionsHasName(PETSC_NULL,"-diagonal_scale",&diagonalscale);CHKERRQ(ierr); if (diagonalscale) { PC pc; PetscInt j,start,end,n; Vec scale; ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); ierr = VecGetSize(x,&n);CHKERRQ(ierr); ierr = VecDuplicate(x,&scale);CHKERRQ(ierr); ierr = VecGetOwnershipRange(scale,&start,&end);CHKERRQ(ierr); for (j=start; j