1*e51e0e81SBarry Smith 2*e51e0e81SBarry Smith /* 3*e51e0e81SBarry Smith This is where the abstract matrix operations are defined 4*e51e0e81SBarry Smith */ 5*e51e0e81SBarry Smith 6*e51e0e81SBarry Smith #include "petsc.h" 7*e51e0e81SBarry Smith #include "matimpl.h" /*I "mat.h" I*/ 8*e51e0e81SBarry Smith #include "vec/vecimpl.h" 9*e51e0e81SBarry Smith 10*e51e0e81SBarry Smith /*@ 11*e51e0e81SBarry Smith MatGetReordering - 12*e51e0e81SBarry Smith 13*e51e0e81SBarry Smith Input Parameters: 14*e51e0e81SBarry Smith . mat - the matrix 15*e51e0e81SBarry Smith . type - type of reordering; one of:ORDER_ND,ORDER_1WD,ORDER_RCM,ORDER_QMD 16*e51e0e81SBarry Smith 17*e51e0e81SBarry Smith OutPut Parameters: 18*e51e0e81SBarry Smith . rperm - row permutation indices 19*e51e0e81SBarry Smith . cperm - column permutation indices 20*e51e0e81SBarry Smith 21*e51e0e81SBarry Smith If the column permutations and row permutations are the same, then 22*e51e0e81SBarry Smith returns 0 in cperm. 23*e51e0e81SBarry Smith @*/ 24*e51e0e81SBarry Smith int MatGetReordering(Mat mat,int type,IS *rperm,IS *cperm) 25*e51e0e81SBarry Smith { 26*e51e0e81SBarry Smith VALIDHEADER(mat,MAT_COOKIE); 27*e51e0e81SBarry Smith if (!mat->ops->order) SETERR(1,"Cannot reorder this matrix"); 28*e51e0e81SBarry Smith return (*mat->ops->order)(mat,type,rperm,cperm); 29*e51e0e81SBarry Smith } 30*e51e0e81SBarry Smith 31*e51e0e81SBarry Smith /*@ 32*e51e0e81SBarry Smith MatGetRow - gets a row of a matrix. This routine is provided 33*e51e0e81SBarry Smith for people who need to have direct address to the 34*e51e0e81SBarry Smith structure of a matrix, we hope that we provide 35*e51e0e81SBarry Smith enough high level matrix routines so that few users 36*e51e0e81SBarry Smith need it. You MUST call MatRestoreRow() for each row 37*e51e0e81SBarry Smith that you get to insure that your application does 38*e51e0e81SBarry Smith not bleed memory. 39*e51e0e81SBarry Smith 40*e51e0e81SBarry Smith Input Parameters: 41*e51e0e81SBarry Smith . mat - the matrix 42*e51e0e81SBarry Smith . row - the row to get 43*e51e0e81SBarry Smith 44*e51e0e81SBarry Smith OutPut Parameters: 45*e51e0e81SBarry Smith . ncols, cols - the number of nonzeros and their columns 46*e51e0e81SBarry Smith . vals - if nonzero the column values 47*e51e0e81SBarry Smith @*/ 48*e51e0e81SBarry Smith int MatGetRow(Mat mat,int row,int *ncols,int **cols,Scalar **vals) 49*e51e0e81SBarry Smith { 50*e51e0e81SBarry Smith VALIDHEADER(mat,MAT_COOKIE); 51*e51e0e81SBarry Smith return (*mat->ops->getrow)(mat,row,ncols,cols,vals); 52*e51e0e81SBarry Smith } 53*e51e0e81SBarry Smith 54*e51e0e81SBarry Smith /*@ 55*e51e0e81SBarry Smith MatRestoreRow - frees any temporary space malloced by 56*e51e0e81SBarry Smith MatGetRow(). 57*e51e0e81SBarry Smith 58*e51e0e81SBarry Smith Input Parameters: 59*e51e0e81SBarry Smith . mat - the matrix 60*e51e0e81SBarry Smith . row - the row to get 61*e51e0e81SBarry Smith . ncols, cols - the number of nonzeros and their columns 62*e51e0e81SBarry Smith . vals - if nonzero the column values 63*e51e0e81SBarry Smith @*/ 64*e51e0e81SBarry Smith int MatRestoreRow(Mat mat,int row,int *ncols,int **cols,Scalar **vals) 65*e51e0e81SBarry Smith { 66*e51e0e81SBarry Smith VALIDHEADER(mat,MAT_COOKIE); 67*e51e0e81SBarry Smith if (!mat->ops->restorerow) return 0; 68*e51e0e81SBarry Smith return (*mat->ops->restorerow)(mat,row,ncols,cols,vals); 69*e51e0e81SBarry Smith } 70*e51e0e81SBarry Smith /*@ 71*e51e0e81SBarry Smith MatView - visualize a matrix object. 72*e51e0e81SBarry Smith 73*e51e0e81SBarry Smith Input Parameters: 74*e51e0e81SBarry Smith . mat - the matrix 75*e51e0e81SBarry Smith . ptr - a visualization context 76*e51e0e81SBarry Smith @*/ 77*e51e0e81SBarry Smith int MatView(Mat mat,Viewer ptr) 78*e51e0e81SBarry Smith { 79*e51e0e81SBarry Smith VALIDHEADER(mat,MAT_COOKIE); 80*e51e0e81SBarry Smith return (*mat->view)((PetscObject)mat,ptr); 81*e51e0e81SBarry Smith } 82*e51e0e81SBarry Smith /*@ 83*e51e0e81SBarry Smith MatDestroy - frees space taken by matrix 84*e51e0e81SBarry Smith 85*e51e0e81SBarry Smith Input Parameters: 86*e51e0e81SBarry Smith . mat the matrix 87*e51e0e81SBarry Smith @*/ 88*e51e0e81SBarry Smith int MatDestroy(Mat mat) 89*e51e0e81SBarry Smith { 90*e51e0e81SBarry Smith VALIDHEADER(mat,MAT_COOKIE); 91*e51e0e81SBarry Smith return (*mat->destroy)((PetscObject)mat); 92*e51e0e81SBarry Smith } 93*e51e0e81SBarry Smith /*@ 94*e51e0e81SBarry Smith MatValidMatrix - returns 1 if a valid matrix else 0 95*e51e0e81SBarry Smith 96*e51e0e81SBarry Smith Input Parameter: 97*e51e0e81SBarry Smith . m - the matrix to check 98*e51e0e81SBarry Smith @*/ 99*e51e0e81SBarry Smith int MatValidMatrix(Mat m) 100*e51e0e81SBarry Smith { 101*e51e0e81SBarry Smith if (!m) return 0; 102*e51e0e81SBarry Smith if (m->cookie != MAT_COOKIE) return 0; 103*e51e0e81SBarry Smith return 1; 104*e51e0e81SBarry Smith } 105*e51e0e81SBarry Smith 106*e51e0e81SBarry Smith /*@ 107*e51e0e81SBarry Smith MatInsertValues - inserts a block of values into a matrix 108*e51e0e81SBarry Smith 109*e51e0e81SBarry Smith Input Parameters: 110*e51e0e81SBarry Smith . mat - the matrix 111*e51e0e81SBarry Smith . v - a logically two dimensional array of values, Fortran ordering 112*e51e0e81SBarry Smith . m, indexm - the number of rows and their indices 113*e51e0e81SBarry Smith . n, indexn - the number of columns and their indices 114*e51e0e81SBarry Smith @*/ 115*e51e0e81SBarry Smith int MatInsertValues(Mat mat,Scalar *v,int m,int *indexm,int n,int *indexn) 116*e51e0e81SBarry Smith { 117*e51e0e81SBarry Smith VALIDHEADER(mat,MAT_COOKIE); 118*e51e0e81SBarry Smith return (*mat->ops->insert)(mat,v,m,indexm,n,indexn); 119*e51e0e81SBarry Smith } 120*e51e0e81SBarry Smith /*@ 121*e51e0e81SBarry Smith MatAddValues - adds a block of values into a matrix 122*e51e0e81SBarry Smith 123*e51e0e81SBarry Smith Input Parameters: 124*e51e0e81SBarry Smith . mat - the matrix 125*e51e0e81SBarry Smith . v - a logically two dimensional array of values, Fortran ordering 126*e51e0e81SBarry Smith . m, indexm - the number of rows and their indices 127*e51e0e81SBarry Smith . n, indexn - the number of columns and their indices 128*e51e0e81SBarry Smith @*/ 129*e51e0e81SBarry Smith int MatAddValues(Mat mat,Scalar *v,int m,int *indexm,int n,int *indexn) 130*e51e0e81SBarry Smith { 131*e51e0e81SBarry Smith VALIDHEADER(mat,MAT_COOKIE); 132*e51e0e81SBarry Smith return (*mat->ops->insertadd)(mat,v,m,indexm,n,indexn); 133*e51e0e81SBarry Smith } 134*e51e0e81SBarry Smith /* --------------------------------------------------------*/ 135*e51e0e81SBarry Smith /*@ 136*e51e0e81SBarry Smith MatMult - Matrix vector multiply 137*e51e0e81SBarry Smith 138*e51e0e81SBarry Smith Input Parameters: 139*e51e0e81SBarry Smith . mat -the matrix 140*e51e0e81SBarry Smith . x - the vector to be multilplied 141*e51e0e81SBarry Smith Output Parameters: 142*e51e0e81SBarry Smith . y - the result 143*e51e0e81SBarry Smith @*/ 144*e51e0e81SBarry Smith int MatMult(Mat mat,Vec x,Vec y) 145*e51e0e81SBarry Smith { 146*e51e0e81SBarry Smith VALIDHEADER(mat,MAT_COOKIE); 147*e51e0e81SBarry Smith VALIDHEADER(x,VEC_COOKIE);VALIDHEADER(y,VEC_COOKIE); 148*e51e0e81SBarry Smith return (*mat->ops->mult)(mat,x,y); 149*e51e0e81SBarry Smith } 150*e51e0e81SBarry Smith /*@ 151*e51e0e81SBarry Smith MatMultTrans - Matrix transpose times a vector 152*e51e0e81SBarry Smith 153*e51e0e81SBarry Smith Input Parameters: 154*e51e0e81SBarry Smith . mat -the matrix 155*e51e0e81SBarry Smith . x - the vector to be multilplied 156*e51e0e81SBarry Smith Output Parameters: 157*e51e0e81SBarry Smith . y - the result 158*e51e0e81SBarry Smith @*/ 159*e51e0e81SBarry Smith int MatMultTrans(Mat mat,Vec x,Vec y) 160*e51e0e81SBarry Smith { 161*e51e0e81SBarry Smith VALIDHEADER(mat,MAT_COOKIE); 162*e51e0e81SBarry Smith VALIDHEADER(x,VEC_COOKIE); VALIDHEADER(y,VEC_COOKIE); 163*e51e0e81SBarry Smith return (*mat->ops->multtrans)(mat,x,y); 164*e51e0e81SBarry Smith } 165*e51e0e81SBarry Smith /*@ 166*e51e0e81SBarry Smith MatMultAdd - v3 = v2 + A v1 167*e51e0e81SBarry Smith 168*e51e0e81SBarry Smith Input Parameters: 169*e51e0e81SBarry Smith . mat -the matrix 170*e51e0e81SBarry Smith . v1, v2 - the vectors 171*e51e0e81SBarry Smith Output Parameters: 172*e51e0e81SBarry Smith . v3 - the result 173*e51e0e81SBarry Smith @*/ 174*e51e0e81SBarry Smith int MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3) 175*e51e0e81SBarry Smith { 176*e51e0e81SBarry Smith VALIDHEADER(mat,MAT_COOKIE);VALIDHEADER(v1,VEC_COOKIE); 177*e51e0e81SBarry Smith VALIDHEADER(v2,VEC_COOKIE); VALIDHEADER(v3,VEC_COOKIE); 178*e51e0e81SBarry Smith return (*mat->ops->multadd)(mat,v1,v2,v3); 179*e51e0e81SBarry Smith } 180*e51e0e81SBarry Smith /*@ 181*e51e0e81SBarry Smith MatMultTransAdd - v3 = v2 + A' v1 182*e51e0e81SBarry Smith 183*e51e0e81SBarry Smith Input Parameters: 184*e51e0e81SBarry Smith . mat -the matrix 185*e51e0e81SBarry Smith . v1, v2 - the vectors 186*e51e0e81SBarry Smith Output Parameters: 187*e51e0e81SBarry Smith . v3 - the result 188*e51e0e81SBarry Smith @*/ 189*e51e0e81SBarry Smith int MatMultTransAdd(Mat mat,Vec v1,Vec v2,Vec v3) 190*e51e0e81SBarry Smith { 191*e51e0e81SBarry Smith VALIDHEADER(mat,MAT_COOKIE); VALIDHEADER(v1,VEC_COOKIE); 192*e51e0e81SBarry Smith VALIDHEADER(v2,VEC_COOKIE); VALIDHEADER(v3,VEC_COOKIE); 193*e51e0e81SBarry Smith return (*mat->ops->multtransadd)(mat,v1,v2,v3); 194*e51e0e81SBarry Smith } 195*e51e0e81SBarry Smith /* ------------------------------------------------------------*/ 196*e51e0e81SBarry Smith /*@ 197*e51e0e81SBarry Smith MatNonZeros - returns the number of nonzeros in a matrix 198*e51e0e81SBarry Smith 199*e51e0e81SBarry Smith Input Parameters: 200*e51e0e81SBarry Smith . mat - the matrix 201*e51e0e81SBarry Smith 202*e51e0e81SBarry Smith Output Parameters: 203*e51e0e81SBarry Smith . returns the number of nonzeros 204*e51e0e81SBarry Smith @*/ 205*e51e0e81SBarry Smith int MatNonZeros(Mat mat,int *nz) 206*e51e0e81SBarry Smith { 207*e51e0e81SBarry Smith VALIDHEADER(mat,MAT_COOKIE); 208*e51e0e81SBarry Smith return (*mat->ops->NZ)(mat,nz); 209*e51e0e81SBarry Smith } 210*e51e0e81SBarry Smith /*@ 211*e51e0e81SBarry Smith MatMemoryUsed - returns the amount of memory used to store matrix. 212*e51e0e81SBarry Smith 213*e51e0e81SBarry Smith Input Parameters: 214*e51e0e81SBarry Smith . mat - the matrix 215*e51e0e81SBarry Smith 216*e51e0e81SBarry Smith Output Parameters: 217*e51e0e81SBarry Smith . mem - memory used 218*e51e0e81SBarry Smith @*/ 219*e51e0e81SBarry Smith int MatMemoryUsed(Mat mat,int *mem) 220*e51e0e81SBarry Smith { 221*e51e0e81SBarry Smith VALIDHEADER(mat,MAT_COOKIE); 222*e51e0e81SBarry Smith return (*mat->ops->memory)(mat,mem); 223*e51e0e81SBarry Smith } 224*e51e0e81SBarry Smith /* ----------------------------------------------------------*/ 225*e51e0e81SBarry Smith /*@ 226*e51e0e81SBarry Smith MatLUFactor - performs an inplace LU factorization of matrix. 227*e51e0e81SBarry Smith See MatLUFactorSymbolic() and MatLUFactorNumeric() for 228*e51e0e81SBarry Smith out-of-place factorization. See MatCholeskyFactor() 229*e51e0e81SBarry Smith for symmetric, positive definite case. 230*e51e0e81SBarry Smith 231*e51e0e81SBarry Smith Input Parameters: 232*e51e0e81SBarry Smith . mat - the matrix 233*e51e0e81SBarry Smith . row, col - row and column permutations 234*e51e0e81SBarry Smith 235*e51e0e81SBarry Smith @*/ 236*e51e0e81SBarry Smith int MatLUFactor(Mat mat,IS row,IS col) 237*e51e0e81SBarry Smith { 238*e51e0e81SBarry Smith VALIDHEADER(mat,MAT_COOKIE); 239*e51e0e81SBarry Smith if (mat->ops->lufactor) return (*mat->ops->lufactor)(mat,row,col); 240*e51e0e81SBarry Smith SETERR(1,"No MatLUFactor for implementation"); 241*e51e0e81SBarry Smith } 242*e51e0e81SBarry Smith /*@ 243*e51e0e81SBarry Smith MatLUFactorSymbolic - performs a symbolic LU factorization of matrix. 244*e51e0e81SBarry Smith See MatLUFactor() for in-place factorization. See 245*e51e0e81SBarry Smith MatCholeskyFactor() for symmetric, positive definite case. 246*e51e0e81SBarry Smith 247*e51e0e81SBarry Smith Input Parameters: 248*e51e0e81SBarry Smith . mat - the matrix 249*e51e0e81SBarry Smith . row, col - row and column permutations 250*e51e0e81SBarry Smith 251*e51e0e81SBarry Smith Output Parameters: 252*e51e0e81SBarry Smith . fact - puts factor else does inplace factorization 253*e51e0e81SBarry Smith @*/ 254*e51e0e81SBarry Smith int MatLUFactorSymbolic(Mat mat,IS row,IS col,Mat *fact) 255*e51e0e81SBarry Smith { 256*e51e0e81SBarry Smith VALIDHEADER(mat,MAT_COOKIE); 257*e51e0e81SBarry Smith if (!fact) SETERR(1,"Missing slot for symbolic factorization"); 258*e51e0e81SBarry Smith if (mat->ops->lufactorsymbolic) return (*mat->ops->lufactorsymbolic)(mat,row, 259*e51e0e81SBarry Smith col,fact); 260*e51e0e81SBarry Smith SETERR(1,"No MatLUFactorSymbolic for implementation"); 261*e51e0e81SBarry Smith } 262*e51e0e81SBarry Smith /*@ 263*e51e0e81SBarry Smith MatLUFactorNumeric - performs a numeric LU factorization of matrix. 264*e51e0e81SBarry Smith See MatLUFactor() for in-place factorization. See 265*e51e0e81SBarry Smith MatCholeskyFactor() for symmetric, positive definite case. 266*e51e0e81SBarry Smith 267*e51e0e81SBarry Smith Input Parameters: 268*e51e0e81SBarry Smith . mat - the matrix 269*e51e0e81SBarry Smith . row, col - row and column permutations 270*e51e0e81SBarry Smith 271*e51e0e81SBarry Smith Output Parameters: 272*e51e0e81SBarry Smith . fact - must have been obtained with MatLUFactorSymbolic() 273*e51e0e81SBarry Smith @*/ 274*e51e0e81SBarry Smith int MatLUFactorNumeric(Mat mat,Mat fact) 275*e51e0e81SBarry Smith { 276*e51e0e81SBarry Smith VALIDHEADER(mat,MAT_COOKIE); 277*e51e0e81SBarry Smith if (!fact) SETERR(1,"Missing symbolic factorization"); 278*e51e0e81SBarry Smith if (mat->ops->lufactornumeric) return (*mat->ops->lufactornumeric)(mat,fact); 279*e51e0e81SBarry Smith SETERR(1,"No MatLUFactorNumeric for implementation"); 280*e51e0e81SBarry Smith } 281*e51e0e81SBarry Smith /*@ 282*e51e0e81SBarry Smith MatCholeskyFactor - performs an inplace CC' factorization of matrix. 283*e51e0e81SBarry Smith See also MatLUFactor(), MatCholeskyFactorSymbolic() and 284*e51e0e81SBarry Smith MatCholeskyFactorNumeric(). 285*e51e0e81SBarry Smith 286*e51e0e81SBarry Smith Input Parameters: 287*e51e0e81SBarry Smith . mat - the matrix 288*e51e0e81SBarry Smith . perm - row and column permutations 289*e51e0e81SBarry Smith 290*e51e0e81SBarry Smith @*/ 291*e51e0e81SBarry Smith int MatCholeskyFactor(Mat mat,IS perm) 292*e51e0e81SBarry Smith { 293*e51e0e81SBarry Smith VALIDHEADER(mat,MAT_COOKIE); 294*e51e0e81SBarry Smith if (mat->ops->chfactor) return (*mat->ops->chfactor)(mat,perm); 295*e51e0e81SBarry Smith SETERR(1,"No MatCholeskyFactor for implementation"); 296*e51e0e81SBarry Smith } 297*e51e0e81SBarry Smith /*@ 298*e51e0e81SBarry Smith MatCholeskyFactorSymbolic - performs a symbolic Cholesky factorization. 299*e51e0e81SBarry Smith See also MatLUFactor(), MatCholeskyFactorSymbolic() and 300*e51e0e81SBarry Smith MatCholeskyFactorNumeric(). 301*e51e0e81SBarry Smith 302*e51e0e81SBarry Smith Input Parameters: 303*e51e0e81SBarry Smith . mat - the matrix 304*e51e0e81SBarry Smith . perm - row and column permutations 305*e51e0e81SBarry Smith 306*e51e0e81SBarry Smith @*/ 307*e51e0e81SBarry Smith int MatCholeskyFactorSymbolic(Mat mat,IS perm,Mat *fact) 308*e51e0e81SBarry Smith { 309*e51e0e81SBarry Smith VALIDHEADER(mat,MAT_COOKIE); 310*e51e0e81SBarry Smith if (!fact) SETERR(1,"Missing slot for symbolic factorization"); 311*e51e0e81SBarry Smith if (mat->ops->chfactorsymbolic) return (*mat->ops->chfactorsymbolic)(mat, 312*e51e0e81SBarry Smith perm,fact); 313*e51e0e81SBarry Smith SETERR(1,"No MatCholeskyFactorSymbolic for implementation"); 314*e51e0e81SBarry Smith } 315*e51e0e81SBarry Smith /*@ 316*e51e0e81SBarry Smith MatCholeskyFactorNumeric - performs a numeric Cholesky factorization. 317*e51e0e81SBarry Smith See also MatLUFactor(), MatCholeskyFactor() and 318*e51e0e81SBarry Smith MatCholeskyFactorSymbolic(). 319*e51e0e81SBarry Smith 320*e51e0e81SBarry Smith Input Parameters: 321*e51e0e81SBarry Smith . mat - the matrix 322*e51e0e81SBarry Smith 323*e51e0e81SBarry Smith 324*e51e0e81SBarry Smith @*/ 325*e51e0e81SBarry Smith int MatCholeskyFactorNumeric(Mat mat,Mat fact) 326*e51e0e81SBarry Smith { 327*e51e0e81SBarry Smith VALIDHEADER(mat,MAT_COOKIE); 328*e51e0e81SBarry Smith if (!fact) SETERR(1,"Missing symbolic factorization"); 329*e51e0e81SBarry Smith if (mat->ops->chfactornumeric) return (*mat->ops->chfactornumeric)(mat, 330*e51e0e81SBarry Smith fact); 331*e51e0e81SBarry Smith SETERR(1,"No MatCholeskyFactorNumeric for implementation"); 332*e51e0e81SBarry Smith } 333*e51e0e81SBarry Smith /* ----------------------------------------------------------------*/ 334*e51e0e81SBarry Smith /*@ 335*e51e0e81SBarry Smith MatSolve - solve A x = b 336*e51e0e81SBarry Smith 337*e51e0e81SBarry Smith Input Parameters: 338*e51e0e81SBarry Smith . mat - the factored matrix 339*e51e0e81SBarry Smith . b - the right hand side 340*e51e0e81SBarry Smith 341*e51e0e81SBarry Smith Output Parameter: 342*e51e0e81SBarry Smith . x- the result 343*e51e0e81SBarry Smith @*/ 344*e51e0e81SBarry Smith int MatSolve(Mat mat,Vec b,Vec x) 345*e51e0e81SBarry Smith { 346*e51e0e81SBarry Smith VALIDHEADER(mat,MAT_COOKIE); 347*e51e0e81SBarry Smith VALIDHEADER(b,VEC_COOKIE); VALIDHEADER(x,VEC_COOKIE); 348*e51e0e81SBarry Smith if (!mat->factor) SETERR(1,"Attempt solve on nonfactored matrix"); 349*e51e0e81SBarry Smith if (mat->ops->solve) return (*mat->ops->solve)(mat,b,x); 350*e51e0e81SBarry Smith SETERR(1,"No MatSolve for implementation"); 351*e51e0e81SBarry Smith } 352*e51e0e81SBarry Smith /*@ 353*e51e0e81SBarry Smith MatSolveAdd - x = y + A^-1 b 354*e51e0e81SBarry Smith 355*e51e0e81SBarry Smith Input Parameters: 356*e51e0e81SBarry Smith . mat - the factored matrix 357*e51e0e81SBarry Smith . b - the right hand side 358*e51e0e81SBarry Smith . y - te vector to be added to 359*e51e0e81SBarry Smith 360*e51e0e81SBarry Smith Output Parameter: 361*e51e0e81SBarry Smith . x- the result 362*e51e0e81SBarry Smith @*/ 363*e51e0e81SBarry Smith int MatSolveAdd(Mat mat,Vec b,Vec y,Vec x) 364*e51e0e81SBarry Smith { 365*e51e0e81SBarry Smith Scalar one = 1.0; 366*e51e0e81SBarry Smith Vec tmp; 367*e51e0e81SBarry Smith int ierr; 368*e51e0e81SBarry Smith VALIDHEADER(mat,MAT_COOKIE);VALIDHEADER(y,VEC_COOKIE); 369*e51e0e81SBarry Smith VALIDHEADER(b,VEC_COOKIE); VALIDHEADER(x,VEC_COOKIE); 370*e51e0e81SBarry Smith if (!mat->factor) SETERR(1,"Attempt solve on nonfactored matrix"); 371*e51e0e81SBarry Smith if (mat->ops->solveadd) return (*mat->ops->solveadd)(mat,b,y,x); 372*e51e0e81SBarry Smith /* do the solve then the add manually */ 373*e51e0e81SBarry Smith if (x != y) { 374*e51e0e81SBarry Smith ierr = MatSolve(mat,b,x); CHKERR(ierr); 375*e51e0e81SBarry Smith ierr = VecAXPY(&one,y,x); CHKERR(ierr); 376*e51e0e81SBarry Smith return 0; 377*e51e0e81SBarry Smith } 378*e51e0e81SBarry Smith else { 379*e51e0e81SBarry Smith ierr = VecCreate(x,&tmp); CHKERR(ierr); 380*e51e0e81SBarry Smith ierr = VecCopy(x,tmp); CHKERR(ierr); 381*e51e0e81SBarry Smith ierr = MatSolve(mat,b,x); CHKERR(ierr); 382*e51e0e81SBarry Smith ierr = VecAXPY(&one,tmp,x); CHKERR(ierr); 383*e51e0e81SBarry Smith ierr = VecDestroy(tmp); CHKERR(ierr); 384*e51e0e81SBarry Smith return 0; 385*e51e0e81SBarry Smith } 386*e51e0e81SBarry Smith } 387*e51e0e81SBarry Smith /*@ 388*e51e0e81SBarry Smith MatSolveTrans - solve A' x = b 389*e51e0e81SBarry Smith 390*e51e0e81SBarry Smith Input Parameters: 391*e51e0e81SBarry Smith . mat - the factored matrix 392*e51e0e81SBarry Smith . b - the right hand side 393*e51e0e81SBarry Smith 394*e51e0e81SBarry Smith Output Parameter: 395*e51e0e81SBarry Smith . x- the result 396*e51e0e81SBarry Smith @*/ 397*e51e0e81SBarry Smith int MatSolveTrans(Mat mat,Vec b,Vec x) 398*e51e0e81SBarry Smith { 399*e51e0e81SBarry Smith VALIDHEADER(mat,MAT_COOKIE); 400*e51e0e81SBarry Smith VALIDHEADER(b,VEC_COOKIE); VALIDHEADER(x,VEC_COOKIE); 401*e51e0e81SBarry Smith if (!mat->factor) SETERR(1,"Attempt solve on nonfactored matrix"); 402*e51e0e81SBarry Smith if (mat->ops->solvetrans) return (*mat->ops->solvetrans)(mat,b,x); 403*e51e0e81SBarry Smith SETERR(1,"No MatSolveTrans for implementation"); 404*e51e0e81SBarry Smith } 405*e51e0e81SBarry Smith /*@ 406*e51e0e81SBarry Smith MatSolveTransAdd - x = y + A^-T b 407*e51e0e81SBarry Smith 408*e51e0e81SBarry Smith Input Parameters: 409*e51e0e81SBarry Smith . mat - the factored matrix 410*e51e0e81SBarry Smith . b - the right hand side 411*e51e0e81SBarry Smith . y - te vector to be added to 412*e51e0e81SBarry Smith 413*e51e0e81SBarry Smith Output Parameter: 414*e51e0e81SBarry Smith . x- the result 415*e51e0e81SBarry Smith @*/ 416*e51e0e81SBarry Smith int MatSolveTransAdd(Mat mat,Vec b,Vec y,Vec x) 417*e51e0e81SBarry Smith { 418*e51e0e81SBarry Smith Scalar one = 1.0; 419*e51e0e81SBarry Smith int ierr; 420*e51e0e81SBarry Smith Vec tmp; 421*e51e0e81SBarry Smith VALIDHEADER(mat,MAT_COOKIE);VALIDHEADER(y,VEC_COOKIE); 422*e51e0e81SBarry Smith VALIDHEADER(b,VEC_COOKIE); VALIDHEADER(x,VEC_COOKIE); 423*e51e0e81SBarry Smith if (!mat->factor) SETERR(1,"Attempt solve on nonfactored matrix"); 424*e51e0e81SBarry Smith if (mat->ops->solvetransadd) return (*mat->ops->solvetransadd)(mat,b,y,x); 425*e51e0e81SBarry Smith /* do the solve then the add manually */ 426*e51e0e81SBarry Smith if (x != y) { 427*e51e0e81SBarry Smith ierr = MatSolveTrans(mat,b,x); CHKERR(ierr); 428*e51e0e81SBarry Smith ierr = VecAXPY(&one,y,x); CHKERR(ierr); 429*e51e0e81SBarry Smith return 0; 430*e51e0e81SBarry Smith } 431*e51e0e81SBarry Smith else { 432*e51e0e81SBarry Smith ierr = VecCreate(x,&tmp); CHKERR(ierr); 433*e51e0e81SBarry Smith ierr = VecCopy(x,tmp); CHKERR(ierr); 434*e51e0e81SBarry Smith ierr = MatSolveTrans(mat,b,x); CHKERR(ierr); 435*e51e0e81SBarry Smith ierr = VecAXPY(&one,tmp,x); CHKERR(ierr); 436*e51e0e81SBarry Smith ierr = VecDestroy(tmp); CHKERR(ierr); 437*e51e0e81SBarry Smith return 0; 438*e51e0e81SBarry Smith } 439*e51e0e81SBarry Smith } 440*e51e0e81SBarry Smith /* ----------------------------------------------------------------*/ 441*e51e0e81SBarry Smith 442*e51e0e81SBarry Smith /*@ 443*e51e0e81SBarry Smith MatRelax - one relaxation sweep 444*e51e0e81SBarry Smith 445*e51e0e81SBarry Smith Input Parameters: 446*e51e0e81SBarry Smith . mat - the matrix 447*e51e0e81SBarry Smith . b - the right hand side 448*e51e0e81SBarry Smith . omega - the relaxation factor 449*e51e0e81SBarry Smith . flag - or together from SOR_FORWARD_SWEEP, SOR_BACKWARD_SWEEP, 450*e51e0e81SBarry Smith . SOR_ZERO_INITIAL_GUESS. (SOR_SYMMETRIC_SWEEP is 451*e51e0e81SBarry Smith . equivalent to SOR_FORWARD_SWEEP | SOR_BACKWARD_SWEEP) 452*e51e0e81SBarry Smith . is - optional index set indicating ordering 453*e51e0e81SBarry Smith . its - the number of iterations 454*e51e0e81SBarry Smith 455*e51e0e81SBarry Smith Output Parameters: 456*e51e0e81SBarry Smith . x - the solution - can contain initial guess 457*e51e0e81SBarry Smith @*/ 458*e51e0e81SBarry Smith int MatRelax(Mat mat,Vec b,double omega,int flag,IS is,int its,Vec x) 459*e51e0e81SBarry Smith { 460*e51e0e81SBarry Smith VALIDHEADER(mat,MAT_COOKIE); 461*e51e0e81SBarry Smith VALIDHEADER(b,VEC_COOKIE); VALIDHEADER(x,VEC_COOKIE); 462*e51e0e81SBarry Smith if (flag < 1 || flag > 7) SETERR(1,"Bad relaxation type"); 463*e51e0e81SBarry Smith if (mat->ops->relax) return (*mat->ops->relax)(mat,b,omega,flag,is,its,x); 464*e51e0e81SBarry Smith SETERR(1,"No MatRelax for implementation"); 465*e51e0e81SBarry Smith } 466*e51e0e81SBarry Smith 467*e51e0e81SBarry Smith /* ----------------------------------------------------------------*/ 468*e51e0e81SBarry Smith /*@ 469*e51e0e81SBarry Smith MatCopy - copies a matrix 470*e51e0e81SBarry Smith 471*e51e0e81SBarry Smith Input Parameters: 472*e51e0e81SBarry Smith . mat - the matrix 473*e51e0e81SBarry Smith 474*e51e0e81SBarry Smith Output Parameters: 475*e51e0e81SBarry Smith . M - pointer to place new matrix 476*e51e0e81SBarry Smith @*/ 477*e51e0e81SBarry Smith int MatCopy(Mat mat,Mat *M) 478*e51e0e81SBarry Smith { 479*e51e0e81SBarry Smith VALIDHEADER(mat,MAT_COOKIE); 480*e51e0e81SBarry Smith if (mat->ops->copy) return (*mat->ops->copy)(mat,M); 481*e51e0e81SBarry Smith SETERR(1,"No MatCopy for implementation"); 482*e51e0e81SBarry Smith } 483*e51e0e81SBarry Smith 484*e51e0e81SBarry Smith /*@ 485*e51e0e81SBarry Smith MatGetDiagonal - get diagonal of matrix 486*e51e0e81SBarry Smith 487*e51e0e81SBarry Smith Input Parameters: 488*e51e0e81SBarry Smith . mat - the matrix 489*e51e0e81SBarry Smith 490*e51e0e81SBarry Smith Output Parameters: 491*e51e0e81SBarry Smith . v - the vector to store the diagonal in 492*e51e0e81SBarry Smith @*/ 493*e51e0e81SBarry Smith int MatGetDiagonal(Mat mat,Vec v) 494*e51e0e81SBarry Smith { 495*e51e0e81SBarry Smith VALIDHEADER(mat,MAT_COOKIE); 496*e51e0e81SBarry Smith VALIDHEADER(v,VEC_COOKIE); 497*e51e0e81SBarry Smith if (mat->ops->getdiag) return (*mat->ops->getdiag)(mat,v); 498*e51e0e81SBarry Smith SETERR(1,"No MatGetDiagonal for implementaion"); 499*e51e0e81SBarry Smith } 500*e51e0e81SBarry Smith 501*e51e0e81SBarry Smith /*@ 502*e51e0e81SBarry Smith MatTranspose - in place transpose of matrix 503*e51e0e81SBarry Smith 504*e51e0e81SBarry Smith Input Parameters: 505*e51e0e81SBarry Smith . mat - the matrix to transpose 506*e51e0e81SBarry Smith @*/ 507*e51e0e81SBarry Smith int MatTranspose(Mat mat) 508*e51e0e81SBarry Smith { 509*e51e0e81SBarry Smith VALIDHEADER(mat,MAT_COOKIE); 510*e51e0e81SBarry Smith if (mat->ops->trans) return (*mat->ops->trans)(mat); 511*e51e0e81SBarry Smith SETERR(1,"No MatTranspose for implementaion"); 512*e51e0e81SBarry Smith } 513*e51e0e81SBarry Smith 514*e51e0e81SBarry Smith /*@ 515*e51e0e81SBarry Smith MatEqual - returns 1 if two matrices are equal 516*e51e0e81SBarry Smith 517*e51e0e81SBarry Smith Input Parameters: 518*e51e0e81SBarry Smith . mat1, mat2 - the matrices 519*e51e0e81SBarry Smith 520*e51e0e81SBarry Smith OutPut Parameter: 521*e51e0e81SBarry Smith . returns 1 if matrices are equal 522*e51e0e81SBarry Smith @*/ 523*e51e0e81SBarry Smith int MatEqual(Mat mat1,Mat mat2) 524*e51e0e81SBarry Smith { 525*e51e0e81SBarry Smith VALIDHEADER(mat1,MAT_COOKIE); VALIDHEADER(mat2,MAT_COOKIE); 526*e51e0e81SBarry Smith if (mat1->ops->equal) return (*mat1->ops->equal)(mat1,mat2); 527*e51e0e81SBarry Smith SETERR(1,"No MatEqual for implementaion"); 528*e51e0e81SBarry Smith } 529*e51e0e81SBarry Smith 530*e51e0e81SBarry Smith /*@ 531*e51e0e81SBarry Smith MatScale - scale a matrix on the left and right by diagonal 532*e51e0e81SBarry Smith matrices stored as vectors. Either of the two may be 533*e51e0e81SBarry Smith null. 534*e51e0e81SBarry Smith 535*e51e0e81SBarry Smith Input Parameters: 536*e51e0e81SBarry Smith . mat - the matrix to be scaled 537*e51e0e81SBarry Smith . l,r - the left and right scaling vectors 538*e51e0e81SBarry Smith @*/ 539*e51e0e81SBarry Smith int MatScale(Mat mat,Vec l,Vec r) 540*e51e0e81SBarry Smith { 541*e51e0e81SBarry Smith VALIDHEADER(mat,MAT_COOKIE); 542*e51e0e81SBarry Smith VALIDHEADER(l,VEC_COOKIE); VALIDHEADER(r,VEC_COOKIE); 543*e51e0e81SBarry Smith if (mat->ops->scale) return (*mat->ops->scale)(mat,l,r); 544*e51e0e81SBarry Smith SETERR(1,"No MatScale for implementaion"); 545*e51e0e81SBarry Smith } 546*e51e0e81SBarry Smith 547*e51e0e81SBarry Smith /*@ 548*e51e0e81SBarry Smith MatNorm - calculate various norms of a matrix 549*e51e0e81SBarry Smith 550*e51e0e81SBarry Smith Input Parameters: 551*e51e0e81SBarry Smith . mat - the matrix 552*e51e0e81SBarry Smith . type - the type of norm, NORM_1, NORM_2, NORM_FROBENIUS, NORM_INFINITY 553*e51e0e81SBarry Smith 554*e51e0e81SBarry Smith Output Parameters: 555*e51e0e81SBarry Smith . norm - the resulting norm 556*e51e0e81SBarry Smith @*/ 557*e51e0e81SBarry Smith int MatNorm(Mat mat,int type,double *norm) 558*e51e0e81SBarry Smith { 559*e51e0e81SBarry Smith VALIDHEADER(mat,MAT_COOKIE); 560*e51e0e81SBarry Smith if (mat->ops->norm) return (*mat->ops->norm)(mat,type,norm); 561*e51e0e81SBarry Smith SETERR(1,"No MatNorm for implementaion"); 562*e51e0e81SBarry Smith } 563*e51e0e81SBarry Smith 564*e51e0e81SBarry Smith /*@ 565*e51e0e81SBarry Smith MatBeginAssembly - begin assemblying the matrix. This should 566*e51e0e81SBarry Smith be called after all the calls to MatInsertValues() 567*e51e0e81SBarry Smith and MatAddValues(). 568*e51e0e81SBarry Smith 569*e51e0e81SBarry Smith Input Parameters: 570*e51e0e81SBarry Smith . mat - the matrix 571*e51e0e81SBarry Smith 572*e51e0e81SBarry Smith Note: when you call MatInsertValues() it generally caches the values 573*e51e0e81SBarry Smith only after you have called MatBeginAssembly() and 574*e51e0e81SBarry Smith MatEndAssembly() is the matrix ready to be used. 575*e51e0e81SBarry Smith @*/ 576*e51e0e81SBarry Smith int MatBeginAssembly(Mat mat) 577*e51e0e81SBarry Smith { 578*e51e0e81SBarry Smith VALIDHEADER(mat,MAT_COOKIE); 579*e51e0e81SBarry Smith if (mat->ops->bassembly) return (*mat->ops->bassembly)(mat); 580*e51e0e81SBarry Smith return 0; 581*e51e0e81SBarry Smith } 582*e51e0e81SBarry Smith /*@ 583*e51e0e81SBarry Smith MatEndAssembly - begin assemblying the matrix. This should 584*e51e0e81SBarry Smith be called after all the calls to MatInsertValues() 585*e51e0e81SBarry Smith and MatAddValues() and after MatBeginAssembly(). 586*e51e0e81SBarry Smith 587*e51e0e81SBarry Smith Input Parameters: 588*e51e0e81SBarry Smith . mat - the matrix 589*e51e0e81SBarry Smith 590*e51e0e81SBarry Smith Note: when you call MatInsertValues() it generally caches the values 591*e51e0e81SBarry Smith only after you have called MatBeginAssembly() and 592*e51e0e81SBarry Smith MatEndAssembly() is the matrix ready to be used. 593*e51e0e81SBarry Smith @*/ 594*e51e0e81SBarry Smith int MatEndAssembly(Mat mat) 595*e51e0e81SBarry Smith { 596*e51e0e81SBarry Smith VALIDHEADER(mat,MAT_COOKIE); 597*e51e0e81SBarry Smith if (mat->ops->eassembly) return (*mat->ops->eassembly)(mat); 598*e51e0e81SBarry Smith return 0; 599*e51e0e81SBarry Smith } 600*e51e0e81SBarry Smith /*@ 601*e51e0e81SBarry Smith MatCompress - trys to store matrix in as little space as 602*e51e0e81SBarry Smith possible. May fail if memory is already fully used as 603*e51e0e81SBarry Smith it tries to allocate new space. 604*e51e0e81SBarry Smith 605*e51e0e81SBarry Smith Input Parameters: 606*e51e0e81SBarry Smith . mat - the matrix 607*e51e0e81SBarry Smith 608*e51e0e81SBarry Smith @*/ 609*e51e0e81SBarry Smith int MatCompress(Mat mat) 610*e51e0e81SBarry Smith { 611*e51e0e81SBarry Smith VALIDHEADER(mat,MAT_COOKIE); 612*e51e0e81SBarry Smith if (mat->ops->compress) return (*mat->ops->compress)(mat); 613*e51e0e81SBarry Smith return 0; 614*e51e0e81SBarry Smith } 615*e51e0e81SBarry Smith /*@ 616*e51e0e81SBarry Smith MatSetInsertOption - set parameter option on how you will insert 617*e51e0e81SBarry Smith (or add) values. In general sorted, row oriented input will assemble 618*e51e0e81SBarry Smith fastest. Defaults to row oriented, nonsorted input. Note that 619*e51e0e81SBarry Smith if you are using a Fortran 77 module to compute an element 620*e51e0e81SBarry Smith stiffness you may need to modify the module or use column 621*e51e0e81SBarry Smith oriented input. 622*e51e0e81SBarry Smith 623*e51e0e81SBarry Smith Input Parameters: 624*e51e0e81SBarry Smith . mat - the matrix 625*e51e0e81SBarry Smith . option - one of ROW_ORIENTED, COLUMN_ORIENTED, ROWS_SORTED, 626*e51e0e81SBarry Smith COLUMNS_SORTED, NO_NEW_NONZERO_LOCATIONS 627*e51e0e81SBarry Smith 628*e51e0e81SBarry Smith NO_NEW_NONZERO_LOCATIONS indicates that any add or insertion 629*e51e0e81SBarry Smith that will generate a new entry in the nonzero structure is ignored. 630*e51e0e81SBarry Smith What this means is if memory is not allocated for this particular 631*e51e0e81SBarry Smith lot then the insertion is ignored. For dense matrices where 632*e51e0e81SBarry Smith the entire array is allocated no entries are every ignored. This 633*e51e0e81SBarry Smith may not be a good idea?? 634*e51e0e81SBarry Smith 635*e51e0e81SBarry Smith @*/ 636*e51e0e81SBarry Smith int MatSetInsertOption(Mat mat,int op) 637*e51e0e81SBarry Smith { 638*e51e0e81SBarry Smith VALIDHEADER(mat,MAT_COOKIE); 639*e51e0e81SBarry Smith if (op < 0 || op > 7) SETERR(1,"Invalid option to MatSetInsertOption"); 640*e51e0e81SBarry Smith if (mat->ops->insopt) return (*mat->ops->insopt)(mat,op); 641*e51e0e81SBarry Smith return 0; 642*e51e0e81SBarry Smith } 643*e51e0e81SBarry Smith 644*e51e0e81SBarry Smith /*@ 645*e51e0e81SBarry Smith MatZeroEntries - zeros all entries in a matrix. For sparse matrices 646*e51e0e81SBarry Smith it keeps the old nonzero structure. 647*e51e0e81SBarry Smith 648*e51e0e81SBarry Smith Input Parameters: 649*e51e0e81SBarry Smith . mat - the matrix 650*e51e0e81SBarry Smith 651*e51e0e81SBarry Smith @*/ 652*e51e0e81SBarry Smith int MatZeroEntries(Mat mat) 653*e51e0e81SBarry Smith { 654*e51e0e81SBarry Smith VALIDHEADER(mat,MAT_COOKIE); 655*e51e0e81SBarry Smith if (mat->ops->zeroentries) return (*mat->ops->zeroentries)(mat); 656*e51e0e81SBarry Smith SETERR(1,"No MatZeroEntries for implementation"); 657*e51e0e81SBarry Smith } 658*e51e0e81SBarry Smith 659*e51e0e81SBarry Smith /*@ 660*e51e0e81SBarry Smith MatZeroRow - zeros all entries in a row of a matrix. For sparse matrices 661*e51e0e81SBarry Smith it removes the old nonzero structure. 662*e51e0e81SBarry Smith 663*e51e0e81SBarry Smith Input Parameters: 664*e51e0e81SBarry Smith . mat - the matrix 665*e51e0e81SBarry Smith . row - the row to zap 666*e51e0e81SBarry Smith 667*e51e0e81SBarry Smith @*/ 668*e51e0e81SBarry Smith int MatZeroRow(int row,Mat mat) 669*e51e0e81SBarry Smith { 670*e51e0e81SBarry Smith VALIDHEADER(mat,MAT_COOKIE); 671*e51e0e81SBarry Smith if (mat->ops->zerorow) return (*mat->ops->zerorow)(row,mat); 672*e51e0e81SBarry Smith SETERR(1,"No MatZeroRow for implementation"); 673*e51e0e81SBarry Smith } 674*e51e0e81SBarry Smith 675*e51e0e81SBarry Smith /*@ 676*e51e0e81SBarry Smith MatScatterBegin - Begins a scatter of one matrix into another. 677*e51e0e81SBarry Smith This is much more general than a standard scatter, it include 678*e51e0e81SBarry Smith scatter, gather and cmobinations. In a parallel enviroment 679*e51e0e81SBarry Smith it can be used to simultaneous gather from a global matrix 680*e51e0e81SBarry Smith into local and vice-versa. 681*e51e0e81SBarry Smith 682*e51e0e81SBarry Smith Input Parameters: 683*e51e0e81SBarry Smith . mat - the matrix 684*e51e0e81SBarry Smith . is1,is2 - the rows and columns to snag 685*e51e0e81SBarry Smith . is3,is4 - rows and columns to drop snagged in 686*e51e0e81SBarry Smith 687*e51e0e81SBarry Smith Output Paramters: 688*e51e0e81SBarry Smith . out - matrix to receive 689*e51e0e81SBarry Smith . ctx - optional pointer to MatScatterCtx - allows reuse of communcation 690*e51e0e81SBarry Smith pattern if same scatter used more than once. 691*e51e0e81SBarry Smith 692*e51e0e81SBarry Smith Keywords: matrix, scatter, gather 693*e51e0e81SBarry Smith @*/ 694*e51e0e81SBarry Smith int MatScatterBegin(Mat mat,IS is1,IS is2,Mat out,IS is3, IS is4, 695*e51e0e81SBarry Smith MatScatterCtx *ctx) 696*e51e0e81SBarry Smith { 697*e51e0e81SBarry Smith VALIDHEADER(mat,MAT_COOKIE); VALIDHEADER(out,MAT_COOKIE); 698*e51e0e81SBarry Smith if (mat->ops->scatbegin) 699*e51e0e81SBarry Smith return (*mat->ops->scatbegin)(mat,is1,is2,out,is3,is4,ctx); 700*e51e0e81SBarry Smith SETERR(1,"No MatScatterBegin for implementation"); 701*e51e0e81SBarry Smith } 702*e51e0e81SBarry Smith 703