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,NULL,"-m",&m,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-n",&n,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,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 **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 **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 **args) { Mat A,RHS,C,F,X; Vec u,x,b; PetscErrorCode ierr; PetscMPIInt rank,nproc; PetscInt i,m,n,nfact,nsolve,nrhs,ipack=0; PetscScalar *array,rval; PetscReal norm,tol=1.e-12; IS perm,iperm; MatFactorInfo info; PetscRandom rand; PetscBool flg,testMatSolve=PETSC_TRUE,testMatMatSolve=PETSC_TRUE; PetscViewer fd; /* viewer */ char file[PETSC_MAX_PATH_LEN]; /* input file name */ PetscInitialize(&argc,&args,(char*)0,help); ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank);CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD, &nproc);CHKERRQ(ierr); /* Determine file from which we read the matrix A */ ierr = PetscOptionsGetString(NULL,"-f",file,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); if (!flg) SETERRQ(PETSC_COMM_WORLD,1,"Must indicate binary file with the -f option"); /* 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 = MatGetLocalSize(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,"-nrhs",&nrhs,NULL);CHKERRQ(ierr); if (!rank) printf("ex125: nrhs %d\n",nrhs); 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 */ /* Test LU Factorization */ ierr = MatGetOrdering(A,MATORDERINGND,&perm,&iperm);CHKERRQ(ierr); /*ierr = ISView(perm,PETSC_VIEWER_STDOUT_WORLD);*/ /*ierr = ISView(perm,PETSC_VIEWER_STDOUT_SELF);*/ ierr = PetscOptionsGetInt(NULL,"-mat_solver_package",&ipack,NULL);CHKERRQ(ierr); switch (ipack) { case 0: #if defined(PETSC_HAVE_SUPERLU) if (!rank) printf(" SUPERLU LU:\n"); ierr = MatGetFactor(A,MATSOLVERSUPERLU,MAT_FACTOR_LU,&F);CHKERRQ(ierr); break; #endif case 1: #if defined(PETSC_HAVE_SUPERLU_DIST) if (!rank) printf(" SUPERLU_DIST LU:\n"); ierr = MatGetFactor(A,MATSOLVERSUPERLU_DIST,MAT_FACTOR_LU,&F);CHKERRQ(ierr); break; #endif case 2: #if defined(PETSC_HAVE_MUMPS) if (!rank) printf(" MUMPS LU:\n"); ierr = MatGetFactor(A,MATSOLVERMUMPS,MAT_FACTOR_LU,&F);CHKERRQ(ierr); { /* test mumps options */ PetscInt icntl_7 = 5; ierr = MatMumpsSetIcntl(F,7,icntl_7);CHKERRQ(ierr); } break; #endif default: if (!rank) printf(" PETSC LU:\n"); ierr = MatGetFactor(A,MATSOLVERPETSC,MAT_FACTOR_LU,&F);CHKERRQ(ierr); } info.fill = 5.0; ierr = MatLUFactorSymbolic(F,A,perm,iperm,&info);CHKERRQ(ierr); for (nfact = 0; nfact < 2; nfact++) { if (!rank) printf(" %d-the LU numfactorization \n",nfact); ierr = MatLUFactorNumeric(F,A,&info);CHKERRQ(ierr); /* Test MatMatSolve() */ /* if ((ipack == 0 || ipack == 2) && testMatMatSolve) { printf(" MatMatSolve() is not implemented for this package. Skip the testing.\n"); testMatMatSolve = PETSC_FALSE; } */ if (testMatMatSolve) { if (!nfact) { ierr = MatMatMult(A,C,MAT_INITIAL_MATRIX,2.0,&RHS);CHKERRQ(ierr); } else { ierr = MatMatMult(A,C,MAT_REUSE_MATRIX,2.0,&RHS);CHKERRQ(ierr); } for (nsolve = 0; nsolve < 2; nsolve++) { if (!rank) printf(" %d-the MatMatSolve \n",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) { if (!rank) { ierr = PetscPrintf(PETSC_COMM_SELF,"1st MatMatSolve: Norm of error %g, nsolve %d\n",norm,nsolve);CHKERRQ(ierr); } } } } /* Test MatSolve() */ if (testMatSolve) { for (nsolve = 0; nsolve < 2; nsolve++) { ierr = VecGetArray(x,&array);CHKERRQ(ierr); for (i=0; i<m; i++) { ierr = PetscRandomGetValue(rand,&rval);CHKERRQ(ierr); array[i] = rval; } ierr = VecRestoreArray(x,&array);CHKERRQ(ierr); ierr = VecCopy(x,u);CHKERRQ(ierr); ierr = MatMult(A,x,b);CHKERRQ(ierr); if (!rank) printf(" %d-the MatSolve \n",nsolve); ierr = MatSolve(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) { ierr = MatMult(A,x,u);CHKERRQ(ierr); /* u = A*x */ PetscReal resi; ierr = VecAXPY(u,-1.0,b);CHKERRQ(ierr); /* u <- (-1.0)b + u */ ierr = VecNorm(u,NORM_2,&resi);CHKERRQ(ierr); if (!rank) { ierr = PetscPrintf(PETSC_COMM_SELF,"MatSolve: Norm of error %g, resi %g, LU numfact %d\n",norm,resi,nfact);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); if (testMatMatSolve) { ierr = MatDestroy(&RHS);CHKERRQ(ierr); } ierr = PetscRandomDestroy(&rand);CHKERRQ(ierr); ierr = ISDestroy(&perm);CHKERRQ(ierr); ierr = ISDestroy(&iperm);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = VecDestroy(&u);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }