static char help[] = "Tests LU, Cholesky factorization and MatMatSolve() for an Elemental dense matrix.\n\n"; #include int main(int argc,char **argv) { Mat A,F,B,X,C,Aher,G; Vec b,x,c,d,e; PetscInt m = 5,n,p,i,j,nrows,ncols; PetscScalar *v,*barray,rval; PetscReal norm,tol=1.e-11; PetscMPIInt size,rank; PetscRandom rand; const PetscInt *rows,*cols; IS isrows,iscols; PetscBool mats_view=PETSC_FALSE; MatFactorInfo finfo; PetscCall(PetscInitialize(&argc,&argv,(char*) 0,help)); PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD,&rank)); PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD,&size)); PetscCall(PetscRandomCreate(PETSC_COMM_WORLD,&rand)); PetscCall(PetscRandomSetFromOptions(rand)); /* Get local dimensions of matrices */ PetscCall(PetscOptionsGetInt(NULL,NULL,"-m",&m,NULL)); n = m; PetscCall(PetscOptionsGetInt(NULL,NULL,"-n",&n,NULL)); p = m/2; PetscCall(PetscOptionsGetInt(NULL,NULL,"-p",&p,NULL)); PetscCall(PetscOptionsHasName(NULL,NULL,"-mats_view",&mats_view)); /* Create matrix A */ PetscCall(PetscPrintf(PETSC_COMM_WORLD," Create Elemental matrix A\n")); PetscCall(MatCreate(PETSC_COMM_WORLD,&A)); PetscCall(MatSetSizes(A,m,n,PETSC_DECIDE,PETSC_DECIDE)); PetscCall(MatSetType(A,MATELEMENTAL)); PetscCall(MatSetFromOptions(A)); PetscCall(MatSetUp(A)); /* Set local matrix entries */ PetscCall(MatGetOwnershipIS(A,&isrows,&iscols)); PetscCall(ISGetLocalSize(isrows,&nrows)); PetscCall(ISGetIndices(isrows,&rows)); PetscCall(ISGetLocalSize(iscols,&ncols)); PetscCall(ISGetIndices(iscols,&cols)); PetscCall(PetscMalloc1(nrows*ncols,&v)); for (i=0; i tol) { PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Warning: |Aher*x - b| for Cholesky %g\n",(double)norm)); } /* Check norm(Aher*X - B) */ PetscCall(MatMatMult(Aher,X,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&C)); PetscCall(MatAXPY(C,-1.0,B,SAME_NONZERO_PATTERN)); PetscCall(MatNorm(C,NORM_1,&norm)); if (norm > tol) { PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Warning: |Aher*X - B| for Cholesky %g\n",(double)norm)); } /* LU factorization */ /*------------------*/ PetscCall(PetscPrintf(PETSC_COMM_WORLD," Test LU Solver \n")); /* In-place LU */ /* Create matrix factor F, then copy A to F */ PetscCall(MatCreate(PETSC_COMM_WORLD,&F)); PetscCall(MatSetSizes(F,m,n,PETSC_DECIDE,PETSC_DECIDE)); PetscCall(MatSetType(F,MATELEMENTAL)); PetscCall(MatSetFromOptions(F)); PetscCall(MatSetUp(F)); PetscCall(MatAssemblyBegin(F,MAT_FINAL_ASSEMBLY)); PetscCall(MatAssemblyEnd(F,MAT_FINAL_ASSEMBLY)); PetscCall(MatCopy(A,F,SAME_NONZERO_PATTERN)); /* Create vector d to test MatSolveAdd() */ PetscCall(VecDuplicate(x,&d)); PetscCall(VecCopy(x,d)); /* 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; PetscCall(MatLUFactor(F,0,0,&finfo)); /* Solve LUX = PB or LUX = B */ PetscCall(MatSolveAdd(F,b,d,x)); PetscCall(MatMatSolve(F,B,X)); PetscCall(MatDestroy(&F)); /* Check norm(A*X - B) */ PetscCall(VecCreate(PETSC_COMM_WORLD,&e)); PetscCall(VecSetSizes(e,m,PETSC_DECIDE)); PetscCall(VecSetFromOptions(e)); PetscCall(MatMult(A,x,c)); PetscCall(MatMult(A,d,e)); PetscCall(VecAXPY(c,-1.0,e)); PetscCall(VecAXPY(c,-1.0,b)); PetscCall(VecNorm(c,NORM_1,&norm)); if (norm > tol) { PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Warning: |A*x - b| for LU %g\n",(double)norm)); } /* Reuse product C; replace Aher with A */ PetscCall(MatProductReplaceMats(A,NULL,NULL,C)); PetscCall(MatMatMult(A,X,MAT_REUSE_MATRIX,PETSC_DEFAULT,&C)); PetscCall(MatAXPY(C,-1.0,B,SAME_NONZERO_PATTERN)); PetscCall(MatNorm(C,NORM_1,&norm)); if (norm > tol) { PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Warning: |A*X - B| for LU %g\n",(double)norm)); } /* Out-place LU */ PetscCall(MatGetFactor(A,MATSOLVERELEMENTAL,MAT_FACTOR_LU,&F)); PetscCall(MatLUFactorSymbolic(F,A,0,0,&finfo)); PetscCall(MatLUFactorNumeric(F,A,&finfo)); if (mats_view) { PetscCall(MatView(F,PETSC_VIEWER_STDOUT_WORLD)); } PetscCall(MatSolve(F,b,x)); PetscCall(MatMatSolve(F,B,X)); PetscCall(MatDestroy(&F)); /* Free space */ PetscCall(MatDestroy(&A)); PetscCall(MatDestroy(&Aher)); PetscCall(MatDestroy(&B)); PetscCall(MatDestroy(&C)); PetscCall(MatDestroy(&X)); PetscCall(VecDestroy(&b)); PetscCall(VecDestroy(&c)); PetscCall(VecDestroy(&d)); PetscCall(VecDestroy(&e)); PetscCall(VecDestroy(&x)); PetscCall(PetscRandomDestroy(&rand)); PetscCall(PetscFinalize()); return 0; } /*TEST build: requires: elemental test: nsize: 2 output_file: output/ex145.out test: suffix: 2 nsize: 6 output_file: output/ex145.out TEST*/