PetscErrorCode bsscr_GMiGt( Mat *_K2, Mat K, Mat G, Mat M){ Mat K2; Vec Mdiag; Mat MinvGt; Mat Gtrans; PetscErrorCode ierr; PetscFunctionBegin; MatGetVecs( M, &Mdiag, PETSC_NULL ); MatGetDiagonal( M, Mdiag ); VecReciprocal(Mdiag); #if( PETSC_VERSION_MAJOR <= 2 ) ierr=MatTranspose(G, &Gtrans);CHKERRQ(ierr); #else ierr=MatTranspose(G, MAT_INITIAL_MATRIX,&Gtrans);CHKERRQ(ierr); #endif ierr=MatConvert(Gtrans, MATSAME, MAT_INITIAL_MATRIX, &MinvGt);CHKERRQ(ierr);/* copy Gtrans -> MinvGt */ MatDiagonalScale(MinvGt, Mdiag, PETSC_NULL);/* Minv*Gtrans */ /* MAT_INITIAL_MATRIX -> creates K2 matrix : PETSC_DEFAULT for fill ratio: run with -info to find what it should be*/ ierr=MatMatMult( G, MinvGt, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &K2);CHKERRQ(ierr);/* K2 = G*Minv*Gtrans */ Stg_MatDestroy(&Gtrans); Stg_MatDestroy(&MinvGt); Stg_VecDestroy(&Mdiag); *_K2=K2; PetscFunctionReturn(0); }
void PetscMatrix<T>::get_transpose (SparseMatrix<T>& dest) const { // Make sure the SparseMatrix passed in is really a PetscMatrix PetscMatrix<T>& petsc_dest = libmesh_cast_ref<PetscMatrix<T>&>(dest); // If we aren't reusing the matrix then need to clear dest, // otherwise we get a memory leak if(&petsc_dest != this) dest.clear(); PetscErrorCode ierr; #if PETSC_VERSION_LESS_THAN(3,0,0) if (&petsc_dest == this) ierr = MatTranspose(_mat,PETSC_NULL); else ierr = MatTranspose(_mat,&petsc_dest._mat); LIBMESH_CHKERRABORT(ierr); #else // FIXME - we can probably use MAT_REUSE_MATRIX in more situations if (&petsc_dest == this) ierr = MatTranspose(_mat,MAT_REUSE_MATRIX,&petsc_dest._mat); else ierr = MatTranspose(_mat,MAT_INITIAL_MATRIX,&petsc_dest._mat); LIBMESH_CHKERRABORT(ierr); #endif // Specify that the transposed matrix is initialized and close it. petsc_dest._is_initialized = true; petsc_dest.close(); }
// updated PetscErrorCode BSSCR_MatStokesMVBlockDefaultBuildScaling( MatStokesBlockScaling BA, Mat A, Vec b, Vec x, PetscTruth sym ) { Mat K,G,D,C; Vec rG; PetscScalar rg2, rg, ra; PetscInt N; Vec rA, rC; Vec L1,L2, R1,R2; Mat S; VecNestGetSubVec( BA->Lz, 0, &L1 ); VecNestGetSubVec( BA->Lz, 1, &L2 ); VecNestGetSubVec( BA->Rz, 0, &R1 ); VecNestGetSubVec( BA->Rz, 1, &R2 ); rA = L1; rC = L2; MatNestGetSubMat( A, 0,0, &K ); MatNestGetSubMat( A, 0,1, &G ); MatNestGetSubMat( A, 1,0, &D ); MatNestGetSubMat( A, 1,1, &C ); VecDuplicate( rA, &rG ); /* Get magnitude of K */ //px_MatGetAbsRowSum( K, rA ); //MatGetRowMax( K, rA, PETSC_NULL ); MatGetDiagonal( K, rA); VecSqrt( rA ); VecReciprocal( rA ); /* VecDot( rA,rA, &ra ); */ /* VecGetSize( rA, &N ); */ /* ra = PetscSqrtScalar( ra/N ); */ /* Get magnitude of G */ //px_MatGetAbsRowSum( G, rG ); //MatGetRowMax( G, rG, PETSC_NULL ); Mat A21_cpy; Mat Shat; Vec diag; /* same as rA*rA */ MatGetVecs( K, &diag, PETSC_NULL ); MatGetDiagonal( K, diag ); VecReciprocal( diag ); if( sym ) #if( PETSC_VERSION_MAJOR <= 2 ) MatTranspose( G, &A21_cpy ); #else MatTranspose( G, MAT_INITIAL_MATRIX, &A21_cpy ); #endif else {
bool PetscMatTools::CheckSymmetry(const Mat matrix, double tol) { Mat trans; #if (PETSC_VERSION_MAJOR == 3) //PETSc 3.x.x MatTranspose(matrix, MAT_INITIAL_MATRIX, &trans); #else MatTranspose(matrix, &trans); #endif bool is_symmetric = PetscMatTools::CheckEquality(matrix, trans, tol); PetscTools::Destroy(trans); return is_symmetric; }
PetscErrorCode MatDuplicate_Transpose(Mat N, MatDuplicateOption op, Mat* m) { Mat_Transpose *Na = (Mat_Transpose*)N->data; PetscErrorCode ierr; PetscFunctionBegin; if (op == MAT_COPY_VALUES) { ierr = MatTranspose(Na->A,MAT_INITIAL_MATRIX,m);CHKERRQ(ierr); } else if (op == MAT_DO_NOT_COPY_VALUES) { ierr = MatDuplicate(Na->A,MAT_DO_NOT_COPY_VALUES,m);CHKERRQ(ierr); ierr = MatTranspose(*m,MAT_INPLACE_MATRIX,m);CHKERRQ(ierr); } else SETERRQ(PetscObjectComm((PetscObject)N),PETSC_ERR_SUP,"MAT_SHARE_NONZERO_PATTERN not supported for this matrix type"); PetscFunctionReturn(0); }
int main(int argc,char **argv) { Mat A,B; PetscInt m = 7,n,i,rstart,rend,cols[3]; PetscErrorCode ierr; PetscScalar v[3]; PetscBool equal; const char *eq[2]; ierr = PetscInitialize(&argc,&argv,(char*)0,help);CHKERRQ(ierr); ierr = PetscViewerSetFormat(PETSC_VIEWER_STDOUT_WORLD,PETSC_VIEWER_ASCII_COMMON);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,"-m",&m,NULL);CHKERRQ(ierr); n = m; /* ------- Assemble matrix, --------- */ ierr = MatCreateAIJ(PETSC_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,m,n,0,0,0,0,&A);CHKERRQ(ierr); ierr = MatSetOption(A,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); if (!rstart) { cols[0] = 0; cols[1] = 1; v[0] = 2.0; v[1] = -1.0; ierr = MatSetValues(A,1,&rstart,2,cols,v,INSERT_VALUES);CHKERRQ(ierr); rstart++; } if (rend == m) { rend--; cols[0] = rend-1; cols[1] = rend; v[0] = -1.0; v[1] = 2.0; ierr = MatSetValues(A,1,&rend,2,cols,v,INSERT_VALUES);CHKERRQ(ierr); } v[0] = -1.0; v[1] = 2.0; v[2] = -1.0; for (i=rstart; i<rend; i++) { cols[0] = i-1; cols[1] = i; cols[2] = i+1; ierr = MatSetValues(A,1,&i,3,cols,v,INSERT_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatTranspose(A,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); ierr = MatEqual(A,B,&equal); eq[0] = "not equal"; eq[1] = "equal"; ierr = PetscPrintf(PETSC_COMM_WORLD,"Matrices are %s\n",eq[equal]);CHKERRQ(ierr); /* Free data structures */ ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = MatDestroy(&B);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
PetscErrorCode bsscr_GGt( Mat *_K2, Mat K, Mat G){ Mat K2; Mat Gtrans; PetscErrorCode ierr; PetscFunctionBegin; #if( PETSC_VERSION_MAJOR <= 2 ) ierr=MatTranspose(G, &Gtrans);CHKERRQ(ierr); #else ierr=MatTranspose(G, MAT_INITIAL_MATRIX,&Gtrans);CHKERRQ(ierr); #endif /* MAT_INITIAL_MATRIX -> creates K2 matrix : PETSC_DEFAULT for fill ratio: run with -info to find what it should be*/ ierr=MatMatMult( G, Gtrans, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &K2);CHKERRQ(ierr); Stg_MatDestroy(&Gtrans); *_K2=K2; PetscFunctionReturn(0); }
PetscErrorCode StokesSetupMatBlock10(Stokes *s) { PetscErrorCode ierr; PetscFunctionBeginUser; /* A[2] is minus transpose of A[1] */ ierr = MatTranspose(s->subA[1], MAT_INITIAL_MATRIX, &s->subA[2]);CHKERRQ(ierr); ierr = MatScale(s->subA[2], -1.0);CHKERRQ(ierr); ierr = MatSetOptionsPrefix(s->subA[2], "a10_");CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode PCSetUp_SPAI(PC pc) { PC_SPAI *ispai = (PC_SPAI*)pc->data; PetscErrorCode ierr; Mat AT; PetscFunctionBegin; init_SPAI(); if (ispai->sp) { ierr = ConvertMatToMatrix(ispai->comm_spai,pc->pmat,pc->pmat,&ispai->B);CHKERRQ(ierr); } else { /* Use the transpose to get the column nonzero structure. */ ierr = MatTranspose(pc->pmat,MAT_INITIAL_MATRIX,&AT);CHKERRQ(ierr); ierr = ConvertMatToMatrix(ispai->comm_spai,pc->pmat,AT,&ispai->B);CHKERRQ(ierr); ierr = MatDestroy(&AT);CHKERRQ(ierr); } /* Destroy the transpose */ /* Don't know how to do it. PETSc developers? */ /* construct SPAI preconditioner */ /* FILE *messages */ /* file for warning messages */ /* double epsilon */ /* tolerance */ /* int nbsteps */ /* max number of "improvement" steps per line */ /* int max */ /* max dimensions of is_I, q, etc. */ /* int maxnew */ /* max number of new entries per step */ /* int block_size */ /* block_size == 1 specifies scalar elments block_size == n specifies nxn constant-block elements block_size == 0 specifies variable-block elements */ /* int cache_size */ /* one of (1,2,3,4,5,6) indicting size of cache */ /* cache_size == 0 indicates no caching */ /* int verbose */ /* verbose == 0 specifies that SPAI is silent verbose == 1 prints timing and matrix statistics */ ierr = bspai(ispai->B,&ispai->M, stdout, ispai->epsilon, ispai->nbsteps, ispai->max, ispai->maxnew, ispai->block_size, ispai->cache_size, ispai->verbose);CHKERRQ(ierr); ierr = ConvertMatrixToMat(((PetscObject)pc)->comm,ispai->M,&ispai->PM);CHKERRQ(ierr); /* free the SPAI matrices */ sp_free_matrix(ispai->B); sp_free_matrix(ispai->M); PetscFunctionReturn(0); }
static PetscErrorCode CreateRestriction(DM dm1,DM dm2,Mat *mat) { DM da1,da2; PetscErrorCode ierr; Mat tmat; ierr = DMShellGetContext(dm1,(void**)&da1);CHKERRQ(ierr); ierr = DMShellGetContext(dm2,(void**)&da2);CHKERRQ(ierr); ierr = DMCreateInterpolation(da1,da2,&tmat,NULL);CHKERRQ(ierr); ierr = MatTranspose(tmat,MAT_INITIAL_MATRIX,mat);CHKERRQ(ierr); ierr = MatDestroy(&tmat);CHKERRQ(ierr); return 0; }
int main(int argc,char **args) { PetscErrorCode ierr; Mat A,AT,B,C; PetscViewer viewer; PetscBool flg; char file[PETSC_MAX_PATH_LEN]; PetscInitialize(&argc,&args,(char *)0,help); ierr = PetscOptionsGetString(PETSC_NULL,"-fA",file,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); if (!flg) SETERRQ(PETSC_COMM_WORLD,1,"Input fileA not specified"); ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,file,FILE_MODE_READ,&viewer);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatSetType(A,MATAIJ);CHKERRQ(ierr); ierr = MatLoad(A,viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); ierr = PetscOptionsGetString(PETSC_NULL,"-fB",file,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); if (!flg) SETERRQ(PETSC_COMM_WORLD,1,"Input fileB not specified"); ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,file,FILE_MODE_READ,&viewer);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&B);CHKERRQ(ierr); ierr = MatSetType(B,MATDENSE);CHKERRQ(ierr); ierr = MatLoad(B,viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); ierr = MatTranspose(A,MAT_INITIAL_MATRIX,&AT);CHKERRQ(ierr); ierr = MatMatMult(AT,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&C); ierr = PetscOptionsHasName(PETSC_NULL,"-view_C",&flg);CHKERRQ(ierr); if (flg){ ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,"C.dat",FILE_MODE_WRITE,&viewer);CHKERRQ(ierr); ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_NATIVE);CHKERRQ(ierr); ierr = MatView(C,viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); } ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = MatDestroy(&B);CHKERRQ(ierr); ierr = MatDestroy(&AT);CHKERRQ(ierr); ierr = MatDestroy(&C);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
int main(int argc,char **args) { Mat C,A; PetscScalar v; PetscInt i,j,m = 4,n = 4,Ii,J,Istart,Iend; PetscMPIInt rank,size; PetscErrorCode ierr; PetscBool equal=PETSC_FALSE; PetscInitialize(&argc,&args,(char *)0,help); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-m",&m,PETSC_NULL);CHKERRQ(ierr); n = m; ierr = MatCreateAIJ(PETSC_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE, m*n,m*n,5,PETSC_NULL,5,PETSC_NULL,&C);CHKERRQ(ierr); /* create the symmetric matrix for the five point stencil */ ierr = MatGetOwnershipRange(C,&Istart,&Iend);CHKERRQ(ierr); for (Ii=Istart; Ii<Iend; Ii++) { v = -1.0; i = Ii/n; j = Ii - i*n; if (i>0) {J = Ii - n; ierr = MatSetValues(C,1,&Ii,1,&J,&v,INSERT_VALUES);CHKERRQ(ierr);} if (i<m-1) {J = Ii + n; ierr = MatSetValues(C,1,&Ii,1,&J,&v,INSERT_VALUES);CHKERRQ(ierr);} if (j>0) {J = Ii - 1; ierr = MatSetValues(C,1,&Ii,1,&J,&v,INSERT_VALUES);CHKERRQ(ierr);} if (j<n-1) {J = Ii + 1; ierr = MatSetValues(C,1,&Ii,1,&J,&v,INSERT_VALUES);CHKERRQ(ierr);} v = 4.0; ierr = MatSetValues(C,1,&Ii,1,&Ii,&v,INSERT_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatTranspose(C,MAT_INITIAL_MATRIX,&A);CHKERRQ(ierr); ierr = MatEqual(C,A,&equal);CHKERRQ(ierr); if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"C != C^T"); ierr = MatDestroy(&C);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
int main(int argc,char **args) { Mat C,A,B,D; PetscErrorCode ierr; PetscInt i,j,ntypes,bs,mbs,m,block,d_nz=6, o_nz=3,col[3],row,verbose=0; PetscMPIInt size,rank; const MatType type[9]; char file[PETSC_MAX_PATH_LEN]; PetscViewer fd; PetscBool equal,flg_loadmat,flg; PetscScalar value[3]; PetscInitialize(&argc,&args,(char *)0,help); ierr = PetscOptionsGetInt(PETSC_NULL,"-verbose",&verbose,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetString(PETSC_NULL,"-f",file,PETSC_MAX_PATH_LEN,&flg_loadmat);CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = PetscOptionsHasName(PETSC_NULL,"-testseqaij",&flg);CHKERRQ(ierr); if (flg){ if (size == 1){ type[0] = MATSEQAIJ; } else { type[0] = MATMPIAIJ; } } else { type[0] = MATAIJ; } if (size == 1){ ntypes = 3; type[1] = MATSEQBAIJ; type[2] = MATSEQSBAIJ; } else { ntypes = 3; type[1] = MATMPIBAIJ; type[2] = MATMPISBAIJ; } /* input matrix C */ if (flg_loadmat){ /* Open binary file. */ ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,file,FILE_MODE_READ,&fd);CHKERRQ(ierr); /* Load a baij matrix, then destroy the viewer. */ ierr = MatCreate(PETSC_COMM_WORLD,&C);CHKERRQ(ierr); if (size == 1){ ierr = MatSetType(C,MATSEQBAIJ);CHKERRQ(ierr); } else { ierr = MatSetType(C,MATMPIBAIJ);CHKERRQ(ierr); } ierr = MatLoad(C,fd);CHKERRQ(ierr); ierr = PetscViewerDestroy(&fd);CHKERRQ(ierr); } else { /* Create a baij mat with bs>1 */ bs = 2; mbs=8; ierr = PetscOptionsGetInt(PETSC_NULL,"-mbs",&mbs,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-bs",&bs,PETSC_NULL);CHKERRQ(ierr); if (bs <= 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG," bs must be >1 in this case"); m = mbs*bs; ierr = MatCreateBAIJ(PETSC_COMM_WORLD,bs,PETSC_DECIDE,PETSC_DECIDE,m,m,d_nz,PETSC_NULL,o_nz,PETSC_NULL,&C);CHKERRQ(ierr); for (block=0; block<mbs; block++){ /* diagonal blocks */ value[0] = -1.0; value[1] = 4.0; value[2] = -1.0; for (i=1+block*bs; i<bs-1+block*bs; i++) { col[0] = i-1; col[1] = i; col[2] = i+1; ierr = MatSetValues(C,1,&i,3,col,value,INSERT_VALUES);CHKERRQ(ierr); } i = bs - 1+block*bs; col[0] = bs - 2+block*bs; col[1] = bs - 1+block*bs; value[0]=-1.0; value[1]=4.0; ierr = MatSetValues(C,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr); i = 0+block*bs; col[0] = 0+block*bs; col[1] = 1+block*bs; value[0]=4.0; value[1] = -1.0; ierr = MatSetValues(C,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr); } /* off-diagonal blocks */ value[0]=-1.0; for (i=0; i<(mbs-1)*bs; i++){ col[0]=i+bs; ierr = MatSetValues(C,1,&i,1,col,value,INSERT_VALUES);CHKERRQ(ierr); col[0]=i; row=i+bs; ierr = MatSetValues(C,1,&row,1,col,value,INSERT_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); } { /* Check the symmetry of C because it will be converted to a sbaij matrix */ Mat Ctrans; ierr = MatTranspose(C, MAT_INITIAL_MATRIX,&Ctrans); ierr = MatEqual(C, Ctrans, &flg);CHKERRQ(ierr); if (flg) { ierr = MatSetOption(C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); } else { SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"C must be symmetric for this example"); } ierr = MatDestroy(&Ctrans);CHKERRQ(ierr); } //ierr = MatView(C,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); /* convert C to other formats */ for (i=0; i<ntypes; i++) { ierr = MatConvert(C,type[i],MAT_INITIAL_MATRIX,&A);CHKERRQ(ierr); ierr = MatMultEqual(A,C,10,&equal);CHKERRQ(ierr); if (!equal) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMETYPE,"Error in conversion from BAIJ to %s",type[i]); for (j=i+1; j<ntypes; j++) { if (verbose>0) { ierr = PetscPrintf(PETSC_COMM_WORLD," \n[%d] test conversion between %s and %s\n",rank,type[i],type[j]);CHKERRQ(ierr); } if (!rank && verbose) printf("Convert %s A to %s B\n",type[i],type[j]); ierr = MatConvert(A,type[j],MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); /* if (j == 2){ ierr = PetscPrintf(PETSC_COMM_SELF," A: %s\n",type[i]);CHKERRQ(ierr); ierr = MatView(A,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF," B: %s\n",type[j]);CHKERRQ(ierr); ierr = MatView(B,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } */ ierr = MatMultEqual(A,B,10,&equal);CHKERRQ(ierr); if (!equal) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMETYPE,"Error in conversion from %s to %s",type[i],type[j]); if (size == 1 || j != 2){ /* Matconvert from mpisbaij mat to other formats are not supported */ if (!rank && verbose) printf("Convert %s B to %s D\n",type[j],type[i]); ierr = MatConvert(B,type[i],MAT_INITIAL_MATRIX,&D);CHKERRQ(ierr); ierr = MatMultEqual(B,D,10,&equal);CHKERRQ(ierr); if (!equal) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMETYPE,"Error in conversion from %s to %s",type[j],type[i]); ierr = MatDestroy(&D);CHKERRQ(ierr); } ierr = MatDestroy(&B);CHKERRQ(ierr); ierr = MatDestroy(&D);CHKERRQ(ierr); } /* Test in-place convert */ if (size == 1){ /* size > 1 is not working yet! */ j = (i+1)%ntypes; /* printf("[%d] i: %d, j: %d\n",rank,i,j); */ ierr = MatConvert(A,type[j],MAT_REUSE_MATRIX,&A);CHKERRQ(ierr); } ierr = MatDestroy(&A);CHKERRQ(ierr); } ierr = MatDestroy(&C);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
int main(int argc,char **args) { Mat A,Atrans,sA,*submatA,*submatsA; PetscErrorCode ierr; PetscMPIInt size,rank; PetscInt bs=1,mbs=10,ov=1,i,j,k,*rows,*cols,nd=2,*idx,rstart,rend,sz,M,N,Mbs; PetscScalar *vals,rval,one=1.0; IS *is1,*is2; PetscRandom rand; PetscBool flg,TestOverlap,TestSubMat,TestAllcols,test_sorted=PETSC_FALSE; PetscInt vid = -1; #if defined(PETSC_USE_LOG) PetscLogStage stages[2]; #endif ierr = PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr; ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-mat_block_size",&bs,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-mat_mbs",&mbs,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-ov",&ov,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-nd",&nd,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-view_id",&vid,NULL);CHKERRQ(ierr); ierr = PetscOptionsHasName(NULL,NULL, "-test_overlap", &TestOverlap);CHKERRQ(ierr); ierr = PetscOptionsHasName(NULL,NULL, "-test_submat", &TestSubMat);CHKERRQ(ierr); ierr = PetscOptionsHasName(NULL,NULL, "-test_allcols", &TestAllcols);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-test_sorted",&test_sorted,NULL);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatSetSizes(A,mbs*bs,mbs*bs,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); ierr = MatSetType(A,MATBAIJ);CHKERRQ(ierr); ierr = MatSeqBAIJSetPreallocation(A,bs,PETSC_DEFAULT,NULL);CHKERRQ(ierr); ierr = MatMPIBAIJSetPreallocation(A,bs,PETSC_DEFAULT,NULL,PETSC_DEFAULT,NULL);CHKERRQ(ierr); ierr = PetscRandomCreate(PETSC_COMM_WORLD,&rand);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rand);CHKERRQ(ierr); ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); Mbs = M/bs; ierr = PetscMalloc1(bs,&rows);CHKERRQ(ierr); ierr = PetscMalloc1(bs,&cols);CHKERRQ(ierr); ierr = PetscMalloc1(bs*bs,&vals);CHKERRQ(ierr); ierr = PetscMalloc1(M,&idx);CHKERRQ(ierr); /* Now set blocks of values */ for (j=0; j<bs*bs; j++) vals[j] = 0.0; for (i=0; i<Mbs; i++) { cols[0] = i*bs; rows[0] = i*bs; for (j=1; j<bs; j++) { rows[j] = rows[j-1]+1; cols[j] = cols[j-1]+1; } ierr = MatSetValues(A,bs,rows,bs,cols,vals,ADD_VALUES);CHKERRQ(ierr); } /* second, add random blocks */ for (i=0; i<20*bs; i++) { ierr = PetscRandomGetValue(rand,&rval);CHKERRQ(ierr); cols[0] = bs*(PetscInt)(PetscRealPart(rval)*Mbs); ierr = PetscRandomGetValue(rand,&rval);CHKERRQ(ierr); rows[0] = rstart + bs*(PetscInt)(PetscRealPart(rval)*mbs); for (j=1; j<bs; j++) { rows[j] = rows[j-1]+1; cols[j] = cols[j-1]+1; } for (j=0; j<bs*bs; j++) { ierr = PetscRandomGetValue(rand,&rval);CHKERRQ(ierr); vals[j] = rval; } ierr = MatSetValues(A,bs,rows,bs,cols,vals,ADD_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* make A a symmetric matrix: A <- A^T + A */ ierr = MatTranspose(A,MAT_INITIAL_MATRIX, &Atrans);CHKERRQ(ierr); ierr = MatAXPY(A,one,Atrans,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); ierr = MatDestroy(&Atrans);CHKERRQ(ierr); ierr = MatTranspose(A,MAT_INITIAL_MATRIX, &Atrans);CHKERRQ(ierr); ierr = MatEqual(A, Atrans, &flg);CHKERRQ(ierr); if (flg) { ierr = MatSetOption(A,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); } else SETERRQ(PETSC_COMM_SELF,1,"A+A^T is non-symmetric"); ierr = MatDestroy(&Atrans);CHKERRQ(ierr); /* create a SeqSBAIJ matrix sA (= A) */ ierr = MatConvert(A,MATSBAIJ,MAT_INITIAL_MATRIX,&sA);CHKERRQ(ierr); if (vid >= 0 && vid < size) { if (!rank) printf("A: \n"); ierr = MatView(A,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); if (!rank) printf("sA: \n"); ierr = MatView(sA,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } /* Test sA==A through MatMult() */ ierr = MatMultEqual(A,sA,10,&flg);CHKERRQ(ierr); if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Error in MatConvert(): A != sA"); /* Test MatIncreaseOverlap() */ ierr = PetscMalloc1(nd,&is1);CHKERRQ(ierr); ierr = PetscMalloc1(nd,&is2);CHKERRQ(ierr); for (i=0; i<nd; i++) { if (!TestAllcols) { ierr = PetscRandomGetValue(rand,&rval);CHKERRQ(ierr); sz = (PetscInt)((0.5+0.2*PetscRealPart(rval))*mbs); /* 0.5*mbs < sz < 0.7*mbs */ for (j=0; j<sz; j++) { ierr = PetscRandomGetValue(rand,&rval);CHKERRQ(ierr); idx[j*bs] = bs*(PetscInt)(PetscRealPart(rval)*Mbs); for (k=1; k<bs; k++) idx[j*bs+k] = idx[j*bs]+k; } ierr = ISCreateGeneral(PETSC_COMM_SELF,sz*bs,idx,PETSC_COPY_VALUES,is1+i);CHKERRQ(ierr); ierr = ISCreateGeneral(PETSC_COMM_SELF,sz*bs,idx,PETSC_COPY_VALUES,is2+i);CHKERRQ(ierr); if (rank == vid) { ierr = PetscPrintf(PETSC_COMM_SELF," [%d] IS sz[%d]: %d\n",rank,i,sz);CHKERRQ(ierr); ierr = ISView(is2[i],PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); } } else { /* Test all rows and colums */ sz = M; ierr = ISCreateStride(PETSC_COMM_SELF,sz,0,1,is1+i);CHKERRQ(ierr); ierr = ISCreateStride(PETSC_COMM_SELF,sz,0,1,is2+i);CHKERRQ(ierr); if (rank == vid) { PetscBool colflag; ierr = ISIdentity(is2[i],&colflag);CHKERRQ(ierr); printf("[%d] is2[%d], colflag %d\n",rank,(int)i,(int)colflag); ierr = ISView(is2[i],PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); } } } ierr = PetscLogStageRegister("MatOv_SBAIJ",&stages[0]);CHKERRQ(ierr); ierr = PetscLogStageRegister("MatOv_BAIJ",&stages[1]);CHKERRQ(ierr); /* Test MatIncreaseOverlap */ if (TestOverlap) { ierr = PetscLogStagePush(stages[0]);CHKERRQ(ierr); ierr = MatIncreaseOverlap(sA,nd,is2,ov);CHKERRQ(ierr); ierr = PetscLogStagePop();CHKERRQ(ierr); ierr = PetscLogStagePush(stages[1]);CHKERRQ(ierr); ierr = MatIncreaseOverlap(A,nd,is1,ov);CHKERRQ(ierr); ierr = PetscLogStagePop();CHKERRQ(ierr); if (rank == vid) { printf("\n[%d] IS from BAIJ:\n",rank); ierr = ISView(is1[0],PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); printf("\n[%d] IS from SBAIJ:\n",rank); ierr = ISView(is2[0],PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); } for (i=0; i<nd; ++i) { ierr = ISEqual(is1[i],is2[i],&flg);CHKERRQ(ierr); if (!flg) { if (!rank) { ierr = ISSort(is1[i]);CHKERRQ(ierr); /* ISView(is1[i],PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); */ ierr = ISSort(is2[i]);CHKERRQ(ierr); /* ISView(is2[i],PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); */ } SETERRQ1(PETSC_COMM_SELF,1,"i=%D, is1 != is2",i); } } } /* Test MatCreateSubmatrices */ if (TestSubMat) { if (test_sorted) { for (i = 0; i < nd; ++i) { ierr = ISSort(is1[i]);CHKERRQ(ierr); } } ierr = MatCreateSubMatrices(A,nd,is1,is1,MAT_INITIAL_MATRIX,&submatA);CHKERRQ(ierr); ierr = MatCreateSubMatrices(sA,nd,is1,is1,MAT_INITIAL_MATRIX,&submatsA);CHKERRQ(ierr); ierr = MatMultEqual(A,sA,10,&flg);CHKERRQ(ierr); if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"A != sA"); /* Now test MatCreateSubmatrices with MAT_REUSE_MATRIX option */ ierr = MatCreateSubMatrices(A,nd,is1,is1,MAT_REUSE_MATRIX,&submatA);CHKERRQ(ierr); ierr = MatCreateSubMatrices(sA,nd,is1,is1,MAT_REUSE_MATRIX,&submatsA);CHKERRQ(ierr); ierr = MatMultEqual(A,sA,10,&flg);CHKERRQ(ierr); if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"MatCreateSubmatrices(): A != sA"); ierr = MatDestroySubMatrices(nd,&submatA);CHKERRQ(ierr); ierr = MatDestroySubMatrices(nd,&submatsA);CHKERRQ(ierr); } /* Free allocated memory */ for (i=0; i<nd; ++i) { ierr = ISDestroy(&is1[i]);CHKERRQ(ierr); ierr = ISDestroy(&is2[i]);CHKERRQ(ierr); } ierr = PetscFree(is1);CHKERRQ(ierr); ierr = PetscFree(is2);CHKERRQ(ierr); ierr = PetscFree(idx);CHKERRQ(ierr); ierr = PetscFree(rows);CHKERRQ(ierr); ierr = PetscFree(cols);CHKERRQ(ierr); ierr = PetscFree(vals);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = MatDestroy(&sA);CHKERRQ(ierr); ierr = PetscRandomDestroy(&rand);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
void _Stokes_SLE_PenaltySolver_Solve( void* solver,void* stokesSLE ) { Stokes_SLE_PenaltySolver* self = (Stokes_SLE_PenaltySolver*)solver; Stokes_SLE* sle = (Stokes_SLE*)stokesSLE; /* Create shortcuts to stuff needed on sle */ Mat kMatrix = sle->kStiffMat->matrix; Mat gradMat = sle->gStiffMat->matrix; Mat divMat = NULL; Mat C_Mat = sle->cStiffMat->matrix; Vec uVec = sle->uSolnVec->vector; Vec pVec = sle->pSolnVec->vector; Vec fVec = sle->fForceVec->vector; Vec hVec = sle->hForceVec->vector; Vec hTempVec; Vec fTempVec; Vec penalty; Mat GTrans, kHat; KSP ksp_v; double negOne=-1.0; double one=1.0; Mat C_InvMat; Vec diagC; PC pc; int rank; MPI_Comm_rank( MPI_COMM_WORLD, &rank ); Journal_DPrintf( self->debug, "In %s():\n", __func__ ); VecDuplicate( hVec, &hTempVec ); VecDuplicate( fVec, &fTempVec ); VecDuplicate( pVec, &diagC ); if( sle->dStiffMat == NULL ) { Journal_DPrintf( self->debug, "Div matrix == NULL : Problem is assumed to be symmetric. ie Div = GTrans \n"); #if( PETSC_VERSION_MAJOR <= 2 ) MatTranspose( gradMat, >rans ); #else MatTranspose( gradMat, MAT_INITIAL_MATRIX, >rans ); #endif divMat = GTrans; } else { MatType type; PetscInt size[2]; MatGetType( sle->dStiffMat->matrix, &type ); MatGetLocalSize( sle->dStiffMat->matrix, size + 0, size + 1 ); /* make a copy we can play with */ MatCreate( sle->comm, >rans ); MatSetSizes( GTrans, size[0], size[1], PETSC_DECIDE, PETSC_DECIDE ); MatSetType( GTrans, type ); #if (((PETSC_VERSION_MAJOR==3) && (PETSC_VERSION_MINOR>=3)) || (PETSC_VERSION_MAJOR>3) ) MatSetUp(GTrans); #endif MatCopy( sle->dStiffMat->matrix, GTrans, DIFFERENT_NONZERO_PATTERN ); divMat = GTrans; } Stokes_SLE_PenaltySolver_MakePenalty( self, sle, &penalty ); /* Create CInv */ MatGetDiagonal( C_Mat, diagC ); VecReciprocal( diagC ); VecPointwiseMult( diagC, penalty, diagC ); { /* Print the maximum and minimum penalties in my system. */ PetscInt idx; PetscReal min, max; VecMin( diagC, &idx, &min ); VecMax( diagC, &idx, &max ); if( rank == 0 ) { printf( "PENALTY RANGE:\n" ); printf( " MIN: %e\n", min ); printf( " MAX: %e\n", max ); } } MatDiagonalSet( C_Mat, diagC, INSERT_VALUES ); C_InvMat = C_Mat; /* Use pointer CInv since C has been inverted */ /* Build RHS : rhs = f - GCInv h */ MatMult( C_InvMat, hVec, hTempVec ); /* hTempVec = C_InvMat * hVec */ VecScale( hTempVec, -1.0 ); MatMult( gradMat, hTempVec, fTempVec ); #if 0 VecPointwiseMult( fTempVec, penalty, fTempVec ); { /* Print the maximum and minimum penalties in my system. */ PetscInt idx; PetscReal min, max; VecMin( fTempVec, &idx, &min ); VecMax( fTempVec, &idx, &max ); printf( "PENALTY RANGE:\n" ); printf( " MIN: %e\n", min ); printf( " MAX: %e\n", max ); } #endif VecAXPY( fTempVec, 1.0, fVec ); /*MatMultAdd( gradMat, hTempVec, fVec, fTempVec );*/ /* Build G CInv GTrans */ /* MatTranspose( gradMat, >rans ); */ /* since CInv is diagonal we can just scale mat entries by the diag vector */ MatDiagonalScale( divMat, diagC, PETSC_NULL ); /* Div = CInve Div */ MatMatMult( gradMat, divMat, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &kHat ); /*MatDiagonalScale( kHat, penalty, PETSC_NULL );*/ MatScale( kHat, -1.0 ); MatAXPY( kMatrix, 1.0, kHat, SAME_NONZERO_PATTERN ); /* Setup solver context and make sure that it uses a direct solver */ KSPCreate( sle->comm, &ksp_v ); Stg_KSPSetOperators( ksp_v, kMatrix, kMatrix, DIFFERENT_NONZERO_PATTERN ); KSPSetType( ksp_v, KSPPREONLY ); KSPGetPC( ksp_v, &pc ); PCSetType( pc, PCLU ); KSPSetFromOptions( ksp_v ); KSPSolve( ksp_v, fTempVec, uVec ); /* Recover p */ if( sle->dStiffMat == NULL ) { /* since Div was modified when C is diagonal, re build the transpose */ if( GTrans != PETSC_NULL ) Stg_MatDestroy(>rans ); #if( PETSC_VERSION_MAJOR <= 2 ) MatTranspose( gradMat, >rans ); #else MatTranspose( gradMat, MAT_INITIAL_MATRIX, >rans ); #endif divMat = GTrans; } else { /* never modified Div_null so set divMat to point back to it */ divMat = sle->dStiffMat->matrix; } MatMult( divMat, uVec, hTempVec ); /* hTemp = Div v */ VecAYPX( hTempVec, negOne, hVec ); /* hTemp = H - hTemp : hTemp = H - Div v */ MatMult( C_InvMat, hTempVec, pVec ); /* p = CInv hTemp : p = CInv ( H - Div v ) */ Stg_MatDestroy(&kHat ); if( fTempVec != PETSC_NULL ) Stg_VecDestroy(&fTempVec ); if( hTempVec != PETSC_NULL ) Stg_VecDestroy(&hTempVec ); if( diagC != PETSC_NULL ) Stg_VecDestroy(&diagC ); if( ksp_v != PETSC_NULL ) Stg_KSPDestroy(&ksp_v ); if( GTrans != PETSC_NULL ) Stg_MatDestroy(>rans ); }
int main(int argc,char **argv) { PetscErrorCode ierr; Vec t,v; Mat Q,M; BV X,Y; PetscInt i,j,n=10,kx=6,lx=3,ky=5,ly=2; PetscScalar *q,*z; PetscReal nrm; PetscViewer view; PetscBool verbose,trans; SlepcInitialize(&argc,&argv,(char*)0,help); ierr = PetscOptionsGetInt(NULL,"-n",&n,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,"-kx",&kx,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,"-lx",&lx,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,"-ky",&ky,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,"-ly",&ly,NULL);CHKERRQ(ierr); ierr = PetscOptionsHasName(NULL,"-verbose",&verbose);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"First BV with %D active columns (%D leading columns) of dimension %D.\n",kx,lx,n);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Second BV with %D active columns (%D leading columns) of dimension %D.\n",ky,ly,n);CHKERRQ(ierr); /* Create template vector */ ierr = VecCreate(PETSC_COMM_WORLD,&t);CHKERRQ(ierr); ierr = VecSetSizes(t,PETSC_DECIDE,n);CHKERRQ(ierr); ierr = VecSetFromOptions(t);CHKERRQ(ierr); /* Create BV object X */ ierr = BVCreate(PETSC_COMM_WORLD,&X);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)X,"X");CHKERRQ(ierr); ierr = BVSetSizesFromVec(X,t,kx+2);CHKERRQ(ierr); /* two extra columns to test active columns */ ierr = BVSetFromOptions(X);CHKERRQ(ierr); ierr = BVSetActiveColumns(X,lx,kx);CHKERRQ(ierr); /* Set up viewer */ ierr = PetscViewerASCIIGetStdout(PETSC_COMM_WORLD,&view);CHKERRQ(ierr); if (verbose) { ierr = PetscViewerPushFormat(view,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); } /* Fill X entries */ for (j=0;j<kx+2;j++) { ierr = BVGetColumn(X,j,&v);CHKERRQ(ierr); ierr = VecZeroEntries(v);CHKERRQ(ierr); for (i=0;i<4;i++) { if (i+j<n) { ierr = VecSetValue(v,i+j,(PetscScalar)(3*i+j-2),INSERT_VALUES);CHKERRQ(ierr); } } ierr = VecAssemblyBegin(v);CHKERRQ(ierr); ierr = VecAssemblyEnd(v);CHKERRQ(ierr); ierr = BVRestoreColumn(X,j,&v);CHKERRQ(ierr); } if (verbose) { ierr = BVView(X,view);CHKERRQ(ierr); } /* Create BV object Y */ ierr = BVCreate(PETSC_COMM_WORLD,&Y);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)Y,"Y");CHKERRQ(ierr); ierr = BVSetSizesFromVec(Y,t,ky+1);CHKERRQ(ierr); ierr = BVSetFromOptions(Y);CHKERRQ(ierr); ierr = BVSetActiveColumns(Y,ly,ky);CHKERRQ(ierr); /* Fill Y entries */ for (j=0;j<ky+1;j++) { ierr = BVGetColumn(Y,j,&v);CHKERRQ(ierr); ierr = VecSet(v,(PetscScalar)(j+1)/4.0);CHKERRQ(ierr); ierr = BVRestoreColumn(Y,j,&v);CHKERRQ(ierr); } if (verbose) { ierr = BVView(Y,view);CHKERRQ(ierr); } /* Create Mat */ ierr = MatCreateSeqDense(PETSC_COMM_SELF,kx,ky,NULL,&Q);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)Q,"Q");CHKERRQ(ierr); ierr = MatDenseGetArray(Q,&q);CHKERRQ(ierr); for (i=0;i<kx;i++) for (j=0;j<ky;j++) q[i+j*kx] = (i<j)? 2.0: -0.5; ierr = MatDenseRestoreArray(Q,&q);CHKERRQ(ierr); if (verbose) { ierr = MatView(Q,NULL);CHKERRQ(ierr); } /* Test BVMult */ ierr = BVMult(Y,2.0,1.0,X,Q);CHKERRQ(ierr); if (verbose) { ierr = PetscPrintf(PETSC_COMM_WORLD,"After BVMult - - - - - - - - -\n");CHKERRQ(ierr); ierr = BVView(Y,view);CHKERRQ(ierr); } /* Test BVMultVec */ ierr = BVGetColumn(Y,0,&v);CHKERRQ(ierr); ierr = PetscMalloc1(kx-lx,&z);CHKERRQ(ierr); z[0] = 2.0; for (i=1;i<kx-lx;i++) z[i] = -0.5*z[i-1]; ierr = BVMultVec(X,-1.0,1.0,v,z);CHKERRQ(ierr); ierr = PetscFree(z);CHKERRQ(ierr); ierr = BVRestoreColumn(Y,0,&v);CHKERRQ(ierr); if (verbose) { ierr = PetscPrintf(PETSC_COMM_WORLD,"After BVMultVec - - - - - - -\n");CHKERRQ(ierr); ierr = BVView(Y,view);CHKERRQ(ierr); } /* Test BVDot */ ierr = MatCreateSeqDense(PETSC_COMM_SELF,ky,kx,NULL,&M);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)M,"M");CHKERRQ(ierr); ierr = BVDot(X,Y,M);CHKERRQ(ierr); if (verbose) { ierr = PetscPrintf(PETSC_COMM_WORLD,"After BVDot - - - - - - - - -\n");CHKERRQ(ierr); ierr = MatView(M,NULL);CHKERRQ(ierr); } /* Test BVDotVec */ ierr = BVGetColumn(Y,0,&v);CHKERRQ(ierr); ierr = PetscMalloc1(kx-lx,&z);CHKERRQ(ierr); ierr = BVDotVec(X,v,z);CHKERRQ(ierr); ierr = BVRestoreColumn(Y,0,&v);CHKERRQ(ierr); if (verbose) { ierr = PetscPrintf(PETSC_COMM_WORLD,"After BVDotVec - - - - - - -\n");CHKERRQ(ierr); ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,kx-lx,z,&v);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)v,"z");CHKERRQ(ierr); ierr = VecView(v,view);CHKERRQ(ierr); ierr = VecDestroy(&v);CHKERRQ(ierr); } ierr = PetscFree(z);CHKERRQ(ierr); /* Test BVMultInPlace and BVScale */ ierr = PetscOptionsHasName(NULL,"-trans",&trans);CHKERRQ(ierr); if (trans) { Mat Qt; ierr = MatTranspose(Q,MAT_INITIAL_MATRIX,&Qt);CHKERRQ(ierr); ierr = BVMultInPlaceTranspose(X,Qt,lx+1,ky);CHKERRQ(ierr); ierr = MatDestroy(&Qt);CHKERRQ(ierr); } else { ierr = BVMultInPlace(X,Q,lx+1,ky);CHKERRQ(ierr); } ierr = BVScale(X,2.0);CHKERRQ(ierr); if (verbose) { ierr = PetscPrintf(PETSC_COMM_WORLD,"After BVMultInPlace - - - - -\n");CHKERRQ(ierr); ierr = BVView(X,view);CHKERRQ(ierr); } /* Test BVNorm */ ierr = BVNormColumn(X,lx,NORM_2,&nrm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"2-Norm or X[%D] = %g\n",lx,(double)nrm);CHKERRQ(ierr); ierr = BVNorm(X,NORM_FROBENIUS,&nrm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Frobenius Norm or X = %g\n",(double)nrm);CHKERRQ(ierr); ierr = BVDestroy(&X);CHKERRQ(ierr); ierr = BVDestroy(&Y);CHKERRQ(ierr); ierr = MatDestroy(&Q);CHKERRQ(ierr); ierr = MatDestroy(&M);CHKERRQ(ierr); ierr = VecDestroy(&t);CHKERRQ(ierr); ierr = SlepcFinalize(); return 0; }
int main(int argc,char **argv) { Mat mat,tmat = 0; PetscInt m = 7,n,i,j,rstart,rend,rect = 0; PetscErrorCode ierr; PetscMPIInt size,rank; PetscBool flg; PetscScalar v, alpha; PetscReal normf,normi,norm1; ierr = PetscInitialize(&argc,&argv,(char*)0,help);CHKERRQ(ierr); ierr = PetscViewerSetFormat(PETSC_VIEWER_STDOUT_WORLD,PETSC_VIEWER_ASCII_COMMON);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,"-m",&m,NULL);CHKERRQ(ierr); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); n = m; ierr = PetscOptionsHasName(NULL,"-rectA",&flg);CHKERRQ(ierr); if (flg) {n += 2; rect = 1;} ierr = PetscOptionsHasName(NULL,"-rectB",&flg);CHKERRQ(ierr); if (flg) {n -= 2; rect = 1;} /* ------- Assemble matrix, test MatValid() --------- */ ierr = MatCreate(PETSC_COMM_WORLD,&mat);CHKERRQ(ierr); ierr = MatSetSizes(mat,PETSC_DECIDE,PETSC_DECIDE,m,n);CHKERRQ(ierr); ierr = MatSetFromOptions(mat);CHKERRQ(ierr); ierr = MatSetUp(mat);CHKERRQ(ierr); ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr); for (i=rstart; i<rend; i++) { for (j=0; j<n; j++) { v = 10.0*i+j; ierr = MatSetValues(mat,1,&i,1,&j,&v,INSERT_VALUES);CHKERRQ(ierr); } } ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* ----------------- Test MatNorm() ----------------- */ ierr = MatNorm(mat,NORM_FROBENIUS,&normf);CHKERRQ(ierr); ierr = MatNorm(mat,NORM_1,&norm1);CHKERRQ(ierr); ierr = MatNorm(mat,NORM_INFINITY,&normi);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"original A: Frobenious norm = %G, one norm = %G, infinity norm = %G\n", normf,norm1,normi);CHKERRQ(ierr); ierr = MatView(mat,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); /* --------------- Test MatTranspose() -------------- */ ierr = PetscOptionsHasName(NULL,"-in_place",&flg);CHKERRQ(ierr); if (!rect && flg) { ierr = MatTranspose(mat,MAT_REUSE_MATRIX,&mat);CHKERRQ(ierr); /* in-place transpose */ tmat = mat; mat = 0; } else { /* out-of-place transpose */ ierr = MatTranspose(mat,MAT_INITIAL_MATRIX,&tmat);CHKERRQ(ierr); } /* ----------------- Test MatNorm() ----------------- */ /* Print info about transpose matrix */ ierr = MatNorm(tmat,NORM_FROBENIUS,&normf);CHKERRQ(ierr); ierr = MatNorm(tmat,NORM_1,&norm1);CHKERRQ(ierr); ierr = MatNorm(tmat,NORM_INFINITY,&normi);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"B = A^T: Frobenious norm = %G, one norm = %G, infinity norm = %G\n", normf,norm1,normi);CHKERRQ(ierr); ierr = MatView(tmat,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); /* ----------------- Test MatAXPY(), MatAYPX() ----------------- */ if (mat && !rect) { alpha = 1.0; ierr = PetscOptionsGetScalar(NULL,"-alpha",&alpha,NULL);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"MatAXPY: B = B + alpha * A\n");CHKERRQ(ierr); ierr = MatAXPY(tmat,alpha,mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); ierr = MatView(tmat,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"MatAYPX: B = alpha*B + A\n");CHKERRQ(ierr); ierr = MatAYPX(tmat,alpha,mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); ierr = MatView(tmat,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } { Mat C; alpha = 1.0; ierr = PetscPrintf(PETSC_COMM_WORLD,"MatAXPY: C = C + alpha * A, C=A, SAME_NONZERO_PATTERN\n");CHKERRQ(ierr); ierr = MatDuplicate(mat,MAT_COPY_VALUES,&C);CHKERRQ(ierr); ierr = MatAXPY(C,alpha,mat,SAME_NONZERO_PATTERN);CHKERRQ(ierr); ierr = MatView(C,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = MatDestroy(&C);CHKERRQ(ierr); } { Mat matB; /* get matB that has nonzeros of mat in all even numbers of row and col */ ierr = MatCreate(PETSC_COMM_WORLD,&matB);CHKERRQ(ierr); ierr = MatSetSizes(matB,PETSC_DECIDE,PETSC_DECIDE,m,n);CHKERRQ(ierr); ierr = MatSetFromOptions(matB);CHKERRQ(ierr); ierr = MatSetUp(matB);CHKERRQ(ierr); ierr = MatGetOwnershipRange(matB,&rstart,&rend);CHKERRQ(ierr); if (rstart % 2 != 0) rstart++; for (i=rstart; i<rend; i += 2) { for (j=0; j<n; j += 2) { v = 10.0*i+j; ierr = MatSetValues(matB,1,&i,1,&j,&v,INSERT_VALUES);CHKERRQ(ierr); } } ierr = MatAssemblyBegin(matB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(matB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); PetscPrintf(PETSC_COMM_WORLD," A: original matrix:\n"); ierr = MatView(mat,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); PetscPrintf(PETSC_COMM_WORLD," B(a subset of A):\n"); ierr = MatView(matB,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"MatAXPY: B = B + alpha * A, SUBSET_NONZERO_PATTERN\n");CHKERRQ(ierr); ierr = MatAXPY(mat,alpha,matB,SUBSET_NONZERO_PATTERN);CHKERRQ(ierr); ierr = MatView(mat,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = MatDestroy(&matB);CHKERRQ(ierr); } /* Free data structures */ if (mat) {ierr = MatDestroy(&mat);CHKERRQ(ierr);} if (tmat) {ierr = MatDestroy(&tmat);CHKERRQ(ierr);} ierr = PetscFinalize(); return 0; }
PetscErrorCode PCGAMGFilterGraph(Mat *a_Gmat,const PetscReal vfilter,const PetscBool symm,const PetscInt verbose) { PetscErrorCode ierr; PetscInt Istart,Iend,Ii,jj,ncols,nnz0,nnz1, NN, MM, nloc; PetscMPIInt rank, size; Mat Gmat = *a_Gmat, tGmat, matTrans; MPI_Comm comm; const PetscScalar *vals; const PetscInt *idx; PetscInt *d_nnz, *o_nnz; Vec diag; PetscFunctionBegin; ierr = PetscObjectGetComm((PetscObject)Gmat,&comm);CHKERRQ(ierr); ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); ierr = MatGetOwnershipRange(Gmat, &Istart, &Iend);CHKERRQ(ierr); nloc = Iend - Istart; ierr = MatGetSize(Gmat, &MM, &NN);CHKERRQ(ierr); #if defined PETSC_GAMG_USE_LOG ierr = PetscLogEventBegin(petsc_gamg_setup_events[GRAPH],0,0,0,0);CHKERRQ(ierr); #endif /* scale Gmat so filter works */ ierr = MatGetVecs(Gmat, &diag, 0);CHKERRQ(ierr); ierr = MatGetDiagonal(Gmat, diag);CHKERRQ(ierr); ierr = VecReciprocal(diag);CHKERRQ(ierr); ierr = VecSqrtAbs(diag);CHKERRQ(ierr); ierr = MatDiagonalScale(Gmat, diag, diag);CHKERRQ(ierr); ierr = VecDestroy(&diag);CHKERRQ(ierr); if (symm) { ierr = MatTranspose(Gmat, MAT_INITIAL_MATRIX, &matTrans);CHKERRQ(ierr); } /* filter - dup zeros out matrix */ ierr = PetscMalloc1(nloc, &d_nnz);CHKERRQ(ierr); ierr = PetscMalloc1(nloc, &o_nnz);CHKERRQ(ierr); for (Ii = Istart, jj = 0; Ii < Iend; Ii++, jj++) { ierr = MatGetRow(Gmat,Ii,&ncols,NULL,NULL);CHKERRQ(ierr); d_nnz[jj] = ncols; o_nnz[jj] = ncols; ierr = MatRestoreRow(Gmat,Ii,&ncols,NULL,NULL);CHKERRQ(ierr); if (symm) { ierr = MatGetRow(matTrans,Ii,&ncols,NULL,NULL);CHKERRQ(ierr); d_nnz[jj] += ncols; o_nnz[jj] += ncols; ierr = MatRestoreRow(matTrans,Ii,&ncols,NULL,NULL);CHKERRQ(ierr); } if (d_nnz[jj] > nloc) d_nnz[jj] = nloc; if (o_nnz[jj] > (MM-nloc)) o_nnz[jj] = MM - nloc; } ierr = MatCreateAIJ(comm, nloc, nloc, MM, MM, 0, d_nnz, 0, o_nnz, &tGmat);CHKERRQ(ierr); ierr = PetscFree(d_nnz);CHKERRQ(ierr); ierr = PetscFree(o_nnz);CHKERRQ(ierr); if (symm) { ierr = MatDestroy(&matTrans);CHKERRQ(ierr); } for (Ii = Istart, nnz0 = nnz1 = 0; Ii < Iend; Ii++) { ierr = MatGetRow(Gmat,Ii,&ncols,&idx,&vals);CHKERRQ(ierr); for (jj=0; jj<ncols; jj++,nnz0++) { PetscScalar sv = PetscAbs(PetscRealPart(vals[jj])); if (PetscRealPart(sv) > vfilter) { nnz1++; if (symm) { sv *= 0.5; ierr = MatSetValues(tGmat,1,&Ii,1,&idx[jj],&sv,ADD_VALUES);CHKERRQ(ierr); ierr = MatSetValues(tGmat,1,&idx[jj],1,&Ii,&sv,ADD_VALUES);CHKERRQ(ierr); } else { ierr = MatSetValues(tGmat,1,&Ii,1,&idx[jj],&sv,ADD_VALUES);CHKERRQ(ierr); } } } ierr = MatRestoreRow(Gmat,Ii,&ncols,&idx,&vals);CHKERRQ(ierr); } ierr = MatAssemblyBegin(tGmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(tGmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); #if defined PETSC_GAMG_USE_LOG ierr = PetscLogEventEnd(petsc_gamg_setup_events[GRAPH],0,0,0,0);CHKERRQ(ierr); #endif if (verbose) { if (verbose == 1) { ierr = PetscPrintf(comm,"\t[%d]%s %g%% nnz after filtering, with threshold %g, %g nnz ave. (N=%d)\n",rank,__FUNCT__, 100.*(double)nnz1/(double)nnz0,vfilter,(double)nnz0/(double)nloc,MM);CHKERRQ(ierr); } else { PetscInt nnz[2],out[2]; nnz[0] = nnz0; nnz[1] = nnz1; ierr = MPI_Allreduce(nnz, out, 2, MPIU_INT, MPI_SUM, comm);CHKERRQ(ierr); ierr = PetscPrintf(comm,"\t[%d]%s %g%% nnz after filtering, with threshold %g, %g nnz ave. (N=%d)\n",rank,__FUNCT__, 100.*(double)out[1]/(double)out[0],vfilter,(double)out[0]/(double)MM,MM);CHKERRQ(ierr); } } ierr = MatDestroy(&Gmat);CHKERRQ(ierr); *a_Gmat = tGmat; PetscFunctionReturn(0); }
PetscInt main(PetscInt argc,char **args) { Mat A,As; Vec x,y,ys; PetscTruth flg,disp_mat=PETSC_FALSE,disp_vec=PETSC_FALSE; PetscErrorCode ierr; PetscMPIInt size,rank; PetscInt m,i,j; PetscScalar v,sigma2; PetscRandom rctx; PetscReal h2,sigma1=100.0,norm; PetscInt dim,Ii,J,n = 3,use_random,rstart,rend; PetscInitialize(&argc,&args,(char *)0,help); #if !defined(PETSC_USE_COMPLEX) SETERRQ(1,"This example requires complex numbers"); #endif ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = PetscOptionsHasName(PETSC_NULL, "-display_mat", &disp_mat);CHKERRQ(ierr); ierr = PetscOptionsHasName(PETSC_NULL, "-display_vec", &disp_vec);CHKERRQ(ierr); ierr = PetscOptionsGetReal(PETSC_NULL,"-sigma1",&sigma1,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-n",&n,PETSC_NULL);CHKERRQ(ierr); dim = n*n; ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,dim,dim);CHKERRQ(ierr); ierr = MatSetType(A,MATAIJ);CHKERRQ(ierr); ierr = MatSetFromOptions(A);CHKERRQ(ierr); ierr = PetscOptionsHasName(PETSC_NULL,"-norandom",&flg);CHKERRQ(ierr); if (flg) use_random = 0; else use_random = 1; if (use_random) { ierr = PetscRandomCreate(PETSC_COMM_WORLD,&rctx);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rctx);CHKERRQ(ierr); ierr = PetscRandomSetInterval(rctx,0.0,PETSC_i);CHKERRQ(ierr); ierr = PetscRandomGetValue(rctx,&sigma2);CHKERRQ(ierr); /* RealPart(sigma2) == 0.0 */ } else { sigma2 = 10.0*PETSC_i; } h2 = 1.0/((n+1)*(n+1)); ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); for (Ii=rstart; Ii<rend; Ii++) { v = -1.0; i = Ii/n; j = Ii - i*n; if (i>0) { J = Ii-n; ierr = MatSetValues(A,1,&Ii,1,&J,&v,ADD_VALUES);CHKERRQ(ierr);} if (i<n-1) { J = Ii+n; ierr = MatSetValues(A,1,&Ii,1,&J,&v,ADD_VALUES);CHKERRQ(ierr);} if (j>0) { J = Ii-1; ierr = MatSetValues(A,1,&Ii,1,&J,&v,ADD_VALUES);CHKERRQ(ierr);} if (j<n-1) { J = Ii+1; ierr = MatSetValues(A,1,&Ii,1,&J,&v,ADD_VALUES);CHKERRQ(ierr);} v = 4.0 - sigma1*h2; ierr = MatSetValues(A,1,&Ii,1,&Ii,&v,ADD_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_symmetric", &flg);CHKERRQ(ierr); if (flg) { Mat Trans; ierr = MatTranspose(A,MAT_INITIAL_MATRIX, &Trans); ierr = MatEqual(A, Trans, &flg); if (!flg) SETERRQ(PETSC_ERR_USER,"A is not symmetric"); ierr = MatDestroy(Trans);CHKERRQ(ierr); } ierr = MatSetOption(A,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); /* make A complex Hermitian */ Ii = 0; J = dim-1; if (Ii >= rstart && Ii < rend){ v = sigma2*h2; /* RealPart(v) = 0.0 */ ierr = MatSetValues(A,1,&Ii,1,&J,&v,ADD_VALUES);CHKERRQ(ierr); v = -sigma2*h2; ierr = MatSetValues(A,1,&J,1,&Ii,&v,ADD_VALUES);CHKERRQ(ierr); } Ii = dim-2; J = dim-1; if (Ii >= rstart && Ii < rend){ v = sigma2*h2; /* RealPart(v) = 0.0 */ ierr = MatSetValues(A,1,&Ii,1,&J,&v,ADD_VALUES);CHKERRQ(ierr); v = -sigma2*h2; ierr = MatSetValues(A,1,&J,1,&Ii,&v,ADD_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* Check whether A is Hermitian */ ierr = PetscOptionsHasName(PETSC_NULL, "-check_Hermitian", &flg);CHKERRQ(ierr); if (flg) { Mat Hermit; if (disp_mat){ if (!rank) printf(" A:\n"); ierr = MatView(A,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } ierr = MatHermitianTranspose(A,MAT_INITIAL_MATRIX, &Hermit); if (disp_mat){ if (!rank) printf(" A_Hermitian:\n"); ierr = MatView(Hermit,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } ierr = MatEqual(A, Hermit, &flg); if (!flg) SETERRQ(PETSC_ERR_USER,"A is not Hermitian"); ierr = MatDestroy(Hermit);CHKERRQ(ierr); } ierr = MatSetOption(A,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); /* Create a Hermitian matrix As in sbaij format */ ierr = MatConvert(A,MATSBAIJ,MAT_INITIAL_MATRIX,&As);CHKERRQ(ierr); if (disp_mat){ if (!rank) {ierr = PetscPrintf(PETSC_COMM_SELF," As:\n");CHKERRQ(ierr);} ierr = MatView(As,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); ierr = VecCreate(PETSC_COMM_WORLD,&x);CHKERRQ(ierr); ierr = VecSetSizes(x,n,PETSC_DECIDE);CHKERRQ(ierr); ierr = VecSetFromOptions(x);CHKERRQ(ierr); if (use_random){ ierr = VecSetRandom(x,rctx);CHKERRQ(ierr); } else { ierr = VecSet(x,1.0);CHKERRQ(ierr); } /* Create vectors */ ierr = VecCreate(PETSC_COMM_WORLD,&y);CHKERRQ(ierr); ierr = VecSetSizes(y,m,PETSC_DECIDE);CHKERRQ(ierr); ierr = VecSetFromOptions(y);CHKERRQ(ierr); ierr = VecDuplicate(y,&ys);CHKERRQ(ierr); /* Test MatMult */ ierr = MatMult(A,x,y);CHKERRQ(ierr); ierr = MatMult(As,x,ys);CHKERRQ(ierr); if (disp_vec){ printf("y = A*x:\n"); ierr = VecView(y,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"ys = As*x:\n"); ierr = VecView(ys,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } ierr = VecAXPY(y,-1.0,ys);CHKERRQ(ierr); ierr = VecNorm(y,NORM_INFINITY,&norm);CHKERRQ(ierr); if (norm > 1.e-12 || disp_vec){ printf("|| A*x - As*x || = %G\n",norm); } /* Free spaces */ if (use_random) {ierr = PetscRandomDestroy(rctx);CHKERRQ(ierr);} ierr = MatDestroy(A);CHKERRQ(ierr); ierr = MatDestroy(As);CHKERRQ(ierr); ierr = VecDestroy(x);CHKERRQ(ierr); ierr = VecDestroy(y);CHKERRQ(ierr); ierr = VecDestroy(ys);CHKERRQ(ierr); ierr = PetscFinalize();CHKERRQ(ierr); return 0; }
int main(int argc,char **argv) { Mat A,B,C,D; PetscInt i,M=10,N=5,j,nrows,ncols,am,an,rstart,rend; PetscErrorCode ierr; PetscRandom r; PetscBool equal,iselemental; PetscReal fill = 1.0; IS isrows,iscols; const PetscInt *rows,*cols; PetscScalar *v,rval; #if defined(PETSC_HAVE_ELEMENTAL) PetscBool Test_MatMatMult=PETSC_TRUE; #else PetscBool Test_MatMatMult=PETSC_FALSE; #endif PetscMPIInt size; ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-M",&M,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-N",&N,NULL);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); ierr = MatSetType(A,MATDENSE);CHKERRQ(ierr); ierr = MatSetFromOptions(A);CHKERRQ(ierr); ierr = MatSetUp(A);CHKERRQ(ierr); ierr = PetscRandomCreate(PETSC_COMM_WORLD,&r);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(r);CHKERRQ(ierr); /* Set local matrix entries */ ierr = MatGetOwnershipIS(A,&isrows,&iscols);CHKERRQ(ierr); ierr = ISGetLocalSize(isrows,&nrows);CHKERRQ(ierr); ierr = ISGetIndices(isrows,&rows);CHKERRQ(ierr); ierr = ISGetLocalSize(iscols,&ncols);CHKERRQ(ierr); ierr = ISGetIndices(iscols,&cols);CHKERRQ(ierr); ierr = PetscMalloc1(nrows*ncols,&v);CHKERRQ(ierr); for (i=0; i<nrows; i++) { for (j=0; j<ncols; j++) { ierr = PetscRandomGetValue(r,&rval);CHKERRQ(ierr); v[i*ncols+j] = rval; } } ierr = MatSetValues(A,nrows,rows,ncols,cols,v,INSERT_VALUES);CHKERRQ(ierr); ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = ISRestoreIndices(isrows,&rows);CHKERRQ(ierr); ierr = ISRestoreIndices(iscols,&cols);CHKERRQ(ierr); ierr = ISDestroy(&isrows);CHKERRQ(ierr); ierr = ISDestroy(&iscols);CHKERRQ(ierr); ierr = PetscRandomDestroy(&r);CHKERRQ(ierr); /* Test MatTranspose() */ ierr = MatCreateTranspose(A,&C);CHKERRQ(ierr); ierr = MatTranspose(A,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); /* B = A^T */ ierr = MatMultEqual(C,B,10,&equal);CHKERRQ(ierr); if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"A^T*x != (x^T*A)^T"); ierr = MatTranspose(A,MAT_REUSE_MATRIX,&B);CHKERRQ(ierr); /* B = A^T */ ierr = MatMultEqual(C,B,10,&equal);CHKERRQ(ierr); if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"A^T*x != (x^T*A)^T"); ierr = MatDestroy(&B);CHKERRQ(ierr); ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); ierr = MatTranspose(B,MAT_INPLACE_MATRIX,&B);CHKERRQ(ierr); ierr = MatMultEqual(C,B,10,&equal);CHKERRQ(ierr); if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"A^T*x != (x^T*A)^T"); ierr = MatDestroy(&B);CHKERRQ(ierr); ierr = MatDestroy(&C);CHKERRQ(ierr); /* Test MatMatMult() */ if (Test_MatMatMult) { #if !defined(PETSC_HAVE_ELEMENTAL) if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"This test requires ELEMENTAL"); #endif ierr = MatTranspose(A,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); /* B = A^T */ ierr = MatMatMult(B,A,MAT_INITIAL_MATRIX,fill,&C);CHKERRQ(ierr); /* C = B*A = A^T*A */ ierr = MatMatMult(B,A,MAT_REUSE_MATRIX,fill,&C);CHKERRQ(ierr); /* Test MatDuplicate for matrix product */ ierr = MatDuplicate(C,MAT_COPY_VALUES,&D);CHKERRQ(ierr); ierr = MatDestroy(&D);CHKERRQ(ierr); /* Test B*A*x = C*x for n random vector x */ ierr = MatMatMultEqual(B,A,C,10,&equal);CHKERRQ(ierr); if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"B*A*x != C*x"); ierr = MatDestroy(&C);CHKERRQ(ierr); ierr = MatMatMultSymbolic(B,A,fill,&C);CHKERRQ(ierr); for (i=0; i<2; i++) { /* Repeat the numeric product to test reuse of the previous symbolic product */ ierr = MatMatMultNumeric(B,A,C);CHKERRQ(ierr); ierr = MatMatMultEqual(B,A,C,10,&equal);CHKERRQ(ierr); if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"B*A*x != C*x"); } ierr = MatDestroy(&C);CHKERRQ(ierr); ierr = MatDestroy(&B);CHKERRQ(ierr); } /* Test MatTransposeMatMult() */ ierr = PetscObjectTypeCompare((PetscObject)A,MATELEMENTAL,&iselemental);CHKERRQ(ierr); if (!iselemental) { ierr = MatTransposeMatMult(A,A,MAT_INITIAL_MATRIX,fill,&D);CHKERRQ(ierr); /* D = A^T*A */ ierr = MatTransposeMatMult(A,A,MAT_REUSE_MATRIX,fill,&D);CHKERRQ(ierr); /* Test MatDuplicate for matrix product */ ierr = MatDuplicate(D,MAT_COPY_VALUES,&C);CHKERRQ(ierr); ierr = MatDestroy(&C);CHKERRQ(ierr); /* ierr = MatView(D,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); */ ierr = MatTransposeMatMultEqual(A,A,D,10,&equal);CHKERRQ(ierr); if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"D*x != A^T*A*x"); ierr = MatDestroy(&D);CHKERRQ(ierr); /* Test D*x = A^T*C*A*x, where C is in AIJ format */ ierr = MatGetLocalSize(A,&am,&an);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&C);CHKERRQ(ierr); if (size == 1) { ierr = MatSetSizes(C,PETSC_DECIDE,PETSC_DECIDE,am,am);CHKERRQ(ierr); } else { ierr = MatSetSizes(C,am,am,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); } ierr = MatSetFromOptions(C);CHKERRQ(ierr); ierr = MatSetUp(C);CHKERRQ(ierr); ierr = MatGetOwnershipRange(C,&rstart,&rend);CHKERRQ(ierr); v[0] = 1.0; for (i=rstart; i<rend; i++) { ierr = MatSetValues(C,1,&i,1,&i,v,INSERT_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* B = C*A, D = A^T*B */ ierr = MatMatMult(C,A,MAT_INITIAL_MATRIX,1.0,&B);CHKERRQ(ierr); ierr = MatTransposeMatMult(A,B,MAT_INITIAL_MATRIX,fill,&D);CHKERRQ(ierr); ierr = MatTransposeMatMultEqual(A,B,D,10,&equal);CHKERRQ(ierr); if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"D*x != A^T*B*x"); ierr = MatDestroy(&D);CHKERRQ(ierr); ierr = MatDestroy(&C);CHKERRQ(ierr); ierr = MatDestroy(&B);CHKERRQ(ierr); } ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = PetscFree(v);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
int main(int argc,char **argv) { Mat A,B,C,D; PetscInt i,M=10,N=5,j,nrows,ncols; PetscErrorCode ierr; PetscRandom r; PetscBool equal,iselemental; PetscReal fill = 1.0; IS isrows,iscols; const PetscInt *rows,*cols; PetscScalar *v,rval; PetscInitialize(&argc,&argv,(char*)0,help); ierr = PetscOptionsGetInt(NULL,"-M",&M,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,"-N",&N,NULL);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); ierr = MatSetType(A,MATDENSE);CHKERRQ(ierr); ierr = MatSetFromOptions(A);CHKERRQ(ierr); ierr = MatSetUp(A);CHKERRQ(ierr); ierr = PetscRandomCreate(PETSC_COMM_WORLD,&r);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(r);CHKERRQ(ierr); /* Set local matrix entries */ ierr = MatGetOwnershipIS(A,&isrows,&iscols);CHKERRQ(ierr); ierr = ISGetLocalSize(isrows,&nrows);CHKERRQ(ierr); ierr = ISGetIndices(isrows,&rows);CHKERRQ(ierr); ierr = ISGetLocalSize(iscols,&ncols);CHKERRQ(ierr); ierr = ISGetIndices(iscols,&cols);CHKERRQ(ierr); ierr = PetscMalloc(nrows*ncols*sizeof(*v),&v);CHKERRQ(ierr); for (i=0; i<nrows; i++) { for (j=0; j<ncols; j++) { ierr = PetscRandomGetValue(r,&rval);CHKERRQ(ierr); v[i*ncols+j] = rval; } } ierr = MatSetValues(A,nrows,rows,ncols,cols,v,INSERT_VALUES);CHKERRQ(ierr); ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = ISRestoreIndices(isrows,&rows);CHKERRQ(ierr); ierr = ISRestoreIndices(iscols,&cols);CHKERRQ(ierr); ierr = ISDestroy(&isrows);CHKERRQ(ierr); ierr = ISDestroy(&iscols);CHKERRQ(ierr); ierr = PetscFree(v);CHKERRQ(ierr); ierr = PetscRandomDestroy(&r);CHKERRQ(ierr); /* Test MatMatMult() */ ierr = MatTranspose(A,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); /* B = A^T */ ierr = MatMatMult(B,A,MAT_INITIAL_MATRIX,fill,&C);CHKERRQ(ierr); /* C = B*A = A^T*A */ ierr = MatMatMultSymbolic(B,A,fill,&D);CHKERRQ(ierr); /* D = B*A = A^T*A */ for (i=0; i<2; i++) { /* Repeat the numeric product to test reuse of the previous symbolic product */ ierr = MatMatMultNumeric(B,A,D);CHKERRQ(ierr); } ierr = MatMultEqual(C,D,10,&equal);CHKERRQ(ierr); if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"C != D"); ierr = MatDestroy(&D);CHKERRQ(ierr); /* Test MatTransposeMatMult() */ ierr = PetscObjectTypeCompare((PetscObject)A,MATELEMENTAL,&iselemental);CHKERRQ(ierr); if (!iselemental) { ierr = MatTransposeMatMult(A,A,MAT_INITIAL_MATRIX,fill,&D);CHKERRQ(ierr); /* D = A^T*A */ ierr = MatEqual(C,D,&equal);CHKERRQ(ierr); if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"C != D"); ierr = MatDestroy(&D);CHKERRQ(ierr); } ierr = MatDestroy(&C);CHKERRQ(ierr); ierr = MatDestroy(&B); ierr = MatDestroy(&A); PetscFinalize(); return(0); }
void cljp_coarsening(Mat depends_on, IS *pCoarse) { const int debug = 0; //create a vector of the weights. Vec w; MatGetVecs(depends_on, PETSC_NULL, &w); VecZeroEntries(w); //Get my local matrix size PetscInt start; PetscInt end; MatGetOwnershipRange(depends_on, &start, &end); //TODO: replace with something that doesn't require re-creating the matrix structure. //Initialize all the weights { Mat influences; MatTranspose(depends_on, &influences); { RawGraph influences_raw(influences); assert(influences_raw.local_nrows() == end-start); //Initialize the weight vector with \norm{S^T_i} + \sigma(i) PetscScalar *local_weights; VecGetArray(w, &local_weights); for (int local_row=0; local_row < influences_raw.local_nrows(); local_row++) { local_weights[local_row] = influences_raw.ia(local_row+1)-influences_raw.ia(local_row) + frand(); } VecRestoreArray(w, &local_weights); } MatDestroy(influences); } //VecView(w, PETSC_VIEWER_STDOUT_WORLD); //-------------------------------------------------------------- //Prepare the scatters needed for the independent set algorithm. IS all_local_nodes; describe_partition(depends_on, &all_local_nodes); NonlocalCollection nonlocal(depends_on, all_local_nodes); ISDestroy(all_local_nodes); //while we are here, get the matrix + graph nodes that we need. Mat extended_depend_mat; get_matrix_rows(depends_on, nonlocal.nodes, &extended_depend_mat); // Vec used only for display purposes enum NodeType {UNKNOWN=-1, FINE, COARSE}; Vec node_type; VecDuplicate(w, &node_type); VecSet(node_type, UNKNOWN); Vec w_nonlocal; VecDuplicate(nonlocal.vec, &w_nonlocal); Vec node_type_nonlocal; VecDuplicate(w_nonlocal, &node_type_nonlocal); VecSet(node_type_nonlocal, UNKNOWN); Vec is_not_independent; VecDuplicate(w, &is_not_independent); Vec is_not_independent_nonlocal; VecDuplicate(w_nonlocal, &is_not_independent_nonlocal); VecScatterBegin(nonlocal.scatter, w, w_nonlocal, INSERT_VALUES, SCATTER_FORWARD); VecScatterEnd(nonlocal.scatter, w, w_nonlocal, INSERT_VALUES, SCATTER_FORWARD); Vec w_update_nonlocal; VecDuplicate(w_nonlocal, &w_update_nonlocal); //get ready to find all the coarse and fine points typedef std::set<PetscInt> IntSet; IntSet unknown; //initialize the unknown set with all points that are local to this processor. for (int ii=start; ii<end; ii++) { unknown.insert(ii); } //we use MPI_INT here because we need to allreduce it with MPI_LAND int all_points_partitioned=0; int inc = 0; { RawGraph dep_nonlocal_raw(extended_depend_mat); //while not done while(!all_points_partitioned) { //Start: non-local weights, non-local coarse points if (debug) { LTRACE(); char fname[] = "weightsXXX"; char selection_graph[] = "selectionXXX"; sprintf(fname, "weights%03d", inc); sprintf(selection_graph, "selection%03d", inc); inc++; /* PetscViewer view; PetscViewerBinaryMatlabOpen(PETSC_COMM_WORLD, fname, &view); PetscViewerBinaryMatlabOutputVecDA(view, "z", w, user->da); PetscViewerBinaryMatlabDestroy(view); PetscViewerBinaryMatlabOpen(PETSC_COMM_WORLD, selection_graph, &view); PetscViewerBinaryMatlabOutputVecDA(view, "z", node_type, user->da); PetscViewerBinaryMatlabDestroy(view); //*/ } //Pre: non-local weights, non-local coarse points //find the independent set. //By using ADD_VALUES in a scattter, we can perform //a boolean OR across procesors. //is_not_independent[*] = false VecSet(is_not_independent_nonlocal, 0); //for all unknown points P { RawVector node_type_nonlocal_raw(node_type_nonlocal); RawVector w_nonlocal_raw(w_nonlocal); RawVector is_not_independent_nonlocal_raw(is_not_independent_nonlocal); FOREACH(P, unknown) { //get weight(P) PetscScalar weight_P = w_nonlocal_raw.at(nonlocal.map[*P]); //for all dependencies K of P (K st P->K) for (PetscInt ii=0; ii<dep_nonlocal_raw.nnz_in_row(nonlocal.map[*P]); ii++) { PetscInt K = dep_nonlocal_raw.col(nonlocal.map[*P], ii); //skip if K is fine/coarse /* Notice that we don't have to consider the independent set we've been generating here. By construction, if K is in the independent set, then P cannot be in the independent set. */ if (node_type_nonlocal_raw.at(nonlocal.map[K]) != UNKNOWN) { continue; } //skip if P->K is marked if (dep_nonlocal_raw.is_marked(nonlocal.map[*P], ii)) { continue; } //get weight(K) PetscScalar weight_K = w_nonlocal_raw.at(nonlocal.map[K]); if (weight_K <= weight_P) { //is_not_independent(K) = true is_not_independent_nonlocal_raw.at(nonlocal.map[K]) = 1; } else { // (weight(P) < weight_K) is_not_independent_nonlocal_raw.at(nonlocal.map[*P]) = 1; } } } } if (debug) {LTRACE();} //VecView(is_not_independent_nonlocal, PETSC_VIEWER_STDOUT_WORLD); //reconstruct is_not_independent vector with a ADD_VALUES, which //performs boolean OR VecSet(is_not_independent, 0); VecScatterBegin(nonlocal.scatter, is_not_independent_nonlocal, is_not_independent, ADD_VALUES, SCATTER_REVERSE); VecScatterEnd(nonlocal.scatter, is_not_independent_nonlocal, is_not_independent, ADD_VALUES, SCATTER_REVERSE); IntSet new_coarse_points; { RawVector is_not_independent_raw(is_not_independent); //for all unknown points P FOREACH(P, unknown) { //if (!is_not_independent(P)) if (is_not_independent_raw.at(*P) == 0) { new_coarse_points.insert(*P); if (debug) {SHOWVAR(*P, d);} } } } //Post: new coarse points (independent set) if (debug) {LTRACE();} //Pre: independent set { RawVector node_type_raw(node_type); // for each independent point FOREACH(I, new_coarse_points) { //mark that point as coarse node_type_raw.at(*I) = COARSE; unknown.erase(*I); } } //Post: updated coarse local if (debug) {LTRACE();} //Pre: updated coarse local //scatter changes to other processors VecScatterBegin(nonlocal.scatter, node_type, node_type_nonlocal, INSERT_VALUES, SCATTER_FORWARD); VecScatterEnd(nonlocal.scatter, node_type, node_type_nonlocal, INSERT_VALUES, SCATTER_FORWARD); //Post: updated coarse non-local if (debug) {LTRACE();} //Pre: updated coarse non-local, new local coarse points VecSet(w_update_nonlocal, 0); { RawVector node_type_nonlocal_raw(node_type_nonlocal); RawVector w_update_nonlocal_raw(w_update_nonlocal); //for all new coarse points C FOREACH(C, new_coarse_points) { //for all K st C->K for(PetscInt ii=0; ii<dep_nonlocal_raw.nnz_in_row(nonlocal.map[*C]); ii++) { //mark (C->K) dep_nonlocal_raw.mark(nonlocal.map[*C], ii); PetscInt K = dep_nonlocal_raw.col(nonlocal.map[*C], ii); //if K is unknown if (node_type_nonlocal_raw.at(nonlocal.map[K]) == UNKNOWN) { //measure(K)-- w_update_nonlocal_raw.at(nonlocal.map[K]) -= 1; } } } //for all unknown points I FOREACH(I, unknown) { IntSet common_coarse; //for all (J->K) for (PetscInt kk=0; kk<dep_nonlocal_raw.nnz_in_row(nonlocal.map[*I]); kk++) { if (!dep_nonlocal_raw.is_marked(nonlocal.map[*I], kk)) { //if K is coarse PetscInt K = dep_nonlocal_raw.col(nonlocal.map[*I], kk); if (node_type_nonlocal_raw.at(nonlocal.map[K]) == COARSE) { //mark K as common coarse common_coarse.insert(K); //mark (J->K) if unmarked dep_nonlocal_raw.mark(nonlocal.map[*I], kk); } } } //for all unmarked (I->J) for (PetscInt jj=0; jj<dep_nonlocal_raw.nnz_in_row(nonlocal.map[*I]); jj++) { if (!dep_nonlocal_raw.is_marked(nonlocal.map[*I], jj)) { //for all (J->K), marked or no PetscInt J = dep_nonlocal_raw.col(nonlocal.map[*I], jj); for(PetscInt kk=0; kk<dep_nonlocal_raw.nnz_in_row(nonlocal.map[J]); kk++) { //if K is in layer or ghost layer and common-coarse PetscInt K = dep_nonlocal_raw.col(nonlocal.map[J], kk); if (is_member(K, common_coarse)) { //mark (I->J) dep_nonlocal_raw.mark(nonlocal.map[*I], jj); //measure(J)-- w_update_nonlocal_raw.at(nonlocal.map[J]) -= 1; } } } } } }
int main(int argc,char **argv) { PetscErrorCode ierr; KSP ksp; PC pc; Vec x,b; DM da; Mat A,Atrans; PetscInt dof=1,M=8; PetscBool flg,trans=PETSC_FALSE; ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; ierr = PetscOptionsGetInt(NULL,NULL,"-dof",&dof,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-M",&M,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-trans",&trans,NULL);CHKERRQ(ierr); ierr = DMDACreate(PETSC_COMM_WORLD,&da);CHKERRQ(ierr); ierr = DMSetDimension(da,3);CHKERRQ(ierr); ierr = DMDASetBoundaryType(da,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE);CHKERRQ(ierr); ierr = DMDASetStencilType(da,DMDA_STENCIL_STAR);CHKERRQ(ierr); ierr = DMDASetSizes(da,M,M,M);CHKERRQ(ierr); ierr = DMDASetNumProcs(da,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); ierr = DMDASetDof(da,dof);CHKERRQ(ierr); ierr = DMDASetStencilWidth(da,1);CHKERRQ(ierr); ierr = DMDASetOwnershipRanges(da,NULL,NULL,NULL);CHKERRQ(ierr); ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMSetUp(da);CHKERRQ(ierr); ierr = DMCreateGlobalVector(da,&x);CHKERRQ(ierr); ierr = DMCreateGlobalVector(da,&b);CHKERRQ(ierr); ierr = ComputeRHS(da,b);CHKERRQ(ierr); ierr = DMSetMatType(da,MATBAIJ);CHKERRQ(ierr); ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMCreateMatrix(da,&A);CHKERRQ(ierr); ierr = ComputeMatrix(da,A);CHKERRQ(ierr); /* A is non-symmetric. Make A = 0.5*(A + Atrans) symmetric for testing icc and cholesky */ ierr = MatTranspose(A,MAT_INITIAL_MATRIX,&Atrans);CHKERRQ(ierr); ierr = MatAXPY(A,1.0,Atrans,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); ierr = MatScale(A,0.5);CHKERRQ(ierr); ierr = MatDestroy(&Atrans);CHKERRQ(ierr); /* Test sbaij matrix */ flg = PETSC_FALSE; ierr = PetscOptionsGetBool(NULL,NULL, "-test_sbaij1", &flg,NULL);CHKERRQ(ierr); if (flg) { Mat sA; PetscBool issymm; ierr = MatIsTranspose(A,A,0.0,&issymm);CHKERRQ(ierr); if (issymm) { ierr = MatSetOption(A,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); } else {ierr = PetscPrintf(PETSC_COMM_WORLD,"Warning: A is non-symmetric\n");CHKERRQ(ierr);} ierr = MatConvert(A,MATSBAIJ,MAT_INITIAL_MATRIX,&sA);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); A = sA; } ierr = KSPCreate(PETSC_COMM_WORLD,&ksp);CHKERRQ(ierr); ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr); ierr = KSPSetOperators(ksp,A,A);CHKERRQ(ierr); ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); ierr = PCSetDM(pc,(DM)da);CHKERRQ(ierr); if (trans) { ierr = KSPSolveTranspose(ksp,b,x);CHKERRQ(ierr); } else { ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); } /* check final residual */ flg = PETSC_FALSE; ierr = PetscOptionsGetBool(NULL,NULL, "-check_final_residual", &flg,NULL);CHKERRQ(ierr); if (flg) { Vec b1; PetscReal norm; ierr = KSPGetSolution(ksp,&x);CHKERRQ(ierr); ierr = VecDuplicate(b,&b1);CHKERRQ(ierr); ierr = MatMult(A,x,b1);CHKERRQ(ierr); ierr = VecAXPY(b1,-1.0,b);CHKERRQ(ierr); ierr = VecNorm(b1,NORM_2,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Final residual %g\n",norm);CHKERRQ(ierr); ierr = VecDestroy(&b1);CHKERRQ(ierr); } ierr = KSPDestroy(&ksp);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
int main(int argc,char **argv) { Mat A,B,C,D; PetscScalar a[]= {1.,1.,0.,0.,1.,1.,0.,0.,1.}; PetscInt ij[]= {0,1,2}; PetscScalar none=-1.; PetscErrorCode ierr; PetscReal fill=4; PetscReal norm; PetscInitialize(&argc,&argv,(char *)0,help); ierr = MatCreate(PETSC_COMM_SELF,&A); CHKERRQ(ierr); ierr = MatSetSizes(A,3,3,3,3); CHKERRQ(ierr); ierr = MatSetType(A,MATSEQAIJ); CHKERRQ(ierr); ierr = MatSetUp(A); CHKERRQ(ierr); ierr = MatSetOption(A,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE); CHKERRQ(ierr); ierr = MatSetValues(A,3,ij,3,ij,a,ADD_VALUES); CHKERRQ(ierr); ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); ierr = MatSetOptionsPrefix(A,"A_"); CHKERRQ(ierr); ierr = MatView(A,PETSC_VIEWER_STDOUT_WORLD); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF,"\n"); CHKERRQ(ierr); /* Test MatMatMult() */ ierr = MatTranspose(A,MAT_INITIAL_MATRIX,&B); CHKERRQ(ierr); /* B = A^T */ ierr = MatMatMult(B,A,MAT_INITIAL_MATRIX,fill,&C); CHKERRQ(ierr); /* C = B*A */ ierr = MatSetOptionsPrefix(C,"C=B*A=A^T*A_"); CHKERRQ(ierr); ierr = MatView(C,PETSC_VIEWER_STDOUT_WORLD); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF,"\n"); CHKERRQ(ierr); ierr = MatMatMultSymbolic(C,A,fill,&D); CHKERRQ(ierr); ierr = MatMatMultNumeric(C,A,D); CHKERRQ(ierr); /* D = C*A = (A^T*A)*A */ ierr = MatSetOptionsPrefix(D,"D=C*A=(A^T*A)*A_"); CHKERRQ(ierr); ierr = MatView(D,PETSC_VIEWER_STDOUT_WORLD); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF,"\n"); CHKERRQ(ierr); /* Repeat the numeric product to test reuse of the previous symbolic product */ ierr = MatMatMultNumeric(C,A,D); CHKERRQ(ierr); ierr = MatView(D,PETSC_VIEWER_STDOUT_WORLD); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF,"\n"); CHKERRQ(ierr); ierr = MatDestroy(&B); CHKERRQ(ierr); ierr = MatDestroy(&C); CHKERRQ(ierr); /* Test PtAP routine. */ ierr = MatDuplicate(A,MAT_COPY_VALUES,&B); CHKERRQ(ierr); /* B = A */ ierr = MatPtAP(A,B,MAT_INITIAL_MATRIX,fill,&C); CHKERRQ(ierr); /* C = B^T*A*B */ ierr = MatAXPY(D,none,C,DIFFERENT_NONZERO_PATTERN); CHKERRQ(ierr); ierr = MatNorm(D,NORM_FROBENIUS,&norm); if (norm > 1.e-15) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error in MatPtAP: %g\n",norm); } ierr = MatDestroy(&C); CHKERRQ(ierr); ierr = MatDestroy(&D); CHKERRQ(ierr); /* Repeat PtAP to test symbolic/numeric separation for reuse of the symbolic product */ ierr = MatPtAP(A,B,MAT_INITIAL_MATRIX,fill,&C); CHKERRQ(ierr); ierr = MatSetOptionsPrefix(C,"C=BtAB_"); CHKERRQ(ierr); ierr = MatView(C,PETSC_VIEWER_STDOUT_WORLD); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF,"\n"); CHKERRQ(ierr); ierr = MatPtAPSymbolic(A,B,fill,&D); CHKERRQ(ierr); ierr = MatPtAPNumeric(A,B,D); CHKERRQ(ierr); ierr = MatSetOptionsPrefix(D,"D=BtAB_"); CHKERRQ(ierr); ierr = MatView(D,PETSC_VIEWER_STDOUT_WORLD); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF,"\n"); CHKERRQ(ierr); /* Repeat numeric product to test reuse of the previous symbolic product */ ierr = MatPtAPNumeric(A,B,D); CHKERRQ(ierr); ierr = MatAXPY(D,none,C,DIFFERENT_NONZERO_PATTERN); CHKERRQ(ierr); ierr = MatNorm(D,NORM_FROBENIUS,&norm); if (norm > 1.e-15) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error in symbolic/numeric MatPtAP: %g\n",norm); } ierr = MatDestroy(&B); ierr = MatDestroy(&C); ierr = MatDestroy(&D); /* A test contributed by Tobias Neckel <*****@*****.**> */ ierr = testPTAPRectangular(); CHKERRQ(ierr); /* test MatMatTransposeMult(): A*B^T */ ierr = MatMatTransposeMult(A,A,MAT_INITIAL_MATRIX,fill,&D); CHKERRQ(ierr); /* D = A*A^T */ ierr = MatSetOptionsPrefix(D,"D=A*A^T_"); CHKERRQ(ierr); ierr = MatView(D,PETSC_VIEWER_STDOUT_WORLD); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF,"\n"); CHKERRQ(ierr); ierr = MatTranspose(A,MAT_INITIAL_MATRIX,&B); CHKERRQ(ierr); /* B = A^T */ ierr = MatMatMult(A,B,MAT_INITIAL_MATRIX,fill,&C); CHKERRQ(ierr); /* C=A*B */ ierr = MatSetOptionsPrefix(C,"D=A*B=A*A^T_"); CHKERRQ(ierr); ierr = MatView(C,PETSC_VIEWER_STDOUT_WORLD); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF,"\n"); CHKERRQ(ierr); ierr = MatDestroy(&A); ierr = MatDestroy(&B); ierr = MatDestroy(&C); ierr = MatDestroy(&D); PetscFinalize(); return(0); }
static PetscErrorCode PCBDDCScalingSetUp_Deluxe_Private(PC pc) { PC_BDDC *pcbddc=(PC_BDDC*)pc->data; PCBDDCDeluxeScaling deluxe_ctx=pcbddc->deluxe_ctx; PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; PetscScalar *matdata,*matdata2; PetscInt i,max_subset_size,cum,cum2; const PetscInt *idxs; PetscBool newsetup = PETSC_FALSE; PetscErrorCode ierr; PetscFunctionBegin; if (!sub_schurs) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"Missing PCBDDCSubSchurs"); if (!sub_schurs->n_subs) PetscFunctionReturn(0); /* Allocate arrays for subproblems */ if (!deluxe_ctx->seq_n) { deluxe_ctx->seq_n = sub_schurs->n_subs; ierr = PetscCalloc5(deluxe_ctx->seq_n,&deluxe_ctx->seq_scctx,deluxe_ctx->seq_n,&deluxe_ctx->seq_work1,deluxe_ctx->seq_n,&deluxe_ctx->seq_work2,deluxe_ctx->seq_n,&deluxe_ctx->seq_mat,deluxe_ctx->seq_n,&deluxe_ctx->seq_mat_inv_sum);CHKERRQ(ierr); newsetup = PETSC_TRUE; } else if (deluxe_ctx->seq_n != sub_schurs->n_subs) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Number of deluxe subproblems %D is different from the sub_schurs %D",deluxe_ctx->seq_n,sub_schurs->n_subs); /* the change of basis is just a reference to sub_schurs->change (if any) */ deluxe_ctx->change = sub_schurs->change; deluxe_ctx->change_with_qr = sub_schurs->change_with_qr; /* Create objects for deluxe */ max_subset_size = 0; for (i=0;i<sub_schurs->n_subs;i++) { PetscInt subset_size; ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); max_subset_size = PetscMax(subset_size,max_subset_size); } if (newsetup) { ierr = PetscMalloc1(2*max_subset_size,&deluxe_ctx->workspace);CHKERRQ(ierr); } cum = cum2 = 0; ierr = ISGetIndices(sub_schurs->is_Ej_all,&idxs);CHKERRQ(ierr); ierr = MatSeqAIJGetArray(sub_schurs->S_Ej_all,&matdata);CHKERRQ(ierr); ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_all,&matdata2);CHKERRQ(ierr); for (i=0;i<deluxe_ctx->seq_n;i++) { PetscInt subset_size; ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); if (newsetup) { IS sub; /* work vectors */ ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,subset_size,deluxe_ctx->workspace,&deluxe_ctx->seq_work1[i]);CHKERRQ(ierr); ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,subset_size,deluxe_ctx->workspace+subset_size,&deluxe_ctx->seq_work2[i]);CHKERRQ(ierr); /* scatters */ ierr = ISCreateGeneral(PETSC_COMM_SELF,subset_size,idxs+cum,PETSC_COPY_VALUES,&sub);CHKERRQ(ierr); ierr = VecScatterCreate(pcbddc->work_scaling,sub,deluxe_ctx->seq_work1[i],NULL,&deluxe_ctx->seq_scctx[i]);CHKERRQ(ierr); ierr = ISDestroy(&sub);CHKERRQ(ierr); } /* S_E_j */ ierr = MatDestroy(&deluxe_ctx->seq_mat[i]);CHKERRQ(ierr); ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,subset_size,matdata+cum2,&deluxe_ctx->seq_mat[i]);CHKERRQ(ierr); /* \sum_k S^k_E_j */ ierr = MatDestroy(&deluxe_ctx->seq_mat_inv_sum[i]);CHKERRQ(ierr); ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,subset_size,matdata2+cum2,&deluxe_ctx->seq_mat_inv_sum[i]);CHKERRQ(ierr); ierr = MatSetOption(deluxe_ctx->seq_mat_inv_sum[i],MAT_SPD,sub_schurs->is_posdef);CHKERRQ(ierr); ierr = MatSetOption(deluxe_ctx->seq_mat_inv_sum[i],MAT_HERMITIAN,sub_schurs->is_hermitian);CHKERRQ(ierr); if (sub_schurs->is_hermitian) { ierr = MatCholeskyFactor(deluxe_ctx->seq_mat_inv_sum[i],NULL,NULL);CHKERRQ(ierr); } else { ierr = MatLUFactor(deluxe_ctx->seq_mat_inv_sum[i],NULL,NULL,NULL);CHKERRQ(ierr); } if (pcbddc->deluxe_singlemat) { Mat X,Y; if (!sub_schurs->is_hermitian) { ierr = MatTranspose(deluxe_ctx->seq_mat[i],MAT_INITIAL_MATRIX,&X);CHKERRQ(ierr); } else { ierr = PetscObjectReference((PetscObject)deluxe_ctx->seq_mat[i]);CHKERRQ(ierr); X = deluxe_ctx->seq_mat[i]; } ierr = MatDuplicate(X,MAT_DO_NOT_COPY_VALUES,&Y);CHKERRQ(ierr); if (!sub_schurs->is_hermitian) { ierr = PCBDDCMatTransposeMatSolve_SeqDense(deluxe_ctx->seq_mat_inv_sum[i],X,Y);CHKERRQ(ierr); } else { ierr = MatMatSolve(deluxe_ctx->seq_mat_inv_sum[i],X,Y);CHKERRQ(ierr); } ierr = MatDestroy(&deluxe_ctx->seq_mat_inv_sum[i]);CHKERRQ(ierr); ierr = MatDestroy(&deluxe_ctx->seq_mat[i]);CHKERRQ(ierr); ierr = MatDestroy(&X);CHKERRQ(ierr); if (deluxe_ctx->change) { Mat C,CY; if (!deluxe_ctx->change_with_qr) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only QR based change of basis"); ierr = KSPGetOperators(deluxe_ctx->change[i],&C,NULL);CHKERRQ(ierr); ierr = MatMatMult(C,Y,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&CY);CHKERRQ(ierr); ierr = MatMatTransposeMult(CY,C,MAT_REUSE_MATRIX,PETSC_DEFAULT,&Y);CHKERRQ(ierr); ierr = MatDestroy(&CY);CHKERRQ(ierr); } ierr = MatTranspose(Y,MAT_INPLACE_MATRIX,&Y);CHKERRQ(ierr); deluxe_ctx->seq_mat[i] = Y; } cum += subset_size; cum2 += subset_size*subset_size; } ierr = ISRestoreIndices(sub_schurs->is_Ej_all,&idxs);CHKERRQ(ierr); ierr = MatSeqAIJRestoreArray(sub_schurs->S_Ej_all,&matdata);CHKERRQ(ierr); ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_all,&matdata2);CHKERRQ(ierr); if (pcbddc->deluxe_singlemat) { deluxe_ctx->change = NULL; deluxe_ctx->change_with_qr = PETSC_FALSE; } if (deluxe_ctx->change && !deluxe_ctx->change_with_qr) { for (i=0;i<deluxe_ctx->seq_n;i++) { if (newsetup) { PC pc; ierr = KSPGetPC(deluxe_ctx->change[i],&pc);CHKERRQ(ierr); ierr = PCSetType(pc,PCLU);CHKERRQ(ierr); ierr = KSPSetFromOptions(deluxe_ctx->change[i]);CHKERRQ(ierr); } ierr = KSPSetUp(deluxe_ctx->change[i]);CHKERRQ(ierr); } } PetscFunctionReturn(0); }
PetscErrorCode DMCoarsen_AKKT(DM dm, MPI_Comm comm, DM *cdm) { PetscErrorCode ierr; DM_AKKT* kkt = (DM_AKKT*)(dm->data); Mat Acc; /* coarse-level KKT matrix */ Mat P0f0c, P1f1c; /* Primal and dual block prolongator */ DM dmc[2] = {PETSC_NULL, PETSC_NULL}; /* Coarse subDMs defining the block prolongators and the coarsened decomposition. */ PetscInt M0,N0,M1,N1; /* Sizes of P0f0c and P1f1c. */ PetscInt start0,end0,start1,end1; /* Ownership ranges for P0f0c and P1f1c. */ static Mat mats[4] = {PETSC_NULL, PETSC_NULL, PETSC_NULL, PETSC_NULL}; /* Used to construct MatNest out of pieces. */ IS isc[2]; /* Used to construct MatNest out of pieces and to define the coarsened decomposition. */ PetscFunctionBegin; if(!cdm) PetscFunctionReturn(0); if(kkt->cdm) { ierr = PetscObjectReference((PetscObject)(kkt->cdm)); CHKERRQ(ierr); *cdm = kkt->cdm; PetscFunctionReturn(0); } /* Coarsen the 00 block with the attached DM and obtain the primal prolongator. */ if(kkt->dmf[0]) { ierr = DMCoarsen(kkt->dmf[0], comm, dmc+0); CHKERRQ(ierr); ierr = DMCreateInterpolation(dmc[0], kkt->dmf[0], &P0f0c, PETSC_NULL); CHKERRQ(ierr); } else SETERRQ(((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "Could not coarsen the primal block: primal subDM not set."); /* Should P0f0c be transposed to act as a prolongator (i.e., to map from coarse to fine). */ ierr = MatGetSize(P0f0c, &M0, &N0); CHKERRQ(ierr); if(M0 == N0) SETERRQ1(((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONGSTATE,"Primal prolongator is square with size %D: cannot distinguish coarse from fine",M0); if(M0 < N0) kkt->transposeP = PETSC_TRUE; else kkt->transposeP = PETSC_FALSE; /* See if the 11 block can be coarsened with an attached DM. If so, we are done. Otherwise, use GAMG to coarsen 11. */ if(kkt->dmf[1]) { ierr = DMCoarsen(kkt->dmf[1], comm, &dmc[1]); CHKERRQ(ierr); ierr = DMCreateInterpolation(dmc[1], kkt->dmf[1], &P1f1c, PETSC_NULL); CHKERRQ(ierr); } else { ierr = DMCoarsen_AKKT_GAMG11(dm, P0f0c, &P1f1c); CHKERRQ(ierr); } /* Determine whether P1f1c should be transposed in order to act as a prolongator (i.e., to map from coarse to fine). */ ierr = MatGetSize(P1f1c, &M1, &N1); CHKERRQ(ierr); if(M1 == N1) SETERRQ1(((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "Dual prlongator is square with size %D: cannot distinguish coarse from fine", M1); if((M1 < N1 && !kkt->transposeP) || (M1 >= N1 && kkt->transposeP)) { Mat P1f1ct; ierr = MatTranspose(P1f1c, MAT_INITIAL_MATRIX, &P1f1ct); CHKERRQ(ierr); ierr = MatDestroy(&P1f1c); CHKERRQ(ierr); P1f1c = P1f1ct; } /* MatNest P0f0c, P1f1c together into Pfc. */ mats[0] = P0f0c; mats[3] = P1f1c; ierr = MatGetOwnershipRange(P0f0c, &start0, &end0); CHKERRQ(ierr); ierr = MatGetOwnershipRange(P1f1c, &start1, &end1); CHKERRQ(ierr); ierr = ISCreateStride(((PetscObject)dm)->comm, end0-start0,start0,1,isc+0); CHKERRQ(ierr); ierr = ISCreateStride(((PetscObject)dm)->comm, end1-start1,start1,1,isc+1); CHKERRQ(ierr); if(kkt->transposeP) { ierr = MatCreateNest(((PetscObject)dm)->comm,2,isc,2,kkt->isf,mats,&(kkt->Pfc)); CHKERRQ(ierr); } else { ierr = MatCreateNest(((PetscObject)dm)->comm,2,kkt->isf,2,isc,mats,&(kkt->Pfc)); CHKERRQ(ierr); } ierr = MatDestroy(&P0f0c); CHKERRQ(ierr); ierr = MatDestroy(&P1f1c); CHKERRQ(ierr); /* Coarsening the underlying matrix and primal-dual decomposition. */ /* We do not coarsen the underlying DM because (a) Its coarsening may be incompatible with the specialized KKT-aware coarsening of the blocks defined here. (b) Even if the coarsening the decomposition is compatible with the decomposition of the coarsening, we can pick the former without loss of generality. (c) Even if (b) is true, the embeddings (IS) of the coarsened subDMs are potentially different now from what they would be in the coarsened DM; thus, embeddings would have to be supplied manually anyhow. (d) In the typical situation we should only use the primal subDM for coarsening -- the whole point of DMAKKT is that the dual block coarsening should be derived from the primal block coarsening for compatibility. If we are given both subDMs, DMAKKT essentially becomes a version of DMComposite, in which case the composition of the coarsened decomposition is by definition the coarsening of the whole system DM. */ /* Create the coarser DM. */ ierr = DMCreate(((PetscObject)dm)->comm, &(kkt->cdm)); CHKERRQ(ierr); ierr = DMSetType(kkt->cdm, DMAKKT); CHKERRQ(ierr); /* Coarsen the underlying matrix. */ ierr = MatPtAP(kkt->Aff, kkt->Pfc, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &Acc); CHKERRQ(ierr); ierr = DMAKKTSetMatrix(dm, Acc); CHKERRQ(ierr); /* Set the coarsened decomposition. */ ierr = DMAKKTSetFieldDecomposition(kkt->cdm, 2, (const char**)kkt->names, isc, dmc); CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@C PCGAMGFilterGraph - filter (remove zero and possibly small values from the) graph and make it symmetric if requested Collective on Mat Input Parameter: + a_Gmat - the graph . vfilter - threshold paramter [0,1) - symm - make the result symmetric Level: developer Notes: This is called before graph coarsers are called. .seealso: PCGAMGSetThreshold() @*/ PetscErrorCode PCGAMGFilterGraph(Mat *a_Gmat,PetscReal vfilter,PetscBool symm) { PetscErrorCode ierr; PetscInt Istart,Iend,Ii,jj,ncols,nnz0,nnz1, NN, MM, nloc; PetscMPIInt rank; Mat Gmat = *a_Gmat, tGmat, matTrans; MPI_Comm comm; const PetscScalar *vals; const PetscInt *idx; PetscInt *d_nnz, *o_nnz; Vec diag; MatType mtype; PetscFunctionBegin; #if defined PETSC_GAMG_USE_LOG ierr = PetscLogEventBegin(petsc_gamg_setup_events[GRAPH],0,0,0,0);CHKERRQ(ierr); #endif /* scale Gmat for all values between -1 and 1 */ ierr = MatCreateVecs(Gmat, &diag, 0);CHKERRQ(ierr); ierr = MatGetDiagonal(Gmat, diag);CHKERRQ(ierr); ierr = VecReciprocal(diag);CHKERRQ(ierr); ierr = VecSqrtAbs(diag);CHKERRQ(ierr); ierr = MatDiagonalScale(Gmat, diag, diag);CHKERRQ(ierr); ierr = VecDestroy(&diag);CHKERRQ(ierr); if (vfilter < 0.0 && !symm) { /* Just use the provided matrix as the graph but make all values positive */ MatInfo info; PetscScalar *avals; PetscBool isaij,ismpiaij; ierr = PetscObjectBaseTypeCompare((PetscObject)Gmat,MATSEQAIJ,&isaij);CHKERRQ(ierr); ierr = PetscObjectBaseTypeCompare((PetscObject)Gmat,MATMPIAIJ,&ismpiaij);CHKERRQ(ierr); if (!isaij && !ismpiaij) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_USER,"Require (MPI)AIJ matrix type"); if (isaij) { ierr = MatGetInfo(Gmat,MAT_LOCAL,&info);CHKERRQ(ierr); ierr = MatSeqAIJGetArray(Gmat,&avals);CHKERRQ(ierr); for (jj = 0; jj<info.nz_used; jj++) avals[jj] = PetscAbsScalar(avals[jj]); ierr = MatSeqAIJRestoreArray(Gmat,&avals);CHKERRQ(ierr); } else { Mat_MPIAIJ *aij = (Mat_MPIAIJ*)Gmat->data; ierr = MatGetInfo(aij->A,MAT_LOCAL,&info);CHKERRQ(ierr); ierr = MatSeqAIJGetArray(aij->A,&avals);CHKERRQ(ierr); for (jj = 0; jj<info.nz_used; jj++) avals[jj] = PetscAbsScalar(avals[jj]); ierr = MatSeqAIJRestoreArray(aij->A,&avals);CHKERRQ(ierr); ierr = MatGetInfo(aij->B,MAT_LOCAL,&info);CHKERRQ(ierr); ierr = MatSeqAIJGetArray(aij->B,&avals);CHKERRQ(ierr); for (jj = 0; jj<info.nz_used; jj++) avals[jj] = PetscAbsScalar(avals[jj]); ierr = MatSeqAIJRestoreArray(aij->B,&avals);CHKERRQ(ierr); } #if defined PETSC_GAMG_USE_LOG ierr = PetscLogEventEnd(petsc_gamg_setup_events[GRAPH],0,0,0,0);CHKERRQ(ierr); #endif PetscFunctionReturn(0); } ierr = PetscObjectGetComm((PetscObject)Gmat,&comm);CHKERRQ(ierr); ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); ierr = MatGetOwnershipRange(Gmat, &Istart, &Iend);CHKERRQ(ierr); nloc = Iend - Istart; ierr = MatGetSize(Gmat, &MM, &NN);CHKERRQ(ierr); if (symm) { ierr = MatTranspose(Gmat, MAT_INITIAL_MATRIX, &matTrans);CHKERRQ(ierr); } /* Determine upper bound on nonzeros needed in new filtered matrix */ ierr = PetscMalloc2(nloc, &d_nnz,nloc, &o_nnz);CHKERRQ(ierr); for (Ii = Istart, jj = 0; Ii < Iend; Ii++, jj++) { ierr = MatGetRow(Gmat,Ii,&ncols,NULL,NULL);CHKERRQ(ierr); d_nnz[jj] = ncols; o_nnz[jj] = ncols; ierr = MatRestoreRow(Gmat,Ii,&ncols,NULL,NULL);CHKERRQ(ierr); if (symm) { ierr = MatGetRow(matTrans,Ii,&ncols,NULL,NULL);CHKERRQ(ierr); d_nnz[jj] += ncols; o_nnz[jj] += ncols; ierr = MatRestoreRow(matTrans,Ii,&ncols,NULL,NULL);CHKERRQ(ierr); } if (d_nnz[jj] > nloc) d_nnz[jj] = nloc; if (o_nnz[jj] > (MM-nloc)) o_nnz[jj] = MM - nloc; } ierr = MatGetType(Gmat,&mtype);CHKERRQ(ierr); ierr = MatCreate(comm, &tGmat);CHKERRQ(ierr); ierr = MatSetSizes(tGmat,nloc,nloc,MM,MM);CHKERRQ(ierr); ierr = MatSetBlockSizes(tGmat, 1, 1);CHKERRQ(ierr); ierr = MatSetType(tGmat, mtype);CHKERRQ(ierr); ierr = MatSeqAIJSetPreallocation(tGmat,0,d_nnz);CHKERRQ(ierr); ierr = MatMPIAIJSetPreallocation(tGmat,0,d_nnz,0,o_nnz);CHKERRQ(ierr); ierr = PetscFree2(d_nnz,o_nnz);CHKERRQ(ierr); if (symm) { ierr = MatDestroy(&matTrans);CHKERRQ(ierr); } else { /* all entries are generated locally so MatAssembly will be slightly faster for large process counts */ ierr = MatSetOption(tGmat,MAT_NO_OFF_PROC_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); } for (Ii = Istart, nnz0 = nnz1 = 0; Ii < Iend; Ii++) { ierr = MatGetRow(Gmat,Ii,&ncols,&idx,&vals);CHKERRQ(ierr); for (jj=0; jj<ncols; jj++,nnz0++) { PetscScalar sv = PetscAbs(PetscRealPart(vals[jj])); if (PetscRealPart(sv) > vfilter) { nnz1++; if (symm) { sv *= 0.5; ierr = MatSetValues(tGmat,1,&Ii,1,&idx[jj],&sv,ADD_VALUES);CHKERRQ(ierr); ierr = MatSetValues(tGmat,1,&idx[jj],1,&Ii,&sv,ADD_VALUES);CHKERRQ(ierr); } else { ierr = MatSetValues(tGmat,1,&Ii,1,&idx[jj],&sv,ADD_VALUES);CHKERRQ(ierr); } } } ierr = MatRestoreRow(Gmat,Ii,&ncols,&idx,&vals);CHKERRQ(ierr); } ierr = MatAssemblyBegin(tGmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(tGmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); #if defined PETSC_GAMG_USE_LOG ierr = PetscLogEventEnd(petsc_gamg_setup_events[GRAPH],0,0,0,0);CHKERRQ(ierr); #endif #if defined(PETSC_USE_INFO) { double t1 = (!nnz0) ? 1. : 100.*(double)nnz1/(double)nnz0, t2 = (!nloc) ? 1. : (double)nnz0/(double)nloc; ierr = PetscInfo4(*a_Gmat,"\t %g%% nnz after filtering, with threshold %g, %g nnz ave. (N=%D)\n",t1,vfilter,t2,MM);CHKERRQ(ierr); } #endif ierr = MatDestroy(&Gmat);CHKERRQ(ierr); *a_Gmat = tGmat; PetscFunctionReturn(0); }
int main(int argc,char **args) { Mat A,B; Vec xx,s1,s2,yy; PetscErrorCode ierr; PetscInt m=45,rows[2],cols[2],bs=1,i,row,col,*idx,M; PetscScalar rval,vals1[4],vals2[4]; PetscRandom rdm; IS is1,is2; PetscReal s1norm,s2norm,rnorm,tol = 1.e-4; PetscTruth flg; MatFactorInfo info; PetscInitialize(&argc,&args,(char *)0,help); /* Test MatSetValues() and MatGetValues() */ ierr = PetscOptionsGetInt(PETSC_NULL,"-mat_block_size",&bs,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-mat_size",&m,PETSC_NULL);CHKERRQ(ierr); M = m*bs; ierr = MatCreateSeqBAIJ(PETSC_COMM_SELF,bs,M,M,1,PETSC_NULL,&A);CHKERRQ(ierr); ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,M,M,15,PETSC_NULL,&B);CHKERRQ(ierr); ierr = PetscRandomCreate(PETSC_COMM_SELF,&rdm);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rdm);CHKERRQ(ierr); ierr = VecCreateSeq(PETSC_COMM_SELF,M,&xx);CHKERRQ(ierr); ierr = VecDuplicate(xx,&s1);CHKERRQ(ierr); ierr = VecDuplicate(xx,&s2);CHKERRQ(ierr); ierr = VecDuplicate(xx,&yy);CHKERRQ(ierr); /* For each row add atleast 15 elements */ for (row=0; row<M; row++) { for (i=0; i<25*bs; i++) { ierr = PetscRandomGetValue(rdm,&rval);CHKERRQ(ierr); col = (PetscInt)(PetscRealPart(rval)*M); ierr = MatSetValues(A,1,&row,1,&col,&rval,INSERT_VALUES);CHKERRQ(ierr); ierr = MatSetValues(B,1,&row,1,&col,&rval,INSERT_VALUES);CHKERRQ(ierr); } } /* Now set blocks of values */ for (i=0; i<20*bs; i++) { ierr = PetscRandomGetValue(rdm,&rval);CHKERRQ(ierr); cols[0] = (PetscInt)(PetscRealPart(rval)*M); vals1[0] = rval; ierr = PetscRandomGetValue(rdm,&rval);CHKERRQ(ierr); cols[1] = (PetscInt)(PetscRealPart(rval)*M); vals1[1] = rval; ierr = PetscRandomGetValue(rdm,&rval);CHKERRQ(ierr); rows[0] = (PetscInt)(PetscRealPart(rval)*M); vals1[2] = rval; ierr = PetscRandomGetValue(rdm,&rval);CHKERRQ(ierr); rows[1] = (PetscInt)(PetscRealPart(rval)*M); vals1[3] = rval; ierr = MatSetValues(A,2,rows,2,cols,vals1,INSERT_VALUES);CHKERRQ(ierr); ierr = MatSetValues(B,2,rows,2,cols,vals1,INSERT_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* Test MatNorm() */ ierr = MatNorm(A,NORM_FROBENIUS,&s1norm);CHKERRQ(ierr); ierr = MatNorm(B,NORM_FROBENIUS,&s2norm);CHKERRQ(ierr); rnorm = PetscAbsScalar(s2norm-s1norm)/s2norm; if ( rnorm>tol ) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error: MatNorm_FROBENIUS()- NormA=%16.14e NormB=%16.14e bs = %D\n",s1norm,s2norm,bs);CHKERRQ(ierr); } ierr = MatNorm(A,NORM_INFINITY,&s1norm);CHKERRQ(ierr); ierr = MatNorm(B,NORM_INFINITY,&s2norm);CHKERRQ(ierr); rnorm = PetscAbsScalar(s2norm-s1norm)/s2norm; if ( rnorm>tol ) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error: MatNorm_INFINITY()- NormA=%16.14e NormB=%16.14e bs = %D\n",s1norm,s2norm,bs);CHKERRQ(ierr); } ierr = MatNorm(A,NORM_1,&s1norm);CHKERRQ(ierr); ierr = MatNorm(B,NORM_1,&s2norm);CHKERRQ(ierr); rnorm = PetscAbsScalar(s2norm-s1norm)/s2norm; if ( rnorm>tol ) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error: MatNorm_NORM_1()- NormA=%16.14e NormB=%16.14e bs = %D\n",s1norm,s2norm,bs);CHKERRQ(ierr); } /* MatShift() */ rval = 10*s1norm; ierr = MatShift(A,rval);CHKERRQ(ierr); ierr = MatShift(B,rval);CHKERRQ(ierr); /* Test MatTranspose() */ ierr = MatTranspose(A,MAT_REUSE_MATRIX,&A);CHKERRQ(ierr); ierr = MatTranspose(B,MAT_REUSE_MATRIX,&B);CHKERRQ(ierr); /* Now do MatGetValues() */ for (i=0; i<30; i++) { ierr = PetscRandomGetValue(rdm,&rval);CHKERRQ(ierr); cols[0] = (PetscInt)(PetscRealPart(rval)*M); ierr = PetscRandomGetValue(rdm,&rval);CHKERRQ(ierr); cols[1] = (PetscInt)(PetscRealPart(rval)*M); ierr = PetscRandomGetValue(rdm,&rval);CHKERRQ(ierr); rows[0] = (PetscInt)(PetscRealPart(rval)*M); ierr = PetscRandomGetValue(rdm,&rval);CHKERRQ(ierr); rows[1] = (PetscInt)(PetscRealPart(rval)*M); ierr = MatGetValues(A,2,rows,2,cols,vals1);CHKERRQ(ierr); ierr = MatGetValues(B,2,rows,2,cols,vals2);CHKERRQ(ierr); ierr = PetscMemcmp(vals1,vals2,4*sizeof(PetscScalar),&flg);CHKERRQ(ierr); if (!flg) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error: MatGetValues bs = %D\n",bs);CHKERRQ(ierr); } } /* Test MatMult(), MatMultAdd() */ for (i=0; i<40; i++) { ierr = VecSetRandom(xx,rdm);CHKERRQ(ierr); ierr = VecSet(s2,0.0);CHKERRQ(ierr); ierr = MatMult(A,xx,s1);CHKERRQ(ierr); ierr = MatMultAdd(A,xx,s2,s2);CHKERRQ(ierr); ierr = VecNorm(s1,NORM_2,&s1norm);CHKERRQ(ierr); ierr = VecNorm(s2,NORM_2,&s2norm);CHKERRQ(ierr); rnorm = s2norm-s1norm; if (rnorm<-tol || rnorm>tol) { ierr = PetscPrintf(PETSC_COMM_SELF,"MatMult not equal to MatMultAdd Norm1=%e Norm2=%e bs = %D\n",s1norm,s2norm,bs);CHKERRQ(ierr); } } /* Test MatMult() */ ierr = MatMultEqual(A,B,10,&flg);CHKERRQ(ierr); if (!flg){ ierr = PetscPrintf(PETSC_COMM_SELF,"Error: MatMult()\n");CHKERRQ(ierr); } /* Test MatMultAdd() */ ierr = MatMultAddEqual(A,B,10,&flg);CHKERRQ(ierr); if (!flg){ ierr = PetscPrintf(PETSC_COMM_SELF,"Error: MatMultAdd()\n");CHKERRQ(ierr); } /* Test MatMultTranspose() */ ierr = MatMultTransposeEqual(A,B,10,&flg);CHKERRQ(ierr); if (!flg){ ierr = PetscPrintf(PETSC_COMM_SELF,"Error: MatMultTranspose()\n");CHKERRQ(ierr); } /* Test MatMultTransposeAdd() */ ierr = MatMultTransposeAddEqual(A,B,10,&flg);CHKERRQ(ierr); if (!flg){ ierr = PetscPrintf(PETSC_COMM_SELF,"Error: MatMultTransposeAdd()\n");CHKERRQ(ierr); } /* Do LUFactor() on both the matrices */ ierr = PetscMalloc(M*sizeof(PetscInt),&idx);CHKERRQ(ierr); for (i=0; i<M; i++) idx[i] = i; ierr = ISCreateGeneral(PETSC_COMM_SELF,M,idx,&is1);CHKERRQ(ierr); ierr = ISCreateGeneral(PETSC_COMM_SELF,M,idx,&is2);CHKERRQ(ierr); ierr = PetscFree(idx);CHKERRQ(ierr); ierr = ISSetPermutation(is1);CHKERRQ(ierr); ierr = ISSetPermutation(is2);CHKERRQ(ierr); ierr = MatFactorInfoInitialize(&info);CHKERRQ(ierr); info.fill = 2.0; info.dtcol = 0.0; info.zeropivot = 1.e-14; info.pivotinblocks = 1.0; ierr = MatLUFactor(B,is1,is2,&info);CHKERRQ(ierr); ierr = MatLUFactor(A,is1,is2,&info);CHKERRQ(ierr); /* Test MatSolveAdd() */ for (i=0; i<10; i++) { ierr = VecSetRandom(xx,rdm);CHKERRQ(ierr); ierr = VecSetRandom(yy,rdm);CHKERRQ(ierr); ierr = MatSolveAdd(B,xx,yy,s2);CHKERRQ(ierr); ierr = MatSolveAdd(A,xx,yy,s1);CHKERRQ(ierr); ierr = VecNorm(s1,NORM_2,&s1norm);CHKERRQ(ierr); ierr = VecNorm(s2,NORM_2,&s2norm);CHKERRQ(ierr); rnorm = s2norm-s1norm; if (rnorm<-tol || rnorm>tol) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error:MatSolveAdd - Norm1=%16.14e Norm2=%16.14e bs = %D\n",s1norm,s2norm,bs);CHKERRQ(ierr); } } /* Test MatSolveAdd() when x = A'b +x */ for (i=0; i<10; i++) { ierr = VecSetRandom(xx,rdm);CHKERRQ(ierr); ierr = VecSetRandom(s1,rdm);CHKERRQ(ierr); ierr = VecCopy(s2,s1);CHKERRQ(ierr); ierr = MatSolveAdd(B,xx,s2,s2);CHKERRQ(ierr); ierr = MatSolveAdd(A,xx,s1,s1);CHKERRQ(ierr); ierr = VecNorm(s1,NORM_2,&s1norm);CHKERRQ(ierr); ierr = VecNorm(s2,NORM_2,&s2norm);CHKERRQ(ierr); rnorm = s2norm-s1norm; if (rnorm<-tol || rnorm>tol) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error:MatSolveAdd(same) - Norm1=%16.14e Norm2=%16.14e bs = %D\n",s1norm,s2norm,bs);CHKERRQ(ierr); } } /* Test MatSolve() */ for (i=0; i<10; i++) { ierr = VecSetRandom(xx,rdm);CHKERRQ(ierr); ierr = MatSolve(B,xx,s2);CHKERRQ(ierr); ierr = MatSolve(A,xx,s1);CHKERRQ(ierr); ierr = VecNorm(s1,NORM_2,&s1norm);CHKERRQ(ierr); ierr = VecNorm(s2,NORM_2,&s2norm);CHKERRQ(ierr); rnorm = s2norm-s1norm; if (rnorm<-tol || rnorm>tol) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error:MatSolve - Norm1=%16.14e Norm2=%16.14e bs = %D\n",s1norm,s2norm,bs);CHKERRQ(ierr); } } /* Test MatSolveTranspose() */ if (bs < 8) { for (i=0; i<10; i++) { ierr = VecSetRandom(xx,rdm);CHKERRQ(ierr); ierr = MatSolveTranspose(B,xx,s2);CHKERRQ(ierr); ierr = MatSolveTranspose(A,xx,s1);CHKERRQ(ierr); ierr = VecNorm(s1,NORM_2,&s1norm);CHKERRQ(ierr); ierr = VecNorm(s2,NORM_2,&s2norm);CHKERRQ(ierr); rnorm = s2norm-s1norm; if (rnorm<-tol || rnorm>tol) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error:MatSolveTranspose - Norm1=%16.14e Norm2=%16.14e bs = %D\n",s1norm,s2norm,bs);CHKERRQ(ierr); } } } ierr = MatDestroy(A);CHKERRQ(ierr); ierr = MatDestroy(B);CHKERRQ(ierr); ierr = VecDestroy(xx);CHKERRQ(ierr); ierr = VecDestroy(s1);CHKERRQ(ierr); ierr = VecDestroy(s2);CHKERRQ(ierr); ierr = VecDestroy(yy);CHKERRQ(ierr); ierr = ISDestroy(is1);CHKERRQ(ierr); ierr = ISDestroy(is2);CHKERRQ(ierr); ierr = PetscRandomDestroy(rdm);CHKERRQ(ierr); ierr = PetscFinalize();CHKERRQ(ierr); return 0; }
int main(int argc,char **argv) { PetscErrorCode ierr; KSP ksp; PC pc; Vec x,b; DA da; Mat A,Atrans; PetscInt dof=1,M=-8; PetscTruth flg,trans=PETSC_FALSE; PetscInitialize(&argc,&argv,(char *)0,help); ierr = PetscOptionsGetInt(PETSC_NULL,"-dof",&dof,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-M",&M,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetTruth(PETSC_NULL,"-trans",&trans,PETSC_NULL);CHKERRQ(ierr); ierr = DACreate(PETSC_COMM_WORLD,&da);CHKERRQ(ierr); ierr = DASetDim(da,3);CHKERRQ(ierr); ierr = DASetPeriodicity(da,DA_NONPERIODIC);CHKERRQ(ierr); ierr = DASetStencilType(da,DA_STENCIL_STAR);CHKERRQ(ierr); ierr = DASetSizes(da,M,M,M);CHKERRQ(ierr); ierr = DASetNumProcs(da,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); ierr = DASetDof(da,dof);CHKERRQ(ierr); ierr = DASetStencilWidth(da,1);CHKERRQ(ierr); ierr = DASetVertexDivision(da,PETSC_NULL,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); ierr = DASetFromOptions(da);CHKERRQ(ierr); ierr = DACreateGlobalVector(da,&x);CHKERRQ(ierr); ierr = DACreateGlobalVector(da,&b);CHKERRQ(ierr); ierr = ComputeRHS(da,b);CHKERRQ(ierr); ierr = DAGetMatrix(da,MATBAIJ,&A);CHKERRQ(ierr); ierr = ComputeMatrix(da,A);CHKERRQ(ierr); /* A is non-symmetric. Make A = 0.5*(A + Atrans) symmetric for testing icc and cholesky */ ierr = MatTranspose(A,MAT_INITIAL_MATRIX,&Atrans);CHKERRQ(ierr); ierr = MatAXPY(A,1.0,Atrans,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); ierr = MatScale(A,0.5);CHKERRQ(ierr); ierr = MatDestroy(Atrans);CHKERRQ(ierr); /* Test sbaij matrix */ flg = PETSC_FALSE; ierr = PetscOptionsGetTruth(PETSC_NULL, "-test_sbaij1", &flg,PETSC_NULL);CHKERRQ(ierr); if (flg){ Mat sA; ierr = MatConvert(A,MATSBAIJ,MAT_INITIAL_MATRIX,&sA);CHKERRQ(ierr); ierr = MatDestroy(A);CHKERRQ(ierr); A = sA; } ierr = KSPCreate(PETSC_COMM_WORLD,&ksp);CHKERRQ(ierr); ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr); ierr = KSPSetOperators(ksp,A,A,SAME_NONZERO_PATTERN);CHKERRQ(ierr); ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); ierr = PCSetDA(pc,da);CHKERRQ(ierr); if (trans) { ierr = KSPSolveTranspose(ksp,b,x);CHKERRQ(ierr); } else { ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); } /* check final residual */ flg = PETSC_FALSE; ierr = PetscOptionsGetTruth(PETSC_NULL, "-check_final_residual", &flg,PETSC_NULL);CHKERRQ(ierr); if (flg){ Vec b1; PetscReal norm; ierr = KSPGetSolution(ksp,&x);CHKERRQ(ierr); ierr = VecDuplicate(b,&b1);CHKERRQ(ierr); ierr = MatMult(A,x,b1);CHKERRQ(ierr); ierr = VecAXPY(b1,-1.0,b);CHKERRQ(ierr); ierr = VecNorm(b1,NORM_2,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Final residual %g\n",norm);CHKERRQ(ierr); ierr = VecDestroy(b1);CHKERRQ(ierr); } ierr = KSPDestroy(ksp);CHKERRQ(ierr); ierr = VecDestroy(x);CHKERRQ(ierr); ierr = VecDestroy(b);CHKERRQ(ierr); ierr = MatDestroy(A);CHKERRQ(ierr); ierr = DADestroy(da);CHKERRQ(ierr); ierr = PetscFinalize();CHKERRQ(ierr); return 0; }
PetscErrorCode test_solve(void) { Mat A11, A12,A21,A22, A, tmp[2][2]; KSP ksp; PC pc; Vec b,x, f,h, diag, x1,x2; Vec tmp_x[2],*_tmp_x; int n, np, i,j; PetscErrorCode ierr; PetscFunctionBeginUser; PetscPrintf(PETSC_COMM_WORLD, "%s \n", PETSC_FUNCTION_NAME); n = 3; np = 2; /* Create matrices */ /* A11 */ ierr = VecCreate(PETSC_COMM_WORLD, &diag);CHKERRQ(ierr); ierr = VecSetSizes(diag, PETSC_DECIDE, n);CHKERRQ(ierr); ierr = VecSetFromOptions(diag);CHKERRQ(ierr); ierr = VecSet(diag, (1.0/10.0));CHKERRQ(ierr); /* so inverse = diag(10) */ /* As a test, create a diagonal matrix for A11 */ ierr = MatCreate(PETSC_COMM_WORLD, &A11);CHKERRQ(ierr); ierr = MatSetSizes(A11, PETSC_DECIDE, PETSC_DECIDE, n, n);CHKERRQ(ierr); ierr = MatSetType(A11, MATAIJ);CHKERRQ(ierr); ierr = MatSeqAIJSetPreallocation(A11, n, NULL);CHKERRQ(ierr); ierr = MatMPIAIJSetPreallocation(A11, np, NULL,np, NULL);CHKERRQ(ierr); ierr = MatDiagonalSet(A11, diag, INSERT_VALUES);CHKERRQ(ierr); ierr = VecDestroy(&diag);CHKERRQ(ierr); /* A12 */ ierr = MatCreate(PETSC_COMM_WORLD, &A12);CHKERRQ(ierr); ierr = MatSetSizes(A12, PETSC_DECIDE, PETSC_DECIDE, n, np);CHKERRQ(ierr); ierr = MatSetType(A12, MATAIJ);CHKERRQ(ierr); ierr = MatSeqAIJSetPreallocation(A12, np, NULL);CHKERRQ(ierr); ierr = MatMPIAIJSetPreallocation(A12, np, NULL,np, NULL);CHKERRQ(ierr); for (i=0; i<n; i++) { for (j=0; j<np; j++) { ierr = MatSetValue(A12, i,j, (PetscScalar)(i+j*n), INSERT_VALUES);CHKERRQ(ierr); } } ierr = MatSetValue(A12, 2,1, (PetscScalar)(4), INSERT_VALUES);CHKERRQ(ierr); ierr = MatAssemblyBegin(A12, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A12, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* A21 */ ierr = MatTranspose(A12, MAT_INITIAL_MATRIX, &A21);CHKERRQ(ierr); A22 = NULL; /* Create block matrix */ tmp[0][0] = A11; tmp[0][1] = A12; tmp[1][0] = A21; tmp[1][1] = A22; ierr = MatCreateNest(PETSC_COMM_WORLD,2,NULL,2,NULL,&tmp[0][0],&A);CHKERRQ(ierr); ierr = MatNestSetVecType(A,VECNEST);CHKERRQ(ierr); ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* Create vectors */ ierr = MatCreateVecs(A12, &h, &f);CHKERRQ(ierr); ierr = VecSet(f, 1.0);CHKERRQ(ierr); ierr = VecSet(h, 0.0);CHKERRQ(ierr); /* Create block vector */ tmp_x[0] = f; tmp_x[1] = h; ierr = VecCreateNest(PETSC_COMM_WORLD,2,NULL,tmp_x,&b);CHKERRQ(ierr); ierr = VecAssemblyBegin(b);CHKERRQ(ierr); ierr = VecAssemblyEnd(b);CHKERRQ(ierr); ierr = VecDuplicate(b, &x);CHKERRQ(ierr); ierr = KSPCreate(PETSC_COMM_WORLD, &ksp);CHKERRQ(ierr); ierr = KSPSetOperators(ksp, A, A);CHKERRQ(ierr); ierr = KSPSetType(ksp, "gmres");CHKERRQ(ierr); ierr = KSPGetPC(ksp, &pc);CHKERRQ(ierr); ierr = PCSetType(pc, "none");CHKERRQ(ierr); ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr); ierr = KSPSolve(ksp, b, x);CHKERRQ(ierr); ierr = VecNestGetSubVecs(x,NULL,&_tmp_x);CHKERRQ(ierr); x1 = _tmp_x[0]; x2 = _tmp_x[1]; PetscPrintf(PETSC_COMM_WORLD, "x1 \n"); PetscViewerPushFormat(PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_ASCII_INFO_DETAIL);CHKERRQ(ierr); ierr = VecView(x1, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); PetscPrintf(PETSC_COMM_WORLD, "x2 \n"); ierr = VecView(x2, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); PetscViewerPopFormat(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = KSPDestroy(&ksp);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = MatDestroy(&A11);CHKERRQ(ierr); ierr = MatDestroy(&A12);CHKERRQ(ierr); ierr = MatDestroy(&A21);CHKERRQ(ierr); ierr = VecDestroy(&f);CHKERRQ(ierr); ierr = VecDestroy(&h);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); PetscFunctionReturn(0); }