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; PetscBool flg; MatFactorInfo info; PetscInitialize(&argc,&args,(char*)0,help); /* Test MatSetValues() and MatGetValues() */ ierr = PetscOptionsGetInt(NULL,"-mat_block_size",&bs,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,"-mat_size",&m,NULL);CHKERRQ(ierr); M = m*bs; ierr = MatCreateSeqBAIJ(PETSC_COMM_SELF,bs,M,M,1,NULL,&A);CHKERRQ(ierr); ierr = MatSetOption(A,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,M,M,15,NULL,&B);CHKERRQ(ierr); ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);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 = PetscMalloc1(M,&idx);CHKERRQ(ierr); for (i=0; i<M; i++) idx[i] = i; ierr = ISCreateGeneral(PETSC_COMM_SELF,M,idx,PETSC_COPY_VALUES,&is1);CHKERRQ(ierr); ierr = ISCreateGeneral(PETSC_COMM_SELF,M,idx,PETSC_COPY_VALUES,&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(); return 0; }
int main(int argc,char **args) { Mat A,RHS,C,F,X,S; Vec u,x,b; Vec xschur,bschur,uschur; IS is_schur; PetscErrorCode ierr; PetscMPIInt size; PetscInt isolver=0,size_schur,m,n,nfact,nsolve,nrhs; PetscReal norm,tol=PETSC_SQRT_MACHINE_EPSILON; PetscRandom rand; PetscBool data_provided,herm,symm,use_lu; PetscReal sratio = 5.1/12.; PetscViewer fd; /* viewer */ char solver[256]; char file[PETSC_MAX_PATH_LEN]; /* input file name */ PetscInitialize(&argc,&args,(char*)0,help); ierr = MPI_Comm_size(PETSC_COMM_WORLD, &size);CHKERRQ(ierr); if (size > 1) SETERRQ(PETSC_COMM_WORLD,1,"This is a uniprocessor test"); /* Determine which type of solver we want to test for */ herm = PETSC_FALSE; symm = PETSC_FALSE; ierr = PetscOptionsGetBool(NULL,NULL,"-symmetric_solve",&symm,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-hermitian_solve",&herm,NULL);CHKERRQ(ierr); if (herm) symm = PETSC_TRUE; /* Determine file from which we read the matrix A */ ierr = PetscOptionsGetString(NULL,NULL,"-f",file,PETSC_MAX_PATH_LEN,&data_provided);CHKERRQ(ierr); if (!data_provided) { /* get matrices from PETSc distribution */ sprintf(file,PETSC_DIR); ierr = PetscStrcat(file,"/share/petsc/datafiles/matrices/");CHKERRQ(ierr); if (symm) { #if defined (PETSC_USE_COMPLEX) ierr = PetscStrcat(file,"hpd-complex-");CHKERRQ(ierr); #else ierr = PetscStrcat(file,"spd-real-");CHKERRQ(ierr); #endif } else { #if defined (PETSC_USE_COMPLEX) ierr = PetscStrcat(file,"nh-complex-");CHKERRQ(ierr); #else ierr = PetscStrcat(file,"ns-real-");CHKERRQ(ierr); #endif } #if defined(PETSC_USE_64BIT_INDICES) ierr = PetscStrcat(file,"int64-");CHKERRQ(ierr); #else ierr = PetscStrcat(file,"int32-");CHKERRQ(ierr); #endif #if defined (PETSC_USE_REAL_SINGLE) ierr = PetscStrcat(file,"float32");CHKERRQ(ierr); #else ierr = PetscStrcat(file,"float64");CHKERRQ(ierr); #endif } /* Load matrix A */ ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,file,FILE_MODE_READ,&fd);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatLoad(A,fd);CHKERRQ(ierr); ierr = PetscViewerDestroy(&fd);CHKERRQ(ierr); ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr); if (m != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ, "This example is not intended for rectangular matrices (%d, %d)", m, n); /* Create dense matrix C and X; C holds true solution with identical colums */ nrhs = 2; ierr = PetscOptionsGetInt(NULL,NULL,"-nrhs",&nrhs,NULL);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&C);CHKERRQ(ierr); ierr = MatSetSizes(C,m,PETSC_DECIDE,PETSC_DECIDE,nrhs);CHKERRQ(ierr); ierr = MatSetType(C,MATDENSE);CHKERRQ(ierr); ierr = MatSetFromOptions(C);CHKERRQ(ierr); ierr = MatSetUp(C);CHKERRQ(ierr); ierr = PetscRandomCreate(PETSC_COMM_WORLD,&rand);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rand);CHKERRQ(ierr); ierr = MatSetRandom(C,rand);CHKERRQ(ierr); ierr = MatDuplicate(C,MAT_DO_NOT_COPY_VALUES,&X);CHKERRQ(ierr); /* Create vectors */ ierr = VecCreate(PETSC_COMM_WORLD,&x);CHKERRQ(ierr); ierr = VecSetSizes(x,n,PETSC_DECIDE);CHKERRQ(ierr); ierr = VecSetFromOptions(x);CHKERRQ(ierr); ierr = VecDuplicate(x,&b);CHKERRQ(ierr); ierr = VecDuplicate(x,&u);CHKERRQ(ierr); /* save the true solution */ ierr = PetscOptionsGetInt(NULL,NULL,"-solver",&isolver,NULL);CHKERRQ(ierr); switch (isolver) { #if defined(PETSC_HAVE_MUMPS) case 0: ierr = PetscStrcpy(solver,MATSOLVERMUMPS);CHKERRQ(ierr); break; #endif #if defined(PETSC_HAVE_MKL_PARDISO) case 1: ierr = PetscStrcpy(solver,MATSOLVERMKL_PARDISO);CHKERRQ(ierr); break; #endif default: ierr = PetscStrcpy(solver,MATSOLVERPETSC);CHKERRQ(ierr); break; } #if defined (PETSC_USE_COMPLEX) if (isolver == 0 && symm && !data_provided) { /* MUMPS (5.0.0) does not have support for hermitian matrices, so make them symmetric */ PetscScalar im = PetscSqrtScalar((PetscScalar)-1.); PetscScalar val = -1.0; val = val + im; ierr = MatSetValue(A,1,0,val,INSERT_VALUES);CHKERRQ(ierr); ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); } #endif ierr = PetscOptionsGetReal(NULL,NULL,"-schur_ratio",&sratio,NULL);CHKERRQ(ierr); if (sratio < 0. || sratio > 1.) { SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ, "Invalid ratio for schur degrees of freedom %f", sratio); } size_schur = (PetscInt)(sratio*m); ierr = PetscPrintf(PETSC_COMM_SELF,"Solving with %s: nrhs %d, sym %d, herm %d, size schur %d, size mat %d\n",solver,nrhs,symm,herm,size_schur,m);CHKERRQ(ierr); /* Test LU/Cholesky Factorization */ use_lu = PETSC_FALSE; if (!symm) use_lu = PETSC_TRUE; #if defined (PETSC_USE_COMPLEX) if (isolver == 1) use_lu = PETSC_TRUE; #endif if (herm && !use_lu) { /* test also conversion routines inside the solver packages */ ierr = MatSetOption(A,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); ierr = MatConvert(A,MATSEQSBAIJ,MAT_INPLACE_MATRIX,&A);CHKERRQ(ierr); } if (use_lu) { ierr = MatGetFactor(A,solver,MAT_FACTOR_LU,&F);CHKERRQ(ierr); } else { if (herm) { ierr = MatSetOption(A,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); ierr = MatSetOption(A,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); } else { ierr = MatSetOption(A,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); ierr = MatSetOption(A,MAT_SPD,PETSC_FALSE);CHKERRQ(ierr); } ierr = MatGetFactor(A,solver,MAT_FACTOR_CHOLESKY,&F);CHKERRQ(ierr); } ierr = ISCreateStride(PETSC_COMM_SELF,size_schur,m-size_schur,1,&is_schur);CHKERRQ(ierr); ierr = MatFactorSetSchurIS(F,is_schur);CHKERRQ(ierr); ierr = ISDestroy(&is_schur);CHKERRQ(ierr); if (use_lu) { ierr = MatLUFactorSymbolic(F,A,NULL,NULL,NULL);CHKERRQ(ierr); } else { ierr = MatCholeskyFactorSymbolic(F,A,NULL,NULL);CHKERRQ(ierr); } for (nfact = 0; nfact < 3; nfact++) { Mat AD; if (!nfact) { ierr = VecSetRandom(x,rand);CHKERRQ(ierr); if (symm && herm) { ierr = VecAbs(x);CHKERRQ(ierr); } ierr = MatDiagonalSet(A,x,ADD_VALUES);CHKERRQ(ierr); } if (use_lu) { ierr = MatLUFactorNumeric(F,A,NULL);CHKERRQ(ierr); } else { ierr = MatCholeskyFactorNumeric(F,A,NULL);CHKERRQ(ierr); } ierr = MatFactorCreateSchurComplement(F,&S);CHKERRQ(ierr); ierr = MatCreateVecs(S,&xschur,&bschur);CHKERRQ(ierr); ierr = VecDuplicate(xschur,&uschur);CHKERRQ(ierr); if (nfact == 1) { ierr = MatFactorInvertSchurComplement(F);CHKERRQ(ierr); } for (nsolve = 0; nsolve < 2; nsolve++) { ierr = VecSetRandom(x,rand);CHKERRQ(ierr); ierr = VecCopy(x,u);CHKERRQ(ierr); if (nsolve) { ierr = MatMult(A,x,b);CHKERRQ(ierr); ierr = MatSolve(F,b,x);CHKERRQ(ierr); } else { ierr = MatMultTranspose(A,x,b);CHKERRQ(ierr); ierr = MatSolveTranspose(F,b,x);CHKERRQ(ierr); } /* Check the error */ ierr = VecAXPY(u,-1.0,x);CHKERRQ(ierr); /* u <- (-1.0)x + u */ ierr = VecNorm(u,NORM_2,&norm);CHKERRQ(ierr); if (norm > tol) { PetscReal resi; if (nsolve) { ierr = MatMult(A,x,u);CHKERRQ(ierr); /* u = A*x */ } else { ierr = MatMultTranspose(A,x,u);CHKERRQ(ierr); /* u = A*x */ } ierr = VecAXPY(u,-1.0,b);CHKERRQ(ierr); /* u <- (-1.0)b + u */ ierr = VecNorm(u,NORM_2,&resi);CHKERRQ(ierr); if (nsolve) { ierr = PetscPrintf(PETSC_COMM_SELF,"(f %d, s %d) MatSolve error: Norm of error %g, residual %f\n",nfact,nsolve,norm,resi);CHKERRQ(ierr); } else { ierr = PetscPrintf(PETSC_COMM_SELF,"(f %d, s %d) MatSolveTranspose error: Norm of error %g, residual %f\n",nfact,nsolve,norm,resi);CHKERRQ(ierr); } } ierr = VecSetRandom(xschur,rand);CHKERRQ(ierr); ierr = VecCopy(xschur,uschur);CHKERRQ(ierr); if (nsolve) { ierr = MatMult(S,xschur,bschur);CHKERRQ(ierr); ierr = MatFactorSolveSchurComplement(F,bschur,xschur);CHKERRQ(ierr); } else { ierr = MatMultTranspose(S,xschur,bschur);CHKERRQ(ierr); ierr = MatFactorSolveSchurComplementTranspose(F,bschur,xschur);CHKERRQ(ierr); } /* Check the error */ ierr = VecAXPY(uschur,-1.0,xschur);CHKERRQ(ierr); /* u <- (-1.0)x + u */ ierr = VecNorm(uschur,NORM_2,&norm);CHKERRQ(ierr); if (norm > tol) { PetscReal resi; if (nsolve) { ierr = MatMult(S,xschur,uschur);CHKERRQ(ierr); /* u = A*x */ } else { ierr = MatMultTranspose(S,xschur,uschur);CHKERRQ(ierr); /* u = A*x */ } ierr = VecAXPY(uschur,-1.0,bschur);CHKERRQ(ierr); /* u <- (-1.0)b + u */ ierr = VecNorm(uschur,NORM_2,&resi);CHKERRQ(ierr); if (nsolve) { ierr = PetscPrintf(PETSC_COMM_SELF,"(f %d, s %d) MatFactorSolveSchurComplement error: Norm of error %g, residual %f\n",nfact,nsolve,norm,resi);CHKERRQ(ierr); } else { ierr = PetscPrintf(PETSC_COMM_SELF,"(f %d, s %d) MatFactorSolveSchurComplementTranspose error: Norm of error %g, residual %f\n",nfact,nsolve,norm,resi);CHKERRQ(ierr); } } } ierr = MatConvert(A,MATSEQAIJ,MAT_INITIAL_MATRIX,&AD); if (!nfact) { ierr = MatMatMult(AD,C,MAT_INITIAL_MATRIX,2.0,&RHS);CHKERRQ(ierr); } else { ierr = MatMatMult(AD,C,MAT_REUSE_MATRIX,2.0,&RHS);CHKERRQ(ierr); } ierr = MatDestroy(&AD);CHKERRQ(ierr); for (nsolve = 0; nsolve < 2; nsolve++) { ierr = MatMatSolve(F,RHS,X);CHKERRQ(ierr); /* Check the error */ ierr = MatAXPY(X,-1.0,C,SAME_NONZERO_PATTERN);CHKERRQ(ierr); ierr = MatNorm(X,NORM_FROBENIUS,&norm);CHKERRQ(ierr); if (norm > tol) { ierr = PetscPrintf(PETSC_COMM_SELF,"(f %D, s %D) MatMatSolve: Norm of error %g\n",nfact,nsolve,norm);CHKERRQ(ierr); } } ierr = MatDestroy(&S);CHKERRQ(ierr); ierr = VecDestroy(&xschur);CHKERRQ(ierr); ierr = VecDestroy(&bschur);CHKERRQ(ierr); ierr = VecDestroy(&uschur);CHKERRQ(ierr); } /* Free data structures */ ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = MatDestroy(&C);CHKERRQ(ierr); ierr = MatDestroy(&F);CHKERRQ(ierr); ierr = MatDestroy(&X);CHKERRQ(ierr); ierr = MatDestroy(&RHS);CHKERRQ(ierr); ierr = PetscRandomDestroy(&rand);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = VecDestroy(&u);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
int main(int argc,char **argv) { Mat A,B,C,D; PetscInt i,M,N,Istart,Iend,n=7,j,J,Ii,m=8,am,an; PetscScalar v; PetscErrorCode ierr; PetscRandom r; PetscBool equal=PETSC_FALSE; PetscReal fill = 1.0; PetscMPIInt size; PetscInitialize(&argc,&argv,(char*)0,help); ierr = PetscOptionsGetInt(NULL,"-m",&m,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,"-n",&n,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,"-fill",&fill,NULL);CHKERRQ(ierr); ierr = PetscRandomCreate(PETSC_COMM_WORLD,&r);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(r);CHKERRQ(ierr); /* Create a aij matrix A */ M = N = m*n; ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); ierr = MatSetType(A,MATAIJ);CHKERRQ(ierr); ierr = MatSetFromOptions(A);CHKERRQ(ierr); ierr = MatMPIAIJSetPreallocation(A,5,NULL,5,NULL);CHKERRQ(ierr); ierr = MatSeqAIJSetPreallocation(A,5,NULL);CHKERRQ(ierr); ierr = MatGetOwnershipRange(A,&Istart,&Iend);CHKERRQ(ierr); am = Iend - Istart; for (Ii=Istart; Ii<Iend; 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,INSERT_VALUES);CHKERRQ(ierr);} if (i<m-1) {J = Ii + n; ierr = MatSetValues(A,1,&Ii,1,&J,&v,INSERT_VALUES);CHKERRQ(ierr);} if (j>0) {J = Ii - 1; ierr = MatSetValues(A,1,&Ii,1,&J,&v,INSERT_VALUES);CHKERRQ(ierr);} if (j<n-1) {J = Ii + 1; ierr = MatSetValues(A,1,&Ii,1,&J,&v,INSERT_VALUES);CHKERRQ(ierr);} v = 4.0; ierr = MatSetValues(A,1,&Ii,1,&Ii,&v,INSERT_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* Create a dense matrix B */ ierr = MatGetLocalSize(A,&am,&an);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&B);CHKERRQ(ierr); ierr = MatSetSizes(B,an,PETSC_DECIDE,PETSC_DECIDE,M);CHKERRQ(ierr); ierr = MatSetType(B,MATDENSE);CHKERRQ(ierr); ierr = MatSeqDenseSetPreallocation(B,NULL);CHKERRQ(ierr); ierr = MatMPIDenseSetPreallocation(B,NULL);CHKERRQ(ierr); ierr = MatSetFromOptions(B);CHKERRQ(ierr); ierr = MatSetRandom(B,r);CHKERRQ(ierr); ierr = PetscRandomDestroy(&r);CHKERRQ(ierr); ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* Test C = A*B (aij*dense) */ ierr = MatMatMult(A,B,MAT_INITIAL_MATRIX,fill,&C);CHKERRQ(ierr); ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,fill,&C);CHKERRQ(ierr); ierr = MatMatMultSymbolic(A,B,fill,&D);CHKERRQ(ierr); for (i=0; i<2; i++) { ierr = MatMatMultNumeric(A,B,D);CHKERRQ(ierr); } ierr = MatEqual(C,D,&equal);CHKERRQ(ierr); if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"C != D"); ierr = MatDestroy(&D);CHKERRQ(ierr); /* Test D = C*A (dense*aij) */ ierr = MatMatMult(C,A,MAT_INITIAL_MATRIX,fill,&D);CHKERRQ(ierr); ierr = MatMatMult(C,A,MAT_REUSE_MATRIX,fill,&D);CHKERRQ(ierr); ierr = MatDestroy(&D);CHKERRQ(ierr); /* Test D = A*C (aij*dense) */ ierr = MatMatMult(A,C,MAT_INITIAL_MATRIX,fill,&D);CHKERRQ(ierr); ierr = MatMatMult(A,C,MAT_REUSE_MATRIX,fill,&D);CHKERRQ(ierr); ierr = MatDestroy(&D);CHKERRQ(ierr); /* Test D = B*C (dense*dense) */ ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); if (size == 1) { ierr = MatMatMult(B,C,MAT_INITIAL_MATRIX,fill,&D);CHKERRQ(ierr); ierr = MatMatMult(B,C,MAT_REUSE_MATRIX,fill,&D);CHKERRQ(ierr); ierr = MatDestroy(&D);CHKERRQ(ierr); } ierr = MatDestroy(&C);CHKERRQ(ierr); ierr = MatDestroy(&B);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); PetscFinalize(); return(0); }
int main(int argc,char **argv) { Mat A,F,B,X,C,Aher,G; Vec b,x,c,d,e; PetscErrorCode ierr; PetscInt m = 5,n,p,i,j,nrows,ncols; PetscScalar *v,*barray,rval; PetscReal norm,tol=1.e-12; PetscMPIInt size,rank; PetscRandom rand; const PetscInt *rows,*cols; IS isrows,iscols; PetscBool mats_view=PETSC_FALSE; MatFactorInfo finfo; PetscInitialize(&argc,&argv,(char*) 0,help); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); ierr = PetscRandomCreate(PETSC_COMM_WORLD,&rand);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rand);CHKERRQ(ierr); /* Get local dimensions of matrices */ ierr = PetscOptionsGetInt(NULL,"-m",&m,NULL);CHKERRQ(ierr); n = m; ierr = PetscOptionsGetInt(NULL,"-n",&n,NULL);CHKERRQ(ierr); p = m/2; ierr = PetscOptionsGetInt(NULL,"-p",&p,NULL);CHKERRQ(ierr); ierr = PetscOptionsHasName(NULL,"-mats_view",&mats_view);CHKERRQ(ierr); /* Create matrix A */ ierr = PetscPrintf(PETSC_COMM_WORLD," Create Elemental matrix A\n");CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatSetSizes(A,m,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); ierr = MatSetType(A,MATELEMENTAL);CHKERRQ(ierr); ierr = MatSetFromOptions(A);CHKERRQ(ierr); ierr = MatSetUp(A);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(rand,&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); if (mats_view) { ierr = PetscPrintf(PETSC_COMM_WORLD, "A: nrows %d, m %d; ncols %d, n %d\n",nrows,m,ncols,n);CHKERRQ(ierr); ierr = MatView(A,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } /* Create rhs matrix B */ ierr = PetscPrintf(PETSC_COMM_WORLD," Create rhs matrix B\n");CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&B);CHKERRQ(ierr); ierr = MatSetSizes(B,m,p,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); ierr = MatSetType(B,MATELEMENTAL);CHKERRQ(ierr); ierr = MatSetFromOptions(B);CHKERRQ(ierr); ierr = MatSetUp(B);CHKERRQ(ierr); ierr = MatGetOwnershipIS(B,&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(rand,&rval);CHKERRQ(ierr); v[i*ncols+j] = rval; } } ierr = MatSetValues(B,nrows,rows,ncols,cols,v,INSERT_VALUES);CHKERRQ(ierr); ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(B,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); if (mats_view) { ierr = PetscPrintf(PETSC_COMM_WORLD, "B: nrows %d, m %d; ncols %d, p %d\n",nrows,m,ncols,p);CHKERRQ(ierr); ierr = MatView(B,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } /* Create rhs vector b and solution x (same size as b) */ ierr = VecCreate(PETSC_COMM_WORLD,&b);CHKERRQ(ierr); ierr = VecSetSizes(b,m,PETSC_DECIDE);CHKERRQ(ierr); ierr = VecSetFromOptions(b);CHKERRQ(ierr); ierr = VecGetArray(b,&barray);CHKERRQ(ierr); for (j=0; j<m; j++) { ierr = PetscRandomGetValue(rand,&rval);CHKERRQ(ierr); barray[j] = rval; } ierr = VecRestoreArray(b,&barray);CHKERRQ(ierr); ierr = VecAssemblyBegin(b);CHKERRQ(ierr); ierr = VecAssemblyEnd(b);CHKERRQ(ierr); if (mats_view) { ierr = PetscSynchronizedPrintf(PETSC_COMM_WORLD, "[%d] b: m %d\n",rank,m);CHKERRQ(ierr); ierr = PetscSynchronizedFlush(PETSC_COMM_WORLD,PETSC_STDOUT);CHKERRQ(ierr); ierr = VecView(b,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } ierr = VecDuplicate(b,&x);CHKERRQ(ierr); /* Create matrix X - same size as B */ ierr = PetscPrintf(PETSC_COMM_WORLD," Create solution matrix X\n");CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&X);CHKERRQ(ierr); ierr = MatSetSizes(X,m,p,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); ierr = MatSetType(X,MATELEMENTAL);CHKERRQ(ierr); ierr = MatSetFromOptions(X);CHKERRQ(ierr); ierr = MatSetUp(X);CHKERRQ(ierr); ierr = MatAssemblyBegin(X,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(X,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* Cholesky factorization */ /*------------------------*/ ierr = PetscPrintf(PETSC_COMM_WORLD," Create Elemental matrix Aher\n");CHKERRQ(ierr); ierr = MatHermitianTranspose(A,MAT_INITIAL_MATRIX,&Aher);CHKERRQ(ierr); ierr = MatAXPY(Aher,1.0,A,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* Aher = A + A^T */ if (!rank) { /* add 100.0 to diagonals of Aher to make it spd */ PetscInt M,N; ierr = MatGetSize(Aher,&M,&N);CHKERRQ(ierr); for (i=0; i<M; i++) { rval = 100.0; ierr = MatSetValues(Aher,1,&i,1,&i,&rval,ADD_VALUES);CHKERRQ(ierr); } } ierr = MatAssemblyBegin(Aher,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(Aher,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); if (mats_view) { ierr = PetscPrintf(PETSC_COMM_WORLD, "Aher:\n");CHKERRQ(ierr); ierr = MatView(Aher,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } /* Cholesky factorization */ /*------------------------*/ ierr = PetscPrintf(PETSC_COMM_WORLD," Test Cholesky Solver \n");CHKERRQ(ierr); /* In-place Cholesky */ /* Create matrix factor G, then copy Aher to G */ ierr = MatCreate(PETSC_COMM_WORLD,&G);CHKERRQ(ierr); ierr = MatSetSizes(G,m,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); ierr = MatSetType(G,MATELEMENTAL);CHKERRQ(ierr); ierr = MatSetFromOptions(G);CHKERRQ(ierr); ierr = MatSetUp(G);CHKERRQ(ierr); ierr = MatAssemblyBegin(G,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(G,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatCopy(Aher,G,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* Only G = U^T * U is implemented for now */ ierr = MatCholeskyFactor(G,0,0);CHKERRQ(ierr); if (mats_view) { ierr = PetscPrintf(PETSC_COMM_WORLD, "Cholesky Factor G:\n");CHKERRQ(ierr); ierr = MatView(G,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } /* Solve U^T * U x = b and U^T * U X = B */ ierr = MatSolve(G,b,x);CHKERRQ(ierr); ierr = MatMatSolve(G,B,X);CHKERRQ(ierr); ierr = MatDestroy(&G);CHKERRQ(ierr); /* Out-place Cholesky */ ierr = MatGetFactor(Aher,MATSOLVERELEMENTAL,MAT_FACTOR_CHOLESKY,&G);CHKERRQ(ierr); ierr = MatCholeskyFactorSymbolic(G,Aher,0,&finfo);CHKERRQ(ierr); ierr = MatCholeskyFactorNumeric(G,Aher,&finfo);CHKERRQ(ierr); if (mats_view) { ierr = MatView(G,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } ierr = MatSolve(G,b,x);CHKERRQ(ierr); ierr = MatMatSolve(G,B,X);CHKERRQ(ierr); ierr = MatDestroy(&G);CHKERRQ(ierr); /* Check norm(Aher*x - b) */ ierr = VecCreate(PETSC_COMM_WORLD,&c);CHKERRQ(ierr); ierr = VecSetSizes(c,m,PETSC_DECIDE);CHKERRQ(ierr); ierr = VecSetFromOptions(c);CHKERRQ(ierr); ierr = MatMult(Aher,x,c);CHKERRQ(ierr); ierr = VecAXPY(c,-1.0,b);CHKERRQ(ierr); ierr = VecNorm(c,NORM_1,&norm);CHKERRQ(ierr); if (norm > tol) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Warning: |Aher*x - b| for Cholesky %g\n",(double)norm);CHKERRQ(ierr); } /* Check norm(Aher*X - B) */ ierr = MatMatMult(Aher,X,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&C);CHKERRQ(ierr); ierr = MatAXPY(C,-1.0,B,SAME_NONZERO_PATTERN);CHKERRQ(ierr); ierr = MatNorm(C,NORM_1,&norm);CHKERRQ(ierr); if (norm > tol) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Warning: |Aher*X - B| for Cholesky %g\n",(double)norm);CHKERRQ(ierr); } /* LU factorization */ /*------------------*/ ierr = PetscPrintf(PETSC_COMM_WORLD," Test LU Solver \n");CHKERRQ(ierr); /* In-place LU */ /* Create matrix factor F, then copy A to F */ ierr = MatCreate(PETSC_COMM_WORLD,&F);CHKERRQ(ierr); ierr = MatSetSizes(F,m,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); ierr = MatSetType(F,MATELEMENTAL);CHKERRQ(ierr); ierr = MatSetFromOptions(F);CHKERRQ(ierr); ierr = MatSetUp(F);CHKERRQ(ierr); ierr = MatAssemblyBegin(F,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(F,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatCopy(A,F,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* Create vector d to test MatSolveAdd() */ ierr = VecDuplicate(x,&d);CHKERRQ(ierr); ierr = VecCopy(x,d);CHKERRQ(ierr); /* PF=LU or F=LU factorization - perms is ignored by Elemental; set finfo.dtcol !0 or 0 to enable/disable partial pivoting */ finfo.dtcol = 0.1; ierr = MatLUFactor(F,0,0,&finfo);CHKERRQ(ierr); /* Solve LUX = PB or LUX = B */ ierr = MatSolveAdd(F,b,d,x);CHKERRQ(ierr); ierr = MatMatSolve(F,B,X);CHKERRQ(ierr); ierr = MatDestroy(&F);CHKERRQ(ierr); /* Check norm(A*X - B) */ ierr = VecCreate(PETSC_COMM_WORLD,&e);CHKERRQ(ierr); ierr = VecSetSizes(e,m,PETSC_DECIDE);CHKERRQ(ierr); ierr = VecSetFromOptions(e);CHKERRQ(ierr); ierr = MatMult(A,x,c);CHKERRQ(ierr); ierr = MatMult(A,d,e);CHKERRQ(ierr); ierr = VecAXPY(c,-1.0,e);CHKERRQ(ierr); ierr = VecAXPY(c,-1.0,b);CHKERRQ(ierr); ierr = VecNorm(c,NORM_1,&norm);CHKERRQ(ierr); if (norm > tol) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Warning: |A*x - b| for LU %g\n",(double)norm);CHKERRQ(ierr); } ierr = MatMatMult(A,X,MAT_REUSE_MATRIX,PETSC_DEFAULT,&C);CHKERRQ(ierr); ierr = MatAXPY(C,-1.0,B,SAME_NONZERO_PATTERN);CHKERRQ(ierr); ierr = MatNorm(C,NORM_1,&norm);CHKERRQ(ierr); if (norm > tol) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Warning: |A*X - B| for LU %g\n",(double)norm);CHKERRQ(ierr); } /* Out-place LU */ ierr = MatGetFactor(A,MATSOLVERELEMENTAL,MAT_FACTOR_LU,&F);CHKERRQ(ierr); ierr = MatLUFactorSymbolic(F,A,0,0,&finfo);CHKERRQ(ierr); ierr = MatLUFactorNumeric(F,A,&finfo);CHKERRQ(ierr); if (mats_view) { ierr = MatView(F,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } ierr = MatSolve(F,b,x);CHKERRQ(ierr); ierr = MatMatSolve(F,B,X);CHKERRQ(ierr); ierr = MatDestroy(&F);CHKERRQ(ierr); /* Free space */ ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = MatDestroy(&Aher);CHKERRQ(ierr); ierr = MatDestroy(&B);CHKERRQ(ierr); ierr = MatDestroy(&C);CHKERRQ(ierr); ierr = MatDestroy(&X);CHKERRQ(ierr); ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = VecDestroy(&c);CHKERRQ(ierr); ierr = VecDestroy(&d);CHKERRQ(ierr); ierr = VecDestroy(&e);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = PetscRandomDestroy(&rand);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
/*@C EPSCreate - Creates the default EPS context. Collective on MPI_Comm Input Parameter: . comm - MPI communicator Output Parameter: . eps - location to put the EPS context Note: The default EPS type is EPSKRYLOVSCHUR Level: beginner .seealso: EPSSetUp(), EPSSolve(), EPSDestroy(), EPS @*/ PetscErrorCode EPSCreate(MPI_Comm comm,EPS *outeps) { PetscErrorCode ierr; EPS eps; PetscFunctionBegin; PetscValidPointer(outeps,2); *outeps = 0; ierr = EPSInitializePackage(); CHKERRQ(ierr); ierr = SlepcHeaderCreate(eps,_p_EPS,struct _EPSOps,EPS_CLASSID,"EPS","Eigenvalue Problem Solver","EPS",comm,EPSDestroy,EPSView); CHKERRQ(ierr); eps->max_it = 0; eps->nev = 1; eps->ncv = 0; eps->mpd = 0; eps->nini = 0; eps->nds = 0; eps->target = 0.0; eps->tol = PETSC_DEFAULT; eps->conv = EPS_CONV_EIG; eps->which = (EPSWhich)0; eps->inta = 0.0; eps->intb = 0.0; eps->problem_type = (EPSProblemType)0; eps->extraction = EPS_RITZ; eps->balance = EPS_BALANCE_NONE; eps->balance_its = 5; eps->balance_cutoff = 1e-8; eps->trueres = PETSC_FALSE; eps->trackall = PETSC_FALSE; eps->converged = EPSConvergedEigRelative; eps->convergeddestroy= NULL; eps->arbitrary = NULL; eps->convergedctx = NULL; eps->arbitraryctx = NULL; eps->numbermonitors = 0; eps->st = NULL; eps->ds = NULL; eps->V = NULL; eps->rg = NULL; eps->rand = NULL; eps->D = NULL; eps->IS = NULL; eps->defl = NULL; eps->eigr = NULL; eps->eigi = NULL; eps->errest = NULL; eps->rr = NULL; eps->ri = NULL; eps->perm = NULL; eps->nwork = 0; eps->work = NULL; eps->data = NULL; eps->state = EPS_STATE_INITIAL; eps->nconv = 0; eps->its = 0; eps->nloc = 0; eps->nrma = 0.0; eps->nrmb = 0.0; eps->isgeneralized = PETSC_FALSE; eps->ispositive = PETSC_FALSE; eps->ishermitian = PETSC_FALSE; eps->reason = EPS_CONVERGED_ITERATING; ierr = PetscNewLog(eps,&eps->sc); CHKERRQ(ierr); ierr = PetscRandomCreate(comm,&eps->rand); CHKERRQ(ierr); ierr = PetscRandomSetSeed(eps->rand,0x12345678); CHKERRQ(ierr); ierr = PetscLogObjectParent((PetscObject)eps,(PetscObject)eps->rand); CHKERRQ(ierr); *outeps = eps; PetscFunctionReturn(0); }
int main(int argc,char **args) { Mat *A,B; /* matrix */ PetscErrorCode ierr; Vec x,y,v,v2,z; PetscReal rnorm; PetscInt n = 20; /* size of the matrix */ PetscInt nmat = 3; /* number of matrices */ PetscInt i; PetscRandom rctx; MatCompositeType type; ierr = PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr; ierr = PetscOptionsGetInt(NULL,NULL,"-n",&n,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-nmat",&nmat,NULL);CHKERRQ(ierr); /* Create random matrices */ ierr = PetscMalloc1(nmat+3,&A);CHKERRQ(ierr); ierr = PetscRandomCreate(PETSC_COMM_WORLD,&rctx);CHKERRQ(ierr); ierr = MatCreateAIJ(PETSC_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,n,n/2,3,NULL,3,NULL,&A[0]);CHKERRQ(ierr); for (i = 1; i < nmat+1; i++) { ierr = MatCreateAIJ(PETSC_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,n,n,3,NULL,3,NULL,&A[i]);CHKERRQ(ierr); } ierr = MatCreateAIJ(PETSC_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,n/2,n,3,NULL,3,NULL,&A[nmat+1]);CHKERRQ(ierr); for (i = 0; i < nmat+2; i++) { ierr = MatSetRandom(A[i],rctx);CHKERRQ(ierr); } ierr = MatCreateVecs(A[1],&x,&y);CHKERRQ(ierr); ierr = VecDuplicate(y,&z);CHKERRQ(ierr); ierr = MatCreateVecs(A[0],&v,NULL);CHKERRQ(ierr); ierr = VecDuplicate(v,&v2);CHKERRQ(ierr); ierr = VecSet(x,1.0);CHKERRQ(ierr); ierr = VecSet(y,0.0);CHKERRQ(ierr); ierr = MatMult(A[1],x,z);CHKERRQ(ierr); for (i = 2; i < nmat+1; i++) { ierr = MatMultAdd(A[i],x,z,z);CHKERRQ(ierr); } ierr = MatCreateComposite(PETSC_COMM_WORLD,nmat,A+1,&B);CHKERRQ(ierr); ierr = MatMultAdd(B,x,y,y);CHKERRQ(ierr); ierr = VecAXPY(y,-1.0,z);CHKERRQ(ierr); ierr = VecNorm(y,NORM_2,&rnorm);CHKERRQ(ierr); if (rnorm > 10000.0*PETSC_MACHINE_EPSILON) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Error with composite add %g\n",(double)rnorm);CHKERRQ(ierr); } ierr = MatCompositeSetMatStructure(B,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); /* default */ ierr = MatCompositeMerge(B);CHKERRQ(ierr); ierr = MatMult(B,x,y);CHKERRQ(ierr); ierr = MatDestroy(&B);CHKERRQ(ierr); ierr = VecAXPY(y,-1.0,z);CHKERRQ(ierr); ierr = VecNorm(y,NORM_2,&rnorm);CHKERRQ(ierr); if (rnorm > 10000.0*PETSC_MACHINE_EPSILON) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Error with composite add after merge %g\n",(double)rnorm);CHKERRQ(ierr); } /* Test n x n/2 multiplicative composite */ ierr = VecSet(v,1.0);CHKERRQ(ierr); ierr = MatMult(A[0],v,z);CHKERRQ(ierr); for (i = 1; i < nmat; i++) { ierr = MatMult(A[i],z,y);CHKERRQ(ierr); ierr = VecCopy(y,z);CHKERRQ(ierr); } ierr = MatCreateComposite(PETSC_COMM_WORLD,nmat,A,&B);CHKERRQ(ierr); ierr = MatCompositeSetType(B,MAT_COMPOSITE_MULTIPLICATIVE);CHKERRQ(ierr); ierr = MatCompositeSetMergeType(B,MAT_COMPOSITE_MERGE_LEFT);CHKERRQ(ierr); ierr = MatSetFromOptions(B);CHKERRQ(ierr); ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* do MatCompositeMerge() if -mat_composite_merge 1 */ ierr = MatMult(B,v,y);CHKERRQ(ierr); ierr = MatDestroy(&B);CHKERRQ(ierr); ierr = VecAXPY(y,-1.0,z);CHKERRQ(ierr); ierr = VecNorm(y,NORM_2,&rnorm);CHKERRQ(ierr); if (rnorm > 10000.0*PETSC_MACHINE_EPSILON) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Error with composite multiplicative %g\n",(double)rnorm);CHKERRQ(ierr); } /* Test n/2 x n multiplicative composite */ ierr = VecSet(x,1.0);CHKERRQ(ierr); ierr = MatMult(A[2],x,z);CHKERRQ(ierr); for (i = 3; i < nmat+1; i++) { ierr = MatMult(A[i],z,y);CHKERRQ(ierr); ierr = VecCopy(y,z);CHKERRQ(ierr); } ierr = MatMult(A[nmat+1],z,v);CHKERRQ(ierr); ierr = MatCreateComposite(PETSC_COMM_WORLD,nmat,A+2,&B);CHKERRQ(ierr); ierr = MatCompositeSetType(B,MAT_COMPOSITE_MULTIPLICATIVE);CHKERRQ(ierr); ierr = MatSetFromOptions(B);CHKERRQ(ierr); ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* do MatCompositeMerge() if -mat_composite_merge 1 */ ierr = MatMult(B,x,v2);CHKERRQ(ierr); ierr = MatDestroy(&B);CHKERRQ(ierr); ierr = VecAXPY(v2,-1.0,v);CHKERRQ(ierr); ierr = VecNorm(v2,NORM_2,&rnorm);CHKERRQ(ierr); if (rnorm > 10000.0*PETSC_MACHINE_EPSILON) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Error with composite multiplicative %g\n",(double)rnorm);CHKERRQ(ierr); } /* Test get functions */ ierr = MatCreateComposite(PETSC_COMM_WORLD,nmat,A,&B);CHKERRQ(ierr); ierr = MatCompositeGetNumberMat(B,&n);CHKERRQ(ierr); if (nmat != n) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Error with GetNumberMat %D != %D\n",nmat,n);CHKERRQ(ierr); } ierr = MatCompositeGetMat(B,0,&A[nmat+2]);CHKERRQ(ierr); if (A[0] != A[nmat+2]) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Error with GetMat\n");CHKERRQ(ierr); } ierr = MatCompositeGetType(B,&type);CHKERRQ(ierr); if (type != MAT_COMPOSITE_ADDITIVE) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Error with GetType\n");CHKERRQ(ierr); } ierr = MatDestroy(&B);CHKERRQ(ierr); /* Free work space. All PETSc objects should be destroyed when they are no longer needed. */ ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&y);CHKERRQ(ierr); ierr = VecDestroy(&v);CHKERRQ(ierr); ierr = VecDestroy(&v2);CHKERRQ(ierr); ierr = VecDestroy(&z);CHKERRQ(ierr); ierr = PetscRandomDestroy(&rctx);CHKERRQ(ierr); for (i = 0; i < nmat+2; i++) { ierr = MatDestroy(&A[i]);CHKERRQ(ierr); } ierr = PetscFree(A);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
int main(int argc, char *argv[]) { double r,dt; int n; unsigned long i,myNumSim,totalNumSim,numdim; /* double payoff; */ double *vol, *St0, x, totalx; int np,myid; time_t start,stop; double *eps; himaInfo hinfo; PetscRandom ran; PetscErrorCode ierr; PetscBool flg; PetscInitialize(&argc,&argv,(char *)0,help); #if defined(PETSC_USE_COMPLEX) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"This example does not work for scalar type complex\n"); #endif time(&start); ierr = PetscRandomCreate(PETSC_COMM_WORLD,&ran);CHKERRQ(ierr); #if defined(PETSC_HAVE_SPRNG) ierr = PetscRandomSetType(ran,PETSCSPRNG);CHKERRQ(ierr); #elif defined(PETSC_HAVE_RAND) ierr = PetscRandomSetType(ran,PETSCRAND);CHKERRQ(ierr); #endif ierr = PetscRandomSetFromOptions(ran);CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD, &np);CHKERRQ(ierr); /* number of nodes */ ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &myid);CHKERRQ(ierr); /* my ranking */ ierr = PetscOptionsHasName(PETSC_NULL, "-check_generators", &flg);CHKERRQ(ierr); if (flg){ ierr = PetscRandomGetValue(ran,(PetscScalar *)&r); ierr = PetscSynchronizedPrintf(PETSC_COMM_WORLD,"[%d] rval: %g\n",myid,r); ierr = PetscSynchronizedFlush(PETSC_COMM_WORLD); } hinfo.n = 31; hinfo.r = 0.04; hinfo.dt = 1.0/12; /* a month as a period */ hinfo.totalNumSim = 1000; ierr = PetscOptionsGetInt(PETSC_NULL,"-num_of_stocks",&(hinfo.n),PETSC_NULL);CHKERRQ(ierr); if (hinfo.n <1 || hinfo.n > 31) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only 31 stocks listed in stock.txt. num_of_stocks %D must between 1 and 31",hinfo.n); ierr = PetscOptionsGetReal(PETSC_NULL,"-interest_rate",&(hinfo.r),PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetReal(PETSC_NULL,"-time_interval",&(hinfo.dt),PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-num_of_simulations",&(hinfo.totalNumSim),PETSC_NULL);CHKERRQ(ierr); n = hinfo.n; r = hinfo.r; dt = hinfo.dt; totalNumSim = hinfo.totalNumSim; vol = hinfo.vol = (double *)malloc(sizeof(double)*(2*n+1)); St0 = hinfo.St0 = hinfo.vol + n; ierr = readData(PETSC_COMM_WORLD,&hinfo);CHKERRQ(ierr); numdim = n*(n+1)/2; if (numdim%2 == 1){ numdim++; } eps = (double *)malloc(sizeof(double)*numdim); myNumSim = divWork(myid,totalNumSim,np); x = 0; for (i=0;i<myNumSim;i++){ stdNormalArray(eps,numdim,ran); x += basketPayoff(vol,St0,n,r,dt,eps); } ierr = MPI_Reduce(&x, &totalx, 1, MPI_DOUBLE, MPI_SUM,0,PETSC_COMM_WORLD);CHKERRQ(ierr); time(&stop); /* payoff = exp(-r*dt*n)*(totalx/totalNumSim); ierr = PetscPrintf(PETSC_COMM_WORLD,"Option price = $%.3f using %ds of %s computation with %d %s for %d stocks, %d trading period per year, %.2f%% interest rate\n", payoff,(int)(stop - start),"parallel",np,"processors",n,(int)(1/dt),r);CHKERRQ(ierr); */ free(vol); free(eps); ierr = PetscRandomDestroy(&ran);CHKERRQ(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; PetscInt vid = -1; #if defined(PETSC_USE_LOG) PetscLogStage stages[2]; #endif PetscInitialize(&argc,&args,(char*)0,help); 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 = 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); 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); 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); ierr = MatEqual(A, Atrans, &flg); 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]); ierr = PetscLogStageRegister("MatOv_BAIJ",&stages[1]); /* 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 MatGetSubmatrices */ if (TestSubMat) { for (i = 0; i < nd; ++i) { ierr = ISSort(is1[i]);CHKERRQ(ierr); ierr = ISSort(is2[i]);CHKERRQ(ierr); } ierr = MatGetSubMatrices(A,nd,is1,is1,MAT_INITIAL_MATRIX,&submatA);CHKERRQ(ierr); ierr = MatGetSubMatrices(sA,nd,is2,is2,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 MatGetSubmatrices with MAT_REUSE_MATRIX option */ ierr = MatGetSubMatrices(A,nd,is1,is1,MAT_REUSE_MATRIX,&submatA);CHKERRQ(ierr); ierr = MatGetSubMatrices(sA,nd,is2,is2,MAT_REUSE_MATRIX,&submatsA);CHKERRQ(ierr); ierr = MatMultEqual(A,sA,10,&flg);CHKERRQ(ierr); if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"MatGetSubmatrices(): A != sA"); for (i=0; i<nd; ++i) { ierr = MatDestroy(&submatA[i]);CHKERRQ(ierr); ierr = MatDestroy(&submatsA[i]);CHKERRQ(ierr); } ierr = PetscFree(submatA);CHKERRQ(ierr); ierr = PetscFree(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 0; }
For MATSEQDENSE matrix, the factorization is just a thin wrapper to LAPACK \n\n"; #include <petscmat.h> #undef __FUNCT__ #define __FUNCT__ "main" int main(int argc,char **argv) { Mat mat,F,RHS,SOLU; MatInfo info; PetscErrorCode ierr; PetscInt m = 10,n = 10,i,j,rstart,rend,nrhs=2; PetscScalar value = 1.0; Vec x,y,b,ytmp; PetscReal norm,tol=1.e-15; PetscMPIInt size; PetscScalar *rhs_array,*solu_array; PetscRandom rand; PetscScalar *array,rval; PetscInitialize(&argc,&argv,(char*) 0,help); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); if (size != 1) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"This is a uniprocessor example only!"); /* create single vectors */ ierr = VecCreate(PETSC_COMM_WORLD,&y);CHKERRQ(ierr); ierr = VecSetSizes(y,PETSC_DECIDE,m);CHKERRQ(ierr); ierr = VecSetFromOptions(y);CHKERRQ(ierr); ierr = VecDuplicate(y,&x);CHKERRQ(ierr); ierr = VecDuplicate(y,&ytmp);CHKERRQ(ierr); ierr = VecSet(x,value);CHKERRQ(ierr); ierr = VecCreate(PETSC_COMM_WORLD,&b);CHKERRQ(ierr); ierr = VecSetSizes(b,PETSC_DECIDE,n);CHKERRQ(ierr); ierr = VecSetFromOptions(b);CHKERRQ(ierr); /* create multiple vectors RHS and SOLU */ ierr = MatCreate(PETSC_COMM_WORLD,&RHS);CHKERRQ(ierr); ierr = MatSetSizes(RHS,PETSC_DECIDE,PETSC_DECIDE,n,nrhs);CHKERRQ(ierr); ierr = MatSetType(RHS,MATDENSE);CHKERRQ(ierr); ierr = MatSetFromOptions(RHS);CHKERRQ(ierr); ierr = MatSeqDenseSetPreallocation(RHS,NULL);CHKERRQ(ierr); ierr = PetscRandomCreate(PETSC_COMM_WORLD,&rand);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rand);CHKERRQ(ierr); ierr = MatDenseGetArray(RHS,&array);CHKERRQ(ierr); for (j=0; j<nrhs; j++) { for (i=0; i<n; i++) { ierr = PetscRandomGetValue(rand,&rval);CHKERRQ(ierr); array[n*j+i] = rval; } } ierr = MatDenseRestoreArray(RHS,&array);CHKERRQ(ierr); ierr = MatDuplicate(RHS,MAT_DO_NOT_COPY_VALUES,&SOLU);CHKERRQ(ierr); /* create matrix */ ierr = MatCreateSeqDense(PETSC_COMM_WORLD,m,n,NULL,&mat);CHKERRQ(ierr); ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr); for (i=rstart; i<rend; i++) { value = (PetscReal)i+1; ierr = MatSetValues(mat,1,&i,1,&i,&value,INSERT_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatGetInfo(mat,MAT_LOCAL,&info);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"matrix nonzeros = %D, allocated nonzeros = %D\n", (PetscInt)info.nz_used,(PetscInt)info.nz_allocated);CHKERRQ(ierr); /* Cholesky factorization - perm and factinfo are ignored by LAPACK */ /* in-place Cholesky */ ierr = MatMult(mat,x,b);CHKERRQ(ierr); ierr = MatDuplicate(mat,MAT_COPY_VALUES,&F);CHKERRQ(ierr); ierr = MatCholeskyFactor(F,0,0);CHKERRQ(ierr); ierr = MatSolve(F,b,y);CHKERRQ(ierr); ierr = MatDestroy(&F);CHKERRQ(ierr); value = -1.0; ierr = VecAXPY(y,value,x);CHKERRQ(ierr); ierr = VecNorm(y,NORM_2,&norm);CHKERRQ(ierr); if (norm > tol) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Warning: Norm of error for Cholesky %G\n",norm);CHKERRQ(ierr); } /* out-place Cholesky */ ierr = MatGetFactor(mat,MATSOLVERPETSC,MAT_FACTOR_CHOLESKY,&F);CHKERRQ(ierr); ierr = MatCholeskyFactorSymbolic(F,mat,0,0);CHKERRQ(ierr); ierr = MatCholeskyFactorNumeric(F,mat,0);CHKERRQ(ierr); ierr = MatSolve(F,b,y);CHKERRQ(ierr); value = -1.0; ierr = VecAXPY(y,value,x);CHKERRQ(ierr); ierr = VecNorm(y,NORM_2,&norm);CHKERRQ(ierr); if (norm > tol) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Warning: Norm of error for Cholesky %G\n",norm);CHKERRQ(ierr); } ierr = MatDestroy(&F);CHKERRQ(ierr); /* LU factorization - perms and factinfo are ignored by LAPACK */ i = m-1; value = 1.0; ierr = MatSetValues(mat,1,&i,1,&i,&value,INSERT_VALUES);CHKERRQ(ierr); ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatMult(mat,x,b);CHKERRQ(ierr); ierr = MatDuplicate(mat,MAT_COPY_VALUES,&F);CHKERRQ(ierr); /* in-place LU */ ierr = MatLUFactor(F,0,0,0);CHKERRQ(ierr); ierr = MatSolve(F,b,y);CHKERRQ(ierr); value = -1.0; ierr = VecAXPY(y,value,x);CHKERRQ(ierr); ierr = VecNorm(y,NORM_2,&norm);CHKERRQ(ierr); if (norm > tol) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Warning: Norm of error for LU %G\n",norm);CHKERRQ(ierr); } ierr = MatMatSolve(F,RHS,SOLU);CHKERRQ(ierr); ierr = MatDenseGetArray(SOLU,&solu_array);CHKERRQ(ierr); ierr = MatDenseGetArray(RHS,&rhs_array);CHKERRQ(ierr); for (j=0; j<nrhs; j++) { ierr = VecPlaceArray(y,solu_array+j*m);CHKERRQ(ierr); ierr = VecPlaceArray(b,rhs_array+j*m);CHKERRQ(ierr); ierr = MatMult(mat,y,ytmp);CHKERRQ(ierr); ierr = VecAXPY(ytmp,-1.0,b);CHKERRQ(ierr); /* ytmp = mat*SOLU[:,j] - RHS[:,j] */ ierr = VecNorm(ytmp,NORM_2,&norm);CHKERRQ(ierr); if (norm > tol) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Error: Norm of residual for LU %G\n",norm);CHKERRQ(ierr); } ierr = VecResetArray(b);CHKERRQ(ierr); ierr = VecResetArray(y);CHKERRQ(ierr); } ierr = MatDenseRestoreArray(RHS,&rhs_array);CHKERRQ(ierr); ierr = MatDenseRestoreArray(SOLU,&solu_array);CHKERRQ(ierr); ierr = MatDestroy(&F);CHKERRQ(ierr); /* out-place LU */ ierr = MatGetFactor(mat,MATSOLVERPETSC,MAT_FACTOR_LU,&F);CHKERRQ(ierr); ierr = MatLUFactorSymbolic(F,mat,0,0,0);CHKERRQ(ierr); ierr = MatLUFactorNumeric(F,mat,0);CHKERRQ(ierr); ierr = MatSolve(F,b,y);CHKERRQ(ierr); value = -1.0; ierr = VecAXPY(y,value,x);CHKERRQ(ierr); ierr = VecNorm(y,NORM_2,&norm);CHKERRQ(ierr); if (norm > tol) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Warning: Norm of error for LU %G\n",norm);CHKERRQ(ierr); } /* free space */ ierr = MatDestroy(&F);CHKERRQ(ierr); ierr = MatDestroy(&mat);CHKERRQ(ierr); ierr = MatDestroy(&RHS);CHKERRQ(ierr); ierr = MatDestroy(&SOLU);CHKERRQ(ierr); ierr = PetscRandomDestroy(&rand);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = VecDestroy(&y);CHKERRQ(ierr); ierr = VecDestroy(&ytmp);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
int main(int argc,char **args) { Vec x,b,u; /* approx solution, RHS, exact solution */ Mat A; /* linear system matrix */ KSP ksp; /* linear solver context */ PetscReal norm; /* norm of solution error */ PetscInt dim,i,j,Ii,J,Istart,Iend,n = 6,its,use_random; PetscErrorCode ierr; PetscScalar v,none = -1.0,sigma2,pfive = 0.5,*xa; PetscRandom rctx; PetscReal h2,sigma1 = 100.0; PetscBool flg = PETSC_FALSE; ierr = PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr; #if !defined(PETSC_USE_COMPLEX) SETERRQ(PETSC_COMM_WORLD,1,"This example requires complex numbers"); #endif ierr = PetscOptionsGetReal(NULL,NULL,"-sigma1",&sigma1,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-n",&n,NULL);CHKERRQ(ierr); dim = n*n; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Compute the matrix and right-hand-side vector that define the linear system, Ax = b. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Create parallel matrix, specifying only its global dimensions. When using MatCreate(), the matrix format can be specified at runtime. Also, the parallel partitioning of the matrix is determined by PETSc at runtime. */ ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,dim,dim);CHKERRQ(ierr); ierr = MatSetFromOptions(A);CHKERRQ(ierr); ierr = MatSetUp(A);CHKERRQ(ierr); /* Currently, all PETSc parallel matrix formats are partitioned by contiguous chunks of rows across the processors. Determine which rows of the matrix are locally owned. */ ierr = MatGetOwnershipRange(A,&Istart,&Iend);CHKERRQ(ierr); /* Set matrix elements in parallel. - Each processor needs to insert only elements that it owns locally (but any non-local elements will be sent to the appropriate processor during matrix assembly). - Always specify global rows and columns of matrix entries. */ ierr = PetscOptionsGetBool(NULL,NULL,"-norandom",&flg,NULL);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); } else { sigma2 = 10.0*PETSC_i; } h2 = 1.0/((n+1)*(n+1)); for (Ii=Istart; Ii<Iend; 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); } if (use_random) {ierr = PetscRandomGetValue(rctx,&sigma2);CHKERRQ(ierr);} v = 4.0 - sigma1*h2 + sigma2*h2; ierr = MatSetValues(A,1,&Ii,1,&Ii,&v,ADD_VALUES);CHKERRQ(ierr); } if (use_random) {ierr = PetscRandomDestroy(&rctx);CHKERRQ(ierr);} /* Assemble matrix, using the 2-step process: MatAssemblyBegin(), MatAssemblyEnd() Computations can be done while messages are in transition by placing code between these two statements. */ ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* Create parallel vectors. - When using VecCreate(), VecSetSizes() and VecSetFromOptions(), we specify only the vector's global dimension; the parallel partitioning is determined at runtime. - Note: We form 1 vector from scratch and then duplicate as needed. */ ierr = VecCreate(PETSC_COMM_WORLD,&u);CHKERRQ(ierr); ierr = VecSetSizes(u,PETSC_DECIDE,dim);CHKERRQ(ierr); ierr = VecSetFromOptions(u);CHKERRQ(ierr); ierr = VecDuplicate(u,&b);CHKERRQ(ierr); ierr = VecDuplicate(b,&x);CHKERRQ(ierr); /* Set exact solution; then compute right-hand-side vector. */ if (use_random) { ierr = PetscRandomCreate(PETSC_COMM_WORLD,&rctx);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rctx);CHKERRQ(ierr); ierr = VecSetRandom(u,rctx);CHKERRQ(ierr); } else { ierr = VecSet(u,pfive);CHKERRQ(ierr); } ierr = MatMult(A,u,b);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create the linear solver and set various options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Create linear solver context */ ierr = KSPCreate(PETSC_COMM_WORLD,&ksp);CHKERRQ(ierr); /* Set operators. Here the matrix that defines the linear system also serves as the preconditioning matrix. */ ierr = KSPSetOperators(ksp,A,A);CHKERRQ(ierr); /* Set runtime options, e.g., -ksp_type <type> -pc_type <type> -ksp_monitor -ksp_rtol <rtol> */ ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve the linear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Check solution and clean up - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Print the first 3 entries of x; this demonstrates extraction of the real and imaginary components of the complex vector, x. */ flg = PETSC_FALSE; ierr = PetscOptionsGetBool(NULL,NULL,"-print_x3",&flg,NULL);CHKERRQ(ierr); if (flg) { ierr = VecGetArray(x,&xa);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"The first three entries of x are:\n");CHKERRQ(ierr); for (i=0; i<3; i++) { ierr = PetscPrintf(PETSC_COMM_WORLD,"x[%D] = %g + %g i\n",i,(double)PetscRealPart(xa[i]),(double)PetscImaginaryPart(xa[i]));CHKERRQ(ierr); } ierr = VecRestoreArray(x,&xa);CHKERRQ(ierr); } /* Check the error */ ierr = VecAXPY(x,none,u);CHKERRQ(ierr); ierr = VecNorm(x,NORM_2,&norm);CHKERRQ(ierr); ierr = KSPGetIterationNumber(ksp,&its);CHKERRQ(ierr); if (norm < 1.e-12) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Norm of error < 1.e-12 iterations %D\n",its);CHKERRQ(ierr); } else { ierr = PetscPrintf(PETSC_COMM_WORLD,"Norm of error %g iterations %D\n",(double)norm,its);CHKERRQ(ierr); } /* Free work space. All PETSc objects should be destroyed when they are no longer needed. */ ierr = KSPDestroy(&ksp);CHKERRQ(ierr); if (use_random) {ierr = PetscRandomDestroy(&rctx);CHKERRQ(ierr);} ierr = VecDestroy(&u);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
int main(int argc,char **argv) { Mat A1,A2; /* problem matrices */ EPS eps; /* eigenproblem solver context */ PetscScalar value[3]; PetscReal tol=1000*PETSC_MACHINE_EPSILON,v; Vec d; PetscInt n=30,i,Istart,Iend,col[3]; PetscBool FirstBlock=PETSC_FALSE,LastBlock=PETSC_FALSE; PetscRandom myrand; PetscErrorCode ierr; SlepcInitialize(&argc,&argv,(char*)0,help); ierr = PetscOptionsGetInt(NULL,"-n",&n,NULL);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"\nTridiagonal with random diagonal, n=%D\n\n",n);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create matrix tridiag([-1 0 -1]) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatCreate(PETSC_COMM_WORLD,&A1);CHKERRQ(ierr); ierr = MatSetSizes(A1,PETSC_DECIDE,PETSC_DECIDE,n,n);CHKERRQ(ierr); ierr = MatSetFromOptions(A1);CHKERRQ(ierr); ierr = MatSetUp(A1);CHKERRQ(ierr); ierr = MatGetOwnershipRange(A1,&Istart,&Iend);CHKERRQ(ierr); if (Istart==0) FirstBlock=PETSC_TRUE; if (Iend==n) LastBlock=PETSC_TRUE; value[0]=-1.0; value[1]=0.0; value[2]=-1.0; for (i=(FirstBlock? Istart+1: Istart); i<(LastBlock? Iend-1: Iend); i++) { col[0]=i-1; col[1]=i; col[2]=i+1; ierr = MatSetValues(A1,1,&i,3,col,value,INSERT_VALUES);CHKERRQ(ierr); } if (LastBlock) { i=n-1; col[0]=n-2; col[1]=n-1; ierr = MatSetValues(A1,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr); } if (FirstBlock) { i=0; col[0]=0; col[1]=1; value[0]=0.0; value[1]=-1.0; ierr = MatSetValues(A1,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(A1,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A1,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create two matrices by filling the diagonal with rand values - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatDuplicate(A1,MAT_COPY_VALUES,&A2);CHKERRQ(ierr); ierr = MatGetVecs(A1,NULL,&d);CHKERRQ(ierr); ierr = PetscRandomCreate(PETSC_COMM_WORLD,&myrand);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(myrand);CHKERRQ(ierr); ierr = PetscRandomSetInterval(myrand,0.0,1.0);CHKERRQ(ierr); for (i=0; i<n; i++) { ierr = PetscRandomGetValueReal(myrand,&v);CHKERRQ(ierr); ierr = VecSetValue(d,i,v,INSERT_VALUES);CHKERRQ(ierr); } ierr = VecAssemblyBegin(d);CHKERRQ(ierr); ierr = VecAssemblyEnd(d);CHKERRQ(ierr); ierr = MatDiagonalSet(A1,d,INSERT_VALUES);CHKERRQ(ierr); for (i=0; i<n; i++) { ierr = PetscRandomGetValueReal(myrand,&v);CHKERRQ(ierr); ierr = VecSetValue(d,i,v,INSERT_VALUES);CHKERRQ(ierr); } ierr = VecAssemblyBegin(d);CHKERRQ(ierr); ierr = VecAssemblyEnd(d);CHKERRQ(ierr); ierr = MatDiagonalSet(A2,d,INSERT_VALUES);CHKERRQ(ierr); ierr = VecDestroy(&d);CHKERRQ(ierr); ierr = PetscRandomDestroy(&myrand);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create the eigensolver - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = EPSCreate(PETSC_COMM_WORLD,&eps);CHKERRQ(ierr); ierr = EPSSetProblemType(eps,EPS_HEP);CHKERRQ(ierr); ierr = EPSSetTolerances(eps,tol,PETSC_DEFAULT);CHKERRQ(ierr); ierr = EPSSetOperators(eps,A1,NULL);CHKERRQ(ierr); ierr = EPSSetFromOptions(eps);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve first eigenproblem - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = EPSSolve(eps);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," - - - First matrix - - -\n");CHKERRQ(ierr); ierr = EPSPrintSolution(eps,NULL);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve second eigenproblem - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = EPSSetOperators(eps,A2,NULL);CHKERRQ(ierr); ierr = EPSSolve(eps);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," - - - Second matrix - - -\n");CHKERRQ(ierr); ierr = EPSPrintSolution(eps,NULL);CHKERRQ(ierr); ierr = EPSDestroy(&eps);CHKERRQ(ierr); ierr = MatDestroy(&A1);CHKERRQ(ierr); ierr = MatDestroy(&A2);CHKERRQ(ierr); ierr = SlepcFinalize(); return 0; }
/* MSA_InitialPoint - Calculates the initial guess in one of three ways. Input Parameters: . user - user-defined application context . X - vector for initial guess Output Parameters: . X - newly computed initial guess */ static PetscErrorCode MSA_InitialPoint(AppCtx * user, Vec X) { PetscErrorCode ierr; PetscInt start=-1,i,j; PetscReal zero=0.0; PetscBool flg; ierr = PetscOptionsGetInt(NULL,NULL,"-start",&start,&flg);CHKERRQ(ierr); if (flg && start==0){ /* The zero vector is reasonable */ ierr = VecSet(X, zero);CHKERRQ(ierr); } else if (flg && start>0){ /* Try a random start between -0.5 and 0.5 */ PetscRandom rctx; PetscReal np5=-0.5; ierr = PetscRandomCreate(MPI_COMM_WORLD,&rctx);CHKERRQ(ierr); for (i=0; i<start; i++){ ierr = VecSetRandom(X, rctx);CHKERRQ(ierr); } ierr = PetscRandomDestroy(&rctx);CHKERRQ(ierr); ierr = VecShift(X, np5); } else { /* Take an average of the boundary conditions */ PetscInt row,xs,xm,gxs,gxm,ys,ym,gys,gym; PetscInt mx=user->mx,my=user->my; PetscReal *x,*left,*right,*bottom,*top; Vec localX = user->localX; /* Get local mesh boundaries */ ierr = DMDAGetCorners(user->dm,&xs,&ys,NULL,&xm,&ym,NULL);CHKERRQ(ierr); ierr = DMDAGetGhostCorners(user->dm,&gxs,&gys,NULL,&gxm,&gym,NULL);CHKERRQ(ierr); /* Get pointers to vector data */ ierr = VecGetArray(user->Top,&top);CHKERRQ(ierr); ierr = VecGetArray(user->Bottom,&bottom);CHKERRQ(ierr); ierr = VecGetArray(user->Left,&left);CHKERRQ(ierr); ierr = VecGetArray(user->Right,&right);CHKERRQ(ierr); ierr = VecGetArray(localX,&x);CHKERRQ(ierr); /* Perform local computations */ for (j=ys; j<ys+ym; j++){ for (i=xs; i< xs+xm; i++){ row=(j-gys)*gxm + (i-gxs); x[row] = ( (j+1)*bottom[i-xs+1]/my + (my-j+1)*top[i-xs+1]/(my+2)+ (i+1)*left[j-ys+1]/mx + (mx-i+1)*right[j-ys+1]/(mx+2))/2.0; } } /* Restore vectors */ ierr = VecRestoreArray(localX,&x);CHKERRQ(ierr); ierr = VecRestoreArray(user->Left,&left);CHKERRQ(ierr); ierr = VecRestoreArray(user->Top,&top);CHKERRQ(ierr); ierr = VecRestoreArray(user->Bottom,&bottom);CHKERRQ(ierr); ierr = VecRestoreArray(user->Right,&right);CHKERRQ(ierr); /* Scatter values into global vector */ ierr = DMLocalToGlobalBegin(user->dm,localX,INSERT_VALUES,X);CHKERRQ(ierr); ierr = DMLocalToGlobalEnd(user->dm,localX,INSERT_VALUES,X);CHKERRQ(ierr); } return 0; }
int main(int argc,char **argv) { Mat A; /* operator matrix */ EPS eps; /* eigenproblem solver context */ EPSType type; DM da; Vec v0; PetscReal error,tol,re,im,*exact; PetscScalar kr,ki; PetscInt M,N,P,m,n,p,nev,maxit,i,its,nconv,seed; PetscLogDouble t1,t2,t3; PetscBool flg; PetscRandom rctx; PetscErrorCode ierr; SlepcInitialize(&argc,&argv,(char*)0,help); ierr = PetscPrintf(PETSC_COMM_WORLD,"\n3-D Laplacian Eigenproblem\n\n");CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Compute the operator matrix that defines the eigensystem, Ax=kx - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMDACreate3d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE, DM_BOUNDARY_NONE,DMDA_STENCIL_STAR,-10,-10,-10, PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE, 1,1,NULL,NULL,NULL,&da);CHKERRQ(ierr); /* print DM information */ ierr = DMDAGetInfo(da,NULL,&M,&N,&P,&m,&n,&p,NULL,NULL,NULL,NULL,NULL,NULL);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Grid partitioning: %D %D %D\n",m,n,p);CHKERRQ(ierr); /* create and fill the matrix */ ierr = DMCreateMatrix(da,&A);CHKERRQ(ierr); ierr = FillMatrix(da,A);CHKERRQ(ierr); /* create random initial vector */ seed = 1; ierr = PetscOptionsGetInt(NULL,"-seed",&seed,NULL);CHKERRQ(ierr); if (seed<0) SETERRQ(PETSC_COMM_WORLD,1,"Seed must be >=0"); ierr = MatGetVecs(A,&v0,NULL);CHKERRQ(ierr); ierr = PetscRandomCreate(PETSC_COMM_WORLD,&rctx);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rctx);CHKERRQ(ierr); for (i=0;i<seed;i++) { /* simulate different seeds in the random generator */ ierr = VecSetRandom(v0,rctx);CHKERRQ(ierr); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create the eigensolver and set various options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Create eigensolver context */ ierr = EPSCreate(PETSC_COMM_WORLD,&eps);CHKERRQ(ierr); /* Set operators. In this case, it is a standard eigenvalue problem */ ierr = EPSSetOperators(eps,A,NULL);CHKERRQ(ierr); ierr = EPSSetProblemType(eps,EPS_HEP);CHKERRQ(ierr); /* Set specific solver options */ ierr = EPSSetWhichEigenpairs(eps,EPS_SMALLEST_REAL);CHKERRQ(ierr); ierr = EPSSetTolerances(eps,1e-8,PETSC_DEFAULT);CHKERRQ(ierr); ierr = EPSSetInitialSpace(eps,1,&v0);CHKERRQ(ierr); /* Set solver parameters at runtime */ ierr = EPSSetFromOptions(eps);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve the eigensystem - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = PetscTime(&t1);CHKERRQ(ierr); ierr = EPSSetUp(eps);CHKERRQ(ierr); ierr = PetscTime(&t2);CHKERRQ(ierr); ierr = EPSSolve(eps);CHKERRQ(ierr); ierr = PetscTime(&t3);CHKERRQ(ierr); ierr = EPSGetIterationNumber(eps,&its);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Number of iterations of the method: %D\n",its);CHKERRQ(ierr); /* Optional: Get some information from the solver and display it */ ierr = EPSGetType(eps,&type);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Solution method: %s\n\n",type);CHKERRQ(ierr); ierr = EPSGetDimensions(eps,&nev,NULL,NULL);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Number of requested eigenvalues: %D\n",nev);CHKERRQ(ierr); ierr = EPSGetTolerances(eps,&tol,&maxit);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Stopping condition: tol=%.4g, maxit=%D\n",(double)tol,maxit);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Display solution and clean up - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Get number of converged approximate eigenpairs */ ierr = EPSGetConverged(eps,&nconv);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Number of converged approximate eigenpairs: %D\n\n",nconv);CHKERRQ(ierr); if (nconv>0) { ierr = PetscMalloc1(nconv,&exact);CHKERRQ(ierr); ierr = GetExactEigenvalues(M,N,P,nconv,exact);CHKERRQ(ierr); /* Display eigenvalues and relative errors */ ierr = PetscPrintf(PETSC_COMM_WORLD, " k ||Ax-kx||/||kx|| Eigenvalue Error \n" " ----------------- ------------------ ------------------\n");CHKERRQ(ierr); for (i=0;i<nconv;i++) { /* Get converged eigenpairs: i-th eigenvalue is stored in kr (real part) and ki (imaginary part) */ ierr = EPSGetEigenpair(eps,i,&kr,&ki,NULL,NULL);CHKERRQ(ierr); /* Compute the relative error associated to each eigenpair */ ierr = EPSComputeRelativeError(eps,i,&error);CHKERRQ(ierr); #if defined(PETSC_USE_COMPLEX) re = PetscRealPart(kr); im = PetscImaginaryPart(kr); #else re = kr; im = ki; #endif if (im!=0.0) SETERRQ(PETSC_COMM_WORLD,1,"Eigenvalue should be real"); else { ierr = PetscPrintf(PETSC_COMM_WORLD," %12g %12g %12g\n",(double)re,(double)error,(double)PetscAbsReal(re-exact[i]));CHKERRQ(ierr); } } ierr = PetscFree(exact);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"\n");CHKERRQ(ierr); } /* Show computing times */ ierr = PetscOptionsHasName(NULL,"-showtimes",&flg);CHKERRQ(ierr); if (flg) { ierr = PetscPrintf(PETSC_COMM_WORLD," Elapsed time: %g (setup), %g (solve)\n",(double)(t2-t1),(double)(t3-t2));CHKERRQ(ierr); } /* Free work space */ ierr = EPSDestroy(&eps);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = VecDestroy(&v0);CHKERRQ(ierr); ierr = PetscRandomDestroy(&rctx);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = SlepcFinalize(); return 0; }
int main(int argc, char *argv[]) { PetscReal r,dt; PetscInt n; unsigned long i,myNumSim,totalNumSim,numdim; PetscReal *vol, *St0, x, totalx; PetscMPIInt size,rank; PetscReal *eps; himaInfo hinfo; PetscRandom ran; PetscErrorCode ierr; ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; ierr = PetscRandomCreate(PETSC_COMM_WORLD,&ran);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(ran);CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD, &size);CHKERRQ(ierr); /* number of nodes */ ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank);CHKERRQ(ierr); /* my ranking */ hinfo.n = 31; hinfo.r = 0.04; hinfo.dt = 1.0/12; /* a month as a period */ hinfo.totalNumSim = 1000; ierr = PetscOptionsGetInt(NULL,NULL,"-num_of_stocks",&(hinfo.n),NULL);CHKERRQ(ierr); if (hinfo.n <1 || hinfo.n > 31) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only 31 stocks listed in stock.txt. num_of_stocks %D must between 1 and 31",hinfo.n); ierr = PetscOptionsGetReal(NULL,NULL,"-interest_rate",&(hinfo.r),NULL);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,NULL,"-time_interval",&(hinfo.dt),NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-num_of_simulations",&(hinfo.totalNumSim),NULL);CHKERRQ(ierr); n = hinfo.n; r = hinfo.r; dt = hinfo.dt; totalNumSim = hinfo.totalNumSim; ierr = PetscMalloc1(2*n+1,&hinfo.vol);CHKERRQ(ierr); vol = hinfo.vol; St0 = hinfo.St0 = hinfo.vol + n; ierr = readData(PETSC_COMM_WORLD,&hinfo);CHKERRQ(ierr); numdim = n*(n+1)/2; if (numdim%2 == 1) numdim++; ierr = PetscMalloc1(numdim,&eps);CHKERRQ(ierr); myNumSim = divWork(rank,totalNumSim,size); x = 0; for (i=0; i<myNumSim; i++) { ierr = stdNormalArray(eps,numdim,ran);CHKERRQ(ierr); x += basketPayoff(vol,St0,n,r,dt,eps); } ierr = MPI_Reduce(&x, &totalx, 1, MPIU_REAL, MPIU_SUM,0,PETSC_COMM_WORLD);CHKERRQ(ierr); /* payoff = exp(-r*dt*n)*(totalx/totalNumSim); ierr = PetscPrintf(PETSC_COMM_WORLD,"Option price = $%.3f using %ds of %s computation with %d %s for %d stocks, %d trading period per year, %.2f%% interest rate\n", payoff,(int)(stop - start),"parallel",size,"processors",n,(int)(1/dt),r);CHKERRQ(ierr); */ ierr = PetscFree(vol);CHKERRQ(ierr); ierr = PetscFree(eps);CHKERRQ(ierr); ierr = PetscRandomDestroy(&ran);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
int test1(void) { PetscLogDouble t1,t2; double value; int i,ierr,*z,*zi,intval; PetscScalar *x,*y; PetscRandom r; ierr = PetscRandomCreate(PETSC_COMM_SELF,&r);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(r);CHKERRQ(ierr); ierr = PetscMalloc1(20000,&x);CHKERRQ(ierr); ierr = PetscMalloc1(20000,&y);CHKERRQ(ierr); ierr = PetscMalloc1(2000,&z);CHKERRQ(ierr); ierr = PetscMalloc1(2000,&zi);CHKERRQ(ierr); /* Take care of paging effects */ ierr = PetscTime(&t1);CHKERRQ(ierr); /* Form the random set of integers */ for (i=0; i<2000; i++) { ierr = PetscRandomGetValue(r,&value);CHKERRQ(ierr); intval = (int)(value*20000.0); z[i] = intval; } for (i=0; i<2000; i++) { ierr = PetscRandomGetValue(r,&value);CHKERRQ(ierr); intval = (int)(value*20000.0); zi[i] = intval; } /* fprintf(stdout,"Done setup\n"); */ ierr = BlastCache();CHKERRQ(ierr); ierr = PetscTime(&t1);CHKERRQ(ierr); for (i=0; i<2000; i++) x[i] = y[i]; ierr = PetscTime(&t2);CHKERRQ(ierr); fprintf(stdout,"%-27s : %e sec\n","x[i] = y[i]",(t2-t1)/2000.0); ierr = BlastCache();CHKERRQ(ierr); ierr = PetscTime(&t1);CHKERRQ(ierr); for (i=0; i<500; i+=4) { x[i] = y[z[i]]; x[1+i] = y[z[1+i]]; x[2+i] = y[z[2+i]]; x[3+i] = y[z[3+i]]; } ierr = PetscTime(&t2);CHKERRQ(ierr); fprintf(stdout,"%-27s : %e sec\n","x[i] = y[idx[i]] - unroll 4",(t2-t1)/2000.0); ierr = BlastCache();CHKERRQ(ierr); ierr = PetscTime(&t1);CHKERRQ(ierr) for (i=0; i<2000; i++) x[i] = y[z[i]]; ierr = PetscTime(&t2);CHKERRQ(ierr); fprintf(stdout,"%-27s : %e sec\n","x[i] = y[idx[i]]",(t2-t1)/2000.0); ierr = BlastCache();CHKERRQ(ierr); ierr = PetscTime(&t1);CHKERRQ(ierr); for (i=0; i<1000; i+=2) { x[i] = y[z[i]]; x[1+i] = y[z[1+i]]; } ierr = PetscTime(&t2);CHKERRQ(ierr); fprintf(stdout,"%-27s : %e sec\n","x[i] = y[idx[i]] - unroll 2",(t2-t1)/2000.0); ierr = BlastCache();CHKERRQ(ierr); ierr = PetscTime(&t1);CHKERRQ(ierr); for (i=0; i<2000; i++) x[z[i]] = y[i]; ierr = PetscTime(&t2);CHKERRQ(ierr); fprintf(stdout,"%-27s : %e sec\n","x[z[i]] = y[i]",(t2-t1)/2000.0); ierr = BlastCache();CHKERRQ(ierr); ierr = PetscTime(&t1);CHKERRQ(ierr); for (i=0; i<2000; i++) x[z[i]] = y[zi[i]]; ierr = PetscTime(&t2);CHKERRQ(ierr); fprintf(stdout,"%-27s : %e sec\n","x[z[i]] = y[zi[i]]",(t2-t1)/2000.0); ierr = PetscMemcpy(x,y,10);CHKERRQ(ierr); ierr = PetscMemcpy(z,zi,10);CHKERRQ(ierr); ierr = PetscFree(z);CHKERRQ(ierr); ierr = PetscFree(zi);CHKERRQ(ierr); ierr = PetscFree(x);CHKERRQ(ierr); ierr = PetscFree(y);CHKERRQ(ierr); ierr = PetscRandomDestroy(&r);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* Mm_ratio - ration of grid lines between fine and coarse grids. */ int main(int argc,char **argv) { PetscErrorCode ierr; AppCtx user; PetscInt Npx=PETSC_DECIDE,Npy=PETSC_DECIDE,Npz=PETSC_DECIDE; PetscMPIInt size,rank; PetscInt m,n,M,N,i,nrows; PetscScalar one = 1.0; PetscReal fill=2.0; Mat A,A_tmp,P,C,C1,C2; PetscScalar *array,none = -1.0,alpha; Vec x,v1,v2,v3,v4; PetscReal norm,norm_tmp,norm_tmp1,tol=100.*PETSC_MACHINE_EPSILON; PetscRandom rdm; PetscBool Test_MatMatMult=PETSC_TRUE,Test_MatPtAP=PETSC_TRUE,Test_3D=PETSC_TRUE,flg; const PetscInt *ia,*ja; ierr = PetscInitialize(&argc,&argv,NULL,help);if (ierr) return ierr; ierr = PetscOptionsGetReal(NULL,NULL,"-tol",&tol,NULL);CHKERRQ(ierr); user.ratio = 2; user.coarse.mx = 20; user.coarse.my = 20; user.coarse.mz = 20; ierr = PetscOptionsGetInt(NULL,NULL,"-Mx",&user.coarse.mx,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-My",&user.coarse.my,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-Mz",&user.coarse.mz,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-ratio",&user.ratio,NULL);CHKERRQ(ierr); if (user.coarse.mz) Test_3D = PETSC_TRUE; user.fine.mx = user.ratio*(user.coarse.mx-1)+1; user.fine.my = user.ratio*(user.coarse.my-1)+1; user.fine.mz = user.ratio*(user.coarse.mz-1)+1; ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-Npx",&Npx,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-Npy",&Npy,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-Npz",&Npz,NULL);CHKERRQ(ierr); /* Set up distributed array for fine grid */ if (!Test_3D) { ierr = DMDACreate2d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE,DMDA_STENCIL_STAR,user.fine.mx,user.fine.my,Npx,Npy,1,1,NULL,NULL,&user.fine.da);CHKERRQ(ierr); } else { ierr = DMDACreate3d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE,DMDA_STENCIL_STAR,user.fine.mx,user.fine.my,user.fine.mz,Npx,Npy,Npz,1,1,NULL,NULL,NULL,&user.fine.da);CHKERRQ(ierr); } ierr = DMSetFromOptions(user.fine.da);CHKERRQ(ierr); ierr = DMSetUp(user.fine.da);CHKERRQ(ierr); /* Test DMCreateMatrix() */ /*------------------------------------------------------------*/ ierr = DMSetMatType(user.fine.da,MATAIJ);CHKERRQ(ierr); ierr = DMCreateMatrix(user.fine.da,&A);CHKERRQ(ierr); ierr = DMSetMatType(user.fine.da,MATBAIJ);CHKERRQ(ierr); ierr = DMCreateMatrix(user.fine.da,&C);CHKERRQ(ierr); ierr = MatConvert(C,MATAIJ,MAT_INITIAL_MATRIX,&A_tmp);CHKERRQ(ierr); /* not work for mpisbaij matrix! */ ierr = MatEqual(A,A_tmp,&flg);CHKERRQ(ierr); if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMETYPE,"A != C"); ierr = MatDestroy(&C);CHKERRQ(ierr); ierr = MatDestroy(&A_tmp);CHKERRQ(ierr); /*------------------------------------------------------------*/ ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); /* if (!rank) printf("A %d, %d\n",M,N); */ /* set val=one to A */ if (size == 1) { ierr = MatGetRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&nrows,&ia,&ja,&flg);CHKERRQ(ierr); if (flg) { ierr = MatSeqAIJGetArray(A,&array);CHKERRQ(ierr); for (i=0; i<ia[nrows]; i++) array[i] = one; ierr = MatSeqAIJRestoreArray(A,&array);CHKERRQ(ierr); } ierr = MatRestoreRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&nrows,&ia,&ja,&flg);CHKERRQ(ierr); } else { Mat AA,AB; ierr = MatMPIAIJGetSeqAIJ(A,&AA,&AB,NULL);CHKERRQ(ierr); ierr = MatGetRowIJ(AA,0,PETSC_FALSE,PETSC_FALSE,&nrows,&ia,&ja,&flg);CHKERRQ(ierr); if (flg) { ierr = MatSeqAIJGetArray(AA,&array);CHKERRQ(ierr); for (i=0; i<ia[nrows]; i++) array[i] = one; ierr = MatSeqAIJRestoreArray(AA,&array);CHKERRQ(ierr); } ierr = MatRestoreRowIJ(AA,0,PETSC_FALSE,PETSC_FALSE,&nrows,&ia,&ja,&flg);CHKERRQ(ierr); ierr = MatGetRowIJ(AB,0,PETSC_FALSE,PETSC_FALSE,&nrows,&ia,&ja,&flg);CHKERRQ(ierr); if (flg) { ierr = MatSeqAIJGetArray(AB,&array);CHKERRQ(ierr); for (i=0; i<ia[nrows]; i++) array[i] = one; ierr = MatSeqAIJRestoreArray(AB,&array);CHKERRQ(ierr); } ierr = MatRestoreRowIJ(AB,0,PETSC_FALSE,PETSC_FALSE,&nrows,&ia,&ja,&flg);CHKERRQ(ierr); } /* ierr = MatView(A, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); */ /* Set up distributed array for coarse grid */ if (!Test_3D) { ierr = DMDACreate2d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE,DMDA_STENCIL_STAR,user.coarse.mx,user.coarse.my,Npx,Npy,1,1,NULL,NULL,&user.coarse.da);CHKERRQ(ierr); } else { ierr = DMDACreate3d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE,DMDA_STENCIL_STAR,user.coarse.mx,user.coarse.my,user.coarse.mz,Npx,Npy,Npz, 1,1,NULL,NULL,NULL,&user.coarse.da);CHKERRQ(ierr); } ierr = DMSetFromOptions(user.coarse.da);CHKERRQ(ierr); ierr = DMSetUp(user.coarse.da);CHKERRQ(ierr); /* Create interpolation between the fine and coarse grids */ ierr = DMCreateInterpolation(user.coarse.da,user.fine.da,&P,NULL);CHKERRQ(ierr); ierr = MatGetLocalSize(P,&m,&n);CHKERRQ(ierr); ierr = MatGetSize(P,&M,&N);CHKERRQ(ierr); /* if (!rank) printf("P %d, %d\n",M,N); */ /* Create vectors v1 and v2 that are compatible with A */ ierr = VecCreate(PETSC_COMM_WORLD,&v1);CHKERRQ(ierr); ierr = MatGetLocalSize(A,&m,NULL);CHKERRQ(ierr); ierr = VecSetSizes(v1,m,PETSC_DECIDE);CHKERRQ(ierr); ierr = VecSetFromOptions(v1);CHKERRQ(ierr); ierr = VecDuplicate(v1,&v2);CHKERRQ(ierr); ierr = PetscRandomCreate(PETSC_COMM_WORLD,&rdm);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rdm);CHKERRQ(ierr); /* Test MatMatMult(): C = A*P */ /*----------------------------*/ if (Test_MatMatMult) { ierr = MatDuplicate(A,MAT_COPY_VALUES,&A_tmp);CHKERRQ(ierr); ierr = MatMatMult(A_tmp,P,MAT_INITIAL_MATRIX,fill,&C);CHKERRQ(ierr); /* Test MAT_REUSE_MATRIX - reuse symbolic C */ alpha=1.0; for (i=0; i<2; i++) { alpha -= 0.1; ierr = MatScale(A_tmp,alpha);CHKERRQ(ierr); ierr = MatMatMult(A_tmp,P,MAT_REUSE_MATRIX,fill,&C);CHKERRQ(ierr); } /* Free intermediate data structures created for reuse of C=Pt*A*P */ ierr = MatFreeIntermediateDataStructures(C);CHKERRQ(ierr); /* Test MatDuplicate() */ /*----------------------------*/ ierr = MatDuplicate(C,MAT_COPY_VALUES,&C1);CHKERRQ(ierr); ierr = MatDuplicate(C1,MAT_COPY_VALUES,&C2);CHKERRQ(ierr); ierr = MatDestroy(&C1);CHKERRQ(ierr); ierr = MatDestroy(&C2);CHKERRQ(ierr); /* Create vector x that is compatible with P */ ierr = VecCreate(PETSC_COMM_WORLD,&x);CHKERRQ(ierr); ierr = MatGetLocalSize(P,NULL,&n);CHKERRQ(ierr); ierr = VecSetSizes(x,n,PETSC_DECIDE);CHKERRQ(ierr); ierr = VecSetFromOptions(x);CHKERRQ(ierr); norm = 0.0; for (i=0; i<10; i++) { ierr = VecSetRandom(x,rdm);CHKERRQ(ierr); ierr = MatMult(P,x,v1);CHKERRQ(ierr); ierr = MatMult(A_tmp,v1,v2);CHKERRQ(ierr); /* v2 = A*P*x */ ierr = MatMult(C,x,v1);CHKERRQ(ierr); /* v1 = C*x */ ierr = VecAXPY(v1,none,v2);CHKERRQ(ierr); ierr = VecNorm(v1,NORM_1,&norm_tmp);CHKERRQ(ierr); ierr = VecNorm(v2,NORM_1,&norm_tmp1);CHKERRQ(ierr); norm_tmp /= norm_tmp1; if (norm_tmp > norm) norm = norm_tmp; } if (norm >= tol && !rank) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error: MatMatMult(), |v1 - v2|/|v2|: %g\n",(double)norm);CHKERRQ(ierr); } ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = MatDestroy(&C);CHKERRQ(ierr); ierr = MatDestroy(&A_tmp);CHKERRQ(ierr); } /* Test P^T * A * P - MatPtAP() */ /*------------------------------*/ if (Test_MatPtAP) { ierr = MatPtAP(A,P,MAT_INITIAL_MATRIX,fill,&C);CHKERRQ(ierr); ierr = MatGetLocalSize(C,&m,&n);CHKERRQ(ierr); /* Test MAT_REUSE_MATRIX - reuse symbolic C */ alpha=1.0; for (i=0; i<1; i++) { alpha -= 0.1; ierr = MatScale(A,alpha);CHKERRQ(ierr); ierr = MatPtAP(A,P,MAT_REUSE_MATRIX,fill,&C);CHKERRQ(ierr); } /* Free intermediate data structures created for reuse of C=Pt*A*P */ ierr = MatFreeIntermediateDataStructures(C);CHKERRQ(ierr); /* Test MatDuplicate() */ /*----------------------------*/ ierr = MatDuplicate(C,MAT_COPY_VALUES,&C1);CHKERRQ(ierr); ierr = MatDuplicate(C1,MAT_COPY_VALUES,&C2);CHKERRQ(ierr); ierr = MatDestroy(&C1);CHKERRQ(ierr); ierr = MatDestroy(&C2);CHKERRQ(ierr); /* Create vector x that is compatible with P */ ierr = VecCreate(PETSC_COMM_WORLD,&x);CHKERRQ(ierr); ierr = MatGetLocalSize(P,&m,&n);CHKERRQ(ierr); ierr = VecSetSizes(x,n,PETSC_DECIDE);CHKERRQ(ierr); ierr = VecSetFromOptions(x);CHKERRQ(ierr); ierr = VecCreate(PETSC_COMM_WORLD,&v3);CHKERRQ(ierr); ierr = VecSetSizes(v3,n,PETSC_DECIDE);CHKERRQ(ierr); ierr = VecSetFromOptions(v3);CHKERRQ(ierr); ierr = VecDuplicate(v3,&v4);CHKERRQ(ierr); norm = 0.0; for (i=0; i<10; i++) { ierr = VecSetRandom(x,rdm);CHKERRQ(ierr); ierr = MatMult(P,x,v1);CHKERRQ(ierr); ierr = MatMult(A,v1,v2);CHKERRQ(ierr); /* v2 = A*P*x */ ierr = MatMultTranspose(P,v2,v3);CHKERRQ(ierr); /* v3 = Pt*A*P*x */ ierr = MatMult(C,x,v4);CHKERRQ(ierr); /* v3 = C*x */ ierr = VecAXPY(v4,none,v3);CHKERRQ(ierr); ierr = VecNorm(v4,NORM_1,&norm_tmp);CHKERRQ(ierr); ierr = VecNorm(v3,NORM_1,&norm_tmp1);CHKERRQ(ierr); norm_tmp /= norm_tmp1; if (norm_tmp > norm) norm = norm_tmp; } if (norm >= tol && !rank) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error: MatPtAP(), |v3 - v4|/|v3|: %g\n",(double)norm);CHKERRQ(ierr); } ierr = MatDestroy(&C);CHKERRQ(ierr); ierr = VecDestroy(&v3);CHKERRQ(ierr); ierr = VecDestroy(&v4);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); } /* Clean up */ ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = PetscRandomDestroy(&rdm);CHKERRQ(ierr); ierr = VecDestroy(&v1);CHKERRQ(ierr); ierr = VecDestroy(&v2);CHKERRQ(ierr); ierr = DMDestroy(&user.fine.da);CHKERRQ(ierr); ierr = DMDestroy(&user.coarse.da);CHKERRQ(ierr); ierr = MatDestroy(&P);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
int main(int argc,char **args) { Vec x,y,u,s1,s2; Mat A,sA,sB; PetscRandom rctx; PetscReal r1,r2,rnorm,tol=1.e-10; PetscScalar one=1.0, neg_one=-1.0, value[3], four=4.0,alpha=0.1; PetscInt n,col[3],n1,block,row,i,j,i2,j2,Ii,J,rstart,rend,bs=1,mbs=16,d_nz=3,o_nz=3,prob=2; PetscErrorCode ierr; PetscMPIInt size,rank; PetscTruth flg; const MatType type; PetscInitialize(&argc,&args,(char *)0,help); ierr = PetscOptionsGetInt(PETSC_NULL,"-mbs",&mbs,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-bs",&bs,PETSC_NULL);CHKERRQ(ierr); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); n = mbs*bs; /* Assemble MPISBAIJ matrix sA */ ierr = MatCreate(PETSC_COMM_WORLD,&sA);CHKERRQ(ierr); ierr = MatSetSizes(sA,PETSC_DECIDE,PETSC_DECIDE,n,n);CHKERRQ(ierr); ierr = MatSetType(sA,MATSBAIJ);CHKERRQ(ierr); ierr = MatSetFromOptions(sA);CHKERRQ(ierr); ierr = MatGetType(sA,&type);CHKERRQ(ierr); /* printf(" mattype: %s\n",type); */ ierr = MatMPISBAIJSetPreallocation(sA,bs,d_nz,PETSC_NULL,o_nz,PETSC_NULL);CHKERRQ(ierr); if (bs == 1){ if (prob == 1){ /* tridiagonal matrix */ value[0] = -1.0; value[1] = 2.0; value[2] = -1.0; for (i=1; i<n-1; i++) { col[0] = i-1; col[1] = i; col[2] = i+1; ierr = MatSetValues(sA,1,&i,3,col,value,INSERT_VALUES);CHKERRQ(ierr); } i = n - 1; col[0]=0; col[1] = n - 2; col[2] = n - 1; value[0]= 0.1; value[1]=-1; value[2]=2; ierr = MatSetValues(sA,1,&i,3,col,value,INSERT_VALUES);CHKERRQ(ierr); i = 0; col[0] = 0; col[1] = 1; col[2]=n-1; value[0] = 2.0; value[1] = -1.0; value[2]=0.1; ierr = MatSetValues(sA,1,&i,3,col,value,INSERT_VALUES);CHKERRQ(ierr); } else if (prob ==2){ /* matrix for the five point stencil */ n1 = (int) sqrt((double)n); if (n1*n1 != n){ SETERRQ(PETSC_ERR_ARG_SIZ,"n must be a perfect square of n1"); } for (i=0; i<n1; i++) { for (j=0; j<n1; j++) { Ii = j + n1*i; if (i>0) {J = Ii - n1; ierr = MatSetValues(sA,1,&Ii,1,&J,&neg_one,INSERT_VALUES);CHKERRQ(ierr);} if (i<n1-1) {J = Ii + n1; ierr = MatSetValues(sA,1,&Ii,1,&J,&neg_one,INSERT_VALUES);CHKERRQ(ierr);} if (j>0) {J = Ii - 1; ierr = MatSetValues(sA,1,&Ii,1,&J,&neg_one,INSERT_VALUES);CHKERRQ(ierr);} if (j<n1-1) {J = Ii + 1; ierr = MatSetValues(sA,1,&Ii,1,&J,&neg_one,INSERT_VALUES);CHKERRQ(ierr);} ierr = MatSetValues(sA,1,&Ii,1,&Ii,&four,INSERT_VALUES);CHKERRQ(ierr); } } } } /* end of if (bs == 1) */ else { /* bs > 1 */ for (block=0; block<n/bs; 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(sA,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(sA,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(sA,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr); } /* off-diagonal blocks */ value[0]=-1.0; for (i=0; i<(n/bs-1)*bs; i++){ col[0]=i+bs; ierr = MatSetValues(sA,1,&i,1,col,value,INSERT_VALUES);CHKERRQ(ierr); col[0]=i; row=i+bs; ierr = MatSetValues(sA,1,&row,1,col,value,INSERT_VALUES);CHKERRQ(ierr); } } ierr = MatAssemblyBegin(sA,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(sA,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* Test MatView() */ /* ierr = MatView(sA, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = MatView(sA, PETSC_VIEWER_DRAW_WORLD);CHKERRQ(ierr); */ /* Assemble MPIBAIJ matrix A */ ierr = MatCreateMPIBAIJ(PETSC_COMM_WORLD,bs,PETSC_DECIDE,PETSC_DECIDE,n,n,d_nz,PETSC_NULL,o_nz,PETSC_NULL,&A);CHKERRQ(ierr); if (bs == 1){ if (prob == 1){ /* tridiagonal matrix */ value[0] = -1.0; value[1] = 2.0; value[2] = -1.0; for (i=1; i<n-1; i++) { col[0] = i-1; col[1] = i; col[2] = i+1; ierr = MatSetValues(A,1,&i,3,col,value,INSERT_VALUES);CHKERRQ(ierr); } i = n - 1; col[0]=0; col[1] = n - 2; col[2] = n - 1; value[0]= 0.1; value[1]=-1; value[2]=2; ierr = MatSetValues(A,1,&i,3,col,value,INSERT_VALUES);CHKERRQ(ierr); i = 0; col[0] = 0; col[1] = 1; col[2]=n-1; value[0] = 2.0; value[1] = -1.0; value[2]=0.1; ierr = MatSetValues(A,1,&i,3,col,value,INSERT_VALUES);CHKERRQ(ierr); } else if (prob ==2){ /* matrix for the five point stencil */ n1 = (int) sqrt((double)n); for (i=0; i<n1; i++) { for (j=0; j<n1; j++) { Ii = j + n1*i; if (i>0) {J = Ii - n1; ierr = MatSetValues(A,1,&Ii,1,&J,&neg_one,INSERT_VALUES);CHKERRQ(ierr);} if (i<n1-1) {J = Ii + n1; ierr = MatSetValues(A,1,&Ii,1,&J,&neg_one,INSERT_VALUES);CHKERRQ(ierr);} if (j>0) {J = Ii - 1; ierr = MatSetValues(A,1,&Ii,1,&J,&neg_one,INSERT_VALUES);CHKERRQ(ierr);} if (j<n1-1) {J = Ii + 1; ierr = MatSetValues(A,1,&Ii,1,&J,&neg_one,INSERT_VALUES);CHKERRQ(ierr);} ierr = MatSetValues(A,1,&Ii,1,&Ii,&four,INSERT_VALUES);CHKERRQ(ierr); } } } } /* end of if (bs == 1) */ else { /* bs > 1 */ for (block=0; block<n/bs; 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(A,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(A,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(A,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr); } /* off-diagonal blocks */ value[0]=-1.0; for (i=0; i<(n/bs-1)*bs; i++){ col[0]=i+bs; ierr = MatSetValues(A,1,&i,1,col,value,INSERT_VALUES);CHKERRQ(ierr); col[0]=i; row=i+bs; ierr = MatSetValues(A,1,&row,1,col,value,INSERT_VALUES);CHKERRQ(ierr); } } ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* Test MatGetSize(), MatGetLocalSize() */ ierr = MatGetSize(sA, &i,&j); ierr = MatGetSize(A, &i2,&j2); i -= i2; j -= j2; if (i || j) { PetscSynchronizedPrintf(PETSC_COMM_WORLD,"[%d], Error: MatGetSize()\n",rank); PetscSynchronizedFlush(PETSC_COMM_WORLD); } ierr = MatGetLocalSize(sA, &i,&j); ierr = MatGetLocalSize(A, &i2,&j2); i2 -= i; j2 -= j; if (i2 || j2) { PetscSynchronizedPrintf(PETSC_COMM_WORLD,"[%d], Error: MatGetLocalSize()\n",rank); PetscSynchronizedFlush(PETSC_COMM_WORLD); } /* vectors */ /*--------------------*/ /* i is obtained from MatGetLocalSize() */ ierr = VecCreate(PETSC_COMM_WORLD,&x);CHKERRQ(ierr); ierr = VecSetSizes(x,i,PETSC_DECIDE);CHKERRQ(ierr); ierr = VecSetFromOptions(x);CHKERRQ(ierr); ierr = VecDuplicate(x,&y);CHKERRQ(ierr); ierr = VecDuplicate(x,&u);CHKERRQ(ierr); ierr = VecDuplicate(x,&s1);CHKERRQ(ierr); ierr = VecDuplicate(x,&s2);CHKERRQ(ierr); ierr = PetscRandomCreate(PETSC_COMM_WORLD,&rctx);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rctx);CHKERRQ(ierr); ierr = VecSetRandom(x,rctx);CHKERRQ(ierr); ierr = VecSet(u,one);CHKERRQ(ierr); /* Test MatNorm() */ ierr = MatNorm(A,NORM_FROBENIUS,&r1);CHKERRQ(ierr); ierr = MatNorm(sA,NORM_FROBENIUS,&r2);CHKERRQ(ierr); rnorm = PetscAbsScalar(r1-r2)/r2; if (rnorm > tol && !rank){ PetscPrintf(PETSC_COMM_SELF,"Error: MatNorm_FROBENIUS(), Anorm=%16.14e, sAnorm=%16.14e bs=%D\n",r1,r2,bs); } ierr = MatNorm(A,NORM_INFINITY,&r1);CHKERRQ(ierr); ierr = MatNorm(sA,NORM_INFINITY,&r2);CHKERRQ(ierr); rnorm = PetscAbsScalar(r1-r2)/r2; if (rnorm > tol && !rank){ PetscPrintf(PETSC_COMM_WORLD,"Error: MatNorm_INFINITY(), Anorm=%16.14e, sAnorm=%16.14e bs=%D\n",r1,r2,bs); } ierr = MatNorm(A,NORM_1,&r1);CHKERRQ(ierr); ierr = MatNorm(sA,NORM_1,&r2);CHKERRQ(ierr); rnorm = PetscAbsScalar(r1-r2)/r2; if (rnorm > tol && !rank){ PetscPrintf(PETSC_COMM_WORLD,"Error: MatNorm_1(), Anorm=%16.14e, sAnorm=%16.14e bs=%D\n",r1,r2,bs); } /* Test MatGetOwnershipRange() */ ierr = MatGetOwnershipRange(sA,&rstart,&rend);CHKERRQ(ierr); ierr = MatGetOwnershipRange(A,&i2,&j2);CHKERRQ(ierr); i2 -= rstart; j2 -= rend; if (i2 || j2) { PetscSynchronizedPrintf(PETSC_COMM_WORLD,"[%d], Error: MaGetOwnershipRange()\n",rank); PetscSynchronizedFlush(PETSC_COMM_WORLD); } /* Test MatDiagonalScale() */ ierr = MatDiagonalScale(A,x,x);CHKERRQ(ierr); ierr = MatDiagonalScale(sA,x,x);CHKERRQ(ierr); ierr = MatMultEqual(A,sA,10,&flg);CHKERRQ(ierr); if (!flg) SETERRQ(PETSC_ERR_ARG_NOTSAMETYPE,"Error in MatDiagonalScale"); /* Test MatGetDiagonal(), MatScale() */ ierr = MatGetDiagonal(A,s1);CHKERRQ(ierr); ierr = MatGetDiagonal(sA,s2);CHKERRQ(ierr); ierr = VecNorm(s1,NORM_1,&r1);CHKERRQ(ierr); ierr = VecNorm(s2,NORM_1,&r2);CHKERRQ(ierr); r1 -= r2; if (r1<-tol || r1>tol) { PetscSynchronizedPrintf(PETSC_COMM_WORLD,"[%d], Error: MatDiagonalScale() or MatGetDiagonal(), r1=%G \n",rank,r1); PetscSynchronizedFlush(PETSC_COMM_WORLD); } ierr = MatScale(A,alpha);CHKERRQ(ierr); ierr = MatScale(sA,alpha);CHKERRQ(ierr); /* Test MatGetRowMaxAbs() */ ierr = MatGetRowMaxAbs(A,s1,PETSC_NULL);CHKERRQ(ierr); ierr = MatGetRowMaxAbs(sA,s2,PETSC_NULL);CHKERRQ(ierr); ierr = VecNorm(s1,NORM_1,&r1);CHKERRQ(ierr); ierr = VecNorm(s2,NORM_1,&r2);CHKERRQ(ierr); r1 -= r2; if (r1<-tol || r1>tol) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error: MatGetRowMaxAbs() \n");CHKERRQ(ierr); } /* Test MatMult(), MatMultAdd() */ ierr = MatMultEqual(A,sA,10,&flg);CHKERRQ(ierr); if (!flg){ PetscSynchronizedPrintf(PETSC_COMM_WORLD,"[%d], Error: MatMult() or MatScale()\n",rank); PetscSynchronizedFlush(PETSC_COMM_WORLD); } ierr = MatMultAddEqual(A,sA,10,&flg);CHKERRQ(ierr); if (!flg){ PetscSynchronizedPrintf(PETSC_COMM_WORLD,"[%d], Error: MatMultAdd()\n",rank); PetscSynchronizedFlush(PETSC_COMM_WORLD); } /* Test MatMultTranspose(), MatMultTransposeAdd() */ for (i=0; i<10; i++) { ierr = VecSetRandom(x,rctx);CHKERRQ(ierr); ierr = MatMultTranspose(A,x,s1);CHKERRQ(ierr); ierr = MatMultTranspose(sA,x,s2);CHKERRQ(ierr); ierr = VecNorm(s1,NORM_1,&r1);CHKERRQ(ierr); ierr = VecNorm(s2,NORM_1,&r2);CHKERRQ(ierr); r1 -= r2; if (r1<-tol || r1>tol) { PetscSynchronizedPrintf(PETSC_COMM_WORLD,"[%d], Error: MatMult() or MatScale(), err=%G\n",rank,r1); PetscSynchronizedFlush(PETSC_COMM_WORLD); } } for (i=0; i<10; i++) { ierr = VecSetRandom(x,rctx);CHKERRQ(ierr); ierr = VecSetRandom(y,rctx);CHKERRQ(ierr); ierr = MatMultTransposeAdd(A,x,y,s1);CHKERRQ(ierr); ierr = MatMultTransposeAdd(sA,x,y,s2);CHKERRQ(ierr); ierr = VecNorm(s1,NORM_1,&r1);CHKERRQ(ierr); ierr = VecNorm(s2,NORM_1,&r2);CHKERRQ(ierr); r1 -= r2; if (r1<-tol || r1>tol) { PetscSynchronizedPrintf(PETSC_COMM_WORLD,"[%d], Error: MatMultAdd(), err=%G \n",rank,r1); PetscSynchronizedFlush(PETSC_COMM_WORLD); } } /* ierr = MatView(sA, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); */ /* ierr = MatView(sA, PETSC_VIEWER_DRAW_WORLD);CHKERRQ(ierr); */ /* Test MatDuplicate() */ ierr = MatDuplicate(sA,MAT_COPY_VALUES,&sB);CHKERRQ(ierr); ierr = MatEqual(sA,sB,&flg);CHKERRQ(ierr); if (!flg){ PetscPrintf(PETSC_COMM_WORLD," Error in MatDuplicate(), sA != sB \n");CHKERRQ(ierr); } ierr = MatMultEqual(sA,sB,5,&flg);CHKERRQ(ierr); if (!flg){ PetscSynchronizedPrintf(PETSC_COMM_WORLD,"[%d], Error: MatDuplicate() or MatMult()\n",rank); PetscSynchronizedFlush(PETSC_COMM_WORLD); } ierr = MatMultAddEqual(sA,sB,5,&flg);CHKERRQ(ierr); if (!flg){ PetscSynchronizedPrintf(PETSC_COMM_WORLD,"[%d], Error: MatDuplicate() or MatMultAdd(()\n",rank); PetscSynchronizedFlush(PETSC_COMM_WORLD); } ierr = MatDestroy(sB);CHKERRQ(ierr); ierr = VecDestroy(u);CHKERRQ(ierr); ierr = VecDestroy(x);CHKERRQ(ierr); ierr = VecDestroy(y);CHKERRQ(ierr); ierr = VecDestroy(s1);CHKERRQ(ierr); ierr = VecDestroy(s2);CHKERRQ(ierr); ierr = MatDestroy(sA);CHKERRQ(ierr); ierr = MatDestroy(A);CHKERRQ(ierr); ierr = PetscRandomDestroy(rctx);CHKERRQ(ierr); ierr = PetscFinalize();CHKERRQ(ierr); return 0; }
PetscInt main(PetscInt argc,char **args) { Mat A,As; Vec x,y,ys; PetscBool 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(PETSC_COMM_WORLD,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(NULL, "-display_mat", &disp_mat);CHKERRQ(ierr); ierr = PetscOptionsHasName(NULL, "-display_vec", &disp_vec);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,"-sigma1",&sigma1,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,"-n",&n,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(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(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_COMM_SELF,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(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_COMM_SELF,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(); return 0; }
int main(int argc, char **argv) { Vec vec, tagged, untagged; VecScatter taggedScatter, untaggedScatter; PetscInt bs; PetscInt n, nloc, nint, i, j, k, localStart, localEnd, ntagged, nuntagged; MPI_Comm comm; VecTagger tagger; PetscScalar *array; PetscRandom rand; VecTaggerBox *defaultBox; VecTaggerBox *boxes; IS is, isBlockGlobal, isComp; PetscErrorCode ierr; ierr = PetscInitialize(&argc,&argv,NULL,help);if (ierr) return ierr; n = 10.; bs = 1; comm = PETSC_COMM_WORLD; ierr = PetscOptionsBegin(comm, "" , "VecTagger Test Options", "Vec");CHKERRQ(ierr); ierr = PetscOptionsInt("-bs","The block size of the vector","ex1.c",bs,&bs,NULL);CHKERRQ(ierr); ierr = PetscOptionsInt("-n","The size of the vector (in blocks)","ex1.c",n,&n,NULL);CHKERRQ(ierr); ierr = PetscOptionsEnd();CHKERRQ(ierr); ierr = PetscRandomCreate(comm,&rand);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rand);CHKERRQ(ierr); ierr = VecCreate(comm,&vec);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)vec,"Vec to Tag");CHKERRQ(ierr); ierr = VecSetBlockSize(vec,bs);CHKERRQ(ierr); ierr = VecSetSizes(vec,PETSC_DECIDE,n);CHKERRQ(ierr); ierr = VecSetUp(vec);CHKERRQ(ierr); ierr = VecGetLocalSize(vec,&nloc);CHKERRQ(ierr); ierr = VecGetArray(vec,&array);CHKERRQ(ierr); for (i = 0; i < nloc; i++) { PetscScalar val; ierr = PetscRandomGetValue(rand,&val);CHKERRQ(ierr); array[i] = val; } ierr = VecRestoreArray(vec,&array);CHKERRQ(ierr); ierr = PetscRandomDestroy(&rand);CHKERRQ(ierr); ierr = VecViewFromOptions(vec,NULL,"-vec_view");CHKERRQ(ierr); ierr = VecTaggerCreate(comm,&tagger);CHKERRQ(ierr); ierr = VecTaggerSetBlockSize(tagger,bs);CHKERRQ(ierr); ierr = VecTaggerSetType(tagger,VECTAGGERABSOLUTE);CHKERRQ(ierr); ierr = PetscMalloc1(bs,&defaultBox);CHKERRQ(ierr); for (i = 0; i < bs; i++) { #if !defined(PETSC_USE_COMPLEX) defaultBox[i].min = 0.1; defaultBox[i].max = 1.5; #else defaultBox[i].min = PetscCMPLX(0.1,0.1); defaultBox[i].max = PetscCMPLX(1.5,1.5); #endif } ierr = VecTaggerAbsoluteSetBox(tagger,defaultBox);CHKERRQ(ierr); ierr = PetscFree(defaultBox);CHKERRQ(ierr); ierr = VecTaggerSetFromOptions(tagger);CHKERRQ(ierr); ierr = VecTaggerSetUp(tagger);CHKERRQ(ierr); ierr = PetscObjectViewFromOptions((PetscObject)tagger,NULL,"-vec_tagger_view");CHKERRQ(ierr); ierr = VecTaggerGetBlockSize(tagger,&bs);CHKERRQ(ierr); ierr = VecTaggerComputeBoxes(tagger,vec,&nint,&boxes); if (ierr && ierr != PETSC_ERR_SUP) CHKERRQ(ierr); else { PetscViewer viewer = NULL; ierr = PetscOptionsGetViewer(comm,NULL,NULL,"-vec_tagger_boxes_view",&viewer,NULL,NULL);CHKERRQ(ierr); if (viewer) { PetscBool iascii; ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); if (iascii) { ierr = PetscViewerASCIIPrintf(viewer,"Num boxes: %D\n",nint);CHKERRQ(ierr); ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); for (i = 0, k = 0; i < nint; i++) { ierr = PetscViewerASCIIPrintf(viewer,"%D: ",i);CHKERRQ(ierr); for (j = 0; j < bs; j++, k++) { if (j) {ierr = PetscViewerASCIIPrintf(viewer," x ");CHKERRQ(ierr);} #if !defined(PETSC_USE_COMPLEX) ierr = PetscViewerASCIIPrintf(viewer,"[%g,%g]",(double)boxes[k].min,(double)boxes[k].max);CHKERRQ(ierr); #else ierr = PetscViewerASCIIPrintf(viewer,"[%g+%gi,%g+%gi]",(double)PetscRealPart(boxes[k].min),(double)PetscImaginaryPart(boxes[k].min),(double)PetscRealPart(boxes[k].max),(double)PetscImaginaryPart(boxes[k].max));CHKERRQ(ierr); #endif } ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); } ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); } } ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); ierr = PetscFree(boxes);CHKERRQ(ierr); } ierr = VecTaggerComputeIS(tagger,vec,&is);CHKERRQ(ierr); ierr = ISGetBlockGlobalIS(is,vec,bs,&isBlockGlobal);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)isBlockGlobal,"Tagged IS (block global)");CHKERRQ(ierr); ierr = ISViewFromOptions(isBlockGlobal,NULL,"-tagged_is_view");CHKERRQ(ierr); ierr = VecGetOwnershipRange(vec,&localStart,&localEnd);CHKERRQ(ierr); ierr = ISComplement(isBlockGlobal,localStart,localEnd,&isComp);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)isComp,"Untagged IS (global)");CHKERRQ(ierr); ierr = ISViewFromOptions(isComp,NULL,"-untagged_is_view");CHKERRQ(ierr); ierr = ISGetLocalSize(isBlockGlobal,&ntagged);CHKERRQ(ierr); ierr = ISGetLocalSize(isComp,&nuntagged);CHKERRQ(ierr); ierr = VecCreate(comm,&tagged);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)tagged,"Tagged selection");CHKERRQ(ierr); ierr = VecSetSizes(tagged,ntagged,PETSC_DETERMINE);CHKERRQ(ierr); ierr = VecSetUp(tagged);CHKERRQ(ierr); ierr = VecCreate(comm,&untagged);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)untagged,"Untagged selection");CHKERRQ(ierr); ierr = VecSetSizes(untagged,nuntagged,PETSC_DETERMINE);CHKERRQ(ierr); ierr = VecSetUp(untagged);CHKERRQ(ierr); ierr = VecScatterCreate(vec,isBlockGlobal,tagged,NULL,&taggedScatter);CHKERRQ(ierr); ierr = VecScatterCreate(vec,isComp,untagged,NULL,&untaggedScatter);CHKERRQ(ierr); ierr = VecScatterBegin(taggedScatter,vec,tagged,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(taggedScatter,vec,tagged,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterBegin(untaggedScatter,vec,untagged,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(untaggedScatter,vec,untagged,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecViewFromOptions(tagged,NULL,"-tagged_vec_view");CHKERRQ(ierr); ierr = VecViewFromOptions(untagged,NULL,"-untagged_vec_view");CHKERRQ(ierr); ierr = VecScatterDestroy(&untaggedScatter);CHKERRQ(ierr); ierr = VecScatterDestroy(&taggedScatter);CHKERRQ(ierr); ierr = VecDestroy(&untagged);CHKERRQ(ierr); ierr = VecDestroy(&tagged);CHKERRQ(ierr); ierr = ISDestroy(&isComp);CHKERRQ(ierr); ierr = ISDestroy(&isBlockGlobal);CHKERRQ(ierr); ierr = ISDestroy(&is);CHKERRQ(ierr); ierr = VecTaggerDestroy(&tagger);CHKERRQ(ierr); ierr = VecDestroy(&vec);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
int main(int argc,char **argv) { Mat A,B; PetscInt i,j,column; PetscInt *di,*dj,*oi,*oj; PetscScalar *oa,*da,value; PetscRandom rctx; PetscErrorCode ierr; PetscBool equal; Mat_SeqAIJ *daij,*oaij; Mat_MPIAIJ *Ampiaij; PetscMPIInt size,rank; PetscInitialize(&argc,&argv,(char*)0,help); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); if (size == 1) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_ARG_OUTOFRANGE,"Must run with 2 or more processes");CHKERRQ(ierr); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); /* Create a mpiaij matrix for checking */ ierr = MatCreateAIJ(PETSC_COMM_WORLD,5,5,PETSC_DECIDE,PETSC_DECIDE,0,NULL,0,NULL,&A);CHKERRQ(ierr); ierr = MatSetOption(A,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); ierr = MatSetUp(A);CHKERRQ(ierr); ierr = PetscRandomCreate(PETSC_COMM_WORLD,&rctx);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rctx);CHKERRQ(ierr); for (i=5*rank; i<5*rank+5; i++) { for (j=0; j<5*size; j++) { ierr = PetscRandomGetValue(rctx,&value);CHKERRQ(ierr); column = (PetscInt) (5*size*PetscRealPart(value)); ierr = PetscRandomGetValue(rctx,&value);CHKERRQ(ierr); ierr = MatSetValues(A,1,&i,1,&column,&value,INSERT_VALUES);CHKERRQ(ierr); } } ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); Ampiaij = (Mat_MPIAIJ*) A->data; daij = (Mat_SeqAIJ*) Ampiaij->A->data; oaij = (Mat_SeqAIJ*) Ampiaij->B->data; di = daij->i; dj = daij->j; da = daij->a; oi = oaij->i; oa = oaij->a; ierr = PetscMalloc1(oi[5],&oj);CHKERRQ(ierr); ierr = PetscMemcpy(oj,oaij->j,oi[5]*sizeof(PetscInt));CHKERRQ(ierr); /* modify the column entries in the non-diagonal portion back to global numbering */ for (i=0; i<oi[5]; i++) { oj[i] = Ampiaij->garray[oj[i]]; } ierr = MatCreateMPIAIJWithSplitArrays(PETSC_COMM_WORLD,5,5,PETSC_DETERMINE,PETSC_DETERMINE,di,dj,da,oi,oj,oa,&B);CHKERRQ(ierr); ierr = MatSetUp(B);CHKERRQ(ierr); ierr = MatEqual(A,B,&equal);CHKERRQ(ierr); if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Likely a bug in MatCreateMPIAIJWithSplitArrays()"); /* Free spaces */ ierr = PetscRandomDestroy(&rctx);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = MatDestroy(&B);CHKERRQ(ierr); ierr = PetscFree(oj);CHKERRQ(ierr); ierr = PetscFinalize(); return(0); }
PetscInt main(PetscInt argc,char **args) { PetscErrorCode ierr; PetscMPIInt rank,size; PetscInt N0=4096,N1=4096,N2=256,N3=10,N4=10,N=N0*N1; PetscRandom rdm; PetscReal enorm; Vec x,y,z,input,output; Mat A; PetscInt DIM, dim[5],vsize,row,col; PetscReal fac; ierr = PetscInitialize(&argc,&args,(char*)0,help);CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD, &size);CHKERRQ(ierr); ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank);CHKERRQ(ierr); #if defined(PETSC_USE_COMPLEX) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP, "Example for Real DFT. Your current data type is complex!"); #endif ierr = PetscRandomCreate(PETSC_COMM_WORLD, &rdm);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rdm);CHKERRQ(ierr); ierr = VecCreate(PETSC_COMM_WORLD,&input);CHKERRQ(ierr); ierr = VecSetSizes(input,PETSC_DECIDE,N);CHKERRQ(ierr); ierr = VecSetFromOptions(input);CHKERRQ(ierr); ierr = VecSetRandom(input,rdm);CHKERRQ(ierr); ierr = VecDuplicate(input,&output); DIM = 2; dim[0] = N0; dim[1] = N1; dim[2] = N2; dim[3] = N3; dim[4] = N4; ierr = MatCreateFFT(PETSC_COMM_WORLD,DIM,dim,MATFFTW,&A);CHKERRQ(ierr); ierr = MatGetLocalSize(A,&row,&col);CHKERRQ(ierr); printf("The Matrix size is %d and %d from process %d\n",row,col,rank); ierr = MatCreateVecsFFTW(A,&x,&y,&z);CHKERRQ(ierr); ierr = VecGetSize(x,&vsize);CHKERRQ(ierr); ierr = VecGetSize(z,&vsize);CHKERRQ(ierr); printf("The vector size of output from the main routine is %d\n",vsize); ierr = VecScatterPetscToFFTW(A,input,x);CHKERRQ(ierr); /*ierr = VecDestroy(&input);CHKERRQ(ierr);*/ ierr = MatMult(A,x,y);CHKERRQ(ierr); ierr = MatMultTranspose(A,y,z);CHKERRQ(ierr); ierr = VecScatterFFTWToPetsc(A,z,output);CHKERRQ(ierr); /*ierr = VecDestroy(&z);CHKERRQ(ierr);*/ fac = 1.0/(PetscReal)N; ierr = VecScale(output,fac);CHKERRQ(ierr); ierr = VecAssemblyBegin(input);CHKERRQ(ierr); ierr = VecAssemblyEnd(input);CHKERRQ(ierr); ierr = VecAssemblyBegin(output);CHKERRQ(ierr); ierr = VecAssemblyEnd(output);CHKERRQ(ierr); /* ierr = VecView(input,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);*/ /* ierr = VecView(output,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);*/ ierr = VecAXPY(output,-1.0,input);CHKERRQ(ierr); ierr = VecNorm(output,NORM_1,&enorm);CHKERRQ(ierr); if (enorm > 1.e-14) { ierr = PetscPrintf(PETSC_COMM_SELF," Error norm of |x - z| %e\n",enorm);CHKERRQ(ierr); } ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&y);CHKERRQ(ierr); ierr = VecDestroy(&z);CHKERRQ(ierr); ierr = VecDestroy(&output);CHKERRQ(ierr); ierr = VecDestroy(&input);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = PetscRandomDestroy(&rdm);CHKERRQ(ierr); PetscFinalize(); return 0; }
int main(int argc,char **args) { Mat Cdense,B,C,Ct; Vec d; PetscInt i,j,m = 5,n,nrows,ncols; const PetscInt *rows,*cols; IS isrows,iscols; PetscErrorCode ierr; PetscScalar *v; PetscMPIInt rank,size; PetscReal Cnorm; PetscBool flg,mats_view=PETSC_FALSE; ierr = PetscInitialize(&argc,&args,(char*)0,help); if (ierr) return ierr; ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank); CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size); CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-m",&m,NULL); CHKERRQ(ierr); n = m; ierr = PetscOptionsGetInt(NULL,NULL,"-n",&n,NULL); CHKERRQ(ierr); ierr = PetscOptionsHasName(NULL,NULL,"-mats_view",&mats_view); CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&C); CHKERRQ(ierr); ierr = MatSetSizes(C,m,n,PETSC_DECIDE,PETSC_DECIDE); CHKERRQ(ierr); ierr = MatSetType(C,MATELEMENTAL); CHKERRQ(ierr); ierr = MatSetFromOptions(C); CHKERRQ(ierr); ierr = MatSetUp(C); CHKERRQ(ierr); ierr = MatGetOwnershipIS(C,&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); #if defined(PETSC_USE_COMPLEX) PetscRandom rand; PetscScalar rval; ierr = PetscRandomCreate(PETSC_COMM_WORLD,&rand); CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rand); CHKERRQ(ierr); for (i=0; i<nrows; i++) { for (j=0; j<ncols; j++) { ierr = PetscRandomGetValue(rand,&rval); CHKERRQ(ierr); v[i*ncols+j] = rval; } } ierr = PetscRandomDestroy(&rand); CHKERRQ(ierr); #else for (i=0; i<nrows; i++) { for (j=0; j<ncols; j++) { v[i*ncols+j] = (PetscReal)(10000*rank+100*rows[i]+cols[j]); } } #endif ierr = MatSetValues(C,nrows,rows,ncols,cols,v,INSERT_VALUES); CHKERRQ(ierr); ierr = ISRestoreIndices(isrows,&rows); CHKERRQ(ierr); ierr = ISRestoreIndices(iscols,&cols); CHKERRQ(ierr); ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); ierr = ISDestroy(&isrows); CHKERRQ(ierr); ierr = ISDestroy(&iscols); CHKERRQ(ierr); /* Test MatView(), MatDuplicate() and out-of-place MatConvert() */ ierr = MatDuplicate(C,MAT_COPY_VALUES,&B); CHKERRQ(ierr); if (mats_view) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Duplicated C:\n"); CHKERRQ(ierr); ierr = MatView(B,PETSC_VIEWER_STDOUT_WORLD); CHKERRQ(ierr); } ierr = MatDestroy(&B); CHKERRQ(ierr); ierr = MatConvert(C,MATMPIDENSE,MAT_INITIAL_MATRIX,&Cdense); CHKERRQ(ierr); ierr = MatMultEqual(C,Cdense,5,&flg); CHKERRQ(ierr); if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMETYPE,"Cdense != C. MatConvert() fails"); /* Test MatNorm() */ ierr = MatNorm(C,NORM_1,&Cnorm); CHKERRQ(ierr); /* Test MatTranspose(), MatZeroEntries() and MatGetDiagonal() */ ierr = MatTranspose(C,MAT_INITIAL_MATRIX,&Ct); CHKERRQ(ierr); ierr = MatConjugate(Ct); CHKERRQ(ierr); if (mats_view) { ierr = PetscPrintf(PETSC_COMM_WORLD,"C's Transpose Conjugate:\n"); CHKERRQ(ierr); ierr = MatView(Ct,PETSC_VIEWER_STDOUT_WORLD); CHKERRQ(ierr); } ierr = MatZeroEntries(Ct); CHKERRQ(ierr); ierr = VecCreate(PETSC_COMM_WORLD,&d); CHKERRQ(ierr); ierr = VecSetSizes(d,m>n ? n : m,PETSC_DECIDE); CHKERRQ(ierr); ierr = VecSetFromOptions(d); CHKERRQ(ierr); ierr = MatGetDiagonal(C,d); CHKERRQ(ierr); if (mats_view) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Diagonal of C:\n"); CHKERRQ(ierr); ierr = VecView(d,PETSC_VIEWER_STDOUT_WORLD); CHKERRQ(ierr); } if (m>n) { ierr = MatDiagonalScale(C,NULL,d); CHKERRQ(ierr); } else { ierr = MatDiagonalScale(C,d,NULL); CHKERRQ(ierr); } if (mats_view) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Diagonal Scaled C:\n"); CHKERRQ(ierr); ierr = MatView(C,PETSC_VIEWER_STDOUT_WORLD); CHKERRQ(ierr); } /* Test MatAXPY(), MatAYPX() and in-place MatConvert() */ ierr = MatCreate(PETSC_COMM_WORLD,&B); CHKERRQ(ierr); ierr = MatSetSizes(B,m,n,PETSC_DECIDE,PETSC_DECIDE); CHKERRQ(ierr); ierr = MatSetType(B,MATELEMENTAL); CHKERRQ(ierr); ierr = MatSetFromOptions(B); CHKERRQ(ierr); ierr = MatSetUp(B); CHKERRQ(ierr); ierr = MatGetOwnershipIS(B,&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); for (i=0; i<nrows; i++) { for (j=0; j<ncols; j++) { v[i*ncols+j] = (PetscReal)(1000*rows[i]+cols[j]); } } ierr = MatSetValues(B,nrows,rows,ncols,cols,v,INSERT_VALUES); CHKERRQ(ierr); ierr = PetscFree(v); CHKERRQ(ierr); ierr = ISRestoreIndices(isrows,&rows); CHKERRQ(ierr); ierr = ISRestoreIndices(iscols,&cols); CHKERRQ(ierr); ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); ierr = MatAXPY(B,2.5,C,SAME_NONZERO_PATTERN); CHKERRQ(ierr); ierr = MatAYPX(B,3.75,C,SAME_NONZERO_PATTERN); CHKERRQ(ierr); ierr = MatConvert(B,MATDENSE,MAT_INPLACE_MATRIX,&B); CHKERRQ(ierr); if (mats_view) { ierr = PetscPrintf(PETSC_COMM_WORLD,"B after MatAXPY and MatAYPX:\n"); CHKERRQ(ierr); ierr = MatView(B,PETSC_VIEWER_STDOUT_WORLD); CHKERRQ(ierr); } ierr = ISDestroy(&isrows); CHKERRQ(ierr); ierr = ISDestroy(&iscols); CHKERRQ(ierr); ierr = MatDestroy(&B); CHKERRQ(ierr); /* Test MatMatTransposeMult(): B = C*C^T */ ierr = MatMatTransposeMult(C,C,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B); CHKERRQ(ierr); if (mats_view) { ierr = PetscPrintf(PETSC_COMM_WORLD,"C MatMatTransposeMult C:\n"); CHKERRQ(ierr); ierr = MatView(B,PETSC_VIEWER_STDOUT_WORLD); CHKERRQ(ierr); } ierr = MatDestroy(&Cdense); CHKERRQ(ierr); ierr = PetscFree(v); CHKERRQ(ierr); ierr = MatDestroy(&B); CHKERRQ(ierr); ierr = MatDestroy(&C); CHKERRQ(ierr); ierr = MatDestroy(&Ct); CHKERRQ(ierr); ierr = VecDestroy(&d); CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
int main(int argc,char **args) { Vec x,y,b; Mat A; /* linear system matrix */ Mat sA,sC; /* symmetric part of the matrices */ PetscInt n,mbs=16,bs=1,nz=3,prob=1,i,j,col[3],block, row,Ii,J,n1,lvl; PetscErrorCode ierr; PetscMPIInt size; PetscReal norm2,tol=1.e-10,err[10]; PetscScalar neg_one = -1.0,four=4.0,value[3]; IS perm,cperm; PetscRandom rdm; PetscInt reorder=0,displ=0; MatFactorInfo factinfo; PetscBool equal; PetscBool TestAIJ =PETSC_FALSE,TestBAIJ=PETSC_TRUE; PetscInt TestShift=0; PetscInitialize(&argc,&args,(char*)0,help); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); if (size != 1) SETERRQ(PETSC_COMM_WORLD,1,"This is a uniprocessor example only!"); ierr = PetscOptionsGetInt(NULL,"-bs",&bs,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,"-mbs",&mbs,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,"-reorder",&reorder,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,"-testaij",&TestAIJ,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,"-testShift",&TestShift,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,"-displ",&displ,NULL);CHKERRQ(ierr); n = mbs*bs; if (TestAIJ) { /* A is in aij format */ ierr = MatCreateSeqAIJ(PETSC_COMM_WORLD,n,n,nz,NULL,&A);CHKERRQ(ierr); TestBAIJ = PETSC_FALSE; } else { /* A is in baij format */ ierr =MatCreateSeqBAIJ(PETSC_COMM_WORLD,bs,n,n,nz,NULL,&A);CHKERRQ(ierr); TestAIJ = PETSC_FALSE; } /* Assemble matrix */ if (bs == 1) { ierr = PetscOptionsGetInt(NULL,"-test_problem",&prob,NULL);CHKERRQ(ierr); if (prob == 1) { /* tridiagonal matrix */ value[0] = -1.0; value[1] = 2.0; value[2] = -1.0; for (i=1; i<n-1; i++) { col[0] = i-1; col[1] = i; col[2] = i+1; ierr = MatSetValues(A,1,&i,3,col,value,INSERT_VALUES);CHKERRQ(ierr); } i = n - 1; col[0]=0; col[1] = n - 2; col[2] = n - 1; value[0]= 0.1; value[1]=-1; value[2]=2; ierr = MatSetValues(A,1,&i,3,col,value,INSERT_VALUES);CHKERRQ(ierr); i = 0; col[0] = 0; col[1] = 1; col[2]=n-1; value[0] = 2.0; value[1] = -1.0; value[2]=0.1; ierr = MatSetValues(A,1,&i,3,col,value,INSERT_VALUES);CHKERRQ(ierr); } else if (prob ==2) { /* matrix for the five point stencil */ n1 = (PetscInt) (PetscSqrtReal((PetscReal)n) + 0.001); if (n1*n1 - n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"sqrt(n) must be a positive interger!"); for (i=0; i<n1; i++) { for (j=0; j<n1; j++) { Ii = j + n1*i; if (i>0) { J = Ii - n1; ierr = MatSetValues(A,1,&Ii,1,&J,&neg_one,INSERT_VALUES);CHKERRQ(ierr); } if (i<n1-1) { J = Ii + n1; ierr = MatSetValues(A,1,&Ii,1,&J,&neg_one,INSERT_VALUES);CHKERRQ(ierr); } if (j>0) { J = Ii - 1; ierr = MatSetValues(A,1,&Ii,1,&J,&neg_one,INSERT_VALUES);CHKERRQ(ierr); } if (j<n1-1) { J = Ii + 1; ierr = MatSetValues(A,1,&Ii,1,&J,&neg_one,INSERT_VALUES);CHKERRQ(ierr); } ierr = MatSetValues(A,1,&Ii,1,&Ii,&four,INSERT_VALUES);CHKERRQ(ierr); } } } } else { /* bs > 1 */ for (block=0; block<n/bs; 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(A,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(A,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(A,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr); } /* off-diagonal blocks */ value[0]=-1.0; for (i=0; i<(n/bs-1)*bs; i++) { col[0]=i+bs; ierr = MatSetValues(A,1,&i,1,col,value,INSERT_VALUES);CHKERRQ(ierr); col[0]=i; row=i+bs; ierr = MatSetValues(A,1,&row,1,col,value,INSERT_VALUES);CHKERRQ(ierr); } } if (TestShift) { /* set diagonals in the 0-th block as 0 for testing shift numerical factor */ for (i=0; i<bs; i++) { row = i; col[0] = i; value[0] = 0.0; ierr = MatSetValues(A,1,&row,1,col,value,INSERT_VALUES);CHKERRQ(ierr); } } ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* Test MatConvert */ ierr = MatSetOption(A,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); ierr = MatConvert(A,MATSEQSBAIJ,MAT_INITIAL_MATRIX,&sA);CHKERRQ(ierr); ierr = MatMultEqual(A,sA,20,&equal);CHKERRQ(ierr); if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"A != sA"); /* Test MatGetOwnershipRange() */ ierr = MatGetOwnershipRange(A,&Ii,&J);CHKERRQ(ierr); ierr = MatGetOwnershipRange(sA,&i,&j);CHKERRQ(ierr); if (i-Ii || j-J) { PetscPrintf(PETSC_COMM_SELF,"Error: MatGetOwnershipRange() in MatSBAIJ format\n"); } /* Vectors */ ierr = PetscRandomCreate(PETSC_COMM_SELF,&rdm);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rdm);CHKERRQ(ierr); ierr = VecCreateSeq(PETSC_COMM_SELF,n,&x);CHKERRQ(ierr); ierr = VecDuplicate(x,&b);CHKERRQ(ierr); ierr = VecDuplicate(x,&y);CHKERRQ(ierr); ierr = VecSetRandom(x,rdm);CHKERRQ(ierr); /* Test MatReordering() - not work on sbaij matrix */ if (reorder) { ierr = MatGetOrdering(A,MATORDERINGRCM,&perm,&cperm);CHKERRQ(ierr); } else { ierr = MatGetOrdering(A,MATORDERINGNATURAL,&perm,&cperm);CHKERRQ(ierr); } ierr = ISDestroy(&cperm);CHKERRQ(ierr); /* initialize factinfo */ ierr = MatFactorInfoInitialize(&factinfo);CHKERRQ(ierr); if (TestShift == 1) { factinfo.shifttype = (PetscReal)MAT_SHIFT_NONZERO; factinfo.shiftamount = 0.1; } else if (TestShift == 2) { factinfo.shifttype = (PetscReal)MAT_SHIFT_POSITIVE_DEFINITE; } /* Test MatCholeskyFactor(), MatICCFactor() */ /*------------------------------------------*/ /* Test aij matrix A */ if (TestAIJ) { if (displ>0) { ierr = PetscPrintf(PETSC_COMM_SELF,"AIJ: \n"); } i = 0; for (lvl=-1; lvl<10; lvl++) { if (lvl==-1) { /* Cholesky factor */ factinfo.fill = 5.0; ierr = MatGetFactor(A,MATSOLVERPETSC,MAT_FACTOR_CHOLESKY,&sC);CHKERRQ(ierr); ierr = MatCholeskyFactorSymbolic(sC,A,perm,&factinfo);CHKERRQ(ierr); } else { /* incomplete Cholesky factor */ factinfo.fill = 5.0; factinfo.levels = lvl; ierr = MatGetFactor(A,MATSOLVERPETSC,MAT_FACTOR_ICC,&sC);CHKERRQ(ierr); ierr = MatICCFactorSymbolic(sC,A,perm,&factinfo);CHKERRQ(ierr); } ierr = MatCholeskyFactorNumeric(sC,A,&factinfo);CHKERRQ(ierr); ierr = MatMult(A,x,b);CHKERRQ(ierr); ierr = MatSolve(sC,b,y);CHKERRQ(ierr); ierr = MatDestroy(&sC);CHKERRQ(ierr); /* Check the error */ ierr = VecAXPY(y,neg_one,x);CHKERRQ(ierr); ierr = VecNorm(y,NORM_2,&norm2);CHKERRQ(ierr); if (displ>0) { ierr = PetscPrintf(PETSC_COMM_SELF," lvl: %D, error: %g\n", lvl,(double)norm2); } err[i++] = norm2; } } /* Test baij matrix A */ if (TestBAIJ) { if (displ>0) { ierr = PetscPrintf(PETSC_COMM_SELF,"BAIJ: \n"); } i = 0; for (lvl=-1; lvl<10; lvl++) { if (lvl==-1) { /* Cholesky factor */ factinfo.fill = 5.0; ierr = MatGetFactor(A,MATSOLVERPETSC,MAT_FACTOR_CHOLESKY,&sC);CHKERRQ(ierr); ierr = MatCholeskyFactorSymbolic(sC,A,perm,&factinfo);CHKERRQ(ierr); } else { /* incomplete Cholesky factor */ factinfo.fill = 5.0; factinfo.levels = lvl; ierr = MatGetFactor(A,MATSOLVERPETSC,MAT_FACTOR_ICC,&sC);CHKERRQ(ierr); ierr = MatICCFactorSymbolic(sC,A,perm,&factinfo);CHKERRQ(ierr); } ierr = MatCholeskyFactorNumeric(sC,A,&factinfo);CHKERRQ(ierr); ierr = MatMult(A,x,b);CHKERRQ(ierr); ierr = MatSolve(sC,b,y);CHKERRQ(ierr); ierr = MatDestroy(&sC);CHKERRQ(ierr); /* Check the error */ ierr = VecAXPY(y,neg_one,x);CHKERRQ(ierr); ierr = VecNorm(y,NORM_2,&norm2);CHKERRQ(ierr); if (displ>0) { ierr = PetscPrintf(PETSC_COMM_SELF," lvl: %D, error: %g\n", lvl,(double)norm2); } err[i++] = norm2; } } /* Test sbaij matrix sA */ if (displ>0) { ierr = PetscPrintf(PETSC_COMM_SELF,"SBAIJ: \n"); } i = 0; for (lvl=-1; lvl<10; lvl++) { if (lvl==-1) { /* Cholesky factor */ factinfo.fill = 5.0; ierr = MatGetFactor(sA,MATSOLVERPETSC,MAT_FACTOR_CHOLESKY,&sC);CHKERRQ(ierr); ierr = MatCholeskyFactorSymbolic(sC,sA,perm,&factinfo);CHKERRQ(ierr); } else { /* incomplete Cholesky factor */ factinfo.fill = 5.0; factinfo.levels = lvl; ierr = MatGetFactor(sA,MATSOLVERPETSC,MAT_FACTOR_ICC,&sC);CHKERRQ(ierr); ierr = MatICCFactorSymbolic(sC,sA,perm,&factinfo);CHKERRQ(ierr); } ierr = MatCholeskyFactorNumeric(sC,sA,&factinfo);CHKERRQ(ierr); if (lvl==0 && bs==1) { /* Test inplace ICC(0) for sbaij sA - does not work for new datastructure */ /* Mat B; ierr = MatDuplicate(sA,MAT_COPY_VALUES,&B);CHKERRQ(ierr); ierr = MatICCFactor(B,perm,&factinfo);CHKERRQ(ierr); ierr = MatEqual(sC,B,&equal);CHKERRQ(ierr); if (!equal) { SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"in-place Cholesky factor != out-place Cholesky factor"); } ierr = MatDestroy(&B);CHKERRQ(ierr); */ } ierr = MatMult(sA,x,b);CHKERRQ(ierr); ierr = MatSolve(sC,b,y);CHKERRQ(ierr); /* Test MatSolves() */ if (bs == 1) { Vecs xx,bb; ierr = VecsCreateSeq(PETSC_COMM_SELF,n,4,&xx);CHKERRQ(ierr); ierr = VecsDuplicate(xx,&bb);CHKERRQ(ierr); ierr = MatSolves(sC,bb,xx);CHKERRQ(ierr); ierr = VecsDestroy(xx);CHKERRQ(ierr); ierr = VecsDestroy(bb);CHKERRQ(ierr); } ierr = MatDestroy(&sC);CHKERRQ(ierr); /* Check the error */ ierr = VecAXPY(y,neg_one,x);CHKERRQ(ierr); ierr = VecNorm(y,NORM_2,&norm2);CHKERRQ(ierr); if (displ>0) { ierr = PetscPrintf(PETSC_COMM_SELF," lvl: %D, error: %g\n", lvl,(double)norm2); } err[i] -= norm2; if (err[i] > tol) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER," level: %d, err: %g\n", lvl,(double)err[i]); } ierr = ISDestroy(&perm);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = MatDestroy(&sA);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&y);CHKERRQ(ierr); ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = PetscRandomDestroy(&rdm);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
PetscErrorCode random_network(PetscInt nvertex,PetscInt *pnbranch,Node **pnode,Branch **pbranch,PetscInt **pedgelist,PetscInt seed) { PetscErrorCode ierr; PetscInt i, j, nedges = 0; PetscInt *edgelist; PetscInt nbat, ncurr, fr, to; PetscReal *x, *y, value, xmax = 10.0; /* generate points in square */ PetscReal maxdist = 0.0, dist, alpha, beta, prob; PetscRandom rnd; Branch *branch; Node *node; Edge *head = NULL, *nnew= NULL, *aux= NULL; PetscFunctionBeginUser; ierr = PetscRandomCreate(PETSC_COMM_SELF,&rnd);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rnd);CHKERRQ(ierr); ierr = PetscRandomSetSeed(rnd, seed);CHKERRQ(ierr); ierr = PetscRandomSeed(rnd);CHKERRQ(ierr); /* These parameters might be modified for experimentation */ nbat = (PetscInt)(0.1*nvertex); ncurr = (PetscInt)(0.1*nvertex); alpha = 0.6; beta = 0.2; ierr = PetscMalloc2(nvertex,&x,nvertex,&y);CHKERRQ(ierr); ierr = PetscRandomSetInterval(rnd,0.0,xmax);CHKERRQ(ierr); for (i=0; i<nvertex; i++) { ierr = PetscRandomGetValueReal(rnd,&x[i]);CHKERRQ(ierr); ierr = PetscRandomGetValueReal(rnd,&y[i]);CHKERRQ(ierr); } /* find maximum distance */ for (i=0; i<nvertex; i++) { for (j=0; j<nvertex; j++) { dist = findDistance(x[i],x[j],y[i],y[j]); if (dist >= maxdist) maxdist = dist; } } ierr = PetscRandomSetInterval(rnd,0.0,1.0);CHKERRQ(ierr); for (i=0; i<nvertex; i++) { for (j=0; j<nvertex; j++) { if (j != i) { dist = findDistance(x[i],x[j],y[i],y[j]); prob = beta*PetscExpScalar(-dist/(maxdist*alpha)); ierr = PetscRandomGetValueReal(rnd,&value);CHKERRQ(ierr); if (value <= prob) { ierr = PetscMalloc1(1,&nnew);CHKERRQ(ierr); if (head == NULL) { head = nnew; head->next = NULL; head->n = nedges; head->i = i; head->j = j; } else { aux = head; head = nnew; head->n = nedges; head->next = aux; head->i = i; head->j = j; } nedges += 1; } } } } ierr = PetscMalloc1(2*nedges,&edgelist);CHKERRQ(ierr); for (aux = head; aux; aux = aux->next) { edgelist[(aux->n)*2] = aux->i; edgelist[(aux->n)*2 + 1] = aux->j; } aux = head; while (aux != NULL) { nnew = aux; aux = aux->next; ierr = PetscFree(nnew);CHKERRQ(ierr); } ierr = PetscCalloc2(nvertex,&node,nedges,&branch);CHKERRQ(ierr); for (i = 0; i < nvertex; i++) { node[i].id = i; node[i].inj = 0; node[i].gr = PETSC_FALSE; } for (i = 0; i < nedges; i++) { branch[i].id = i; branch[i].r = 1.0; branch[i].bat = 0; } /* Chose random node as ground voltage */ ierr = PetscRandomSetInterval(rnd,0.0,nvertex);CHKERRQ(ierr); ierr = PetscRandomGetValueReal(rnd,&value);CHKERRQ(ierr); node[(int)value].gr = PETSC_TRUE; /* Create random current and battery injectionsa */ for (i=0; i<ncurr; i++) { ierr = PetscRandomSetInterval(rnd,0.0,nvertex);CHKERRQ(ierr); ierr = PetscRandomGetValueReal(rnd,&value);CHKERRQ(ierr); fr = edgelist[(int)value*2]; to = edgelist[(int)value*2 + 1]; node[fr].inj += 1.0; node[to].inj -= 1.0; } for (i=0; i<nbat; i++) { ierr = PetscRandomSetInterval(rnd,0.0,nedges);CHKERRQ(ierr); ierr = PetscRandomGetValueReal(rnd,&value);CHKERRQ(ierr); branch[(int)value].bat += 1.0; } ierr = PetscFree2(x,y);CHKERRQ(ierr); ierr = PetscRandomDestroy(&rnd);CHKERRQ(ierr); /* assign pointers */ *pnbranch = nedges; *pedgelist = edgelist; *pbranch = branch; *pnode = node; PetscFunctionReturn(ierr); }
int main(int argc,char **argv) { DM da; /* distributed array */ Vec x,b,u; /* approx solution, RHS, exact solution */ Mat A; /* linear system matrix */ KSP ksp; /* linear solver context */ PetscRandom rctx; /* random number generator context */ PetscReal norm; /* norm of solution error */ PetscInt i,j,its; PetscErrorCode ierr; PetscBool flg = PETSC_FALSE; PetscLogStage stage; DMDALocalInfo info; ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; /* Create distributed array to handle parallel distribution. The problem size will default to 8 by 7, but this can be changed using -da_grid_x M -da_grid_y N */ ierr = DMDACreate2d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE,DMDA_STENCIL_STAR,-8,-7,PETSC_DECIDE,PETSC_DECIDE,1,1,NULL,NULL,&da);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Compute the matrix and right-hand-side vector that define the linear system, Ax = b. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Create parallel matrix preallocated according to the DMDA, format AIJ by default. To use symmetric storage, run with -dm_mat_type sbaij -mat_ignore_lower_triangular */ ierr = DMCreateMatrix(da,&A);CHKERRQ(ierr); /* Set matrix elements for the 2-D, five-point stencil in parallel. - Each processor needs to insert only elements that it owns locally (but any non-local elements will be sent to the appropriate processor during matrix assembly). - Rows and columns are specified by the stencil - Entries are normalized for a domain [0,1]x[0,1] */ ierr = PetscLogStageRegister("Assembly", &stage);CHKERRQ(ierr); ierr = PetscLogStagePush(stage);CHKERRQ(ierr); ierr = DMDAGetLocalInfo(da,&info);CHKERRQ(ierr); for (j=info.ys; j<info.ys+info.ym; j++) { for (i=info.xs; i<info.xs+info.xm; i++) { PetscReal hx = 1./info.mx,hy = 1./info.my; MatStencil row = {0},col[5] = {{0}}; PetscScalar v[5]; PetscInt ncols = 0; row.j = j; row.i = i; col[ncols].j = j; col[ncols].i = i; v[ncols++] = 2*(hx/hy + hy/hx); /* boundaries */ if (i>0) {col[ncols].j = j; col[ncols].i = i-1; v[ncols++] = -hy/hx;} if (i<info.mx-1) {col[ncols].j = j; col[ncols].i = i+1; v[ncols++] = -hy/hx;} if (j>0) {col[ncols].j = j-1; col[ncols].i = i; v[ncols++] = -hx/hy;} if (j<info.my-1) {col[ncols].j = j+1; col[ncols].i = i; v[ncols++] = -hx/hy;} ierr = MatSetValuesStencil(A,1,&row,ncols,col,v,INSERT_VALUES);CHKERRQ(ierr); } } /* Assemble matrix, using the 2-step process: MatAssemblyBegin(), MatAssemblyEnd() Computations can be done while messages are in transition by placing code between these two statements. */ ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = PetscLogStagePop();CHKERRQ(ierr); /* Create parallel vectors compatible with the DMDA. */ ierr = DMCreateGlobalVector(da,&u);CHKERRQ(ierr); ierr = VecDuplicate(u,&b);CHKERRQ(ierr); ierr = VecDuplicate(u,&x);CHKERRQ(ierr); /* Set exact solution; then compute right-hand-side vector. By default we use an exact solution of a vector with all elements of 1.0; Alternatively, using the runtime option -random_sol forms a solution vector with random components. */ ierr = PetscOptionsGetBool(NULL,NULL,"-random_exact_sol",&flg,NULL);CHKERRQ(ierr); if (flg) { ierr = PetscRandomCreate(PETSC_COMM_WORLD,&rctx);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rctx);CHKERRQ(ierr); ierr = VecSetRandom(u,rctx);CHKERRQ(ierr); ierr = PetscRandomDestroy(&rctx);CHKERRQ(ierr); } else { ierr = VecSet(u,1.);CHKERRQ(ierr); } ierr = MatMult(A,u,b);CHKERRQ(ierr); /* View the exact solution vector if desired */ flg = PETSC_FALSE; ierr = PetscOptionsGetBool(NULL,NULL,"-view_exact_sol",&flg,NULL);CHKERRQ(ierr); if (flg) {ierr = VecView(u,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create the linear solver and set various options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Create linear solver context */ ierr = KSPCreate(PETSC_COMM_WORLD,&ksp);CHKERRQ(ierr); /* Set operators. Here the matrix that defines the linear system also serves as the preconditioning matrix. */ ierr = KSPSetOperators(ksp,A,A);CHKERRQ(ierr); /* Set runtime options, e.g., -ksp_type <type> -pc_type <type> -ksp_monitor -ksp_rtol <rtol> These options will override those specified above as long as KSPSetFromOptions() is called _after_ any other customization routines. */ ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve the linear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Check solution and clean up - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Check the error */ ierr = VecAXPY(x,-1.,u);CHKERRQ(ierr); ierr = VecNorm(x,NORM_2,&norm);CHKERRQ(ierr); ierr = KSPGetIterationNumber(ksp,&its);CHKERRQ(ierr); /* Print convergence information. PetscPrintf() produces a single print statement from all processes that share a communicator. An alternative is PetscFPrintf(), which prints to a file. */ ierr = PetscPrintf(PETSC_COMM_WORLD,"Norm of error %g iterations %D\n",(double)norm,its);CHKERRQ(ierr); /* Free work space. All PETSc objects should be destroyed when they are no longer needed. */ ierr = KSPDestroy(&ksp);CHKERRQ(ierr); ierr = VecDestroy(&u);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); /* Always call PetscFinalize() before exiting a program. This routine - finalizes the PETSc libraries as well as MPI - provides summary and diagnostic information if certain runtime options are chosen (e.g., -log_summary). */ ierr = PetscFinalize(); return ierr; }
-ov <overlap> : >=0 amount of overlap between domains\n\n"; #include <petscmat.h> int main(int argc,char **args) { PetscErrorCode ierr; PetscInt nd = 2,ov=1,i,start,m,n,end,lsize; PetscMPIInt rank; PetscBool flg; Mat A,B; char file[PETSC_MAX_PATH_LEN]; PetscViewer fd; IS *is1,*is2; PetscRandom r; PetscScalar rand; ierr = PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr; #if defined(PETSC_USE_COMPLEX) SETERRQ(PETSC_COMM_WORLD,1,"This example does not work with complex numbers"); #else ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = PetscOptionsGetString(NULL,NULL,"-f",file,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); if (!flg) SETERRQ(PETSC_COMM_WORLD,1,"Must use -f filename to indicate a file containing a PETSc binary matrix"); ierr = PetscOptionsGetInt(NULL,NULL,"-nd",&nd,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-ov",&ov,NULL);CHKERRQ(ierr); /* Read matrix and RHS */ ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,file,FILE_MODE_READ,&fd);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatSetType(A,MATMPIAIJ);CHKERRQ(ierr); ierr = MatLoad(A,fd);CHKERRQ(ierr); ierr = MatSetFromOptions(A);CHKERRQ(ierr); ierr = PetscViewerDestroy(&fd);CHKERRQ(ierr); /* Read the matrix again as a sequential matrix */ ierr = PetscViewerBinaryOpen(PETSC_COMM_SELF,file,FILE_MODE_READ,&fd);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_SELF,&B);CHKERRQ(ierr); ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr); ierr = MatLoad(B,fd);CHKERRQ(ierr); ierr = MatSetFromOptions(B);CHKERRQ(ierr); ierr = PetscViewerDestroy(&fd);CHKERRQ(ierr); /* Create the IS corresponding to subdomains */ ierr = PetscMalloc1(nd,&is1);CHKERRQ(ierr); ierr = PetscMalloc1(nd,&is2);CHKERRQ(ierr); /* Create the random Index Sets */ ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr); ierr = PetscRandomCreate(PETSC_COMM_SELF,&r);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(r);CHKERRQ(ierr); for (i=0; i<nd; i++) { ierr = PetscRandomGetValue(r,&rand);CHKERRQ(ierr); start = (PetscInt)(rand*m); ierr = PetscRandomGetValue(r,&rand);CHKERRQ(ierr); end = (PetscInt)(rand*m); lsize = end - start; if (start > end) { start = end; lsize = -lsize;} ierr = ISCreateStride(PETSC_COMM_SELF,lsize,start,1,is1+i);CHKERRQ(ierr); ierr = ISCreateStride(PETSC_COMM_SELF,lsize,start,1,is2+i);CHKERRQ(ierr); } ierr = MatIncreaseOverlap(A,nd,is1,ov);CHKERRQ(ierr); ierr = MatIncreaseOverlap(B,nd,is2,ov);CHKERRQ(ierr); /* Now see if the serial and parallel case have the same answers */ for (i=0; i<nd; ++i) { ierr = ISEqual(is1[i],is2[i],&flg);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF,"proc:[%d], i=%D, flg =%d\n",rank,i,(int)flg);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 = PetscRandomDestroy(&r);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = MatDestroy(&B);CHKERRQ(ierr); #endif ierr = PetscFinalize(); return ierr; }
int main(int argc,char **args) { PetscMPIInt size; PetscErrorCode ierr; Vec x,y,b,s1,s2; Mat A; /* linear system matrix */ Mat sA,sB,sFactor; /* symmetric matrices */ PetscInt n,mbs=16,bs=1,nz=3,prob=1,i,j,k1,k2,col[3],lf,block, row,Ii,J,n1,inc; PetscReal norm1,norm2,rnorm,tol=PETSC_SMALL; PetscScalar neg_one = -1.0,four=4.0,value[3]; IS perm, iscol; PetscRandom rdm; PetscBool doIcc=PETSC_TRUE,equal; MatInfo minfo1,minfo2; MatFactorInfo factinfo; MatType type; ierr = PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr; ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); if (size != 1) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"This is a uniprocessor example only!"); ierr = PetscOptionsGetInt(NULL,NULL,"-bs",&bs,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-mbs",&mbs,NULL);CHKERRQ(ierr); n = mbs*bs; ierr = MatCreate(PETSC_COMM_SELF,&A);CHKERRQ(ierr); ierr = MatSetSizes(A,n,n,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); ierr = MatSetType(A,MATSEQBAIJ);CHKERRQ(ierr); ierr = MatSetFromOptions(A);CHKERRQ(ierr); ierr = MatSeqBAIJSetPreallocation(A,bs,nz,NULL);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_SELF,&sA);CHKERRQ(ierr); ierr = MatSetSizes(sA,n,n,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); ierr = MatSetType(sA,MATSEQSBAIJ);CHKERRQ(ierr); ierr = MatSetFromOptions(sA);CHKERRQ(ierr); ierr = MatGetType(sA,&type);CHKERRQ(ierr); ierr = PetscObjectTypeCompare((PetscObject)sA,MATSEQSBAIJ,&doIcc);CHKERRQ(ierr); ierr = MatSeqSBAIJSetPreallocation(sA,bs,nz,NULL);CHKERRQ(ierr); ierr = MatSetOption(sA,MAT_IGNORE_LOWER_TRIANGULAR,PETSC_TRUE);CHKERRQ(ierr); /* Test MatGetOwnershipRange() */ ierr = MatGetOwnershipRange(A,&Ii,&J);CHKERRQ(ierr); ierr = MatGetOwnershipRange(sA,&i,&j);CHKERRQ(ierr); if (i-Ii || j-J) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error: MatGetOwnershipRange() in MatSBAIJ format\n");CHKERRQ(ierr); } /* Assemble matrix */ if (bs == 1) { ierr = PetscOptionsGetInt(NULL,NULL,"-test_problem",&prob,NULL);CHKERRQ(ierr); if (prob == 1) { /* tridiagonal matrix */ value[0] = -1.0; value[1] = 2.0; value[2] = -1.0; for (i=1; i<n-1; i++) { col[0] = i-1; col[1] = i; col[2] = i+1; ierr = MatSetValues(A,1,&i,3,col,value,INSERT_VALUES);CHKERRQ(ierr); ierr = MatSetValues(sA,1,&i,3,col,value,INSERT_VALUES);CHKERRQ(ierr); } i = n - 1; col[0]=0; col[1] = n - 2; col[2] = n - 1; value[0]= 0.1; value[1]=-1; value[2]=2; ierr = MatSetValues(A,1,&i,3,col,value,INSERT_VALUES);CHKERRQ(ierr); ierr = MatSetValues(sA,1,&i,3,col,value,INSERT_VALUES);CHKERRQ(ierr); i = 0; col[0] = n-1; col[1] = 1; col[2] = 0; value[0] = 0.1; value[1] = -1.0; value[2] = 2; ierr = MatSetValues(A,1,&i,3,col,value,INSERT_VALUES);CHKERRQ(ierr); ierr = MatSetValues(sA,1,&i,3,col,value,INSERT_VALUES);CHKERRQ(ierr); } else if (prob ==2) { /* matrix for the five point stencil */ n1 = (PetscInt) (PetscSqrtReal((PetscReal)n) + 0.001); if (n1*n1 - n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"sqrt(n) must be a positive interger!"); for (i=0; i<n1; i++) { for (j=0; j<n1; j++) { Ii = j + n1*i; if (i>0) { J = Ii - n1; ierr = MatSetValues(A,1,&Ii,1,&J,&neg_one,INSERT_VALUES);CHKERRQ(ierr); ierr = MatSetValues(sA,1,&Ii,1,&J,&neg_one,INSERT_VALUES);CHKERRQ(ierr); } if (i<n1-1) { J = Ii + n1; ierr = MatSetValues(A,1,&Ii,1,&J,&neg_one,INSERT_VALUES);CHKERRQ(ierr); ierr = MatSetValues(sA,1,&Ii,1,&J,&neg_one,INSERT_VALUES);CHKERRQ(ierr); } if (j>0) { J = Ii - 1; ierr = MatSetValues(A,1,&Ii,1,&J,&neg_one,INSERT_VALUES);CHKERRQ(ierr); ierr = MatSetValues(sA,1,&Ii,1,&J,&neg_one,INSERT_VALUES);CHKERRQ(ierr); } if (j<n1-1) { J = Ii + 1; ierr = MatSetValues(A,1,&Ii,1,&J,&neg_one,INSERT_VALUES);CHKERRQ(ierr); ierr = MatSetValues(sA,1,&Ii,1,&J,&neg_one,INSERT_VALUES);CHKERRQ(ierr); } ierr = MatSetValues(A,1,&Ii,1,&Ii,&four,INSERT_VALUES);CHKERRQ(ierr); ierr = MatSetValues(sA,1,&Ii,1,&Ii,&four,INSERT_VALUES);CHKERRQ(ierr); } } } } else { /* bs > 1 */ for (block=0; block<n/bs; 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(A,1,&i,3,col,value,INSERT_VALUES);CHKERRQ(ierr); ierr = MatSetValues(sA,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(A,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr); ierr = MatSetValues(sA,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(A,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr); ierr = MatSetValues(sA,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr); } /* off-diagonal blocks */ value[0]=-1.0; for (i=0; i<(n/bs-1)*bs; i++) { col[0]=i+bs; ierr = MatSetValues(A,1,&i,1,col,value,INSERT_VALUES);CHKERRQ(ierr); ierr = MatSetValues(sA,1,&i,1,col,value,INSERT_VALUES);CHKERRQ(ierr); col[0]=i; row=i+bs; ierr = MatSetValues(A,1,&row,1,col,value,INSERT_VALUES);CHKERRQ(ierr); ierr = MatSetValues(sA,1,&row,1,col,value,INSERT_VALUES);CHKERRQ(ierr); } } ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyBegin(sA,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(sA,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* Test MatGetInfo() of A and sA */ ierr = MatGetInfo(A,MAT_LOCAL,&minfo1);CHKERRQ(ierr); ierr = MatGetInfo(sA,MAT_LOCAL,&minfo2);CHKERRQ(ierr); /* printf("A matrix nonzeros (BAIJ format) = %d, allocated nonzeros= %d\n", (int)minfo1.nz_used,(int)minfo1.nz_allocated); printf("sA matrix nonzeros(SBAIJ format) = %d, allocated nonzeros= %d\n", (int)minfo2.nz_used,(int)minfo2.nz_allocated); */ i = (int) (minfo1.nz_used - minfo2.nz_used); j = (int) (minfo1.nz_allocated - minfo2.nz_allocated); k1 = (int) (minfo1.nz_allocated - minfo1.nz_used); k2 = (int) (minfo2.nz_allocated - minfo2.nz_used); if (i < 0 || j < 0 || k1 < 0 || k2 < 0) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error (compare A and sA): MatGetInfo()\n");CHKERRQ(ierr); } /* Test MatDuplicate() */ ierr = MatNorm(A,NORM_FROBENIUS,&norm1);CHKERRQ(ierr); ierr = MatDuplicate(sA,MAT_COPY_VALUES,&sB);CHKERRQ(ierr); ierr = MatEqual(sA,sB,&equal);CHKERRQ(ierr); if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMETYPE,"Error in MatDuplicate()"); /* Test MatNorm() */ ierr = MatNorm(A,NORM_FROBENIUS,&norm1);CHKERRQ(ierr); ierr = MatNorm(sB,NORM_FROBENIUS,&norm2);CHKERRQ(ierr); rnorm = PetscAbsReal(norm1-norm2)/norm2; if (rnorm > tol) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error: MatNorm_FROBENIUS, NormA=%16.14e NormsB=%16.14e\n",norm1,norm2);CHKERRQ(ierr); } ierr = MatNorm(A,NORM_INFINITY,&norm1);CHKERRQ(ierr); ierr = MatNorm(sB,NORM_INFINITY,&norm2);CHKERRQ(ierr); rnorm = PetscAbsReal(norm1-norm2)/norm2; if (rnorm > tol) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error: MatNorm_INFINITY(), NormA=%16.14e NormsB=%16.14e\n",norm1,norm2);CHKERRQ(ierr); } ierr = MatNorm(A,NORM_1,&norm1);CHKERRQ(ierr); ierr = MatNorm(sB,NORM_1,&norm2);CHKERRQ(ierr); rnorm = PetscAbsReal(norm1-norm2)/norm2; if (rnorm > tol) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error: MatNorm_INFINITY(), NormA=%16.14e NormsB=%16.14e\n",norm1,norm2);CHKERRQ(ierr); } /* Test MatGetInfo(), MatGetSize(), MatGetBlockSize() */ ierr = MatGetInfo(A,MAT_LOCAL,&minfo1);CHKERRQ(ierr); ierr = MatGetInfo(sB,MAT_LOCAL,&minfo2);CHKERRQ(ierr); /* printf("matrix nonzeros (BAIJ format) = %d, allocated nonzeros= %d\n", (int)minfo1.nz_used,(int)minfo1.nz_allocated); printf("matrix nonzeros(SBAIJ format) = %d, allocated nonzeros= %d\n", (int)minfo2.nz_used,(int)minfo2.nz_allocated); */ i = (int) (minfo1.nz_used - minfo2.nz_used); j = (int) (minfo1.nz_allocated - minfo2.nz_allocated); k1 = (int) (minfo1.nz_allocated - minfo1.nz_used); k2 = (int) (minfo2.nz_allocated - minfo2.nz_used); if (i < 0 || j < 0 || k1 < 0 || k2 < 0) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error(compare A and sB): MatGetInfo()\n");CHKERRQ(ierr); } ierr = MatGetSize(A,&Ii,&J);CHKERRQ(ierr); ierr = MatGetSize(sB,&i,&j);CHKERRQ(ierr); if (i-Ii || j-J) { PetscPrintf(PETSC_COMM_SELF,"Error: MatGetSize()\n");CHKERRQ(ierr); } ierr = MatGetBlockSize(A, &Ii);CHKERRQ(ierr); ierr = MatGetBlockSize(sB, &i);CHKERRQ(ierr); if (i-Ii) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error: MatGetBlockSize()\n");CHKERRQ(ierr); } ierr = PetscRandomCreate(PETSC_COMM_SELF,&rdm);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rdm);CHKERRQ(ierr); ierr = VecCreateSeq(PETSC_COMM_SELF,n,&x);CHKERRQ(ierr); ierr = VecDuplicate(x,&s1);CHKERRQ(ierr); ierr = VecDuplicate(x,&s2);CHKERRQ(ierr); ierr = VecDuplicate(x,&y);CHKERRQ(ierr); ierr = VecDuplicate(x,&b);CHKERRQ(ierr); ierr = VecSetRandom(x,rdm);CHKERRQ(ierr); /* Test MatDiagonalScale(), MatGetDiagonal(), MatScale() */ #if !defined(PETSC_USE_COMPLEX) /* Scaling matrix with complex numbers results non-spd matrix, causing crash of MatForwardSolve() and MatBackwardSolve() */ ierr = MatDiagonalScale(A,x,x);CHKERRQ(ierr); ierr = MatDiagonalScale(sB,x,x);CHKERRQ(ierr); ierr = MatMultEqual(A,sB,10,&equal);CHKERRQ(ierr); if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMETYPE,"Error in MatDiagonalScale"); ierr = MatGetDiagonal(A,s1);CHKERRQ(ierr); ierr = MatGetDiagonal(sB,s2);CHKERRQ(ierr); ierr = VecAXPY(s2,neg_one,s1);CHKERRQ(ierr); ierr = VecNorm(s2,NORM_1,&norm1);CHKERRQ(ierr); if (norm1>tol) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error:MatGetDiagonal(), ||s1-s2||=%g\n",(double)norm1);CHKERRQ(ierr); } { PetscScalar alpha=0.1; ierr = MatScale(A,alpha);CHKERRQ(ierr); ierr = MatScale(sB,alpha);CHKERRQ(ierr); } #endif /* Test MatGetRowMaxAbs() */ ierr = MatGetRowMaxAbs(A,s1,NULL);CHKERRQ(ierr); ierr = MatGetRowMaxAbs(sB,s2,NULL);CHKERRQ(ierr); ierr = VecNorm(s1,NORM_1,&norm1);CHKERRQ(ierr); ierr = VecNorm(s2,NORM_1,&norm2);CHKERRQ(ierr); norm1 -= norm2; if (norm1<-tol || norm1>tol) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error:MatGetRowMaxAbs() \n");CHKERRQ(ierr); } /* Test MatMult() */ for (i=0; i<40; i++) { ierr = VecSetRandom(x,rdm);CHKERRQ(ierr); ierr = MatMult(A,x,s1);CHKERRQ(ierr); ierr = MatMult(sB,x,s2);CHKERRQ(ierr); ierr = VecNorm(s1,NORM_1,&norm1);CHKERRQ(ierr); ierr = VecNorm(s2,NORM_1,&norm2);CHKERRQ(ierr); norm1 -= norm2; if (norm1<-tol || norm1>tol) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error: MatMult(), norm1-norm2: %g\n",(double)norm1);CHKERRQ(ierr); } } /* MatMultAdd() */ for (i=0; i<40; i++) { ierr = VecSetRandom(x,rdm);CHKERRQ(ierr); ierr = VecSetRandom(y,rdm);CHKERRQ(ierr); ierr = MatMultAdd(A,x,y,s1);CHKERRQ(ierr); ierr = MatMultAdd(sB,x,y,s2);CHKERRQ(ierr); ierr = VecNorm(s1,NORM_1,&norm1);CHKERRQ(ierr); ierr = VecNorm(s2,NORM_1,&norm2);CHKERRQ(ierr); norm1 -= norm2; if (norm1<-tol || norm1>tol) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error:MatMultAdd(), norm1-norm2: %g\n",(double)norm1);CHKERRQ(ierr); } } /* Test MatCholeskyFactor(), MatICCFactor() with natural ordering */ ierr = MatGetOrdering(A,MATORDERINGNATURAL,&perm,&iscol);CHKERRQ(ierr); ierr = ISDestroy(&iscol);CHKERRQ(ierr); norm1 = tol; inc = bs; /* initialize factinfo */ ierr = PetscMemzero(&factinfo,sizeof(MatFactorInfo));CHKERRQ(ierr); for (lf=-1; lf<10; lf += inc) { if (lf==-1) { /* Cholesky factor of sB (duplicate sA) */ factinfo.fill = 5.0; ierr = MatGetFactor(sB,MATSOLVERPETSC,MAT_FACTOR_CHOLESKY,&sFactor);CHKERRQ(ierr); ierr = MatCholeskyFactorSymbolic(sFactor,sB,perm,&factinfo);CHKERRQ(ierr); } else if (!doIcc) break; else { /* incomplete Cholesky factor */ factinfo.fill = 5.0; factinfo.levels = lf; ierr = MatGetFactor(sB,MATSOLVERPETSC,MAT_FACTOR_ICC,&sFactor);CHKERRQ(ierr); ierr = MatICCFactorSymbolic(sFactor,sB,perm,&factinfo);CHKERRQ(ierr); } ierr = MatCholeskyFactorNumeric(sFactor,sB,&factinfo);CHKERRQ(ierr); /* MatView(sFactor, PETSC_VIEWER_DRAW_WORLD); */ /* test MatGetDiagonal on numeric factor */ /* if (lf == -1) { ierr = MatGetDiagonal(sFactor,s1);CHKERRQ(ierr); printf(" in ex74.c, diag: \n"); ierr = VecView(s1,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); } */ ierr = MatMult(sB,x,b);CHKERRQ(ierr); /* test MatForwardSolve() and MatBackwardSolve() */ if (lf == -1) { ierr = MatForwardSolve(sFactor,b,s1);CHKERRQ(ierr); ierr = MatBackwardSolve(sFactor,s1,s2);CHKERRQ(ierr); ierr = VecAXPY(s2,neg_one,x);CHKERRQ(ierr); ierr = VecNorm(s2,NORM_2,&norm2);CHKERRQ(ierr); if (10*norm1 < norm2) { ierr = PetscPrintf(PETSC_COMM_SELF,"MatForwardSolve and BackwardSolve: Norm of error=%g, bs=%D\n",(double)norm2,bs);CHKERRQ(ierr); } } /* test MatSolve() */ ierr = MatSolve(sFactor,b,y);CHKERRQ(ierr); ierr = MatDestroy(&sFactor);CHKERRQ(ierr); /* Check the error */ ierr = VecAXPY(y,neg_one,x);CHKERRQ(ierr); ierr = VecNorm(y,NORM_2,&norm2);CHKERRQ(ierr); if (10*norm1 < norm2 && lf-inc != -1) { ierr = PetscPrintf(PETSC_COMM_SELF,"lf=%D, %D, Norm of error=%g, %g\n",lf-inc,lf,(double)norm1,(double)norm2);CHKERRQ(ierr); } norm1 = norm2; if (norm2 < tol && lf != -1) break; } ierr = ISDestroy(&perm);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = MatDestroy(&sB);CHKERRQ(ierr); ierr = MatDestroy(&sA);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&y);CHKERRQ(ierr); ierr = VecDestroy(&s1);CHKERRQ(ierr); ierr = VecDestroy(&s2);CHKERRQ(ierr); ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = PetscRandomDestroy(&rdm);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
int test2(void) { PetscLogDouble t1,t2; double value; int i,ierr,z[20000],zi[20000],intval,tmp; PetscScalar x[20000],y[20000]; PetscRandom r; ierr = PetscRandomCreate(PETSC_COMM_SELF,&r);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(r);CHKERRQ(ierr); /* Take care of paging effects */ ierr = PetscTime(&t1);CHKERRQ(ierr); for (i=0; i<20000; i++) { x[i] = i; y[i] = i; z[i] = i; zi[i] = i; } /* Form the random set of integers */ for (i=0; i<20000; i++) { ierr = PetscRandomGetValue(r,&value);CHKERRQ(ierr); intval = (int)(value*20000.0); tmp = z[i]; z[i] = z[intval]; z[intval] = tmp; } for (i=0; i<20000; i++) { ierr = PetscRandomGetValue(r,&value);CHKERRQ(ierr); intval = (int)(value*20000.0); tmp = zi[i]; zi[i] = zi[intval]; zi[intval] = tmp; } /* fprintf(stdout,"Done setup\n"); */ /* ierr = BlastCache();CHKERRQ(ierr); */ ierr = PetscTime(&t1);CHKERRQ(ierr); for (i=0; i<2000; i++) x[i] = y[i]; ierr = PetscTime(&t2);CHKERRQ(ierr); fprintf(stdout,"%-27s : %e sec\n","x[i] = y[i]",(t2-t1)/2000.0); /* ierr = BlastCache();CHKERRQ(ierr); */ ierr = PetscTime(&t1);CHKERRQ(ierr); for (i=0; i<2000; i++) y[i] = x[z[i]]; ierr = PetscTime(&t2);CHKERRQ(ierr); fprintf(stdout,"%-27s : %e sec\n","x[i] = y[idx[i]]",(t2-t1)/2000.0); /* ierr = BlastCache();CHKERRQ(ierr); */ ierr = PetscTime(&t1);CHKERRQ(ierr); for (i=0; i<2000; i++) x[z[i]] = y[i]; ierr = PetscTime(&t2);CHKERRQ(ierr); fprintf(stdout,"%-27s : %e sec\n","x[z[i]] = y[i]",(t2-t1)/2000.0); /* ierr = BlastCache();CHKERRQ(ierr); */ ierr = PetscTime(&t1);CHKERRQ(ierr); for (i=0; i<2000; i++) y[z[i]] = x[zi[i]]; ierr = PetscTime(&t2);CHKERRQ(ierr); fprintf(stdout,"%-27s : %e sec\n","x[z[i]] = y[zi[i]]",(t2-t1)/2000.0); ierr = PetscRandomDestroy(&r);CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc,char **args) { PetscErrorCode ierr; PetscMPIInt rank,size; PetscInt N0=50,N1=20,N=N0*N1,DIM; PetscRandom rdm; PetscScalar a; PetscReal enorm; Vec x,y,z; PetscBool view=PETSC_FALSE,use_interface=PETSC_TRUE; ierr = PetscInitialize(&argc,&args,(char*)0,help);CHKERRQ(ierr); #if !defined(PETSC_USE_COMPLEX) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP, "This example requires complex numbers"); #endif ierr = PetscOptionsBegin(PETSC_COMM_WORLD, NULL, "FFTW Options", "ex143");CHKERRQ(ierr); ierr = PetscOptionsBool("-vec_view draw", "View the vectors", "ex143", view, &view, NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-use_FFTW_interface", "Use PETSc-FFTW interface", "ex143",use_interface, &use_interface, NULL);CHKERRQ(ierr); ierr = PetscOptionsEnd();CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,"-use_FFTW_interface",&use_interface,NULL);CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD, &size);CHKERRQ(ierr); ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank);CHKERRQ(ierr); ierr = PetscRandomCreate(PETSC_COMM_WORLD, &rdm);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rdm);CHKERRQ(ierr); if (!use_interface) { /* Use mpi FFTW without PETSc-FFTW interface, 2D case only */ /*---------------------------------------------------------*/ fftw_plan fplan,bplan; fftw_complex *data_in,*data_out,*data_out2; ptrdiff_t alloc_local,local_n0,local_0_start; DIM = 2; if (!rank) { ierr = PetscPrintf(PETSC_COMM_SELF,"Use FFTW without PETSc-FFTW interface, DIM %D\n",DIM);CHKERRQ(ierr); } fftw_mpi_init(); N = N0*N1; alloc_local = fftw_mpi_local_size_2d(N0,N1,PETSC_COMM_WORLD,&local_n0,&local_0_start); data_in = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*alloc_local); data_out = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*alloc_local); data_out2 = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*alloc_local); ierr = VecCreateMPIWithArray(PETSC_COMM_WORLD,1,(PetscInt)local_n0*N1,(PetscInt)N,(const PetscScalar*)data_in,&x);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) x, "Real Space vector");CHKERRQ(ierr); ierr = VecCreateMPIWithArray(PETSC_COMM_WORLD,1,(PetscInt)local_n0*N1,(PetscInt)N,(const PetscScalar*)data_out,&y);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) y, "Frequency space vector");CHKERRQ(ierr); ierr = VecCreateMPIWithArray(PETSC_COMM_WORLD,1,(PetscInt)local_n0*N1,(PetscInt)N,(const PetscScalar*)data_out2,&z);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) z, "Reconstructed vector");CHKERRQ(ierr); fplan = fftw_mpi_plan_dft_2d(N0,N1,data_in,data_out,PETSC_COMM_WORLD,FFTW_FORWARD,FFTW_ESTIMATE); bplan = fftw_mpi_plan_dft_2d(N0,N1,data_out,data_out2,PETSC_COMM_WORLD,FFTW_BACKWARD,FFTW_ESTIMATE); ierr = VecSetRandom(x, rdm);CHKERRQ(ierr); if (view) {ierr = VecView(x,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);} fftw_execute(fplan); if (view) {ierr = VecView(y,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);} fftw_execute(bplan); /* Compare x and z. FFTW computes an unnormalized DFT, thus z = N*x */ a = 1.0/(PetscReal)N; ierr = VecScale(z,a);CHKERRQ(ierr); if (view) {ierr = VecView(z, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);} ierr = VecAXPY(z,-1.0,x);CHKERRQ(ierr); ierr = VecNorm(z,NORM_1,&enorm);CHKERRQ(ierr); if (enorm > 1.e-11 && !rank) { ierr = PetscPrintf(PETSC_COMM_SELF," Error norm of |x - z| %g\n",(double)enorm);CHKERRQ(ierr); } /* Free spaces */ fftw_destroy_plan(fplan); fftw_destroy_plan(bplan); fftw_free(data_in); ierr = VecDestroy(&x);CHKERRQ(ierr); fftw_free(data_out); ierr = VecDestroy(&y);CHKERRQ(ierr); fftw_free(data_out2);ierr = VecDestroy(&z);CHKERRQ(ierr); } else { /* Use PETSc-FFTW interface */ /*-------------------------------------------*/ PetscInt i,*dim,k; Mat A; N=1; for (i=1; i<5; i++) { DIM = i; ierr = PetscMalloc1(i,&dim);CHKERRQ(ierr); for (k=0; k<i; k++) { dim[k]=30; } N *= dim[i-1]; /* Create FFTW object */ if (!rank) printf("Use PETSc-FFTW interface...%d-DIM: %d\n",(int)DIM,(int)N); ierr = MatCreateFFT(PETSC_COMM_WORLD,DIM,dim,MATFFTW,&A);CHKERRQ(ierr); /* Create vectors that are compatible with parallel layout of A - must call MatGetVecs()! */ ierr = MatGetVecsFFTW(A,&x,&y,&z);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) x, "Real space vector");CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) y, "Frequency space vector");CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) z, "Reconstructed vector");CHKERRQ(ierr); /* Set values of space vector x */ ierr = VecSetRandom(x,rdm);CHKERRQ(ierr); if (view) {ierr = VecView(x,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);} /* Apply FFTW_FORWARD and FFTW_BACKWARD */ ierr = MatMult(A,x,y);CHKERRQ(ierr); if (view) {ierr = VecView(y,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);} ierr = MatMultTranspose(A,y,z);CHKERRQ(ierr); /* Compare x and z. FFTW computes an unnormalized DFT, thus z = N*x */ a = 1.0/(PetscReal)N; ierr = VecScale(z,a);CHKERRQ(ierr); if (view) {ierr = VecView(z,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);} ierr = VecAXPY(z,-1.0,x);CHKERRQ(ierr); ierr = VecNorm(z,NORM_1,&enorm);CHKERRQ(ierr); if (enorm > 1.e-9 && !rank) { ierr = PetscPrintf(PETSC_COMM_SELF," Error norm of |x - z| %e\n",enorm);CHKERRQ(ierr); } ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&y);CHKERRQ(ierr); ierr = VecDestroy(&z);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = PetscFree(dim);CHKERRQ(ierr); } } ierr = PetscRandomDestroy(&rdm);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
int main(int argc,char **args) { Vec x,b,u; Mat A; /* linear system matrix */ KSP ksp; /* linear solver context */ PetscRandom rctx; /* random number generator context */ PetscReal norm; /* norm of solution error */ PetscInt i,j,k,l,n = 27,its,bs = 2,Ii,J; PetscErrorCode ierr; PetscScalar v; ierr = PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr; ierr = PetscOptionsGetInt(NULL,NULL,"-bs",&bs,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-n",&n,NULL);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatSetSizes(A,n*bs,n*bs,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); ierr = MatSetBlockSize(A,bs);CHKERRQ(ierr); ierr = MatSetType(A,MATSEQBAIJ);CHKERRQ(ierr); ierr = MatSetFromOptions(A);CHKERRQ(ierr); ierr = MatSetUp(A);CHKERRQ(ierr); /* Don't bother to preallocate matrix */ ierr = PetscRandomCreate(PETSC_COMM_SELF,&rctx);CHKERRQ(ierr); for (i=0; i<n; i++) { for (j=0; j<n; j++) { ierr = PetscRandomGetValue(rctx,&v);CHKERRQ(ierr); if (PetscRealPart(v) < .25 || i == j) { for (k=0; k<bs; k++) { for (l=0; l<bs; l++) { ierr = PetscRandomGetValue(rctx,&v);CHKERRQ(ierr); Ii = i*bs + k; J = j*bs + l; if (Ii == J) v += 10.; ierr = MatSetValue(A,Ii,J,v,INSERT_VALUES);CHKERRQ(ierr); } } } } } ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = VecCreate(PETSC_COMM_WORLD,&u);CHKERRQ(ierr); ierr = VecSetSizes(u,PETSC_DECIDE,n*bs);CHKERRQ(ierr); ierr = VecSetFromOptions(u);CHKERRQ(ierr); ierr = VecDuplicate(u,&b);CHKERRQ(ierr); ierr = VecDuplicate(b,&x);CHKERRQ(ierr); ierr = VecSet(u,1.0);CHKERRQ(ierr); ierr = MatMult(A,u,b);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create the linear solver and set various options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Create linear solver context */ ierr = KSPCreate(PETSC_COMM_WORLD,&ksp);CHKERRQ(ierr); /* Set operators. Here the matrix that defines the linear system also serves as the preconditioning matrix. */ ierr = KSPSetOperators(ksp,A,A);CHKERRQ(ierr); ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve the linear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Check solution and clean up - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Check the error */ ierr = VecAXPY(x,-1.0,u);CHKERRQ(ierr); ierr = VecNorm(x,NORM_2,&norm);CHKERRQ(ierr); ierr = KSPGetIterationNumber(ksp,&its);CHKERRQ(ierr); /* Print convergence information. PetscPrintf() produces a single print statement from all processes that share a communicator. An alternative is PetscFPrintf(), which prints to a file. */ if (norm > .1) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Norm of residual %g iterations %D bs %D\n",(double)norm,its,bs);CHKERRQ(ierr); } /* Free work space. All PETSc objects should be destroyed when they are no longer needed. */ ierr = KSPDestroy(&ksp);CHKERRQ(ierr); ierr = VecDestroy(&u);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = PetscRandomDestroy(&rctx);CHKERRQ(ierr); /* Always call PetscFinalize() before exiting a program. This routine - finalizes the PETSc libraries as well as MPI - provides summary and diagnostic information if certain runtime options are chosen (e.g., -log_summary). */ ierr = PetscFinalize(); return ierr; }