1*c4762a1bSJed Brown 2*c4762a1bSJed Brown static char help[] = "Tests MatSolve() and MatMatSolve() with MUMPS or MKL_PARDISO sequential solvers in Schur complement mode.\n\ 3*c4762a1bSJed Brown Example: mpiexec -n 1 ./ex192 -f <matrix binary file> -nrhs 4 -symmetric_solve -hermitian_solve -schur_ratio 0.3\n\n"; 4*c4762a1bSJed Brown 5*c4762a1bSJed Brown #include <petscmat.h> 6*c4762a1bSJed Brown 7*c4762a1bSJed Brown int main(int argc,char **args) 8*c4762a1bSJed Brown { 9*c4762a1bSJed Brown Mat A,RHS,C,F,X,S; 10*c4762a1bSJed Brown Vec u,x,b; 11*c4762a1bSJed Brown Vec xschur,bschur,uschur; 12*c4762a1bSJed Brown IS is_schur; 13*c4762a1bSJed Brown PetscErrorCode ierr; 14*c4762a1bSJed Brown PetscMPIInt size; 15*c4762a1bSJed Brown PetscInt isolver=0,size_schur,m,n,nfact,nsolve,nrhs; 16*c4762a1bSJed Brown PetscReal norm,tol=PETSC_SQRT_MACHINE_EPSILON; 17*c4762a1bSJed Brown PetscRandom rand; 18*c4762a1bSJed Brown PetscBool data_provided,herm,symm,use_lu,cuda = PETSC_FALSE; 19*c4762a1bSJed Brown PetscReal sratio = 5.1/12.; 20*c4762a1bSJed Brown PetscViewer fd; /* viewer */ 21*c4762a1bSJed Brown char solver[256]; 22*c4762a1bSJed Brown char file[PETSC_MAX_PATH_LEN]; /* input file name */ 23*c4762a1bSJed Brown 24*c4762a1bSJed Brown ierr = PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr; 25*c4762a1bSJed Brown ierr = MPI_Comm_size(PETSC_COMM_WORLD, &size);CHKERRQ(ierr); 26*c4762a1bSJed Brown if (size > 1) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_WRONG_MPI_SIZE,"This is a uniprocessor test"); 27*c4762a1bSJed Brown /* Determine which type of solver we want to test for */ 28*c4762a1bSJed Brown herm = PETSC_FALSE; 29*c4762a1bSJed Brown symm = PETSC_FALSE; 30*c4762a1bSJed Brown ierr = PetscOptionsGetBool(NULL,NULL,"-symmetric_solve",&symm,NULL);CHKERRQ(ierr); 31*c4762a1bSJed Brown ierr = PetscOptionsGetBool(NULL,NULL,"-hermitian_solve",&herm,NULL);CHKERRQ(ierr); 32*c4762a1bSJed Brown if (herm) symm = PETSC_TRUE; 33*c4762a1bSJed Brown ierr = PetscOptionsGetBool(NULL,NULL,"-cuda_solve",&cuda,NULL);CHKERRQ(ierr); 34*c4762a1bSJed Brown ierr = PetscOptionsGetReal(NULL,NULL,"-tol",&tol,NULL);CHKERRQ(ierr); 35*c4762a1bSJed Brown 36*c4762a1bSJed Brown /* Determine file from which we read the matrix A */ 37*c4762a1bSJed Brown ierr = PetscOptionsGetString(NULL,NULL,"-f",file,PETSC_MAX_PATH_LEN,&data_provided);CHKERRQ(ierr); 38*c4762a1bSJed Brown if (!data_provided) { /* get matrices from PETSc distribution */ 39*c4762a1bSJed Brown ierr = PetscStrncpy(file,"${PETSC_DIR}/share/petsc/datafiles/matrices/",sizeof(file));CHKERRQ(ierr); 40*c4762a1bSJed Brown if (symm) { 41*c4762a1bSJed Brown #if defined (PETSC_USE_COMPLEX) 42*c4762a1bSJed Brown ierr = PetscStrlcat(file,"hpd-complex-",sizeof(file));CHKERRQ(ierr); 43*c4762a1bSJed Brown #else 44*c4762a1bSJed Brown ierr = PetscStrlcat(file,"spd-real-",sizeof(file));CHKERRQ(ierr); 45*c4762a1bSJed Brown #endif 46*c4762a1bSJed Brown } else { 47*c4762a1bSJed Brown #if defined (PETSC_USE_COMPLEX) 48*c4762a1bSJed Brown ierr = PetscStrlcat(file,"nh-complex-",sizeof(file));CHKERRQ(ierr); 49*c4762a1bSJed Brown #else 50*c4762a1bSJed Brown ierr = PetscStrlcat(file,"ns-real-",sizeof(file));CHKERRQ(ierr); 51*c4762a1bSJed Brown #endif 52*c4762a1bSJed Brown } 53*c4762a1bSJed Brown #if defined(PETSC_USE_64BIT_INDICES) 54*c4762a1bSJed Brown ierr = PetscStrlcat(file,"int64-",sizeof(file));CHKERRQ(ierr); 55*c4762a1bSJed Brown #else 56*c4762a1bSJed Brown ierr = PetscStrlcat(file,"int32-",sizeof(file));CHKERRQ(ierr); 57*c4762a1bSJed Brown #endif 58*c4762a1bSJed Brown #if defined (PETSC_USE_REAL_SINGLE) 59*c4762a1bSJed Brown ierr = PetscStrlcat(file,"float32",sizeof(file));CHKERRQ(ierr); 60*c4762a1bSJed Brown #else 61*c4762a1bSJed Brown ierr = PetscStrlcat(file,"float64",sizeof(file));CHKERRQ(ierr); 62*c4762a1bSJed Brown #endif 63*c4762a1bSJed Brown } 64*c4762a1bSJed Brown /* Load matrix A */ 65*c4762a1bSJed Brown ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,file,FILE_MODE_READ,&fd);CHKERRQ(ierr); 66*c4762a1bSJed Brown ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); 67*c4762a1bSJed Brown ierr = MatLoad(A,fd);CHKERRQ(ierr); 68*c4762a1bSJed Brown ierr = PetscViewerDestroy(&fd);CHKERRQ(ierr); 69*c4762a1bSJed Brown ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr); 70*c4762a1bSJed Brown if (m != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ, "This example is not intended for rectangular matrices (%d, %d)", m, n); 71*c4762a1bSJed Brown 72*c4762a1bSJed Brown /* Create dense matrix C and X; C holds true solution with identical colums */ 73*c4762a1bSJed Brown nrhs = 2; 74*c4762a1bSJed Brown ierr = PetscOptionsGetInt(NULL,NULL,"-nrhs",&nrhs,NULL);CHKERRQ(ierr); 75*c4762a1bSJed Brown ierr = MatCreate(PETSC_COMM_WORLD,&C);CHKERRQ(ierr); 76*c4762a1bSJed Brown ierr = MatSetSizes(C,m,PETSC_DECIDE,PETSC_DECIDE,nrhs);CHKERRQ(ierr); 77*c4762a1bSJed Brown ierr = MatSetType(C,MATDENSE);CHKERRQ(ierr); 78*c4762a1bSJed Brown ierr = MatSetFromOptions(C);CHKERRQ(ierr); 79*c4762a1bSJed Brown ierr = MatSetUp(C);CHKERRQ(ierr); 80*c4762a1bSJed Brown 81*c4762a1bSJed Brown ierr = PetscRandomCreate(PETSC_COMM_WORLD,&rand);CHKERRQ(ierr); 82*c4762a1bSJed Brown ierr = PetscRandomSetFromOptions(rand);CHKERRQ(ierr); 83*c4762a1bSJed Brown ierr = MatSetRandom(C,rand);CHKERRQ(ierr); 84*c4762a1bSJed Brown ierr = MatDuplicate(C,MAT_DO_NOT_COPY_VALUES,&X);CHKERRQ(ierr); 85*c4762a1bSJed Brown 86*c4762a1bSJed Brown /* Create vectors */ 87*c4762a1bSJed Brown ierr = VecCreate(PETSC_COMM_WORLD,&x);CHKERRQ(ierr); 88*c4762a1bSJed Brown ierr = VecSetSizes(x,n,PETSC_DECIDE);CHKERRQ(ierr); 89*c4762a1bSJed Brown ierr = VecSetFromOptions(x);CHKERRQ(ierr); 90*c4762a1bSJed Brown ierr = VecDuplicate(x,&b);CHKERRQ(ierr); 91*c4762a1bSJed Brown ierr = VecDuplicate(x,&u);CHKERRQ(ierr); /* save the true solution */ 92*c4762a1bSJed Brown 93*c4762a1bSJed Brown ierr = PetscOptionsGetInt(NULL,NULL,"-solver",&isolver,NULL);CHKERRQ(ierr); 94*c4762a1bSJed Brown switch (isolver) { 95*c4762a1bSJed Brown #if defined(PETSC_HAVE_MUMPS) 96*c4762a1bSJed Brown case 0: 97*c4762a1bSJed Brown ierr = PetscStrcpy(solver,MATSOLVERMUMPS);CHKERRQ(ierr); 98*c4762a1bSJed Brown break; 99*c4762a1bSJed Brown #endif 100*c4762a1bSJed Brown #if defined(PETSC_HAVE_MKL_PARDISO) 101*c4762a1bSJed Brown case 1: 102*c4762a1bSJed Brown ierr = PetscStrcpy(solver,MATSOLVERMKL_PARDISO);CHKERRQ(ierr); 103*c4762a1bSJed Brown break; 104*c4762a1bSJed Brown #endif 105*c4762a1bSJed Brown default: 106*c4762a1bSJed Brown ierr = PetscStrcpy(solver,MATSOLVERPETSC);CHKERRQ(ierr); 107*c4762a1bSJed Brown break; 108*c4762a1bSJed Brown } 109*c4762a1bSJed Brown 110*c4762a1bSJed Brown #if defined (PETSC_USE_COMPLEX) 111*c4762a1bSJed Brown if (isolver == 0 && symm && !data_provided) { /* MUMPS (5.0.0) does not have support for hermitian matrices, so make them symmetric */ 112*c4762a1bSJed Brown PetscScalar im = PetscSqrtScalar((PetscScalar)-1.); 113*c4762a1bSJed Brown PetscScalar val = -1.0; 114*c4762a1bSJed Brown val = val + im; 115*c4762a1bSJed Brown ierr = MatSetValue(A,1,0,val,INSERT_VALUES);CHKERRQ(ierr); 116*c4762a1bSJed Brown ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 117*c4762a1bSJed Brown ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 118*c4762a1bSJed Brown } 119*c4762a1bSJed Brown #endif 120*c4762a1bSJed Brown 121*c4762a1bSJed Brown ierr = PetscOptionsGetReal(NULL,NULL,"-schur_ratio",&sratio,NULL);CHKERRQ(ierr); 122*c4762a1bSJed Brown if (sratio < 0. || sratio > 1.) { 123*c4762a1bSJed Brown SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ, "Invalid ratio for schur degrees of freedom %f", sratio); 124*c4762a1bSJed Brown } 125*c4762a1bSJed Brown size_schur = (PetscInt)(sratio*m); 126*c4762a1bSJed Brown 127*c4762a1bSJed Brown 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); 128*c4762a1bSJed Brown 129*c4762a1bSJed Brown /* Test LU/Cholesky Factorization */ 130*c4762a1bSJed Brown use_lu = PETSC_FALSE; 131*c4762a1bSJed Brown if (!symm) use_lu = PETSC_TRUE; 132*c4762a1bSJed Brown #if defined (PETSC_USE_COMPLEX) 133*c4762a1bSJed Brown if (isolver == 1) use_lu = PETSC_TRUE; 134*c4762a1bSJed Brown #endif 135*c4762a1bSJed Brown if (cuda && symm && !herm) use_lu = PETSC_TRUE; 136*c4762a1bSJed Brown 137*c4762a1bSJed Brown if (herm && !use_lu) { /* test also conversion routines inside the solver packages */ 138*c4762a1bSJed Brown ierr = MatSetOption(A,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 139*c4762a1bSJed Brown ierr = MatConvert(A,MATSEQSBAIJ,MAT_INPLACE_MATRIX,&A);CHKERRQ(ierr); 140*c4762a1bSJed Brown } 141*c4762a1bSJed Brown 142*c4762a1bSJed Brown if (use_lu) { 143*c4762a1bSJed Brown ierr = MatGetFactor(A,solver,MAT_FACTOR_LU,&F);CHKERRQ(ierr); 144*c4762a1bSJed Brown } else { 145*c4762a1bSJed Brown if (herm) { 146*c4762a1bSJed Brown ierr = MatSetOption(A,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 147*c4762a1bSJed Brown ierr = MatSetOption(A,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 148*c4762a1bSJed Brown } else { 149*c4762a1bSJed Brown ierr = MatSetOption(A,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 150*c4762a1bSJed Brown ierr = MatSetOption(A,MAT_SPD,PETSC_FALSE);CHKERRQ(ierr); 151*c4762a1bSJed Brown } 152*c4762a1bSJed Brown ierr = MatGetFactor(A,solver,MAT_FACTOR_CHOLESKY,&F);CHKERRQ(ierr); 153*c4762a1bSJed Brown } 154*c4762a1bSJed Brown ierr = ISCreateStride(PETSC_COMM_SELF,size_schur,m-size_schur,1,&is_schur);CHKERRQ(ierr); 155*c4762a1bSJed Brown ierr = MatFactorSetSchurIS(F,is_schur);CHKERRQ(ierr); 156*c4762a1bSJed Brown 157*c4762a1bSJed Brown ierr = ISDestroy(&is_schur);CHKERRQ(ierr); 158*c4762a1bSJed Brown if (use_lu) { 159*c4762a1bSJed Brown ierr = MatLUFactorSymbolic(F,A,NULL,NULL,NULL);CHKERRQ(ierr); 160*c4762a1bSJed Brown } else { 161*c4762a1bSJed Brown ierr = MatCholeskyFactorSymbolic(F,A,NULL,NULL);CHKERRQ(ierr); 162*c4762a1bSJed Brown } 163*c4762a1bSJed Brown 164*c4762a1bSJed Brown for (nfact = 0; nfact < 3; nfact++) { 165*c4762a1bSJed Brown Mat AD; 166*c4762a1bSJed Brown 167*c4762a1bSJed Brown if (!nfact) { 168*c4762a1bSJed Brown ierr = VecSetRandom(x,rand);CHKERRQ(ierr); 169*c4762a1bSJed Brown if (symm && herm) { 170*c4762a1bSJed Brown ierr = VecAbs(x);CHKERRQ(ierr); 171*c4762a1bSJed Brown } 172*c4762a1bSJed Brown ierr = MatDiagonalSet(A,x,ADD_VALUES);CHKERRQ(ierr); 173*c4762a1bSJed Brown } 174*c4762a1bSJed Brown if (use_lu) { 175*c4762a1bSJed Brown ierr = MatLUFactorNumeric(F,A,NULL);CHKERRQ(ierr); 176*c4762a1bSJed Brown } else { 177*c4762a1bSJed Brown ierr = MatCholeskyFactorNumeric(F,A,NULL);CHKERRQ(ierr); 178*c4762a1bSJed Brown } 179*c4762a1bSJed Brown if (cuda) { 180*c4762a1bSJed Brown ierr = MatFactorGetSchurComplement(F,&S,NULL);CHKERRQ(ierr); 181*c4762a1bSJed Brown ierr = MatSetType(S,MATSEQDENSECUDA);CHKERRQ(ierr); 182*c4762a1bSJed Brown ierr = MatCreateVecs(S,&xschur,&bschur);CHKERRQ(ierr); 183*c4762a1bSJed Brown ierr = MatFactorRestoreSchurComplement(F,&S,MAT_FACTOR_SCHUR_UNFACTORED);CHKERRQ(ierr); 184*c4762a1bSJed Brown } 185*c4762a1bSJed Brown ierr = MatFactorCreateSchurComplement(F,&S,NULL);CHKERRQ(ierr); 186*c4762a1bSJed Brown if (!cuda) { 187*c4762a1bSJed Brown ierr = MatCreateVecs(S,&xschur,&bschur);CHKERRQ(ierr); 188*c4762a1bSJed Brown } 189*c4762a1bSJed Brown ierr = VecDuplicate(xschur,&uschur);CHKERRQ(ierr); 190*c4762a1bSJed Brown if (nfact == 1 && (!cuda || (herm && symm))) { 191*c4762a1bSJed Brown ierr = MatFactorInvertSchurComplement(F);CHKERRQ(ierr); 192*c4762a1bSJed Brown } 193*c4762a1bSJed Brown for (nsolve = 0; nsolve < 2; nsolve++) { 194*c4762a1bSJed Brown ierr = VecSetRandom(x,rand);CHKERRQ(ierr); 195*c4762a1bSJed Brown ierr = VecCopy(x,u);CHKERRQ(ierr); 196*c4762a1bSJed Brown 197*c4762a1bSJed Brown if (nsolve) { 198*c4762a1bSJed Brown ierr = MatMult(A,x,b);CHKERRQ(ierr); 199*c4762a1bSJed Brown ierr = MatSolve(F,b,x);CHKERRQ(ierr); 200*c4762a1bSJed Brown } else { 201*c4762a1bSJed Brown ierr = MatMultTranspose(A,x,b);CHKERRQ(ierr); 202*c4762a1bSJed Brown ierr = MatSolveTranspose(F,b,x);CHKERRQ(ierr); 203*c4762a1bSJed Brown } 204*c4762a1bSJed Brown /* Check the error */ 205*c4762a1bSJed Brown ierr = VecAXPY(u,-1.0,x);CHKERRQ(ierr); /* u <- (-1.0)x + u */ 206*c4762a1bSJed Brown ierr = VecNorm(u,NORM_2,&norm);CHKERRQ(ierr); 207*c4762a1bSJed Brown if (norm > tol) { 208*c4762a1bSJed Brown PetscReal resi; 209*c4762a1bSJed Brown if (nsolve) { 210*c4762a1bSJed Brown ierr = MatMult(A,x,u);CHKERRQ(ierr); /* u = A*x */ 211*c4762a1bSJed Brown } else { 212*c4762a1bSJed Brown ierr = MatMultTranspose(A,x,u);CHKERRQ(ierr); /* u = A*x */ 213*c4762a1bSJed Brown } 214*c4762a1bSJed Brown ierr = VecAXPY(u,-1.0,b);CHKERRQ(ierr); /* u <- (-1.0)b + u */ 215*c4762a1bSJed Brown ierr = VecNorm(u,NORM_2,&resi);CHKERRQ(ierr); 216*c4762a1bSJed Brown if (nsolve) { 217*c4762a1bSJed Brown ierr = PetscPrintf(PETSC_COMM_SELF,"(f %D, s %D) MatSolve error: Norm of error %g, residual %f\n",nfact,nsolve,norm,resi);CHKERRQ(ierr); 218*c4762a1bSJed Brown } else { 219*c4762a1bSJed Brown ierr = PetscPrintf(PETSC_COMM_SELF,"(f %D, s %D) MatSolveTranspose error: Norm of error %g, residual %f\n",nfact,nsolve,norm,resi);CHKERRQ(ierr); 220*c4762a1bSJed Brown } 221*c4762a1bSJed Brown } 222*c4762a1bSJed Brown ierr = VecSetRandom(xschur,rand);CHKERRQ(ierr); 223*c4762a1bSJed Brown ierr = VecCopy(xschur,uschur);CHKERRQ(ierr); 224*c4762a1bSJed Brown if (nsolve) { 225*c4762a1bSJed Brown ierr = MatMult(S,xschur,bschur);CHKERRQ(ierr); 226*c4762a1bSJed Brown ierr = MatFactorSolveSchurComplement(F,bschur,xschur);CHKERRQ(ierr); 227*c4762a1bSJed Brown } else { 228*c4762a1bSJed Brown ierr = MatMultTranspose(S,xschur,bschur);CHKERRQ(ierr); 229*c4762a1bSJed Brown ierr = MatFactorSolveSchurComplementTranspose(F,bschur,xschur);CHKERRQ(ierr); 230*c4762a1bSJed Brown } 231*c4762a1bSJed Brown /* Check the error */ 232*c4762a1bSJed Brown ierr = VecAXPY(uschur,-1.0,xschur);CHKERRQ(ierr); /* u <- (-1.0)x + u */ 233*c4762a1bSJed Brown ierr = VecNorm(uschur,NORM_2,&norm);CHKERRQ(ierr); 234*c4762a1bSJed Brown if (norm > tol) { 235*c4762a1bSJed Brown PetscReal resi; 236*c4762a1bSJed Brown if (nsolve) { 237*c4762a1bSJed Brown ierr = MatMult(S,xschur,uschur);CHKERRQ(ierr); /* u = A*x */ 238*c4762a1bSJed Brown } else { 239*c4762a1bSJed Brown ierr = MatMultTranspose(S,xschur,uschur);CHKERRQ(ierr); /* u = A*x */ 240*c4762a1bSJed Brown } 241*c4762a1bSJed Brown ierr = VecAXPY(uschur,-1.0,bschur);CHKERRQ(ierr); /* u <- (-1.0)b + u */ 242*c4762a1bSJed Brown ierr = VecNorm(uschur,NORM_2,&resi);CHKERRQ(ierr); 243*c4762a1bSJed Brown if (nsolve) { 244*c4762a1bSJed Brown ierr = PetscPrintf(PETSC_COMM_SELF,"(f %D, s %D) MatFactorSolveSchurComplement error: Norm of error %g, residual %f\n",nfact,nsolve,norm,resi);CHKERRQ(ierr); 245*c4762a1bSJed Brown } else { 246*c4762a1bSJed Brown ierr = PetscPrintf(PETSC_COMM_SELF,"(f %D, s %D) MatFactorSolveSchurComplementTranspose error: Norm of error %g, residual %f\n",nfact,nsolve,norm,resi);CHKERRQ(ierr); 247*c4762a1bSJed Brown } 248*c4762a1bSJed Brown } 249*c4762a1bSJed Brown } 250*c4762a1bSJed Brown ierr = MatConvert(A,MATSEQAIJ,MAT_INITIAL_MATRIX,&AD);CHKERRQ(ierr); 251*c4762a1bSJed Brown if (!nfact) { 252*c4762a1bSJed Brown ierr = MatMatMult(AD,C,MAT_INITIAL_MATRIX,2.0,&RHS);CHKERRQ(ierr); 253*c4762a1bSJed Brown } else { 254*c4762a1bSJed Brown ierr = MatMatMult(AD,C,MAT_REUSE_MATRIX,2.0,&RHS);CHKERRQ(ierr); 255*c4762a1bSJed Brown } 256*c4762a1bSJed Brown ierr = MatDestroy(&AD);CHKERRQ(ierr); 257*c4762a1bSJed Brown for (nsolve = 0; nsolve < 2; nsolve++) { 258*c4762a1bSJed Brown ierr = MatMatSolve(F,RHS,X);CHKERRQ(ierr); 259*c4762a1bSJed Brown 260*c4762a1bSJed Brown /* Check the error */ 261*c4762a1bSJed Brown ierr = MatAXPY(X,-1.0,C,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 262*c4762a1bSJed Brown ierr = MatNorm(X,NORM_FROBENIUS,&norm);CHKERRQ(ierr); 263*c4762a1bSJed Brown if (norm > tol) { 264*c4762a1bSJed Brown ierr = PetscPrintf(PETSC_COMM_SELF,"(f %D, s %D) MatMatSolve: Norm of error %g\n",nfact,nsolve,norm);CHKERRQ(ierr); 265*c4762a1bSJed Brown } 266*c4762a1bSJed Brown } 267*c4762a1bSJed Brown if (isolver == 0) { 268*c4762a1bSJed Brown Mat spRHS,spRHST,RHST; 269*c4762a1bSJed Brown 270*c4762a1bSJed Brown ierr = MatTranspose(RHS,MAT_INITIAL_MATRIX,&RHST);CHKERRQ(ierr); 271*c4762a1bSJed Brown ierr = MatConvert(RHST,MATSEQAIJ,MAT_INITIAL_MATRIX,&spRHST);CHKERRQ(ierr); 272*c4762a1bSJed Brown ierr = MatCreateTranspose(spRHST,&spRHS);CHKERRQ(ierr); 273*c4762a1bSJed Brown for (nsolve = 0; nsolve < 2; nsolve++) { 274*c4762a1bSJed Brown ierr = MatMatSolve(F,spRHS,X);CHKERRQ(ierr); 275*c4762a1bSJed Brown 276*c4762a1bSJed Brown /* Check the error */ 277*c4762a1bSJed Brown ierr = MatAXPY(X,-1.0,C,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 278*c4762a1bSJed Brown ierr = MatNorm(X,NORM_FROBENIUS,&norm);CHKERRQ(ierr); 279*c4762a1bSJed Brown if (norm > tol) { 280*c4762a1bSJed Brown ierr = PetscPrintf(PETSC_COMM_SELF,"(f %D, s %D) sparse MatMatSolve: Norm of error %g\n",nfact,nsolve,norm);CHKERRQ(ierr); 281*c4762a1bSJed Brown } 282*c4762a1bSJed Brown } 283*c4762a1bSJed Brown ierr = MatDestroy(&spRHST);CHKERRQ(ierr); 284*c4762a1bSJed Brown ierr = MatDestroy(&spRHS);CHKERRQ(ierr); 285*c4762a1bSJed Brown ierr = MatDestroy(&RHST);CHKERRQ(ierr); 286*c4762a1bSJed Brown } 287*c4762a1bSJed Brown ierr = MatDestroy(&S);CHKERRQ(ierr); 288*c4762a1bSJed Brown ierr = VecDestroy(&xschur);CHKERRQ(ierr); 289*c4762a1bSJed Brown ierr = VecDestroy(&bschur);CHKERRQ(ierr); 290*c4762a1bSJed Brown ierr = VecDestroy(&uschur);CHKERRQ(ierr); 291*c4762a1bSJed Brown } 292*c4762a1bSJed Brown /* Free data structures */ 293*c4762a1bSJed Brown ierr = MatDestroy(&A);CHKERRQ(ierr); 294*c4762a1bSJed Brown ierr = MatDestroy(&C);CHKERRQ(ierr); 295*c4762a1bSJed Brown ierr = MatDestroy(&F);CHKERRQ(ierr); 296*c4762a1bSJed Brown ierr = MatDestroy(&X);CHKERRQ(ierr); 297*c4762a1bSJed Brown ierr = MatDestroy(&RHS);CHKERRQ(ierr); 298*c4762a1bSJed Brown ierr = PetscRandomDestroy(&rand);CHKERRQ(ierr); 299*c4762a1bSJed Brown ierr = VecDestroy(&x);CHKERRQ(ierr); 300*c4762a1bSJed Brown ierr = VecDestroy(&b);CHKERRQ(ierr); 301*c4762a1bSJed Brown ierr = VecDestroy(&u);CHKERRQ(ierr); 302*c4762a1bSJed Brown ierr = PetscFinalize(); 303*c4762a1bSJed Brown return ierr; 304*c4762a1bSJed Brown } 305*c4762a1bSJed Brown 306*c4762a1bSJed Brown 307*c4762a1bSJed Brown /*TEST 308*c4762a1bSJed Brown 309*c4762a1bSJed Brown testset: 310*c4762a1bSJed Brown requires: mkl_pardiso double !complex !define(PETSC_USE_64BIT_INDICES) 311*c4762a1bSJed Brown args: -solver 1 312*c4762a1bSJed Brown 313*c4762a1bSJed Brown test: 314*c4762a1bSJed Brown suffix: mkl_pardiso 315*c4762a1bSJed Brown test: 316*c4762a1bSJed Brown requires: cuda 317*c4762a1bSJed Brown suffix: mkl_pardiso_cuda 318*c4762a1bSJed Brown args: -cuda_solve 319*c4762a1bSJed Brown output_file: output/ex192_mkl_pardiso.out 320*c4762a1bSJed Brown test: 321*c4762a1bSJed Brown suffix: mkl_pardiso_1 322*c4762a1bSJed Brown args: -symmetric_solve 323*c4762a1bSJed Brown output_file: output/ex192_mkl_pardiso_1.out 324*c4762a1bSJed Brown test: 325*c4762a1bSJed Brown requires: cuda 326*c4762a1bSJed Brown suffix: mkl_pardiso_cuda_1 327*c4762a1bSJed Brown args: -symmetric_solve -cuda_solve 328*c4762a1bSJed Brown output_file: output/ex192_mkl_pardiso_1.out 329*c4762a1bSJed Brown test: 330*c4762a1bSJed Brown suffix: mkl_pardiso_3 331*c4762a1bSJed Brown args: -symmetric_solve -hermitian_solve 332*c4762a1bSJed Brown output_file: output/ex192_mkl_pardiso_3.out 333*c4762a1bSJed Brown test: 334*c4762a1bSJed Brown requires: cuda 335*c4762a1bSJed Brown suffix: mkl_pardiso_cuda_3 336*c4762a1bSJed Brown args: -symmetric_solve -hermitian_solve -cuda_solve 337*c4762a1bSJed Brown output_file: output/ex192_mkl_pardiso_3.out 338*c4762a1bSJed Brown 339*c4762a1bSJed Brown testset: 340*c4762a1bSJed Brown requires: mumps double !complex 341*c4762a1bSJed Brown args: -solver 0 342*c4762a1bSJed Brown 343*c4762a1bSJed Brown test: 344*c4762a1bSJed Brown suffix: mumps 345*c4762a1bSJed Brown test: 346*c4762a1bSJed Brown requires: cuda 347*c4762a1bSJed Brown suffix: mumps_cuda 348*c4762a1bSJed Brown args: -cuda_solve 349*c4762a1bSJed Brown output_file: output/ex192_mumps.out 350*c4762a1bSJed Brown test: 351*c4762a1bSJed Brown suffix: mumps_2 352*c4762a1bSJed Brown args: -symmetric_solve 353*c4762a1bSJed Brown output_file: output/ex192_mumps_2.out 354*c4762a1bSJed Brown test: 355*c4762a1bSJed Brown requires: cuda 356*c4762a1bSJed Brown suffix: mumps_cuda_2 357*c4762a1bSJed Brown args: -symmetric_solve -cuda_solve 358*c4762a1bSJed Brown output_file: output/ex192_mumps_2.out 359*c4762a1bSJed Brown test: 360*c4762a1bSJed Brown suffix: mumps_3 361*c4762a1bSJed Brown args: -symmetric_solve -hermitian_solve 362*c4762a1bSJed Brown output_file: output/ex192_mumps_3.out 363*c4762a1bSJed Brown test: 364*c4762a1bSJed Brown requires: cuda 365*c4762a1bSJed Brown suffix: mumps_cuda_3 366*c4762a1bSJed Brown args: -symmetric_solve -hermitian_solve -cuda_solve 367*c4762a1bSJed Brown output_file: output/ex192_mumps_3.out 368*c4762a1bSJed Brown 369*c4762a1bSJed Brown TEST*/ 370