1 /* 2 This is where the abstract matrix operations are defined 3 */ 4 5 #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/ 6 #include <petsc/private/isimpl.h> 7 #include <petsc/private/vecimpl.h> 8 9 /* Logging support */ 10 PetscClassId MAT_CLASSID; 11 PetscClassId MAT_COLORING_CLASSID; 12 PetscClassId MAT_FDCOLORING_CLASSID; 13 PetscClassId MAT_TRANSPOSECOLORING_CLASSID; 14 15 PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultAdd, MAT_MultTranspose; 16 PetscLogEvent MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve,MAT_MatTrSolve; 17 PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic; 18 PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor; 19 PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin; 20 PetscLogEvent MAT_QRFactorNumeric, MAT_QRFactorSymbolic, MAT_QRFactor; 21 PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_CreateSubMats, MAT_GetOrdering, MAT_RedundantMat, MAT_GetSeqNonzeroStructure; 22 PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_PartitioningND, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate; 23 PetscLogEvent MAT_FDColoringSetUp, MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction, MAT_CreateSubMat; 24 PetscLogEvent MAT_TransposeColoringCreate; 25 PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric; 26 PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric; 27 PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric; 28 PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric; 29 PetscLogEvent MAT_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric; 30 PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd; 31 PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_GetBrowsOfAcols; 32 PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym; 33 PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure; 34 PetscLogEvent MAT_GetMultiProcBlock; 35 PetscLogEvent MAT_CUSPARSECopyToGPU, MAT_CUSPARSECopyFromGPU, MAT_CUSPARSEGenerateTranspose, MAT_CUSPARSESolveAnalysis; 36 PetscLogEvent MAT_PreallCOO, MAT_SetVCOO; 37 PetscLogEvent MAT_SetValuesBatch; 38 PetscLogEvent MAT_ViennaCLCopyToGPU; 39 PetscLogEvent MAT_DenseCopyToGPU, MAT_DenseCopyFromGPU; 40 PetscLogEvent MAT_Merge,MAT_Residual,MAT_SetRandom; 41 PetscLogEvent MAT_FactorFactS,MAT_FactorInvS; 42 PetscLogEvent MATCOLORING_Apply,MATCOLORING_Comm,MATCOLORING_Local,MATCOLORING_ISCreate,MATCOLORING_SetUp,MATCOLORING_Weights; 43 PetscLogEvent MAT_H2Opus_Build,MAT_H2Opus_Compress,MAT_H2Opus_Orthog,MAT_H2Opus_LR; 44 45 const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","QR","MatFactorType","MAT_FACTOR_",NULL}; 46 47 /*@ 48 MatSetRandom - Sets all components of a matrix to random numbers. For sparse matrices that have been preallocated but not been assembled it randomly selects appropriate locations, 49 for sparse matrices that already have locations it fills the locations with random numbers 50 51 Logically Collective on Mat 52 53 Input Parameters: 54 + x - the matrix 55 - rctx - the random number context, formed by PetscRandomCreate(), or NULL and 56 it will create one internally. 57 58 Output Parameter: 59 . x - the matrix 60 61 Example of Usage: 62 .vb 63 PetscRandomCreate(PETSC_COMM_WORLD,&rctx); 64 MatSetRandom(x,rctx); 65 PetscRandomDestroy(rctx); 66 .ve 67 68 Level: intermediate 69 70 .seealso: MatZeroEntries(), MatSetValues(), PetscRandomCreate(), PetscRandomDestroy() 71 @*/ 72 PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx) 73 { 74 PetscRandom randObj = NULL; 75 76 PetscFunctionBegin; 77 PetscValidHeaderSpecific(x,MAT_CLASSID,1); 78 if (rctx) PetscValidHeaderSpecific(rctx,PETSC_RANDOM_CLASSID,2); 79 PetscValidType(x,1); 80 MatCheckPreallocated(x,1); 81 82 PetscCheck(x->ops->setrandom,PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Mat type %s",((PetscObject)x)->type_name); 83 84 if (!rctx) { 85 MPI_Comm comm; 86 CHKERRQ(PetscObjectGetComm((PetscObject)x,&comm)); 87 CHKERRQ(PetscRandomCreate(comm,&randObj)); 88 CHKERRQ(PetscRandomSetFromOptions(randObj)); 89 rctx = randObj; 90 } 91 CHKERRQ(PetscLogEventBegin(MAT_SetRandom,x,rctx,0,0)); 92 CHKERRQ((*x->ops->setrandom)(x,rctx)); 93 CHKERRQ(PetscLogEventEnd(MAT_SetRandom,x,rctx,0,0)); 94 95 CHKERRQ(MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY)); 96 CHKERRQ(MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY)); 97 CHKERRQ(PetscRandomDestroy(&randObj)); 98 PetscFunctionReturn(0); 99 } 100 101 /*@ 102 MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in 103 104 Logically Collective on Mat 105 106 Input Parameter: 107 . mat - the factored matrix 108 109 Output Parameters: 110 + pivot - the pivot value computed 111 - row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes 112 the share the matrix 113 114 Level: advanced 115 116 Notes: 117 This routine does not work for factorizations done with external packages. 118 119 This routine should only be called if MatGetFactorError() returns a value of MAT_FACTOR_NUMERIC_ZEROPIVOT 120 121 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 122 123 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatLUFactorSymbolic(), MatCholeskyFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot() 124 @*/ 125 PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row) 126 { 127 PetscFunctionBegin; 128 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 129 PetscValidRealPointer(pivot,2); 130 PetscValidIntPointer(row,3); 131 *pivot = mat->factorerror_zeropivot_value; 132 *row = mat->factorerror_zeropivot_row; 133 PetscFunctionReturn(0); 134 } 135 136 /*@ 137 MatFactorGetError - gets the error code from a factorization 138 139 Logically Collective on Mat 140 141 Input Parameters: 142 . mat - the factored matrix 143 144 Output Parameter: 145 . err - the error code 146 147 Level: advanced 148 149 Notes: 150 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 151 152 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatLUFactorSymbolic(), MatCholeskyFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot() 153 @*/ 154 PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err) 155 { 156 PetscFunctionBegin; 157 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 158 PetscValidPointer(err,2); 159 *err = mat->factorerrortype; 160 PetscFunctionReturn(0); 161 } 162 163 /*@ 164 MatFactorClearError - clears the error code in a factorization 165 166 Logically Collective on Mat 167 168 Input Parameter: 169 . mat - the factored matrix 170 171 Level: developer 172 173 Notes: 174 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 175 176 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatLUFactorSymbolic(), MatCholeskyFactorSymbolic(), MatFactorGetError(), MatFactorGetErrorZeroPivot() 177 @*/ 178 PetscErrorCode MatFactorClearError(Mat mat) 179 { 180 PetscFunctionBegin; 181 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 182 mat->factorerrortype = MAT_FACTOR_NOERROR; 183 mat->factorerror_zeropivot_value = 0.0; 184 mat->factorerror_zeropivot_row = 0; 185 PetscFunctionReturn(0); 186 } 187 188 PETSC_INTERN PetscErrorCode MatFindNonzeroRowsOrCols_Basic(Mat mat,PetscBool cols,PetscReal tol,IS *nonzero) 189 { 190 Vec r,l; 191 const PetscScalar *al; 192 PetscInt i,nz,gnz,N,n; 193 194 PetscFunctionBegin; 195 CHKERRQ(MatCreateVecs(mat,&r,&l)); 196 if (!cols) { /* nonzero rows */ 197 CHKERRQ(MatGetSize(mat,&N,NULL)); 198 CHKERRQ(MatGetLocalSize(mat,&n,NULL)); 199 CHKERRQ(VecSet(l,0.0)); 200 CHKERRQ(VecSetRandom(r,NULL)); 201 CHKERRQ(MatMult(mat,r,l)); 202 CHKERRQ(VecGetArrayRead(l,&al)); 203 } else { /* nonzero columns */ 204 CHKERRQ(MatGetSize(mat,NULL,&N)); 205 CHKERRQ(MatGetLocalSize(mat,NULL,&n)); 206 CHKERRQ(VecSet(r,0.0)); 207 CHKERRQ(VecSetRandom(l,NULL)); 208 CHKERRQ(MatMultTranspose(mat,l,r)); 209 CHKERRQ(VecGetArrayRead(r,&al)); 210 } 211 if (tol <= 0.0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++; } 212 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nz++; } 213 CHKERRMPI(MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat))); 214 if (gnz != N) { 215 PetscInt *nzr; 216 CHKERRQ(PetscMalloc1(nz,&nzr)); 217 if (nz) { 218 if (tol < 0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; } 219 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nzr[nz++] = i; } 220 } 221 CHKERRQ(ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,nonzero)); 222 } else *nonzero = NULL; 223 if (!cols) { /* nonzero rows */ 224 CHKERRQ(VecRestoreArrayRead(l,&al)); 225 } else { 226 CHKERRQ(VecRestoreArrayRead(r,&al)); 227 } 228 CHKERRQ(VecDestroy(&l)); 229 CHKERRQ(VecDestroy(&r)); 230 PetscFunctionReturn(0); 231 } 232 233 /*@ 234 MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix 235 236 Input Parameter: 237 . A - the matrix 238 239 Output Parameter: 240 . keptrows - the rows that are not completely zero 241 242 Notes: 243 keptrows is set to NULL if all rows are nonzero. 244 245 Level: intermediate 246 247 @*/ 248 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows) 249 { 250 PetscFunctionBegin; 251 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 252 PetscValidType(mat,1); 253 PetscValidPointer(keptrows,2); 254 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 255 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 256 if (mat->ops->findnonzerorows) { 257 CHKERRQ((*mat->ops->findnonzerorows)(mat,keptrows)); 258 } else { 259 CHKERRQ(MatFindNonzeroRowsOrCols_Basic(mat,PETSC_FALSE,0.0,keptrows)); 260 } 261 PetscFunctionReturn(0); 262 } 263 264 /*@ 265 MatFindZeroRows - Locate all rows that are completely zero in the matrix 266 267 Input Parameter: 268 . A - the matrix 269 270 Output Parameter: 271 . zerorows - the rows that are completely zero 272 273 Notes: 274 zerorows is set to NULL if no rows are zero. 275 276 Level: intermediate 277 278 @*/ 279 PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows) 280 { 281 IS keptrows; 282 PetscInt m, n; 283 284 PetscFunctionBegin; 285 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 286 PetscValidType(mat,1); 287 PetscValidPointer(zerorows,2); 288 CHKERRQ(MatFindNonzeroRows(mat, &keptrows)); 289 /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows. 290 In keeping with this convention, we set zerorows to NULL if there are no zero 291 rows. */ 292 if (keptrows == NULL) { 293 *zerorows = NULL; 294 } else { 295 CHKERRQ(MatGetOwnershipRange(mat,&m,&n)); 296 CHKERRQ(ISComplement(keptrows,m,n,zerorows)); 297 CHKERRQ(ISDestroy(&keptrows)); 298 } 299 PetscFunctionReturn(0); 300 } 301 302 /*@ 303 MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling 304 305 Not Collective 306 307 Input Parameters: 308 . A - the matrix 309 310 Output Parameters: 311 . a - the diagonal part (which is a SEQUENTIAL matrix) 312 313 Notes: 314 see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix. 315 Use caution, as the reference count on the returned matrix is not incremented and it is used as 316 part of the containing MPI Mat's normal operation. 317 318 Level: advanced 319 320 @*/ 321 PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a) 322 { 323 PetscFunctionBegin; 324 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 325 PetscValidType(A,1); 326 PetscValidPointer(a,2); 327 PetscCheck(!A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 328 if (A->ops->getdiagonalblock) { 329 CHKERRQ((*A->ops->getdiagonalblock)(A,a)); 330 } else { 331 PetscMPIInt size; 332 333 CHKERRMPI(MPI_Comm_size(PetscObjectComm((PetscObject)A),&size)); 334 PetscCheck(size == 1,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not for parallel matrix type %s",((PetscObject)A)->type_name); 335 *a = A; 336 } 337 PetscFunctionReturn(0); 338 } 339 340 /*@ 341 MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries. 342 343 Collective on Mat 344 345 Input Parameters: 346 . mat - the matrix 347 348 Output Parameter: 349 . trace - the sum of the diagonal entries 350 351 Level: advanced 352 353 @*/ 354 PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace) 355 { 356 Vec diag; 357 358 PetscFunctionBegin; 359 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 360 PetscValidScalarPointer(trace,2); 361 CHKERRQ(MatCreateVecs(mat,&diag,NULL)); 362 CHKERRQ(MatGetDiagonal(mat,diag)); 363 CHKERRQ(VecSum(diag,trace)); 364 CHKERRQ(VecDestroy(&diag)); 365 PetscFunctionReturn(0); 366 } 367 368 /*@ 369 MatRealPart - Zeros out the imaginary part of the matrix 370 371 Logically Collective on Mat 372 373 Input Parameters: 374 . mat - the matrix 375 376 Level: advanced 377 378 .seealso: MatImaginaryPart() 379 @*/ 380 PetscErrorCode MatRealPart(Mat mat) 381 { 382 PetscFunctionBegin; 383 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 384 PetscValidType(mat,1); 385 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 386 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 387 PetscCheck(mat->ops->realpart,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 388 MatCheckPreallocated(mat,1); 389 CHKERRQ((*mat->ops->realpart)(mat)); 390 PetscFunctionReturn(0); 391 } 392 393 /*@C 394 MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix 395 396 Collective on Mat 397 398 Input Parameter: 399 . mat - the matrix 400 401 Output Parameters: 402 + nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block) 403 - ghosts - the global indices of the ghost points 404 405 Notes: 406 the nghosts and ghosts are suitable to pass into VecCreateGhost() 407 408 Level: advanced 409 410 @*/ 411 PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[]) 412 { 413 PetscFunctionBegin; 414 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 415 PetscValidType(mat,1); 416 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 417 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 418 if (mat->ops->getghosts) { 419 CHKERRQ((*mat->ops->getghosts)(mat,nghosts,ghosts)); 420 } else { 421 if (nghosts) *nghosts = 0; 422 if (ghosts) *ghosts = NULL; 423 } 424 PetscFunctionReturn(0); 425 } 426 427 /*@ 428 MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part 429 430 Logically Collective on Mat 431 432 Input Parameters: 433 . mat - the matrix 434 435 Level: advanced 436 437 .seealso: MatRealPart() 438 @*/ 439 PetscErrorCode MatImaginaryPart(Mat mat) 440 { 441 PetscFunctionBegin; 442 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 443 PetscValidType(mat,1); 444 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 445 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 446 PetscCheck(mat->ops->imaginarypart,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 447 MatCheckPreallocated(mat,1); 448 CHKERRQ((*mat->ops->imaginarypart)(mat)); 449 PetscFunctionReturn(0); 450 } 451 452 /*@ 453 MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices) 454 455 Not Collective 456 457 Input Parameter: 458 . mat - the matrix 459 460 Output Parameters: 461 + missing - is any diagonal missing 462 - dd - first diagonal entry that is missing (optional) on this process 463 464 Level: advanced 465 466 .seealso: MatRealPart() 467 @*/ 468 PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd) 469 { 470 PetscFunctionBegin; 471 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 472 PetscValidType(mat,1); 473 PetscValidBoolPointer(missing,2); 474 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix %s",((PetscObject)mat)->type_name); 475 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 476 PetscCheck(mat->ops->missingdiagonal,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 477 CHKERRQ((*mat->ops->missingdiagonal)(mat,missing,dd)); 478 PetscFunctionReturn(0); 479 } 480 481 /*@C 482 MatGetRow - Gets a row of a matrix. You MUST call MatRestoreRow() 483 for each row that you get to ensure that your application does 484 not bleed memory. 485 486 Not Collective 487 488 Input Parameters: 489 + mat - the matrix 490 - row - the row to get 491 492 Output Parameters: 493 + ncols - if not NULL, the number of nonzeros in the row 494 . cols - if not NULL, the column numbers 495 - vals - if not NULL, the values 496 497 Notes: 498 This routine is provided for people who need to have direct access 499 to the structure of a matrix. We hope that we provide enough 500 high-level matrix routines that few users will need it. 501 502 MatGetRow() always returns 0-based column indices, regardless of 503 whether the internal representation is 0-based (default) or 1-based. 504 505 For better efficiency, set cols and/or vals to NULL if you do 506 not wish to extract these quantities. 507 508 The user can only examine the values extracted with MatGetRow(); 509 the values cannot be altered. To change the matrix entries, one 510 must use MatSetValues(). 511 512 You can only have one call to MatGetRow() outstanding for a particular 513 matrix at a time, per processor. MatGetRow() can only obtain rows 514 associated with the given processor, it cannot get rows from the 515 other processors; for that we suggest using MatCreateSubMatrices(), then 516 MatGetRow() on the submatrix. The row index passed to MatGetRow() 517 is in the global number of rows. 518 519 Fortran Notes: 520 The calling sequence from Fortran is 521 .vb 522 MatGetRow(matrix,row,ncols,cols,values,ierr) 523 Mat matrix (input) 524 integer row (input) 525 integer ncols (output) 526 integer cols(maxcols) (output) 527 double precision (or double complex) values(maxcols) output 528 .ve 529 where maxcols >= maximum nonzeros in any row of the matrix. 530 531 Caution: 532 Do not try to change the contents of the output arrays (cols and vals). 533 In some cases, this may corrupt the matrix. 534 535 Level: advanced 536 537 .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatCreateSubMatrices(), MatGetDiagonal() 538 @*/ 539 PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 540 { 541 PetscInt incols; 542 543 PetscFunctionBegin; 544 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 545 PetscValidType(mat,1); 546 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 547 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 548 PetscCheck(mat->ops->getrow,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 549 MatCheckPreallocated(mat,1); 550 PetscCheckFalse(row < mat->rmap->rstart || row >= mat->rmap->rend,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Only for local rows, %" PetscInt_FMT " not in [%" PetscInt_FMT ",%" PetscInt_FMT ")",row,mat->rmap->rstart,mat->rmap->rend); 551 CHKERRQ(PetscLogEventBegin(MAT_GetRow,mat,0,0,0)); 552 CHKERRQ((*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals)); 553 if (ncols) *ncols = incols; 554 CHKERRQ(PetscLogEventEnd(MAT_GetRow,mat,0,0,0)); 555 PetscFunctionReturn(0); 556 } 557 558 /*@ 559 MatConjugate - replaces the matrix values with their complex conjugates 560 561 Logically Collective on Mat 562 563 Input Parameters: 564 . mat - the matrix 565 566 Level: advanced 567 568 .seealso: VecConjugate() 569 @*/ 570 PetscErrorCode MatConjugate(Mat mat) 571 { 572 PetscFunctionBegin; 573 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 574 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 575 if (PetscDefined(USE_COMPLEX)) { 576 PetscCheck(mat->ops->conjugate,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not provided for matrix type %s, send email to petsc-maint@mcs.anl.gov",((PetscObject)mat)->type_name); 577 CHKERRQ((*mat->ops->conjugate)(mat)); 578 } 579 PetscFunctionReturn(0); 580 } 581 582 /*@C 583 MatRestoreRow - Frees any temporary space allocated by MatGetRow(). 584 585 Not Collective 586 587 Input Parameters: 588 + mat - the matrix 589 . row - the row to get 590 . ncols, cols - the number of nonzeros and their columns 591 - vals - if nonzero the column values 592 593 Notes: 594 This routine should be called after you have finished examining the entries. 595 596 This routine zeros out ncols, cols, and vals. This is to prevent accidental 597 us of the array after it has been restored. If you pass NULL, it will 598 not zero the pointers. Use of cols or vals after MatRestoreRow is invalid. 599 600 Fortran Notes: 601 The calling sequence from Fortran is 602 .vb 603 MatRestoreRow(matrix,row,ncols,cols,values,ierr) 604 Mat matrix (input) 605 integer row (input) 606 integer ncols (output) 607 integer cols(maxcols) (output) 608 double precision (or double complex) values(maxcols) output 609 .ve 610 Where maxcols >= maximum nonzeros in any row of the matrix. 611 612 In Fortran MatRestoreRow() MUST be called after MatGetRow() 613 before another call to MatGetRow() can be made. 614 615 Level: advanced 616 617 .seealso: MatGetRow() 618 @*/ 619 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 620 { 621 PetscFunctionBegin; 622 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 623 if (ncols) PetscValidIntPointer(ncols,3); 624 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 625 if (!mat->ops->restorerow) PetscFunctionReturn(0); 626 CHKERRQ((*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals)); 627 if (ncols) *ncols = 0; 628 if (cols) *cols = NULL; 629 if (vals) *vals = NULL; 630 PetscFunctionReturn(0); 631 } 632 633 /*@ 634 MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format. 635 You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag. 636 637 Not Collective 638 639 Input Parameters: 640 . mat - the matrix 641 642 Notes: 643 The flag is to ensure that users are aware of MatGetRow() only provides the upper triangular part of the row for the matrices in MATSBAIJ format. 644 645 Level: advanced 646 647 .seealso: MatRestoreRowUpperTriangular() 648 @*/ 649 PetscErrorCode MatGetRowUpperTriangular(Mat mat) 650 { 651 PetscFunctionBegin; 652 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 653 PetscValidType(mat,1); 654 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 655 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 656 MatCheckPreallocated(mat,1); 657 if (!mat->ops->getrowuppertriangular) PetscFunctionReturn(0); 658 CHKERRQ((*mat->ops->getrowuppertriangular)(mat)); 659 PetscFunctionReturn(0); 660 } 661 662 /*@ 663 MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format. 664 665 Not Collective 666 667 Input Parameters: 668 . mat - the matrix 669 670 Notes: 671 This routine should be called after you have finished MatGetRow/MatRestoreRow(). 672 673 Level: advanced 674 675 .seealso: MatGetRowUpperTriangular() 676 @*/ 677 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat) 678 { 679 PetscFunctionBegin; 680 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 681 PetscValidType(mat,1); 682 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 683 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 684 MatCheckPreallocated(mat,1); 685 if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0); 686 CHKERRQ((*mat->ops->restorerowuppertriangular)(mat)); 687 PetscFunctionReturn(0); 688 } 689 690 /*@C 691 MatSetOptionsPrefix - Sets the prefix used for searching for all 692 Mat options in the database. 693 694 Logically Collective on Mat 695 696 Input Parameters: 697 + A - the Mat context 698 - prefix - the prefix to prepend to all option names 699 700 Notes: 701 A hyphen (-) must NOT be given at the beginning of the prefix name. 702 The first character of all runtime options is AUTOMATICALLY the hyphen. 703 704 Level: advanced 705 706 .seealso: MatSetFromOptions() 707 @*/ 708 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[]) 709 { 710 PetscFunctionBegin; 711 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 712 CHKERRQ(PetscObjectSetOptionsPrefix((PetscObject)A,prefix)); 713 PetscFunctionReturn(0); 714 } 715 716 /*@C 717 MatAppendOptionsPrefix - Appends to the prefix used for searching for all 718 Mat options in the database. 719 720 Logically Collective on Mat 721 722 Input Parameters: 723 + A - the Mat context 724 - prefix - the prefix to prepend to all option names 725 726 Notes: 727 A hyphen (-) must NOT be given at the beginning of the prefix name. 728 The first character of all runtime options is AUTOMATICALLY the hyphen. 729 730 Level: advanced 731 732 .seealso: MatGetOptionsPrefix() 733 @*/ 734 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[]) 735 { 736 PetscFunctionBegin; 737 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 738 CHKERRQ(PetscObjectAppendOptionsPrefix((PetscObject)A,prefix)); 739 PetscFunctionReturn(0); 740 } 741 742 /*@C 743 MatGetOptionsPrefix - Gets the prefix used for searching for all 744 Mat options in the database. 745 746 Not Collective 747 748 Input Parameter: 749 . A - the Mat context 750 751 Output Parameter: 752 . prefix - pointer to the prefix string used 753 754 Notes: 755 On the fortran side, the user should pass in a string 'prefix' of 756 sufficient length to hold the prefix. 757 758 Level: advanced 759 760 .seealso: MatAppendOptionsPrefix() 761 @*/ 762 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[]) 763 { 764 PetscFunctionBegin; 765 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 766 PetscValidPointer(prefix,2); 767 CHKERRQ(PetscObjectGetOptionsPrefix((PetscObject)A,prefix)); 768 PetscFunctionReturn(0); 769 } 770 771 /*@ 772 MatResetPreallocation - Reset mat to use the original nonzero pattern provided by users. 773 774 Collective on Mat 775 776 Input Parameters: 777 . A - the Mat context 778 779 Notes: 780 The allocated memory will be shrunk after calling MatAssembly with MAT_FINAL_ASSEMBLY. Users can reset the preallocation to access the original memory. 781 Currently support MPIAIJ and SEQAIJ. 782 783 Level: beginner 784 785 .seealso: MatSeqAIJSetPreallocation(), MatMPIAIJSetPreallocation(), MatXAIJSetPreallocation() 786 @*/ 787 PetscErrorCode MatResetPreallocation(Mat A) 788 { 789 PetscFunctionBegin; 790 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 791 PetscValidType(A,1); 792 CHKERRQ(PetscUseMethod(A,"MatResetPreallocation_C",(Mat),(A))); 793 PetscFunctionReturn(0); 794 } 795 796 /*@ 797 MatSetUp - Sets up the internal matrix data structures for later use. 798 799 Collective on Mat 800 801 Input Parameters: 802 . A - the Mat context 803 804 Notes: 805 If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used. 806 807 If a suitable preallocation routine is used, this function does not need to be called. 808 809 See the Performance chapter of the PETSc users manual for how to preallocate matrices 810 811 Level: beginner 812 813 .seealso: MatCreate(), MatDestroy() 814 @*/ 815 PetscErrorCode MatSetUp(Mat A) 816 { 817 PetscFunctionBegin; 818 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 819 if (!((PetscObject)A)->type_name) { 820 PetscMPIInt size; 821 822 CHKERRMPI(MPI_Comm_size(PetscObjectComm((PetscObject)A), &size)); 823 CHKERRQ(MatSetType(A, size == 1 ? MATSEQAIJ : MATMPIAIJ)); 824 } 825 if (!A->preallocated && A->ops->setup) { 826 CHKERRQ(PetscInfo(A,"Warning not preallocating matrix storage\n")); 827 CHKERRQ((*A->ops->setup)(A)); 828 } 829 CHKERRQ(PetscLayoutSetUp(A->rmap)); 830 CHKERRQ(PetscLayoutSetUp(A->cmap)); 831 A->preallocated = PETSC_TRUE; 832 PetscFunctionReturn(0); 833 } 834 835 #if defined(PETSC_HAVE_SAWS) 836 #include <petscviewersaws.h> 837 #endif 838 839 /*@C 840 MatViewFromOptions - View from Options 841 842 Collective on Mat 843 844 Input Parameters: 845 + A - the Mat context 846 . obj - Optional object 847 - name - command line option 848 849 Level: intermediate 850 .seealso: Mat, MatView, PetscObjectViewFromOptions(), MatCreate() 851 @*/ 852 PetscErrorCode MatViewFromOptions(Mat A,PetscObject obj,const char name[]) 853 { 854 PetscFunctionBegin; 855 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 856 CHKERRQ(PetscObjectViewFromOptions((PetscObject)A,obj,name)); 857 PetscFunctionReturn(0); 858 } 859 860 /*@C 861 MatView - Visualizes a matrix object. 862 863 Collective on Mat 864 865 Input Parameters: 866 + mat - the matrix 867 - viewer - visualization context 868 869 Notes: 870 The available visualization contexts include 871 + PETSC_VIEWER_STDOUT_SELF - for sequential matrices 872 . PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD 873 . PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm 874 - PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure 875 876 The user can open alternative visualization contexts with 877 + PetscViewerASCIIOpen() - Outputs matrix to a specified file 878 . PetscViewerBinaryOpen() - Outputs matrix in binary to a 879 specified file; corresponding input uses MatLoad() 880 . PetscViewerDrawOpen() - Outputs nonzero matrix structure to 881 an X window display 882 - PetscViewerSocketOpen() - Outputs matrix to Socket viewer. 883 Currently only the sequential dense and AIJ 884 matrix types support the Socket viewer. 885 886 The user can call PetscViewerPushFormat() to specify the output 887 format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF, 888 PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen). Available formats include 889 + PETSC_VIEWER_DEFAULT - default, prints matrix contents 890 . PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format 891 . PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros 892 . PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse 893 format common among all matrix types 894 . PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific 895 format (which is in many cases the same as the default) 896 . PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix 897 size and structure (not the matrix entries) 898 - PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about 899 the matrix structure 900 901 Options Database Keys: 902 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatAssemblyEnd() 903 . -mat_view ::ascii_info_detail - Prints more detailed info 904 . -mat_view - Prints matrix in ASCII format 905 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 906 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 907 . -display <name> - Sets display name (default is host) 908 . -draw_pause <sec> - Sets number of seconds to pause after display 909 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details) 910 . -viewer_socket_machine <machine> - 911 . -viewer_socket_port <port> - 912 . -mat_view binary - save matrix to file in binary format 913 - -viewer_binary_filename <name> - 914 915 Level: beginner 916 917 Notes: 918 The ASCII viewers are only recommended for small matrices on at most a moderate number of processes, 919 the program will seemingly hang and take hours for larger matrices, for larger matrices one should use the binary format. 920 921 In the debugger you can do "call MatView(mat,0)" to display the matrix. (The same holds for any PETSc object viewer). 922 923 See the manual page for MatLoad() for the exact format of the binary file when the binary 924 viewer is used. 925 926 See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary 927 viewer is used and lib/petsc/bin/PetscBinaryIO.py for loading them into Python. 928 929 One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure, 930 and then use the following mouse functions. 931 .vb 932 left mouse: zoom in 933 middle mouse: zoom out 934 right mouse: continue with the simulation 935 .ve 936 937 .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(), 938 PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad() 939 @*/ 940 PetscErrorCode MatView(Mat mat,PetscViewer viewer) 941 { 942 PetscInt rows,cols,rbs,cbs; 943 PetscBool isascii,isstring,issaws; 944 PetscViewerFormat format; 945 PetscMPIInt size; 946 947 PetscFunctionBegin; 948 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 949 PetscValidType(mat,1); 950 if (!viewer) CHKERRQ(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer)); 951 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 952 PetscCheckSameComm(mat,1,viewer,2); 953 MatCheckPreallocated(mat,1); 954 955 CHKERRQ(PetscViewerGetFormat(viewer,&format)); 956 CHKERRMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 957 if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0); 958 959 CHKERRQ(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring)); 960 CHKERRQ(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii)); 961 CHKERRQ(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws)); 962 if ((!isascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) { 963 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detail"); 964 } 965 966 CHKERRQ(PetscLogEventBegin(MAT_View,mat,viewer,0,0)); 967 if (isascii) { 968 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix"); 969 CHKERRQ(PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer)); 970 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 971 MatNullSpace nullsp,transnullsp; 972 973 CHKERRQ(PetscViewerASCIIPushTab(viewer)); 974 CHKERRQ(MatGetSize(mat,&rows,&cols)); 975 CHKERRQ(MatGetBlockSizes(mat,&rbs,&cbs)); 976 if (rbs != 1 || cbs != 1) { 977 if (rbs != cbs) CHKERRQ(PetscViewerASCIIPrintf(viewer,"rows=%" PetscInt_FMT ", cols=%" PetscInt_FMT ", rbs=%" PetscInt_FMT ", cbs=%" PetscInt_FMT "\n",rows,cols,rbs,cbs)); 978 else CHKERRQ(PetscViewerASCIIPrintf(viewer,"rows=%" PetscInt_FMT ", cols=%" PetscInt_FMT ", bs=%" PetscInt_FMT "\n",rows,cols,rbs)); 979 } else CHKERRQ(PetscViewerASCIIPrintf(viewer,"rows=%" PetscInt_FMT ", cols=%" PetscInt_FMT "\n",rows,cols)); 980 if (mat->factortype) { 981 MatSolverType solver; 982 CHKERRQ(MatFactorGetSolverType(mat,&solver)); 983 CHKERRQ(PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver)); 984 } 985 if (mat->ops->getinfo) { 986 MatInfo info; 987 CHKERRQ(MatGetInfo(mat,MAT_GLOBAL_SUM,&info)); 988 CHKERRQ(PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated)); 989 if (!mat->factortype) CHKERRQ(PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls=%" PetscInt_FMT "\n",(PetscInt)info.mallocs)); 990 } 991 CHKERRQ(MatGetNullSpace(mat,&nullsp)); 992 CHKERRQ(MatGetTransposeNullSpace(mat,&transnullsp)); 993 if (nullsp) CHKERRQ(PetscViewerASCIIPrintf(viewer," has attached null space\n")); 994 if (transnullsp && transnullsp != nullsp) CHKERRQ(PetscViewerASCIIPrintf(viewer," has attached transposed null space\n")); 995 CHKERRQ(MatGetNearNullSpace(mat,&nullsp)); 996 if (nullsp) CHKERRQ(PetscViewerASCIIPrintf(viewer," has attached near null space\n")); 997 CHKERRQ(PetscViewerASCIIPushTab(viewer)); 998 CHKERRQ(MatProductView(mat,viewer)); 999 CHKERRQ(PetscViewerASCIIPopTab(viewer)); 1000 } 1001 } else if (issaws) { 1002 #if defined(PETSC_HAVE_SAWS) 1003 PetscMPIInt rank; 1004 1005 CHKERRQ(PetscObjectName((PetscObject)mat)); 1006 CHKERRMPI(MPI_Comm_rank(PETSC_COMM_WORLD,&rank)); 1007 if (!((PetscObject)mat)->amsmem && rank == 0) { 1008 CHKERRQ(PetscObjectViewSAWs((PetscObject)mat,viewer)); 1009 } 1010 #endif 1011 } else if (isstring) { 1012 const char *type; 1013 CHKERRQ(MatGetType(mat,&type)); 1014 CHKERRQ(PetscViewerStringSPrintf(viewer," MatType: %-7.7s",type)); 1015 if (mat->ops->view) CHKERRQ((*mat->ops->view)(mat,viewer)); 1016 } 1017 if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) { 1018 CHKERRQ(PetscViewerASCIIPushTab(viewer)); 1019 CHKERRQ((*mat->ops->viewnative)(mat,viewer)); 1020 CHKERRQ(PetscViewerASCIIPopTab(viewer)); 1021 } else if (mat->ops->view) { 1022 CHKERRQ(PetscViewerASCIIPushTab(viewer)); 1023 CHKERRQ((*mat->ops->view)(mat,viewer)); 1024 CHKERRQ(PetscViewerASCIIPopTab(viewer)); 1025 } 1026 if (isascii) { 1027 CHKERRQ(PetscViewerGetFormat(viewer,&format)); 1028 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1029 CHKERRQ(PetscViewerASCIIPopTab(viewer)); 1030 } 1031 } 1032 CHKERRQ(PetscLogEventEnd(MAT_View,mat,viewer,0,0)); 1033 PetscFunctionReturn(0); 1034 } 1035 1036 #if defined(PETSC_USE_DEBUG) 1037 #include <../src/sys/totalview/tv_data_display.h> 1038 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat) 1039 { 1040 TV_add_row("Local rows", "int", &mat->rmap->n); 1041 TV_add_row("Local columns", "int", &mat->cmap->n); 1042 TV_add_row("Global rows", "int", &mat->rmap->N); 1043 TV_add_row("Global columns", "int", &mat->cmap->N); 1044 TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name); 1045 return TV_format_OK; 1046 } 1047 #endif 1048 1049 /*@C 1050 MatLoad - Loads a matrix that has been stored in binary/HDF5 format 1051 with MatView(). The matrix format is determined from the options database. 1052 Generates a parallel MPI matrix if the communicator has more than one 1053 processor. The default matrix type is AIJ. 1054 1055 Collective on PetscViewer 1056 1057 Input Parameters: 1058 + mat - the newly loaded matrix, this needs to have been created with MatCreate() 1059 or some related function before a call to MatLoad() 1060 - viewer - binary/HDF5 file viewer 1061 1062 Options Database Keys: 1063 Used with block matrix formats (MATSEQBAIJ, ...) to specify 1064 block size 1065 . -matload_block_size <bs> - set block size 1066 1067 Level: beginner 1068 1069 Notes: 1070 If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the 1071 Mat before calling this routine if you wish to set it from the options database. 1072 1073 MatLoad() automatically loads into the options database any options 1074 given in the file filename.info where filename is the name of the file 1075 that was passed to the PetscViewerBinaryOpen(). The options in the info 1076 file will be ignored if you use the -viewer_binary_skip_info option. 1077 1078 If the type or size of mat is not set before a call to MatLoad, PETSc 1079 sets the default matrix type AIJ and sets the local and global sizes. 1080 If type and/or size is already set, then the same are used. 1081 1082 In parallel, each processor can load a subset of rows (or the 1083 entire matrix). This routine is especially useful when a large 1084 matrix is stored on disk and only part of it is desired on each 1085 processor. For example, a parallel solver may access only some of 1086 the rows from each processor. The algorithm used here reads 1087 relatively small blocks of data rather than reading the entire 1088 matrix and then subsetting it. 1089 1090 Viewer's PetscViewerType must be either PETSCVIEWERBINARY or PETSCVIEWERHDF5. 1091 Such viewer can be created using PetscViewerBinaryOpen()/PetscViewerHDF5Open(), 1092 or the sequence like 1093 $ PetscViewer v; 1094 $ PetscViewerCreate(PETSC_COMM_WORLD,&v); 1095 $ PetscViewerSetType(v,PETSCVIEWERBINARY); 1096 $ PetscViewerSetFromOptions(v); 1097 $ PetscViewerFileSetMode(v,FILE_MODE_READ); 1098 $ PetscViewerFileSetName(v,"datafile"); 1099 The optional PetscViewerSetFromOptions() call allows to override PetscViewerSetType() using option 1100 $ -viewer_type {binary,hdf5} 1101 1102 See the example src/ksp/ksp/tutorials/ex27.c with the first approach, 1103 and src/mat/tutorials/ex10.c with the second approach. 1104 1105 Notes about the PETSc binary format: 1106 In case of PETSCVIEWERBINARY, a native PETSc binary format is used. Each of the blocks 1107 is read onto rank 0 and then shipped to its destination rank, one after another. 1108 Multiple objects, both matrices and vectors, can be stored within the same file. 1109 Their PetscObject name is ignored; they are loaded in the order of their storage. 1110 1111 Most users should not need to know the details of the binary storage 1112 format, since MatLoad() and MatView() completely hide these details. 1113 But for anyone who's interested, the standard binary matrix storage 1114 format is 1115 1116 $ PetscInt MAT_FILE_CLASSID 1117 $ PetscInt number of rows 1118 $ PetscInt number of columns 1119 $ PetscInt total number of nonzeros 1120 $ PetscInt *number nonzeros in each row 1121 $ PetscInt *column indices of all nonzeros (starting index is zero) 1122 $ PetscScalar *values of all nonzeros 1123 1124 PETSc automatically does the byte swapping for 1125 machines that store the bytes reversed, e.g. DEC alpha, freebsd, 1126 Linux, Microsoft Windows and the Intel Paragon; thus if you write your own binary 1127 read/write routines you have to swap the bytes; see PetscBinaryRead() 1128 and PetscBinaryWrite() to see how this may be done. 1129 1130 Notes about the HDF5 (MATLAB MAT-File Version 7.3) format: 1131 In case of PETSCVIEWERHDF5, a parallel HDF5 reader is used. 1132 Each processor's chunk is loaded independently by its owning rank. 1133 Multiple objects, both matrices and vectors, can be stored within the same file. 1134 They are looked up by their PetscObject name. 1135 1136 As the MATLAB MAT-File Version 7.3 format is also a HDF5 flavor, we decided to use 1137 by default the same structure and naming of the AIJ arrays and column count 1138 within the HDF5 file. This means that a MAT file saved with -v7.3 flag, e.g. 1139 $ save example.mat A b -v7.3 1140 can be directly read by this routine (see Reference 1 for details). 1141 Note that depending on your MATLAB version, this format might be a default, 1142 otherwise you can set it as default in Preferences. 1143 1144 Unless -nocompression flag is used to save the file in MATLAB, 1145 PETSc must be configured with ZLIB package. 1146 1147 See also examples src/mat/tutorials/ex10.c and src/ksp/ksp/tutorials/ex27.c 1148 1149 Current HDF5 (MAT-File) limitations: 1150 This reader currently supports only real MATSEQAIJ, MATMPIAIJ, MATSEQDENSE and MATMPIDENSE matrices. 1151 1152 Corresponding MatView() is not yet implemented. 1153 1154 The loaded matrix is actually a transpose of the original one in MATLAB, 1155 unless you push PETSC_VIEWER_HDF5_MAT format (see examples above). 1156 With this format, matrix is automatically transposed by PETSc, 1157 unless the matrix is marked as SPD or symmetric 1158 (see MatSetOption(), MAT_SPD, MAT_SYMMETRIC). 1159 1160 References: 1161 . * - MATLAB(R) Documentation, manual page of save(), https://www.mathworks.com/help/matlab/ref/save.html#btox10b-1-version 1162 1163 .seealso: PetscViewerBinaryOpen(), PetscViewerSetType(), MatView(), VecLoad() 1164 1165 @*/ 1166 PetscErrorCode MatLoad(Mat mat,PetscViewer viewer) 1167 { 1168 PetscBool flg; 1169 1170 PetscFunctionBegin; 1171 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1172 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1173 1174 if (!((PetscObject)mat)->type_name) CHKERRQ(MatSetType(mat,MATAIJ)); 1175 1176 flg = PETSC_FALSE; 1177 CHKERRQ(PetscOptionsGetBool(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matload_symmetric",&flg,NULL)); 1178 if (flg) { 1179 CHKERRQ(MatSetOption(mat,MAT_SYMMETRIC,PETSC_TRUE)); 1180 CHKERRQ(MatSetOption(mat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE)); 1181 } 1182 flg = PETSC_FALSE; 1183 CHKERRQ(PetscOptionsGetBool(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matload_spd",&flg,NULL)); 1184 if (flg) CHKERRQ(MatSetOption(mat,MAT_SPD,PETSC_TRUE)); 1185 1186 PetscCheck(mat->ops->load,PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type %s",((PetscObject)mat)->type_name); 1187 CHKERRQ(PetscLogEventBegin(MAT_Load,mat,viewer,0,0)); 1188 CHKERRQ((*mat->ops->load)(mat,viewer)); 1189 CHKERRQ(PetscLogEventEnd(MAT_Load,mat,viewer,0,0)); 1190 PetscFunctionReturn(0); 1191 } 1192 1193 static PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant) 1194 { 1195 Mat_Redundant *redund = *redundant; 1196 1197 PetscFunctionBegin; 1198 if (redund) { 1199 if (redund->matseq) { /* via MatCreateSubMatrices() */ 1200 CHKERRQ(ISDestroy(&redund->isrow)); 1201 CHKERRQ(ISDestroy(&redund->iscol)); 1202 CHKERRQ(MatDestroySubMatrices(1,&redund->matseq)); 1203 } else { 1204 CHKERRQ(PetscFree2(redund->send_rank,redund->recv_rank)); 1205 CHKERRQ(PetscFree(redund->sbuf_j)); 1206 CHKERRQ(PetscFree(redund->sbuf_a)); 1207 for (PetscInt i=0; i<redund->nrecvs; i++) { 1208 CHKERRQ(PetscFree(redund->rbuf_j[i])); 1209 CHKERRQ(PetscFree(redund->rbuf_a[i])); 1210 } 1211 CHKERRQ(PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a)); 1212 } 1213 1214 if (redund->subcomm) CHKERRQ(PetscCommDestroy(&redund->subcomm)); 1215 CHKERRQ(PetscFree(redund)); 1216 } 1217 PetscFunctionReturn(0); 1218 } 1219 1220 /*@C 1221 MatDestroy - Frees space taken by a matrix. 1222 1223 Collective on Mat 1224 1225 Input Parameter: 1226 . A - the matrix 1227 1228 Level: beginner 1229 1230 @*/ 1231 PetscErrorCode MatDestroy(Mat *A) 1232 { 1233 PetscFunctionBegin; 1234 if (!*A) PetscFunctionReturn(0); 1235 PetscValidHeaderSpecific(*A,MAT_CLASSID,1); 1236 if (--((PetscObject)(*A))->refct > 0) {*A = NULL; PetscFunctionReturn(0);} 1237 1238 /* if memory was published with SAWs then destroy it */ 1239 CHKERRQ(PetscObjectSAWsViewOff((PetscObject)*A)); 1240 if ((*A)->ops->destroy) CHKERRQ((*(*A)->ops->destroy)(*A)); 1241 1242 CHKERRQ(PetscFree((*A)->defaultvectype)); 1243 CHKERRQ(PetscFree((*A)->bsizes)); 1244 CHKERRQ(PetscFree((*A)->solvertype)); 1245 for (PetscInt i=0; i<MAT_FACTOR_NUM_TYPES; i++) CHKERRQ(PetscFree((*A)->preferredordering[i])); 1246 CHKERRQ(MatDestroy_Redundant(&(*A)->redundant)); 1247 CHKERRQ(MatProductClear(*A)); 1248 CHKERRQ(MatNullSpaceDestroy(&(*A)->nullsp)); 1249 CHKERRQ(MatNullSpaceDestroy(&(*A)->transnullsp)); 1250 CHKERRQ(MatNullSpaceDestroy(&(*A)->nearnullsp)); 1251 CHKERRQ(MatDestroy(&(*A)->schur)); 1252 CHKERRQ(PetscLayoutDestroy(&(*A)->rmap)); 1253 CHKERRQ(PetscLayoutDestroy(&(*A)->cmap)); 1254 CHKERRQ(PetscHeaderDestroy(A)); 1255 PetscFunctionReturn(0); 1256 } 1257 1258 /*@C 1259 MatSetValues - Inserts or adds a block of values into a matrix. 1260 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 1261 MUST be called after all calls to MatSetValues() have been completed. 1262 1263 Not Collective 1264 1265 Input Parameters: 1266 + mat - the matrix 1267 . v - a logically two-dimensional array of values 1268 . m, idxm - the number of rows and their global indices 1269 . n, idxn - the number of columns and their global indices 1270 - addv - either ADD_VALUES or INSERT_VALUES, where 1271 ADD_VALUES adds values to any existing entries, and 1272 INSERT_VALUES replaces existing entries with new values 1273 1274 Notes: 1275 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 1276 MatSetUp() before using this routine 1277 1278 By default the values, v, are row-oriented. See MatSetOption() for other options. 1279 1280 Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES 1281 options cannot be mixed without intervening calls to the assembly 1282 routines. 1283 1284 MatSetValues() uses 0-based row and column numbers in Fortran 1285 as well as in C. 1286 1287 Negative indices may be passed in idxm and idxn, these rows and columns are 1288 simply ignored. This allows easily inserting element stiffness matrices 1289 with homogeneous Dirchlet boundary conditions that you don't want represented 1290 in the matrix. 1291 1292 Efficiency Alert: 1293 The routine MatSetValuesBlocked() may offer much better efficiency 1294 for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ). 1295 1296 Level: beginner 1297 1298 Developer Notes: 1299 This is labeled with C so does not automatically generate Fortran stubs and interfaces 1300 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 1301 1302 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1303 InsertMode, INSERT_VALUES, ADD_VALUES 1304 @*/ 1305 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1306 { 1307 PetscFunctionBeginHot; 1308 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1309 PetscValidType(mat,1); 1310 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1311 PetscValidIntPointer(idxm,3); 1312 PetscValidIntPointer(idxn,5); 1313 MatCheckPreallocated(mat,1); 1314 1315 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 1316 else PetscCheck(mat->insertmode == addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1317 1318 if (PetscDefined(USE_DEBUG)) { 1319 PetscInt i,j; 1320 1321 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1322 PetscCheck(mat->ops->setvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1323 1324 for (i=0; i<m; i++) { 1325 for (j=0; j<n; j++) { 1326 if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j])) 1327 #if defined(PETSC_USE_COMPLEX) 1328 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g+i%g at matrix entry (%" PetscInt_FMT ",%" PetscInt_FMT ")",(double)PetscRealPart(v[i*n+j]),(double)PetscImaginaryPart(v[i*n+j]),idxm[i],idxn[j]); 1329 #else 1330 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%" PetscInt_FMT ",%" PetscInt_FMT ")",(double)v[i*n+j],idxm[i],idxn[j]); 1331 #endif 1332 } 1333 } 1334 for (i=0; i<m; i++) PetscCheck(idxm[i] < mat->rmap->N,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Cannot insert in row %" PetscInt_FMT ", maximum is %" PetscInt_FMT,idxm[i],mat->rmap->N-1); 1335 for (i=0; i<n; i++) PetscCheck(idxn[i] < mat->cmap->N,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Cannot insert in column %" PetscInt_FMT ", maximum is %" PetscInt_FMT,idxn[i],mat->cmap->N-1); 1336 } 1337 1338 if (mat->assembled) { 1339 mat->was_assembled = PETSC_TRUE; 1340 mat->assembled = PETSC_FALSE; 1341 } 1342 CHKERRQ(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 1343 CHKERRQ((*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv)); 1344 CHKERRQ(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 1345 PetscFunctionReturn(0); 1346 } 1347 1348 /*@ 1349 MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero 1350 values into a matrix 1351 1352 Not Collective 1353 1354 Input Parameters: 1355 + mat - the matrix 1356 . row - the (block) row to set 1357 - v - a logically two-dimensional array of values 1358 1359 Notes: 1360 By the values, v, are column-oriented (for the block version) and sorted 1361 1362 All the nonzeros in the row must be provided 1363 1364 The matrix must have previously had its column indices set 1365 1366 The row must belong to this process 1367 1368 Level: intermediate 1369 1370 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1371 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping() 1372 @*/ 1373 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[]) 1374 { 1375 PetscInt globalrow; 1376 1377 PetscFunctionBegin; 1378 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1379 PetscValidType(mat,1); 1380 PetscValidScalarPointer(v,3); 1381 CHKERRQ(ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow)); 1382 CHKERRQ(MatSetValuesRow(mat,globalrow,v)); 1383 PetscFunctionReturn(0); 1384 } 1385 1386 /*@ 1387 MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero 1388 values into a matrix 1389 1390 Not Collective 1391 1392 Input Parameters: 1393 + mat - the matrix 1394 . row - the (block) row to set 1395 - v - a logically two-dimensional (column major) array of values for block matrices with blocksize larger than one, otherwise a one dimensional array of values 1396 1397 Notes: 1398 The values, v, are column-oriented for the block version. 1399 1400 All the nonzeros in the row must be provided 1401 1402 THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used. 1403 1404 The row must belong to this process 1405 1406 Level: advanced 1407 1408 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1409 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues() 1410 @*/ 1411 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[]) 1412 { 1413 PetscFunctionBeginHot; 1414 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1415 PetscValidType(mat,1); 1416 MatCheckPreallocated(mat,1); 1417 PetscValidScalarPointer(v,3); 1418 PetscCheckFalse(mat->insertmode == ADD_VALUES,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values"); 1419 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1420 mat->insertmode = INSERT_VALUES; 1421 1422 if (mat->assembled) { 1423 mat->was_assembled = PETSC_TRUE; 1424 mat->assembled = PETSC_FALSE; 1425 } 1426 CHKERRQ(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 1427 PetscCheck(mat->ops->setvaluesrow,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1428 CHKERRQ((*mat->ops->setvaluesrow)(mat,row,v)); 1429 CHKERRQ(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 1430 PetscFunctionReturn(0); 1431 } 1432 1433 /*@ 1434 MatSetValuesStencil - Inserts or adds a block of values into a matrix. 1435 Using structured grid indexing 1436 1437 Not Collective 1438 1439 Input Parameters: 1440 + mat - the matrix 1441 . m - number of rows being entered 1442 . idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered 1443 . n - number of columns being entered 1444 . idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered 1445 . v - a logically two-dimensional array of values 1446 - addv - either ADD_VALUES or INSERT_VALUES, where 1447 ADD_VALUES adds values to any existing entries, and 1448 INSERT_VALUES replaces existing entries with new values 1449 1450 Notes: 1451 By default the values, v, are row-oriented. See MatSetOption() for other options. 1452 1453 Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES 1454 options cannot be mixed without intervening calls to the assembly 1455 routines. 1456 1457 The grid coordinates are across the entire grid, not just the local portion 1458 1459 MatSetValuesStencil() uses 0-based row and column numbers in Fortran 1460 as well as in C. 1461 1462 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine 1463 1464 In order to use this routine you must either obtain the matrix with DMCreateMatrix() 1465 or call MatSetLocalToGlobalMapping() and MatSetStencil() first. 1466 1467 The columns and rows in the stencil passed in MUST be contained within the 1468 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example, 1469 if you create a DMDA with an overlap of one grid level and on a particular process its first 1470 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1471 first i index you can use in your column and row indices in MatSetStencil() is 5. 1472 1473 In Fortran idxm and idxn should be declared as 1474 $ MatStencil idxm(4,m),idxn(4,n) 1475 and the values inserted using 1476 $ idxm(MatStencil_i,1) = i 1477 $ idxm(MatStencil_j,1) = j 1478 $ idxm(MatStencil_k,1) = k 1479 $ idxm(MatStencil_c,1) = c 1480 etc 1481 1482 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 1483 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 1484 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 1485 DM_BOUNDARY_PERIODIC boundary type. 1486 1487 For indices that don't mean anything for your case (like the k index when working in 2d) or the c index when you have 1488 a single value per point) you can skip filling those indices. 1489 1490 Inspired by the structured grid interface to the HYPRE package 1491 (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods) 1492 1493 Efficiency Alert: 1494 The routine MatSetValuesBlockedStencil() may offer much better efficiency 1495 for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ). 1496 1497 Level: beginner 1498 1499 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1500 MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil 1501 @*/ 1502 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1503 { 1504 PetscInt buf[8192],*bufm=NULL,*bufn=NULL,*jdxm,*jdxn; 1505 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1506 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1507 1508 PetscFunctionBegin; 1509 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1510 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1511 PetscValidType(mat,1); 1512 PetscValidPointer(idxm,3); 1513 PetscValidPointer(idxn,5); 1514 1515 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1516 jdxm = buf; jdxn = buf+m; 1517 } else { 1518 CHKERRQ(PetscMalloc2(m,&bufm,n,&bufn)); 1519 jdxm = bufm; jdxn = bufn; 1520 } 1521 for (i=0; i<m; i++) { 1522 for (j=0; j<3-sdim; j++) dxm++; 1523 tmp = *dxm++ - starts[0]; 1524 for (j=0; j<dim-1; j++) { 1525 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1526 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1527 } 1528 if (mat->stencil.noc) dxm++; 1529 jdxm[i] = tmp; 1530 } 1531 for (i=0; i<n; i++) { 1532 for (j=0; j<3-sdim; j++) dxn++; 1533 tmp = *dxn++ - starts[0]; 1534 for (j=0; j<dim-1; j++) { 1535 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1536 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1537 } 1538 if (mat->stencil.noc) dxn++; 1539 jdxn[i] = tmp; 1540 } 1541 CHKERRQ(MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv)); 1542 CHKERRQ(PetscFree2(bufm,bufn)); 1543 PetscFunctionReturn(0); 1544 } 1545 1546 /*@ 1547 MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix. 1548 Using structured grid indexing 1549 1550 Not Collective 1551 1552 Input Parameters: 1553 + mat - the matrix 1554 . m - number of rows being entered 1555 . idxm - grid coordinates for matrix rows being entered 1556 . n - number of columns being entered 1557 . idxn - grid coordinates for matrix columns being entered 1558 . v - a logically two-dimensional array of values 1559 - addv - either ADD_VALUES or INSERT_VALUES, where 1560 ADD_VALUES adds values to any existing entries, and 1561 INSERT_VALUES replaces existing entries with new values 1562 1563 Notes: 1564 By default the values, v, are row-oriented and unsorted. 1565 See MatSetOption() for other options. 1566 1567 Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES 1568 options cannot be mixed without intervening calls to the assembly 1569 routines. 1570 1571 The grid coordinates are across the entire grid, not just the local portion 1572 1573 MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran 1574 as well as in C. 1575 1576 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine 1577 1578 In order to use this routine you must either obtain the matrix with DMCreateMatrix() 1579 or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first. 1580 1581 The columns and rows in the stencil passed in MUST be contained within the 1582 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example, 1583 if you create a DMDA with an overlap of one grid level and on a particular process its first 1584 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1585 first i index you can use in your column and row indices in MatSetStencil() is 5. 1586 1587 In Fortran idxm and idxn should be declared as 1588 $ MatStencil idxm(4,m),idxn(4,n) 1589 and the values inserted using 1590 $ idxm(MatStencil_i,1) = i 1591 $ idxm(MatStencil_j,1) = j 1592 $ idxm(MatStencil_k,1) = k 1593 etc 1594 1595 Negative indices may be passed in idxm and idxn, these rows and columns are 1596 simply ignored. This allows easily inserting element stiffness matrices 1597 with homogeneous Dirchlet boundary conditions that you don't want represented 1598 in the matrix. 1599 1600 Inspired by the structured grid interface to the HYPRE package 1601 (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods) 1602 1603 Level: beginner 1604 1605 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1606 MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil, 1607 MatSetBlockSize(), MatSetLocalToGlobalMapping() 1608 @*/ 1609 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1610 { 1611 PetscInt buf[8192],*bufm=NULL,*bufn=NULL,*jdxm,*jdxn; 1612 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1613 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1614 1615 PetscFunctionBegin; 1616 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1617 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1618 PetscValidType(mat,1); 1619 PetscValidPointer(idxm,3); 1620 PetscValidPointer(idxn,5); 1621 PetscValidScalarPointer(v,6); 1622 1623 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1624 jdxm = buf; jdxn = buf+m; 1625 } else { 1626 CHKERRQ(PetscMalloc2(m,&bufm,n,&bufn)); 1627 jdxm = bufm; jdxn = bufn; 1628 } 1629 for (i=0; i<m; i++) { 1630 for (j=0; j<3-sdim; j++) dxm++; 1631 tmp = *dxm++ - starts[0]; 1632 for (j=0; j<sdim-1; j++) { 1633 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1634 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1635 } 1636 dxm++; 1637 jdxm[i] = tmp; 1638 } 1639 for (i=0; i<n; i++) { 1640 for (j=0; j<3-sdim; j++) dxn++; 1641 tmp = *dxn++ - starts[0]; 1642 for (j=0; j<sdim-1; j++) { 1643 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1644 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1645 } 1646 dxn++; 1647 jdxn[i] = tmp; 1648 } 1649 CHKERRQ(MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv)); 1650 CHKERRQ(PetscFree2(bufm,bufn)); 1651 PetscFunctionReturn(0); 1652 } 1653 1654 /*@ 1655 MatSetStencil - Sets the grid information for setting values into a matrix via 1656 MatSetValuesStencil() 1657 1658 Not Collective 1659 1660 Input Parameters: 1661 + mat - the matrix 1662 . dim - dimension of the grid 1, 2, or 3 1663 . dims - number of grid points in x, y, and z direction, including ghost points on your processor 1664 . starts - starting point of ghost nodes on your processor in x, y, and z direction 1665 - dof - number of degrees of freedom per node 1666 1667 Inspired by the structured grid interface to the HYPRE package 1668 (www.llnl.gov/CASC/hyper) 1669 1670 For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the 1671 user. 1672 1673 Level: beginner 1674 1675 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1676 MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil() 1677 @*/ 1678 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof) 1679 { 1680 PetscFunctionBegin; 1681 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1682 PetscValidIntPointer(dims,3); 1683 PetscValidIntPointer(starts,4); 1684 1685 mat->stencil.dim = dim + (dof > 1); 1686 for (PetscInt i=0; i<dim; i++) { 1687 mat->stencil.dims[i] = dims[dim-i-1]; /* copy the values in backwards */ 1688 mat->stencil.starts[i] = starts[dim-i-1]; 1689 } 1690 mat->stencil.dims[dim] = dof; 1691 mat->stencil.starts[dim] = 0; 1692 mat->stencil.noc = (PetscBool)(dof == 1); 1693 PetscFunctionReturn(0); 1694 } 1695 1696 /*@C 1697 MatSetValuesBlocked - Inserts or adds a block of values into a matrix. 1698 1699 Not Collective 1700 1701 Input Parameters: 1702 + mat - the matrix 1703 . v - a logically two-dimensional array of values 1704 . m, idxm - the number of block rows and their global block indices 1705 . n, idxn - the number of block columns and their global block indices 1706 - addv - either ADD_VALUES or INSERT_VALUES, where 1707 ADD_VALUES adds values to any existing entries, and 1708 INSERT_VALUES replaces existing entries with new values 1709 1710 Notes: 1711 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call 1712 MatXXXXSetPreallocation() or MatSetUp() before using this routine. 1713 1714 The m and n count the NUMBER of blocks in the row direction and column direction, 1715 NOT the total number of rows/columns; for example, if the block size is 2 and 1716 you are passing in values for rows 2,3,4,5 then m would be 2 (not 4). 1717 The values in idxm would be 1 2; that is the first index for each block divided by 1718 the block size. 1719 1720 Note that you must call MatSetBlockSize() when constructing this matrix (before 1721 preallocating it). 1722 1723 By default the values, v, are row-oriented, so the layout of 1724 v is the same as for MatSetValues(). See MatSetOption() for other options. 1725 1726 Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES 1727 options cannot be mixed without intervening calls to the assembly 1728 routines. 1729 1730 MatSetValuesBlocked() uses 0-based row and column numbers in Fortran 1731 as well as in C. 1732 1733 Negative indices may be passed in idxm and idxn, these rows and columns are 1734 simply ignored. This allows easily inserting element stiffness matrices 1735 with homogeneous Dirchlet boundary conditions that you don't want represented 1736 in the matrix. 1737 1738 Each time an entry is set within a sparse matrix via MatSetValues(), 1739 internal searching must be done to determine where to place the 1740 data in the matrix storage space. By instead inserting blocks of 1741 entries via MatSetValuesBlocked(), the overhead of matrix assembly is 1742 reduced. 1743 1744 Example: 1745 $ Suppose m=n=2 and block size(bs) = 2 The array is 1746 $ 1747 $ 1 2 | 3 4 1748 $ 5 6 | 7 8 1749 $ - - - | - - - 1750 $ 9 10 | 11 12 1751 $ 13 14 | 15 16 1752 $ 1753 $ v[] should be passed in like 1754 $ v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] 1755 $ 1756 $ If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then 1757 $ v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16] 1758 1759 Level: intermediate 1760 1761 .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal() 1762 @*/ 1763 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1764 { 1765 PetscFunctionBeginHot; 1766 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1767 PetscValidType(mat,1); 1768 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1769 PetscValidIntPointer(idxm,3); 1770 PetscValidIntPointer(idxn,5); 1771 MatCheckPreallocated(mat,1); 1772 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 1773 else PetscCheckFalse(mat->insertmode != addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1774 if (PetscDefined(USE_DEBUG)) { 1775 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1776 PetscCheck(mat->ops->setvaluesblocked || mat->ops->setvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1777 } 1778 if (PetscDefined(USE_DEBUG)) { 1779 PetscInt rbs,cbs,M,N,i; 1780 CHKERRQ(MatGetBlockSizes(mat,&rbs,&cbs)); 1781 CHKERRQ(MatGetSize(mat,&M,&N)); 1782 for (i=0; i<m; i++) PetscCheck(idxm[i]*rbs < M,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row block index %" PetscInt_FMT " (index %" PetscInt_FMT ") greater than row length %" PetscInt_FMT,i,idxm[i],M); 1783 for (i=0; i<n; i++) PetscCheck(idxn[i]*cbs < N,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column block index %" PetscInt_FMT " (index %" PetscInt_FMT ") great than column length %" PetscInt_FMT,i,idxn[i],N); 1784 } 1785 if (mat->assembled) { 1786 mat->was_assembled = PETSC_TRUE; 1787 mat->assembled = PETSC_FALSE; 1788 } 1789 CHKERRQ(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 1790 if (mat->ops->setvaluesblocked) { 1791 CHKERRQ((*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv)); 1792 } else { 1793 PetscInt buf[8192],*bufr=NULL,*bufc=NULL,*iidxm,*iidxn; 1794 PetscInt i,j,bs,cbs; 1795 1796 CHKERRQ(MatGetBlockSizes(mat,&bs,&cbs)); 1797 if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1798 iidxm = buf; 1799 iidxn = buf + m*bs; 1800 } else { 1801 CHKERRQ(PetscMalloc2(m*bs,&bufr,n*cbs,&bufc)); 1802 iidxm = bufr; 1803 iidxn = bufc; 1804 } 1805 for (i=0; i<m; i++) { 1806 for (j=0; j<bs; j++) { 1807 iidxm[i*bs+j] = bs*idxm[i] + j; 1808 } 1809 } 1810 if (m != n || bs != cbs || idxm != idxn) { 1811 for (i=0; i<n; i++) { 1812 for (j=0; j<cbs; j++) { 1813 iidxn[i*cbs+j] = cbs*idxn[i] + j; 1814 } 1815 } 1816 } else iidxn = iidxm; 1817 CHKERRQ(MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv)); 1818 CHKERRQ(PetscFree2(bufr,bufc)); 1819 } 1820 CHKERRQ(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 1821 PetscFunctionReturn(0); 1822 } 1823 1824 /*@C 1825 MatGetValues - Gets a block of values from a matrix. 1826 1827 Not Collective; can only return values that are owned by the give process 1828 1829 Input Parameters: 1830 + mat - the matrix 1831 . v - a logically two-dimensional array for storing the values 1832 . m, idxm - the number of rows and their global indices 1833 - n, idxn - the number of columns and their global indices 1834 1835 Notes: 1836 The user must allocate space (m*n PetscScalars) for the values, v. 1837 The values, v, are then returned in a row-oriented format, 1838 analogous to that used by default in MatSetValues(). 1839 1840 MatGetValues() uses 0-based row and column numbers in 1841 Fortran as well as in C. 1842 1843 MatGetValues() requires that the matrix has been assembled 1844 with MatAssemblyBegin()/MatAssemblyEnd(). Thus, calls to 1845 MatSetValues() and MatGetValues() CANNOT be made in succession 1846 without intermediate matrix assembly. 1847 1848 Negative row or column indices will be ignored and those locations in v[] will be 1849 left unchanged. 1850 1851 For the standard row-based matrix formats, idxm[] can only contain rows owned by the requesting MPI rank. 1852 That is, rows with global index greater than or equal to rstart and less than rend where rstart and rend are obtainable 1853 from MatGetOwnershipRange(mat,&rstart,&rend). 1854 1855 Level: advanced 1856 1857 .seealso: MatGetRow(), MatCreateSubMatrices(), MatSetValues(), MatGetOwnershipRange(), MatGetValuesLocal(), MatGetValue() 1858 @*/ 1859 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[]) 1860 { 1861 PetscFunctionBegin; 1862 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1863 PetscValidType(mat,1); 1864 if (!m || !n) PetscFunctionReturn(0); 1865 PetscValidIntPointer(idxm,3); 1866 PetscValidIntPointer(idxn,5); 1867 PetscValidScalarPointer(v,6); 1868 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 1869 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1870 PetscCheck(mat->ops->getvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1871 MatCheckPreallocated(mat,1); 1872 1873 CHKERRQ(PetscLogEventBegin(MAT_GetValues,mat,0,0,0)); 1874 CHKERRQ((*mat->ops->getvalues)(mat,m,idxm,n,idxn,v)); 1875 CHKERRQ(PetscLogEventEnd(MAT_GetValues,mat,0,0,0)); 1876 PetscFunctionReturn(0); 1877 } 1878 1879 /*@C 1880 MatGetValuesLocal - retrieves values from certain locations in a matrix using the local numbering of the indices 1881 defined previously by MatSetLocalToGlobalMapping() 1882 1883 Not Collective 1884 1885 Input Parameters: 1886 + mat - the matrix 1887 . nrow, irow - number of rows and their local indices 1888 - ncol, icol - number of columns and their local indices 1889 1890 Output Parameter: 1891 . y - a logically two-dimensional array of values 1892 1893 Notes: 1894 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine. 1895 1896 This routine can only return values that are owned by the requesting MPI rank. That is, for standard matrix formats, rows that, in the global numbering, 1897 are greater than or equal to rstart and less than rend where rstart and rend are obtainable from MatGetOwnershipRange(mat,&rstart,&rend). One can 1898 determine if the resulting global row associated with the local row r is owned by the requesting MPI rank by applying the ISLocalToGlobalMapping set 1899 with MatSetLocalToGlobalMapping(). 1900 1901 Developer Notes: 1902 This is labelled with C so does not automatically generate Fortran stubs and interfaces 1903 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 1904 1905 Level: advanced 1906 1907 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(), 1908 MatSetValuesLocal(), MatGetValues() 1909 @*/ 1910 PetscErrorCode MatGetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],PetscScalar y[]) 1911 { 1912 PetscFunctionBeginHot; 1913 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1914 PetscValidType(mat,1); 1915 MatCheckPreallocated(mat,1); 1916 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to retrieve */ 1917 PetscValidIntPointer(irow,3); 1918 PetscValidIntPointer(icol,5); 1919 if (PetscDefined(USE_DEBUG)) { 1920 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1921 PetscCheck(mat->ops->getvalueslocal || mat->ops->getvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1922 } 1923 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 1924 CHKERRQ(PetscLogEventBegin(MAT_GetValues,mat,0,0,0)); 1925 if (mat->ops->getvalueslocal) { 1926 CHKERRQ((*mat->ops->getvalueslocal)(mat,nrow,irow,ncol,icol,y)); 1927 } else { 1928 PetscInt buf[8192],*bufr=NULL,*bufc=NULL,*irowm,*icolm; 1929 if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1930 irowm = buf; icolm = buf+nrow; 1931 } else { 1932 CHKERRQ(PetscMalloc2(nrow,&bufr,ncol,&bufc)); 1933 irowm = bufr; icolm = bufc; 1934 } 1935 PetscCheck(mat->rmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MatGetValuesLocal() cannot proceed without local-to-global row mapping (See MatSetLocalToGlobalMapping())."); 1936 PetscCheck(mat->cmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MatGetValuesLocal() cannot proceed without local-to-global column mapping (See MatSetLocalToGlobalMapping())."); 1937 CHKERRQ(ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm)); 1938 CHKERRQ(ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm)); 1939 CHKERRQ(MatGetValues(mat,nrow,irowm,ncol,icolm,y)); 1940 CHKERRQ(PetscFree2(bufr,bufc)); 1941 } 1942 CHKERRQ(PetscLogEventEnd(MAT_GetValues,mat,0,0,0)); 1943 PetscFunctionReturn(0); 1944 } 1945 1946 /*@ 1947 MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and 1948 the same size. Currently, this can only be called once and creates the given matrix. 1949 1950 Not Collective 1951 1952 Input Parameters: 1953 + mat - the matrix 1954 . nb - the number of blocks 1955 . bs - the number of rows (and columns) in each block 1956 . rows - a concatenation of the rows for each block 1957 - v - a concatenation of logically two-dimensional arrays of values 1958 1959 Notes: 1960 In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix. 1961 1962 Level: advanced 1963 1964 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1965 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues() 1966 @*/ 1967 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[]) 1968 { 1969 PetscFunctionBegin; 1970 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1971 PetscValidType(mat,1); 1972 PetscValidIntPointer(rows,4); 1973 PetscValidScalarPointer(v,5); 1974 PetscAssert(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1975 1976 CHKERRQ(PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0)); 1977 if (mat->ops->setvaluesbatch) { 1978 CHKERRQ((*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v)); 1979 } else { 1980 for (PetscInt b = 0; b < nb; ++b) CHKERRQ(MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES)); 1981 } 1982 CHKERRQ(PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0)); 1983 PetscFunctionReturn(0); 1984 } 1985 1986 /*@ 1987 MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by 1988 the routine MatSetValuesLocal() to allow users to insert matrix entries 1989 using a local (per-processor) numbering. 1990 1991 Not Collective 1992 1993 Input Parameters: 1994 + x - the matrix 1995 . rmapping - row mapping created with ISLocalToGlobalMappingCreate() or ISLocalToGlobalMappingCreateIS() 1996 - cmapping - column mapping 1997 1998 Level: intermediate 1999 2000 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal(), MatGetValuesLocal() 2001 @*/ 2002 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 2003 { 2004 PetscFunctionBegin; 2005 PetscValidHeaderSpecific(x,MAT_CLASSID,1); 2006 PetscValidType(x,1); 2007 if (rmapping) PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2); 2008 if (cmapping) PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3); 2009 if (x->ops->setlocaltoglobalmapping) { 2010 CHKERRQ((*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping)); 2011 } else { 2012 CHKERRQ(PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping)); 2013 CHKERRQ(PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping)); 2014 } 2015 PetscFunctionReturn(0); 2016 } 2017 2018 /*@ 2019 MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping() 2020 2021 Not Collective 2022 2023 Input Parameter: 2024 . A - the matrix 2025 2026 Output Parameters: 2027 + rmapping - row mapping 2028 - cmapping - column mapping 2029 2030 Level: advanced 2031 2032 .seealso: MatSetValuesLocal() 2033 @*/ 2034 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping) 2035 { 2036 PetscFunctionBegin; 2037 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2038 PetscValidType(A,1); 2039 if (rmapping) { 2040 PetscValidPointer(rmapping,2); 2041 *rmapping = A->rmap->mapping; 2042 } 2043 if (cmapping) { 2044 PetscValidPointer(cmapping,3); 2045 *cmapping = A->cmap->mapping; 2046 } 2047 PetscFunctionReturn(0); 2048 } 2049 2050 /*@ 2051 MatSetLayouts - Sets the PetscLayout objects for rows and columns of a matrix 2052 2053 Logically Collective on A 2054 2055 Input Parameters: 2056 + A - the matrix 2057 . rmap - row layout 2058 - cmap - column layout 2059 2060 Level: advanced 2061 2062 .seealso: MatCreateVecs(), MatGetLocalToGlobalMapping(), MatGetLayouts() 2063 @*/ 2064 PetscErrorCode MatSetLayouts(Mat A,PetscLayout rmap,PetscLayout cmap) 2065 { 2066 PetscFunctionBegin; 2067 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2068 CHKERRQ(PetscLayoutReference(rmap,&A->rmap)); 2069 CHKERRQ(PetscLayoutReference(cmap,&A->cmap)); 2070 PetscFunctionReturn(0); 2071 } 2072 2073 /*@ 2074 MatGetLayouts - Gets the PetscLayout objects for rows and columns 2075 2076 Not Collective 2077 2078 Input Parameter: 2079 . A - the matrix 2080 2081 Output Parameters: 2082 + rmap - row layout 2083 - cmap - column layout 2084 2085 Level: advanced 2086 2087 .seealso: MatCreateVecs(), MatGetLocalToGlobalMapping(), MatSetLayouts() 2088 @*/ 2089 PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap) 2090 { 2091 PetscFunctionBegin; 2092 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2093 PetscValidType(A,1); 2094 if (rmap) { 2095 PetscValidPointer(rmap,2); 2096 *rmap = A->rmap; 2097 } 2098 if (cmap) { 2099 PetscValidPointer(cmap,3); 2100 *cmap = A->cmap; 2101 } 2102 PetscFunctionReturn(0); 2103 } 2104 2105 /*@C 2106 MatSetValuesLocal - Inserts or adds values into certain locations of a matrix, 2107 using a local numbering of the nodes. 2108 2109 Not Collective 2110 2111 Input Parameters: 2112 + mat - the matrix 2113 . nrow, irow - number of rows and their local indices 2114 . ncol, icol - number of columns and their local indices 2115 . y - a logically two-dimensional array of values 2116 - addv - either INSERT_VALUES or ADD_VALUES, where 2117 ADD_VALUES adds values to any existing entries, and 2118 INSERT_VALUES replaces existing entries with new values 2119 2120 Notes: 2121 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2122 MatSetUp() before using this routine 2123 2124 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine 2125 2126 Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES 2127 options cannot be mixed without intervening calls to the assembly 2128 routines. 2129 2130 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2131 MUST be called after all calls to MatSetValuesLocal() have been completed. 2132 2133 Level: intermediate 2134 2135 Developer Notes: 2136 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2137 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2138 2139 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(), 2140 MatSetValueLocal(), MatGetValuesLocal() 2141 @*/ 2142 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2143 { 2144 PetscFunctionBeginHot; 2145 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2146 PetscValidType(mat,1); 2147 MatCheckPreallocated(mat,1); 2148 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2149 PetscValidIntPointer(irow,3); 2150 PetscValidIntPointer(icol,5); 2151 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 2152 else PetscCheckFalse(mat->insertmode != addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2153 if (PetscDefined(USE_DEBUG)) { 2154 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2155 PetscCheck(mat->ops->setvalueslocal || mat->ops->setvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2156 } 2157 2158 if (mat->assembled) { 2159 mat->was_assembled = PETSC_TRUE; 2160 mat->assembled = PETSC_FALSE; 2161 } 2162 CHKERRQ(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 2163 if (mat->ops->setvalueslocal) { 2164 CHKERRQ((*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv)); 2165 } else { 2166 PetscInt buf[8192],*bufr=NULL,*bufc=NULL; 2167 const PetscInt *irowm,*icolm; 2168 2169 if ((!mat->rmap->mapping && !mat->cmap->mapping) || (nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2170 bufr = buf; 2171 bufc = buf + nrow; 2172 irowm = bufr; 2173 icolm = bufc; 2174 } else { 2175 CHKERRQ(PetscMalloc2(nrow,&bufr,ncol,&bufc)); 2176 irowm = bufr; 2177 icolm = bufc; 2178 } 2179 if (mat->rmap->mapping) CHKERRQ(ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,bufr)); 2180 else irowm = irow; 2181 if (mat->cmap->mapping) { 2182 if (mat->cmap->mapping != mat->rmap->mapping || ncol != nrow || icol != irow) { 2183 CHKERRQ(ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,bufc)); 2184 } else icolm = irowm; 2185 } else icolm = icol; 2186 CHKERRQ(MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv)); 2187 if (bufr != buf) CHKERRQ(PetscFree2(bufr,bufc)); 2188 } 2189 CHKERRQ(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 2190 PetscFunctionReturn(0); 2191 } 2192 2193 /*@C 2194 MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix, 2195 using a local ordering of the nodes a block at a time. 2196 2197 Not Collective 2198 2199 Input Parameters: 2200 + x - the matrix 2201 . nrow, irow - number of rows and their local indices 2202 . ncol, icol - number of columns and their local indices 2203 . y - a logically two-dimensional array of values 2204 - addv - either INSERT_VALUES or ADD_VALUES, where 2205 ADD_VALUES adds values to any existing entries, and 2206 INSERT_VALUES replaces existing entries with new values 2207 2208 Notes: 2209 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2210 MatSetUp() before using this routine 2211 2212 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping() 2213 before using this routineBefore calling MatSetValuesLocal(), the user must first set the 2214 2215 Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES 2216 options cannot be mixed without intervening calls to the assembly 2217 routines. 2218 2219 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2220 MUST be called after all calls to MatSetValuesBlockedLocal() have been completed. 2221 2222 Level: intermediate 2223 2224 Developer Notes: 2225 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2226 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2227 2228 .seealso: MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(), 2229 MatSetValuesLocal(), MatSetValuesBlocked() 2230 @*/ 2231 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2232 { 2233 PetscFunctionBeginHot; 2234 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2235 PetscValidType(mat,1); 2236 MatCheckPreallocated(mat,1); 2237 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2238 PetscValidIntPointer(irow,3); 2239 PetscValidIntPointer(icol,5); 2240 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 2241 else PetscCheckFalse(mat->insertmode != addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2242 if (PetscDefined(USE_DEBUG)) { 2243 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2244 PetscCheckFalse(!mat->ops->setvaluesblockedlocal && !mat->ops->setvaluesblocked && !mat->ops->setvalueslocal && !mat->ops->setvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2245 } 2246 2247 if (mat->assembled) { 2248 mat->was_assembled = PETSC_TRUE; 2249 mat->assembled = PETSC_FALSE; 2250 } 2251 if (PetscUnlikelyDebug(mat->rmap->mapping)) { /* Condition on the mapping existing, because MatSetValuesBlockedLocal_IS does not require it to be set. */ 2252 PetscInt irbs, rbs; 2253 CHKERRQ(MatGetBlockSizes(mat, &rbs, NULL)); 2254 CHKERRQ(ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&irbs)); 2255 PetscCheckFalse(rbs != irbs,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different row block sizes! mat %" PetscInt_FMT ", row l2g map %" PetscInt_FMT,rbs,irbs); 2256 } 2257 if (PetscUnlikelyDebug(mat->cmap->mapping)) { 2258 PetscInt icbs, cbs; 2259 CHKERRQ(MatGetBlockSizes(mat,NULL,&cbs)); 2260 CHKERRQ(ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&icbs)); 2261 PetscCheckFalse(cbs != icbs,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different col block sizes! mat %" PetscInt_FMT ", col l2g map %" PetscInt_FMT,cbs,icbs); 2262 } 2263 CHKERRQ(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 2264 if (mat->ops->setvaluesblockedlocal) { 2265 CHKERRQ((*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv)); 2266 } else { 2267 PetscInt buf[8192],*bufr=NULL,*bufc=NULL; 2268 const PetscInt *irowm,*icolm; 2269 2270 if ((!mat->rmap->mapping && !mat->cmap->mapping) || (nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2271 bufr = buf; 2272 bufc = buf + nrow; 2273 irowm = bufr; 2274 icolm = bufc; 2275 } else { 2276 CHKERRQ(PetscMalloc2(nrow,&bufr,ncol,&bufc)); 2277 irowm = bufr; 2278 icolm = bufc; 2279 } 2280 if (mat->rmap->mapping) CHKERRQ(ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,bufr)); 2281 else irowm = irow; 2282 if (mat->cmap->mapping) { 2283 if (mat->cmap->mapping != mat->rmap->mapping || ncol != nrow || icol != irow) { 2284 CHKERRQ(ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,bufc)); 2285 } else icolm = irowm; 2286 } else icolm = icol; 2287 CHKERRQ(MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv)); 2288 if (bufr != buf) CHKERRQ(PetscFree2(bufr,bufc)); 2289 } 2290 CHKERRQ(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 2291 PetscFunctionReturn(0); 2292 } 2293 2294 /*@ 2295 MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal 2296 2297 Collective on Mat 2298 2299 Input Parameters: 2300 + mat - the matrix 2301 - x - the vector to be multiplied 2302 2303 Output Parameters: 2304 . y - the result 2305 2306 Notes: 2307 The vectors x and y cannot be the same. I.e., one cannot 2308 call MatMult(A,y,y). 2309 2310 Level: developer 2311 2312 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2313 @*/ 2314 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y) 2315 { 2316 PetscFunctionBegin; 2317 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2318 PetscValidType(mat,1); 2319 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2320 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2321 2322 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2323 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2324 PetscCheckFalse(x == y,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2325 MatCheckPreallocated(mat,1); 2326 2327 PetscCheck(mat->ops->multdiagonalblock,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a multiply defined",((PetscObject)mat)->type_name); 2328 CHKERRQ((*mat->ops->multdiagonalblock)(mat,x,y)); 2329 CHKERRQ(PetscObjectStateIncrease((PetscObject)y)); 2330 PetscFunctionReturn(0); 2331 } 2332 2333 /* --------------------------------------------------------*/ 2334 /*@ 2335 MatMult - Computes the matrix-vector product, y = Ax. 2336 2337 Neighbor-wise Collective on Mat 2338 2339 Input Parameters: 2340 + mat - the matrix 2341 - x - the vector to be multiplied 2342 2343 Output Parameters: 2344 . y - the result 2345 2346 Notes: 2347 The vectors x and y cannot be the same. I.e., one cannot 2348 call MatMult(A,y,y). 2349 2350 Level: beginner 2351 2352 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2353 @*/ 2354 PetscErrorCode MatMult(Mat mat,Vec x,Vec y) 2355 { 2356 PetscFunctionBegin; 2357 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2358 PetscValidType(mat,1); 2359 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2360 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2361 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2362 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2363 PetscCheckFalse(x == y,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2364 PetscCheckFalse(mat->cmap->N != x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,x->map->N); 2365 PetscCheckFalse(mat->rmap->N != y->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,y->map->N); 2366 PetscCheckFalse(mat->cmap->n != x->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->n,x->map->n); 2367 PetscCheckFalse(mat->rmap->n != y->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,y->map->n); 2368 CHKERRQ(VecSetErrorIfLocked(y,3)); 2369 if (mat->erroriffailure) CHKERRQ(VecValidValues(x,2,PETSC_TRUE)); 2370 MatCheckPreallocated(mat,1); 2371 2372 CHKERRQ(VecLockReadPush(x)); 2373 PetscCheck(mat->ops->mult,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a multiply defined",((PetscObject)mat)->type_name); 2374 CHKERRQ(PetscLogEventBegin(MAT_Mult,mat,x,y,0)); 2375 CHKERRQ((*mat->ops->mult)(mat,x,y)); 2376 CHKERRQ(PetscLogEventEnd(MAT_Mult,mat,x,y,0)); 2377 if (mat->erroriffailure) CHKERRQ(VecValidValues(y,3,PETSC_FALSE)); 2378 CHKERRQ(VecLockReadPop(x)); 2379 PetscFunctionReturn(0); 2380 } 2381 2382 /*@ 2383 MatMultTranspose - Computes matrix transpose times a vector y = A^T * x. 2384 2385 Neighbor-wise Collective on Mat 2386 2387 Input Parameters: 2388 + mat - the matrix 2389 - x - the vector to be multiplied 2390 2391 Output Parameters: 2392 . y - the result 2393 2394 Notes: 2395 The vectors x and y cannot be the same. I.e., one cannot 2396 call MatMultTranspose(A,y,y). 2397 2398 For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple, 2399 use MatMultHermitianTranspose() 2400 2401 Level: beginner 2402 2403 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose() 2404 @*/ 2405 PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y) 2406 { 2407 PetscErrorCode (*op)(Mat,Vec,Vec) = NULL; 2408 2409 PetscFunctionBegin; 2410 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2411 PetscValidType(mat,1); 2412 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2413 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2414 2415 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2416 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2417 PetscCheck(x != y,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2418 PetscCheck(mat->cmap->N == y->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,y->map->N); 2419 PetscCheck(mat->rmap->N == x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,x->map->N); 2420 PetscCheck(mat->cmap->n == y->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->n,y->map->n); 2421 PetscCheck(mat->rmap->n == x->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,x->map->n); 2422 if (mat->erroriffailure) CHKERRQ(VecValidValues(x,2,PETSC_TRUE)); 2423 MatCheckPreallocated(mat,1); 2424 2425 if (!mat->ops->multtranspose) { 2426 if (mat->symmetric && mat->ops->mult) op = mat->ops->mult; 2427 PetscCheck(op,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a multiply transpose defined or is symmetric and does not have a multiply defined",((PetscObject)mat)->type_name); 2428 } else op = mat->ops->multtranspose; 2429 CHKERRQ(PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0)); 2430 CHKERRQ(VecLockReadPush(x)); 2431 CHKERRQ((*op)(mat,x,y)); 2432 CHKERRQ(VecLockReadPop(x)); 2433 CHKERRQ(PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0)); 2434 CHKERRQ(PetscObjectStateIncrease((PetscObject)y)); 2435 if (mat->erroriffailure) CHKERRQ(VecValidValues(y,3,PETSC_FALSE)); 2436 PetscFunctionReturn(0); 2437 } 2438 2439 /*@ 2440 MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector. 2441 2442 Neighbor-wise Collective on Mat 2443 2444 Input Parameters: 2445 + mat - the matrix 2446 - x - the vector to be multilplied 2447 2448 Output Parameters: 2449 . y - the result 2450 2451 Notes: 2452 The vectors x and y cannot be the same. I.e., one cannot 2453 call MatMultHermitianTranspose(A,y,y). 2454 2455 Also called the conjugate transpose, complex conjugate transpose, or adjoint. 2456 2457 For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical. 2458 2459 Level: beginner 2460 2461 .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose() 2462 @*/ 2463 PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y) 2464 { 2465 PetscFunctionBegin; 2466 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2467 PetscValidType(mat,1); 2468 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2469 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2470 2471 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2472 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2473 PetscCheckFalse(x == y,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2474 PetscCheckFalse(mat->cmap->N != y->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,y->map->N); 2475 PetscCheckFalse(mat->rmap->N != x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,x->map->N); 2476 PetscCheckFalse(mat->cmap->n != y->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->n,y->map->n); 2477 PetscCheckFalse(mat->rmap->n != x->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,x->map->n); 2478 MatCheckPreallocated(mat,1); 2479 2480 CHKERRQ(PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0)); 2481 #if defined(PETSC_USE_COMPLEX) 2482 if (mat->ops->multhermitiantranspose || (mat->hermitian && mat->ops->mult)) { 2483 CHKERRQ(VecLockReadPush(x)); 2484 if (mat->ops->multhermitiantranspose) { 2485 CHKERRQ((*mat->ops->multhermitiantranspose)(mat,x,y)); 2486 } else { 2487 CHKERRQ((*mat->ops->mult)(mat,x,y)); 2488 } 2489 CHKERRQ(VecLockReadPop(x)); 2490 } else { 2491 Vec w; 2492 CHKERRQ(VecDuplicate(x,&w)); 2493 CHKERRQ(VecCopy(x,w)); 2494 CHKERRQ(VecConjugate(w)); 2495 CHKERRQ(MatMultTranspose(mat,w,y)); 2496 CHKERRQ(VecDestroy(&w)); 2497 CHKERRQ(VecConjugate(y)); 2498 } 2499 CHKERRQ(PetscObjectStateIncrease((PetscObject)y)); 2500 #else 2501 CHKERRQ(MatMultTranspose(mat,x,y)); 2502 #endif 2503 CHKERRQ(PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0)); 2504 PetscFunctionReturn(0); 2505 } 2506 2507 /*@ 2508 MatMultAdd - Computes v3 = v2 + A * v1. 2509 2510 Neighbor-wise Collective on Mat 2511 2512 Input Parameters: 2513 + mat - the matrix 2514 - v1, v2 - the vectors 2515 2516 Output Parameters: 2517 . v3 - the result 2518 2519 Notes: 2520 The vectors v1 and v3 cannot be the same. I.e., one cannot 2521 call MatMultAdd(A,v1,v2,v1). 2522 2523 Level: beginner 2524 2525 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd() 2526 @*/ 2527 PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2528 { 2529 PetscFunctionBegin; 2530 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2531 PetscValidType(mat,1); 2532 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2533 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2534 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2535 2536 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2537 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2538 PetscCheckFalse(mat->cmap->N != v1->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,v1->map->N); 2539 /* PetscCheckFalse(mat->rmap->N != v2->map->N,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,v2->map->N); 2540 PetscCheckFalse(mat->rmap->N != v3->map->N,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,v3->map->N); */ 2541 PetscCheckFalse(mat->rmap->n != v3->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,v3->map->n); 2542 PetscCheckFalse(mat->rmap->n != v2->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,v2->map->n); 2543 PetscCheckFalse(v1 == v3,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2544 MatCheckPreallocated(mat,1); 2545 2546 PetscCheck(mat->ops->multadd,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type %s",((PetscObject)mat)->type_name); 2547 CHKERRQ(PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3)); 2548 CHKERRQ(VecLockReadPush(v1)); 2549 CHKERRQ((*mat->ops->multadd)(mat,v1,v2,v3)); 2550 CHKERRQ(VecLockReadPop(v1)); 2551 CHKERRQ(PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3)); 2552 CHKERRQ(PetscObjectStateIncrease((PetscObject)v3)); 2553 PetscFunctionReturn(0); 2554 } 2555 2556 /*@ 2557 MatMultTransposeAdd - Computes v3 = v2 + A' * v1. 2558 2559 Neighbor-wise Collective on Mat 2560 2561 Input Parameters: 2562 + mat - the matrix 2563 - v1, v2 - the vectors 2564 2565 Output Parameters: 2566 . v3 - the result 2567 2568 Notes: 2569 The vectors v1 and v3 cannot be the same. I.e., one cannot 2570 call MatMultTransposeAdd(A,v1,v2,v1). 2571 2572 Level: beginner 2573 2574 .seealso: MatMultTranspose(), MatMultAdd(), MatMult() 2575 @*/ 2576 PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2577 { 2578 PetscErrorCode (*op)(Mat,Vec,Vec,Vec) = (!mat->ops->multtransposeadd && mat->symmetric) ? mat->ops->multadd : mat->ops->multtransposeadd; 2579 2580 PetscFunctionBegin; 2581 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2582 PetscValidType(mat,1); 2583 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2584 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2585 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2586 2587 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2588 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2589 PetscCheckFalse(mat->rmap->N != v1->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,v1->map->N); 2590 PetscCheckFalse(mat->cmap->N != v2->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,v2->map->N); 2591 PetscCheckFalse(mat->cmap->N != v3->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,v3->map->N); 2592 PetscCheckFalse(v1 == v3,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2593 PetscCheck(op,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2594 MatCheckPreallocated(mat,1); 2595 2596 CHKERRQ(PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3)); 2597 CHKERRQ(VecLockReadPush(v1)); 2598 CHKERRQ((*op)(mat,v1,v2,v3)); 2599 CHKERRQ(VecLockReadPop(v1)); 2600 CHKERRQ(PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3)); 2601 CHKERRQ(PetscObjectStateIncrease((PetscObject)v3)); 2602 PetscFunctionReturn(0); 2603 } 2604 2605 /*@ 2606 MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1. 2607 2608 Neighbor-wise Collective on Mat 2609 2610 Input Parameters: 2611 + mat - the matrix 2612 - v1, v2 - the vectors 2613 2614 Output Parameters: 2615 . v3 - the result 2616 2617 Notes: 2618 The vectors v1 and v3 cannot be the same. I.e., one cannot 2619 call MatMultHermitianTransposeAdd(A,v1,v2,v1). 2620 2621 Level: beginner 2622 2623 .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult() 2624 @*/ 2625 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2626 { 2627 PetscFunctionBegin; 2628 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2629 PetscValidType(mat,1); 2630 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2631 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2632 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2633 2634 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2635 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2636 PetscCheckFalse(v1 == v3,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2637 PetscCheckFalse(mat->rmap->N != v1->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,v1->map->N); 2638 PetscCheckFalse(mat->cmap->N != v2->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,v2->map->N); 2639 PetscCheckFalse(mat->cmap->N != v3->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,v3->map->N); 2640 MatCheckPreallocated(mat,1); 2641 2642 CHKERRQ(PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3)); 2643 CHKERRQ(VecLockReadPush(v1)); 2644 if (mat->ops->multhermitiantransposeadd) { 2645 CHKERRQ((*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3)); 2646 } else { 2647 Vec w,z; 2648 CHKERRQ(VecDuplicate(v1,&w)); 2649 CHKERRQ(VecCopy(v1,w)); 2650 CHKERRQ(VecConjugate(w)); 2651 CHKERRQ(VecDuplicate(v3,&z)); 2652 CHKERRQ(MatMultTranspose(mat,w,z)); 2653 CHKERRQ(VecDestroy(&w)); 2654 CHKERRQ(VecConjugate(z)); 2655 if (v2 != v3) { 2656 CHKERRQ(VecWAXPY(v3,1.0,v2,z)); 2657 } else { 2658 CHKERRQ(VecAXPY(v3,1.0,z)); 2659 } 2660 CHKERRQ(VecDestroy(&z)); 2661 } 2662 CHKERRQ(VecLockReadPop(v1)); 2663 CHKERRQ(PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3)); 2664 CHKERRQ(PetscObjectStateIncrease((PetscObject)v3)); 2665 PetscFunctionReturn(0); 2666 } 2667 2668 /*@C 2669 MatGetFactorType - gets the type of factorization it is 2670 2671 Not Collective 2672 2673 Input Parameters: 2674 . mat - the matrix 2675 2676 Output Parameters: 2677 . t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT 2678 2679 Level: intermediate 2680 2681 .seealso: MatFactorType, MatGetFactor(), MatSetFactorType() 2682 @*/ 2683 PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t) 2684 { 2685 PetscFunctionBegin; 2686 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2687 PetscValidType(mat,1); 2688 PetscValidPointer(t,2); 2689 *t = mat->factortype; 2690 PetscFunctionReturn(0); 2691 } 2692 2693 /*@C 2694 MatSetFactorType - sets the type of factorization it is 2695 2696 Logically Collective on Mat 2697 2698 Input Parameters: 2699 + mat - the matrix 2700 - t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT 2701 2702 Level: intermediate 2703 2704 .seealso: MatFactorType, MatGetFactor(), MatGetFactorType() 2705 @*/ 2706 PetscErrorCode MatSetFactorType(Mat mat, MatFactorType t) 2707 { 2708 PetscFunctionBegin; 2709 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2710 PetscValidType(mat,1); 2711 mat->factortype = t; 2712 PetscFunctionReturn(0); 2713 } 2714 2715 /* ------------------------------------------------------------*/ 2716 /*@C 2717 MatGetInfo - Returns information about matrix storage (number of 2718 nonzeros, memory, etc.). 2719 2720 Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag 2721 2722 Input Parameter: 2723 . mat - the matrix 2724 2725 Output Parameters: 2726 + flag - flag indicating the type of parameters to be returned 2727 (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors, 2728 MAT_GLOBAL_SUM - sum over all processors) 2729 - info - matrix information context 2730 2731 Notes: 2732 The MatInfo context contains a variety of matrix data, including 2733 number of nonzeros allocated and used, number of mallocs during 2734 matrix assembly, etc. Additional information for factored matrices 2735 is provided (such as the fill ratio, number of mallocs during 2736 factorization, etc.). Much of this info is printed to PETSC_STDOUT 2737 when using the runtime options 2738 $ -info -mat_view ::ascii_info 2739 2740 Example for C/C++ Users: 2741 See the file ${PETSC_DIR}/include/petscmat.h for a complete list of 2742 data within the MatInfo context. For example, 2743 .vb 2744 MatInfo info; 2745 Mat A; 2746 double mal, nz_a, nz_u; 2747 2748 MatGetInfo(A,MAT_LOCAL,&info); 2749 mal = info.mallocs; 2750 nz_a = info.nz_allocated; 2751 .ve 2752 2753 Example for Fortran Users: 2754 Fortran users should declare info as a double precision 2755 array of dimension MAT_INFO_SIZE, and then extract the parameters 2756 of interest. See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h 2757 a complete list of parameter names. 2758 .vb 2759 double precision info(MAT_INFO_SIZE) 2760 double precision mal, nz_a 2761 Mat A 2762 integer ierr 2763 2764 call MatGetInfo(A,MAT_LOCAL,info,ierr) 2765 mal = info(MAT_INFO_MALLOCS) 2766 nz_a = info(MAT_INFO_NZ_ALLOCATED) 2767 .ve 2768 2769 Level: intermediate 2770 2771 Developer Note: fortran interface is not autogenerated as the f90 2772 interface definition cannot be generated correctly [due to MatInfo] 2773 2774 .seealso: MatStashGetInfo() 2775 2776 @*/ 2777 PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info) 2778 { 2779 PetscFunctionBegin; 2780 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2781 PetscValidType(mat,1); 2782 PetscValidPointer(info,3); 2783 PetscCheck(mat->ops->getinfo,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2784 MatCheckPreallocated(mat,1); 2785 CHKERRQ((*mat->ops->getinfo)(mat,flag,info)); 2786 PetscFunctionReturn(0); 2787 } 2788 2789 /* 2790 This is used by external packages where it is not easy to get the info from the actual 2791 matrix factorization. 2792 */ 2793 PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info) 2794 { 2795 PetscFunctionBegin; 2796 CHKERRQ(PetscMemzero(info,sizeof(MatInfo))); 2797 PetscFunctionReturn(0); 2798 } 2799 2800 /* ----------------------------------------------------------*/ 2801 2802 /*@C 2803 MatLUFactor - Performs in-place LU factorization of matrix. 2804 2805 Collective on Mat 2806 2807 Input Parameters: 2808 + mat - the matrix 2809 . row - row permutation 2810 . col - column permutation 2811 - info - options for factorization, includes 2812 $ fill - expected fill as ratio of original fill. 2813 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 2814 $ Run with the option -info to determine an optimal value to use 2815 2816 Notes: 2817 Most users should employ the simplified KSP interface for linear solvers 2818 instead of working directly with matrix algebra routines such as this. 2819 See, e.g., KSPCreate(). 2820 2821 This changes the state of the matrix to a factored matrix; it cannot be used 2822 for example with MatSetValues() unless one first calls MatSetUnfactored(). 2823 2824 Level: developer 2825 2826 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), 2827 MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor() 2828 2829 Developer Note: fortran interface is not autogenerated as the f90 2830 interface definition cannot be generated correctly [due to MatFactorInfo] 2831 2832 @*/ 2833 PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 2834 { 2835 MatFactorInfo tinfo; 2836 2837 PetscFunctionBegin; 2838 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2839 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 2840 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 2841 if (info) PetscValidPointer(info,4); 2842 PetscValidType(mat,1); 2843 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2844 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2845 PetscCheck(mat->ops->lufactor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2846 MatCheckPreallocated(mat,1); 2847 if (!info) { 2848 CHKERRQ(MatFactorInfoInitialize(&tinfo)); 2849 info = &tinfo; 2850 } 2851 2852 CHKERRQ(PetscLogEventBegin(MAT_LUFactor,mat,row,col,0)); 2853 CHKERRQ((*mat->ops->lufactor)(mat,row,col,info)); 2854 CHKERRQ(PetscLogEventEnd(MAT_LUFactor,mat,row,col,0)); 2855 CHKERRQ(PetscObjectStateIncrease((PetscObject)mat)); 2856 PetscFunctionReturn(0); 2857 } 2858 2859 /*@C 2860 MatILUFactor - Performs in-place ILU factorization of matrix. 2861 2862 Collective on Mat 2863 2864 Input Parameters: 2865 + mat - the matrix 2866 . row - row permutation 2867 . col - column permutation 2868 - info - structure containing 2869 $ levels - number of levels of fill. 2870 $ expected fill - as ratio of original fill. 2871 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 2872 missing diagonal entries) 2873 2874 Notes: 2875 Probably really in-place only when level of fill is zero, otherwise allocates 2876 new space to store factored matrix and deletes previous memory. 2877 2878 Most users should employ the simplified KSP interface for linear solvers 2879 instead of working directly with matrix algebra routines such as this. 2880 See, e.g., KSPCreate(). 2881 2882 Level: developer 2883 2884 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo 2885 2886 Developer Note: fortran interface is not autogenerated as the f90 2887 interface definition cannot be generated correctly [due to MatFactorInfo] 2888 2889 @*/ 2890 PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 2891 { 2892 PetscFunctionBegin; 2893 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2894 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 2895 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 2896 PetscValidPointer(info,4); 2897 PetscValidType(mat,1); 2898 PetscCheckFalse(mat->rmap->N != mat->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 2899 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2900 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2901 PetscCheck(mat->ops->ilufactor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2902 MatCheckPreallocated(mat,1); 2903 2904 CHKERRQ(PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0)); 2905 CHKERRQ((*mat->ops->ilufactor)(mat,row,col,info)); 2906 CHKERRQ(PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0)); 2907 CHKERRQ(PetscObjectStateIncrease((PetscObject)mat)); 2908 PetscFunctionReturn(0); 2909 } 2910 2911 /*@C 2912 MatLUFactorSymbolic - Performs symbolic LU factorization of matrix. 2913 Call this routine before calling MatLUFactorNumeric(). 2914 2915 Collective on Mat 2916 2917 Input Parameters: 2918 + fact - the factor matrix obtained with MatGetFactor() 2919 . mat - the matrix 2920 . row, col - row and column permutations 2921 - info - options for factorization, includes 2922 $ fill - expected fill as ratio of original fill. 2923 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 2924 $ Run with the option -info to determine an optimal value to use 2925 2926 Notes: 2927 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 2928 2929 Most users should employ the simplified KSP interface for linear solvers 2930 instead of working directly with matrix algebra routines such as this. 2931 See, e.g., KSPCreate(). 2932 2933 Level: developer 2934 2935 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo, MatFactorInfoInitialize() 2936 2937 Developer Note: fortran interface is not autogenerated as the f90 2938 interface definition cannot be generated correctly [due to MatFactorInfo] 2939 2940 @*/ 2941 PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 2942 { 2943 MatFactorInfo tinfo; 2944 2945 PetscFunctionBegin; 2946 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 2947 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,3); 2948 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,4); 2949 if (info) PetscValidPointer(info,5); 2950 PetscValidType(mat,2); 2951 PetscValidPointer(fact,1); 2952 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2953 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2954 if (!(fact)->ops->lufactorsymbolic) { 2955 MatSolverType stype; 2956 CHKERRQ(MatFactorGetSolverType(fact,&stype)); 2957 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,stype); 2958 } 2959 MatCheckPreallocated(mat,2); 2960 if (!info) { 2961 CHKERRQ(MatFactorInfoInitialize(&tinfo)); 2962 info = &tinfo; 2963 } 2964 2965 if (!fact->trivialsymbolic) CHKERRQ(PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0)); 2966 CHKERRQ((fact->ops->lufactorsymbolic)(fact,mat,row,col,info)); 2967 if (!fact->trivialsymbolic) CHKERRQ(PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0)); 2968 CHKERRQ(PetscObjectStateIncrease((PetscObject)fact)); 2969 PetscFunctionReturn(0); 2970 } 2971 2972 /*@C 2973 MatLUFactorNumeric - Performs numeric LU factorization of a matrix. 2974 Call this routine after first calling MatLUFactorSymbolic(). 2975 2976 Collective on Mat 2977 2978 Input Parameters: 2979 + fact - the factor matrix obtained with MatGetFactor() 2980 . mat - the matrix 2981 - info - options for factorization 2982 2983 Notes: 2984 See MatLUFactor() for in-place factorization. See 2985 MatCholeskyFactorNumeric() for the symmetric, positive definite case. 2986 2987 Most users should employ the simplified KSP interface for linear solvers 2988 instead of working directly with matrix algebra routines such as this. 2989 See, e.g., KSPCreate(). 2990 2991 Level: developer 2992 2993 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor() 2994 2995 Developer Note: fortran interface is not autogenerated as the f90 2996 interface definition cannot be generated correctly [due to MatFactorInfo] 2997 2998 @*/ 2999 PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3000 { 3001 MatFactorInfo tinfo; 3002 3003 PetscFunctionBegin; 3004 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3005 PetscValidType(mat,2); 3006 PetscValidPointer(fact,1); 3007 PetscValidHeaderSpecific(fact,MAT_CLASSID,1); 3008 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3009 PetscCheckFalse(mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dimensions are different %" PetscInt_FMT " should = %" PetscInt_FMT " %" PetscInt_FMT " should = %" PetscInt_FMT,mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N); 3010 3011 PetscCheckFalse(!(fact)->ops->lufactornumeric,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name); 3012 MatCheckPreallocated(mat,2); 3013 if (!info) { 3014 CHKERRQ(MatFactorInfoInitialize(&tinfo)); 3015 info = &tinfo; 3016 } 3017 3018 if (!fact->trivialsymbolic) CHKERRQ(PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0)); 3019 else CHKERRQ(PetscLogEventBegin(MAT_LUFactor,mat,fact,0,0)); 3020 CHKERRQ((fact->ops->lufactornumeric)(fact,mat,info)); 3021 if (!fact->trivialsymbolic) CHKERRQ(PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0)); 3022 else CHKERRQ(PetscLogEventEnd(MAT_LUFactor,mat,fact,0,0)); 3023 CHKERRQ(MatViewFromOptions(fact,NULL,"-mat_factor_view")); 3024 CHKERRQ(PetscObjectStateIncrease((PetscObject)fact)); 3025 PetscFunctionReturn(0); 3026 } 3027 3028 /*@C 3029 MatCholeskyFactor - Performs in-place Cholesky factorization of a 3030 symmetric matrix. 3031 3032 Collective on Mat 3033 3034 Input Parameters: 3035 + mat - the matrix 3036 . perm - row and column permutations 3037 - f - expected fill as ratio of original fill 3038 3039 Notes: 3040 See MatLUFactor() for the nonsymmetric case. See also 3041 MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric(). 3042 3043 Most users should employ the simplified KSP interface for linear solvers 3044 instead of working directly with matrix algebra routines such as this. 3045 See, e.g., KSPCreate(). 3046 3047 Level: developer 3048 3049 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric() 3050 MatGetOrdering() 3051 3052 Developer Note: fortran interface is not autogenerated as the f90 3053 interface definition cannot be generated correctly [due to MatFactorInfo] 3054 3055 @*/ 3056 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info) 3057 { 3058 MatFactorInfo tinfo; 3059 3060 PetscFunctionBegin; 3061 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3062 PetscValidType(mat,1); 3063 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2); 3064 if (info) PetscValidPointer(info,3); 3065 PetscCheckFalse(mat->rmap->N != mat->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square"); 3066 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3067 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3068 PetscCheck(mat->ops->choleskyfactor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"In-place factorization for Mat type %s is not supported, try out-of-place factorization. See MatCholeskyFactorSymbolic/Numeric",((PetscObject)mat)->type_name); 3069 MatCheckPreallocated(mat,1); 3070 if (!info) { 3071 CHKERRQ(MatFactorInfoInitialize(&tinfo)); 3072 info = &tinfo; 3073 } 3074 3075 CHKERRQ(PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0)); 3076 CHKERRQ((*mat->ops->choleskyfactor)(mat,perm,info)); 3077 CHKERRQ(PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0)); 3078 CHKERRQ(PetscObjectStateIncrease((PetscObject)mat)); 3079 PetscFunctionReturn(0); 3080 } 3081 3082 /*@C 3083 MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization 3084 of a symmetric matrix. 3085 3086 Collective on Mat 3087 3088 Input Parameters: 3089 + fact - the factor matrix obtained with MatGetFactor() 3090 . mat - the matrix 3091 . perm - row and column permutations 3092 - info - options for factorization, includes 3093 $ fill - expected fill as ratio of original fill. 3094 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3095 $ Run with the option -info to determine an optimal value to use 3096 3097 Notes: 3098 See MatLUFactorSymbolic() for the nonsymmetric case. See also 3099 MatCholeskyFactor() and MatCholeskyFactorNumeric(). 3100 3101 Most users should employ the simplified KSP interface for linear solvers 3102 instead of working directly with matrix algebra routines such as this. 3103 See, e.g., KSPCreate(). 3104 3105 Level: developer 3106 3107 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric() 3108 MatGetOrdering() 3109 3110 Developer Note: fortran interface is not autogenerated as the f90 3111 interface definition cannot be generated correctly [due to MatFactorInfo] 3112 3113 @*/ 3114 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 3115 { 3116 MatFactorInfo tinfo; 3117 3118 PetscFunctionBegin; 3119 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3120 PetscValidType(mat,2); 3121 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,3); 3122 if (info) PetscValidPointer(info,4); 3123 PetscValidPointer(fact,1); 3124 PetscCheckFalse(mat->rmap->N != mat->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square"); 3125 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3126 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3127 if (!(fact)->ops->choleskyfactorsymbolic) { 3128 MatSolverType stype; 3129 CHKERRQ(MatFactorGetSolverType(fact,&stype)); 3130 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,stype); 3131 } 3132 MatCheckPreallocated(mat,2); 3133 if (!info) { 3134 CHKERRQ(MatFactorInfoInitialize(&tinfo)); 3135 info = &tinfo; 3136 } 3137 3138 if (!fact->trivialsymbolic) CHKERRQ(PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0)); 3139 CHKERRQ((fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info)); 3140 if (!fact->trivialsymbolic) CHKERRQ(PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0)); 3141 CHKERRQ(PetscObjectStateIncrease((PetscObject)fact)); 3142 PetscFunctionReturn(0); 3143 } 3144 3145 /*@C 3146 MatCholeskyFactorNumeric - Performs numeric Cholesky factorization 3147 of a symmetric matrix. Call this routine after first calling 3148 MatCholeskyFactorSymbolic(). 3149 3150 Collective on Mat 3151 3152 Input Parameters: 3153 + fact - the factor matrix obtained with MatGetFactor() 3154 . mat - the initial matrix 3155 . info - options for factorization 3156 - fact - the symbolic factor of mat 3157 3158 Notes: 3159 Most users should employ the simplified KSP interface for linear solvers 3160 instead of working directly with matrix algebra routines such as this. 3161 See, e.g., KSPCreate(). 3162 3163 Level: developer 3164 3165 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric() 3166 3167 Developer Note: fortran interface is not autogenerated as the f90 3168 interface definition cannot be generated correctly [due to MatFactorInfo] 3169 3170 @*/ 3171 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3172 { 3173 MatFactorInfo tinfo; 3174 3175 PetscFunctionBegin; 3176 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3177 PetscValidType(mat,2); 3178 PetscValidPointer(fact,1); 3179 PetscValidHeaderSpecific(fact,MAT_CLASSID,1); 3180 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3181 PetscCheckFalse(!(fact)->ops->choleskyfactornumeric,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name); 3182 PetscCheckFalse(mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dim %" PetscInt_FMT " should = %" PetscInt_FMT " %" PetscInt_FMT " should = %" PetscInt_FMT,mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N); 3183 MatCheckPreallocated(mat,2); 3184 if (!info) { 3185 CHKERRQ(MatFactorInfoInitialize(&tinfo)); 3186 info = &tinfo; 3187 } 3188 3189 if (!fact->trivialsymbolic) CHKERRQ(PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0)); 3190 else CHKERRQ(PetscLogEventBegin(MAT_CholeskyFactor,mat,fact,0,0)); 3191 CHKERRQ((fact->ops->choleskyfactornumeric)(fact,mat,info)); 3192 if (!fact->trivialsymbolic) CHKERRQ(PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0)); 3193 else CHKERRQ(PetscLogEventEnd(MAT_CholeskyFactor,mat,fact,0,0)); 3194 CHKERRQ(MatViewFromOptions(fact,NULL,"-mat_factor_view")); 3195 CHKERRQ(PetscObjectStateIncrease((PetscObject)fact)); 3196 PetscFunctionReturn(0); 3197 } 3198 3199 /*@ 3200 MatQRFactor - Performs in-place QR factorization of matrix. 3201 3202 Collective on Mat 3203 3204 Input Parameters: 3205 + mat - the matrix 3206 . col - column permutation 3207 - info - options for factorization, includes 3208 $ fill - expected fill as ratio of original fill. 3209 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3210 $ Run with the option -info to determine an optimal value to use 3211 3212 Notes: 3213 Most users should employ the simplified KSP interface for linear solvers 3214 instead of working directly with matrix algebra routines such as this. 3215 See, e.g., KSPCreate(). 3216 3217 This changes the state of the matrix to a factored matrix; it cannot be used 3218 for example with MatSetValues() unless one first calls MatSetUnfactored(). 3219 3220 Level: developer 3221 3222 .seealso: MatQRFactorSymbolic(), MatQRFactorNumeric(), MatLUFactor(), 3223 MatSetUnfactored(), MatFactorInfo, MatGetFactor() 3224 3225 Developer Note: fortran interface is not autogenerated as the f90 3226 interface definition cannot be generated correctly [due to MatFactorInfo] 3227 3228 @*/ 3229 PetscErrorCode MatQRFactor(Mat mat, IS col, const MatFactorInfo *info) 3230 { 3231 PetscFunctionBegin; 3232 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3233 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,2); 3234 if (info) PetscValidPointer(info,3); 3235 PetscValidType(mat,1); 3236 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3237 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3238 MatCheckPreallocated(mat,1); 3239 CHKERRQ(PetscLogEventBegin(MAT_QRFactor,mat,col,0,0)); 3240 CHKERRQ(PetscUseMethod(mat,"MatQRFactor_C", (Mat,IS,const MatFactorInfo*), (mat, col, info))); 3241 CHKERRQ(PetscLogEventEnd(MAT_QRFactor,mat,col,0,0)); 3242 CHKERRQ(PetscObjectStateIncrease((PetscObject)mat)); 3243 PetscFunctionReturn(0); 3244 } 3245 3246 /*@ 3247 MatQRFactorSymbolic - Performs symbolic QR factorization of matrix. 3248 Call this routine before calling MatQRFactorNumeric(). 3249 3250 Collective on Mat 3251 3252 Input Parameters: 3253 + fact - the factor matrix obtained with MatGetFactor() 3254 . mat - the matrix 3255 . col - column permutation 3256 - info - options for factorization, includes 3257 $ fill - expected fill as ratio of original fill. 3258 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3259 $ Run with the option -info to determine an optimal value to use 3260 3261 Most users should employ the simplified KSP interface for linear solvers 3262 instead of working directly with matrix algebra routines such as this. 3263 See, e.g., KSPCreate(). 3264 3265 Level: developer 3266 3267 .seealso: MatQRFactor(), MatQRFactorNumeric(), MatLUFactor(), MatFactorInfo, MatFactorInfoInitialize() 3268 3269 Developer Note: fortran interface is not autogenerated as the f90 3270 interface definition cannot be generated correctly [due to MatFactorInfo] 3271 3272 @*/ 3273 PetscErrorCode MatQRFactorSymbolic(Mat fact,Mat mat,IS col,const MatFactorInfo *info) 3274 { 3275 MatFactorInfo tinfo; 3276 3277 PetscFunctionBegin; 3278 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3279 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 3280 if (info) PetscValidPointer(info,4); 3281 PetscValidType(mat,2); 3282 PetscValidPointer(fact,1); 3283 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3284 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3285 MatCheckPreallocated(mat,2); 3286 if (!info) { 3287 CHKERRQ(MatFactorInfoInitialize(&tinfo)); 3288 info = &tinfo; 3289 } 3290 3291 if (!fact->trivialsymbolic) CHKERRQ(PetscLogEventBegin(MAT_QRFactorSymbolic,fact,mat,col,0)); 3292 CHKERRQ(PetscUseMethod(fact,"MatQRFactorSymbolic_C", (Mat,Mat,IS,const MatFactorInfo*), (fact, mat, col, info))); 3293 if (!fact->trivialsymbolic) CHKERRQ(PetscLogEventEnd(MAT_QRFactorSymbolic,fact,mat,col,0)); 3294 CHKERRQ(PetscObjectStateIncrease((PetscObject)fact)); 3295 PetscFunctionReturn(0); 3296 } 3297 3298 /*@ 3299 MatQRFactorNumeric - Performs numeric QR factorization of a matrix. 3300 Call this routine after first calling MatQRFactorSymbolic(). 3301 3302 Collective on Mat 3303 3304 Input Parameters: 3305 + fact - the factor matrix obtained with MatGetFactor() 3306 . mat - the matrix 3307 - info - options for factorization 3308 3309 Notes: 3310 See MatQRFactor() for in-place factorization. 3311 3312 Most users should employ the simplified KSP interface for linear solvers 3313 instead of working directly with matrix algebra routines such as this. 3314 See, e.g., KSPCreate(). 3315 3316 Level: developer 3317 3318 .seealso: MatQRFactorSymbolic(), MatLUFactor() 3319 3320 Developer Note: fortran interface is not autogenerated as the f90 3321 interface definition cannot be generated correctly [due to MatFactorInfo] 3322 3323 @*/ 3324 PetscErrorCode MatQRFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3325 { 3326 MatFactorInfo tinfo; 3327 3328 PetscFunctionBegin; 3329 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3330 PetscValidType(mat,2); 3331 PetscValidPointer(fact,1); 3332 PetscValidHeaderSpecific(fact,MAT_CLASSID,1); 3333 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3334 PetscCheckFalse(mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dimensions are different %" PetscInt_FMT " should = %" PetscInt_FMT " %" PetscInt_FMT " should = %" PetscInt_FMT,mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N); 3335 3336 MatCheckPreallocated(mat,2); 3337 if (!info) { 3338 CHKERRQ(MatFactorInfoInitialize(&tinfo)); 3339 info = &tinfo; 3340 } 3341 3342 if (!fact->trivialsymbolic) CHKERRQ(PetscLogEventBegin(MAT_QRFactorNumeric,mat,fact,0,0)); 3343 else CHKERRQ(PetscLogEventBegin(MAT_QRFactor,mat,fact,0,0)); 3344 CHKERRQ(PetscUseMethod(fact,"MatQRFactorNumeric_C", (Mat,Mat,const MatFactorInfo*), (fact, mat, info))); 3345 if (!fact->trivialsymbolic) CHKERRQ(PetscLogEventEnd(MAT_QRFactorNumeric,mat,fact,0,0)); 3346 else CHKERRQ(PetscLogEventEnd(MAT_QRFactor,mat,fact,0,0)); 3347 CHKERRQ(MatViewFromOptions(fact,NULL,"-mat_factor_view")); 3348 CHKERRQ(PetscObjectStateIncrease((PetscObject)fact)); 3349 PetscFunctionReturn(0); 3350 } 3351 3352 /* ----------------------------------------------------------------*/ 3353 /*@ 3354 MatSolve - Solves A x = b, given a factored matrix. 3355 3356 Neighbor-wise Collective on Mat 3357 3358 Input Parameters: 3359 + mat - the factored matrix 3360 - b - the right-hand-side vector 3361 3362 Output Parameter: 3363 . x - the result vector 3364 3365 Notes: 3366 The vectors b and x cannot be the same. I.e., one cannot 3367 call MatSolve(A,x,x). 3368 3369 Notes: 3370 Most users should employ the simplified KSP interface for linear solvers 3371 instead of working directly with matrix algebra routines such as this. 3372 See, e.g., KSPCreate(). 3373 3374 Level: developer 3375 3376 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd() 3377 @*/ 3378 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x) 3379 { 3380 PetscFunctionBegin; 3381 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3382 PetscValidType(mat,1); 3383 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3384 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3385 PetscCheckSameComm(mat,1,b,2); 3386 PetscCheckSameComm(mat,1,x,3); 3387 PetscCheckFalse(x == b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3388 PetscCheckFalse(mat->cmap->N != x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,x->map->N); 3389 PetscCheckFalse(mat->rmap->N != b->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,b->map->N); 3390 PetscCheckFalse(mat->rmap->n != b->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,b->map->n); 3391 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3392 MatCheckPreallocated(mat,1); 3393 3394 CHKERRQ(PetscLogEventBegin(MAT_Solve,mat,b,x,0)); 3395 if (mat->factorerrortype) { 3396 CHKERRQ(PetscInfo(mat,"MatFactorError %d\n",mat->factorerrortype)); 3397 CHKERRQ(VecSetInf(x)); 3398 } else { 3399 PetscCheck(mat->ops->solve,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3400 CHKERRQ((*mat->ops->solve)(mat,b,x)); 3401 } 3402 CHKERRQ(PetscLogEventEnd(MAT_Solve,mat,b,x,0)); 3403 CHKERRQ(PetscObjectStateIncrease((PetscObject)x)); 3404 PetscFunctionReturn(0); 3405 } 3406 3407 static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X,PetscBool trans) 3408 { 3409 Vec b,x; 3410 PetscInt N,i; 3411 PetscErrorCode (*f)(Mat,Vec,Vec); 3412 PetscBool Abound,Bneedconv = PETSC_FALSE,Xneedconv = PETSC_FALSE; 3413 3414 PetscFunctionBegin; 3415 if (A->factorerrortype) { 3416 CHKERRQ(PetscInfo(A,"MatFactorError %d\n",A->factorerrortype)); 3417 CHKERRQ(MatSetInf(X)); 3418 PetscFunctionReturn(0); 3419 } 3420 f = (!trans || (!A->ops->solvetranspose && A->symmetric)) ? A->ops->solve : A->ops->solvetranspose; 3421 PetscCheck(f,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 3422 CHKERRQ(MatBoundToCPU(A,&Abound)); 3423 if (!Abound) { 3424 CHKERRQ(PetscObjectTypeCompareAny((PetscObject)B,&Bneedconv,MATSEQDENSE,MATMPIDENSE,"")); 3425 CHKERRQ(PetscObjectTypeCompareAny((PetscObject)X,&Xneedconv,MATSEQDENSE,MATMPIDENSE,"")); 3426 } 3427 if (Bneedconv) { 3428 CHKERRQ(MatConvert(B,MATDENSECUDA,MAT_INPLACE_MATRIX,&B)); 3429 } 3430 if (Xneedconv) { 3431 CHKERRQ(MatConvert(X,MATDENSECUDA,MAT_INPLACE_MATRIX,&X)); 3432 } 3433 CHKERRQ(MatGetSize(B,NULL,&N)); 3434 for (i=0; i<N; i++) { 3435 CHKERRQ(MatDenseGetColumnVecRead(B,i,&b)); 3436 CHKERRQ(MatDenseGetColumnVecWrite(X,i,&x)); 3437 CHKERRQ((*f)(A,b,x)); 3438 CHKERRQ(MatDenseRestoreColumnVecWrite(X,i,&x)); 3439 CHKERRQ(MatDenseRestoreColumnVecRead(B,i,&b)); 3440 } 3441 if (Bneedconv) { 3442 CHKERRQ(MatConvert(B,MATDENSE,MAT_INPLACE_MATRIX,&B)); 3443 } 3444 if (Xneedconv) { 3445 CHKERRQ(MatConvert(X,MATDENSE,MAT_INPLACE_MATRIX,&X)); 3446 } 3447 PetscFunctionReturn(0); 3448 } 3449 3450 /*@ 3451 MatMatSolve - Solves A X = B, given a factored matrix. 3452 3453 Neighbor-wise Collective on Mat 3454 3455 Input Parameters: 3456 + A - the factored matrix 3457 - B - the right-hand-side matrix MATDENSE (or sparse -- when using MUMPS) 3458 3459 Output Parameter: 3460 . X - the result matrix (dense matrix) 3461 3462 Notes: 3463 If B is a MATDENSE matrix then one can call MatMatSolve(A,B,B) except with MKL_CPARDISO; 3464 otherwise, B and X cannot be the same. 3465 3466 Notes: 3467 Most users should usually employ the simplified KSP interface for linear solvers 3468 instead of working directly with matrix algebra routines such as this. 3469 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3470 at a time. 3471 3472 Level: developer 3473 3474 .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor() 3475 @*/ 3476 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X) 3477 { 3478 PetscFunctionBegin; 3479 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3480 PetscValidType(A,1); 3481 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3482 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3483 PetscCheckSameComm(A,1,B,2); 3484 PetscCheckSameComm(A,1,X,3); 3485 PetscCheckFalse(A->cmap->N != X->rmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %" PetscInt_FMT " %" PetscInt_FMT,A->cmap->N,X->rmap->N); 3486 PetscCheckFalse(A->rmap->N != B->rmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %" PetscInt_FMT " %" PetscInt_FMT,A->rmap->N,B->rmap->N); 3487 PetscCheckFalse(X->cmap->N != B->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix"); 3488 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3489 PetscCheck(A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3490 MatCheckPreallocated(A,1); 3491 3492 CHKERRQ(PetscLogEventBegin(MAT_MatSolve,A,B,X,0)); 3493 if (!A->ops->matsolve) { 3494 CHKERRQ(PetscInfo(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name)); 3495 CHKERRQ(MatMatSolve_Basic(A,B,X,PETSC_FALSE)); 3496 } else { 3497 CHKERRQ((*A->ops->matsolve)(A,B,X)); 3498 } 3499 CHKERRQ(PetscLogEventEnd(MAT_MatSolve,A,B,X,0)); 3500 CHKERRQ(PetscObjectStateIncrease((PetscObject)X)); 3501 PetscFunctionReturn(0); 3502 } 3503 3504 /*@ 3505 MatMatSolveTranspose - Solves A^T X = B, given a factored matrix. 3506 3507 Neighbor-wise Collective on Mat 3508 3509 Input Parameters: 3510 + A - the factored matrix 3511 - B - the right-hand-side matrix (dense matrix) 3512 3513 Output Parameter: 3514 . X - the result matrix (dense matrix) 3515 3516 Notes: 3517 The matrices B and X cannot be the same. I.e., one cannot 3518 call MatMatSolveTranspose(A,X,X). 3519 3520 Notes: 3521 Most users should usually employ the simplified KSP interface for linear solvers 3522 instead of working directly with matrix algebra routines such as this. 3523 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3524 at a time. 3525 3526 When using SuperLU_Dist or MUMPS as a parallel solver, PETSc will use their functionality to solve multiple right hand sides simultaneously. 3527 3528 Level: developer 3529 3530 .seealso: MatMatSolve(), MatLUFactor(), MatCholeskyFactor() 3531 @*/ 3532 PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X) 3533 { 3534 PetscFunctionBegin; 3535 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3536 PetscValidType(A,1); 3537 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3538 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3539 PetscCheckSameComm(A,1,B,2); 3540 PetscCheckSameComm(A,1,X,3); 3541 PetscCheckFalse(X == B,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3542 PetscCheckFalse(A->cmap->N != X->rmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %" PetscInt_FMT " %" PetscInt_FMT,A->cmap->N,X->rmap->N); 3543 PetscCheckFalse(A->rmap->N != B->rmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %" PetscInt_FMT " %" PetscInt_FMT,A->rmap->N,B->rmap->N); 3544 PetscCheckFalse(A->rmap->n != B->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat A,Mat B: local dim %" PetscInt_FMT " %" PetscInt_FMT,A->rmap->n,B->rmap->n); 3545 PetscCheckFalse(X->cmap->N < B->cmap->N,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix"); 3546 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3547 PetscCheck(A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3548 MatCheckPreallocated(A,1); 3549 3550 CHKERRQ(PetscLogEventBegin(MAT_MatSolve,A,B,X,0)); 3551 if (!A->ops->matsolvetranspose) { 3552 CHKERRQ(PetscInfo(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name)); 3553 CHKERRQ(MatMatSolve_Basic(A,B,X,PETSC_TRUE)); 3554 } else { 3555 CHKERRQ((*A->ops->matsolvetranspose)(A,B,X)); 3556 } 3557 CHKERRQ(PetscLogEventEnd(MAT_MatSolve,A,B,X,0)); 3558 CHKERRQ(PetscObjectStateIncrease((PetscObject)X)); 3559 PetscFunctionReturn(0); 3560 } 3561 3562 /*@ 3563 MatMatTransposeSolve - Solves A X = B^T, given a factored matrix. 3564 3565 Neighbor-wise Collective on Mat 3566 3567 Input Parameters: 3568 + A - the factored matrix 3569 - Bt - the transpose of right-hand-side matrix 3570 3571 Output Parameter: 3572 . X - the result matrix (dense matrix) 3573 3574 Notes: 3575 Most users should usually employ the simplified KSP interface for linear solvers 3576 instead of working directly with matrix algebra routines such as this. 3577 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3578 at a time. 3579 3580 For MUMPS, it only supports centralized sparse compressed column format on the host processor for right hand side matrix. User must create B^T in sparse compressed row format on the host processor and call MatMatTransposeSolve() to implement MUMPS' MatMatSolve(). 3581 3582 Level: developer 3583 3584 .seealso: MatMatSolve(), MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor() 3585 @*/ 3586 PetscErrorCode MatMatTransposeSolve(Mat A,Mat Bt,Mat X) 3587 { 3588 PetscFunctionBegin; 3589 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3590 PetscValidType(A,1); 3591 PetscValidHeaderSpecific(Bt,MAT_CLASSID,2); 3592 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3593 PetscCheckSameComm(A,1,Bt,2); 3594 PetscCheckSameComm(A,1,X,3); 3595 3596 PetscCheckFalse(X == Bt,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3597 PetscCheckFalse(A->cmap->N != X->rmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %" PetscInt_FMT " %" PetscInt_FMT,A->cmap->N,X->rmap->N); 3598 PetscCheckFalse(A->rmap->N != Bt->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat Bt: global dim %" PetscInt_FMT " %" PetscInt_FMT,A->rmap->N,Bt->cmap->N); 3599 PetscCheckFalse(X->cmap->N < Bt->rmap->N,PetscObjectComm((PetscObject)X),PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as row number of the rhs matrix"); 3600 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3601 PetscCheck(A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3602 MatCheckPreallocated(A,1); 3603 3604 PetscCheck(A->ops->mattransposesolve,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 3605 CHKERRQ(PetscLogEventBegin(MAT_MatTrSolve,A,Bt,X,0)); 3606 CHKERRQ((*A->ops->mattransposesolve)(A,Bt,X)); 3607 CHKERRQ(PetscLogEventEnd(MAT_MatTrSolve,A,Bt,X,0)); 3608 CHKERRQ(PetscObjectStateIncrease((PetscObject)X)); 3609 PetscFunctionReturn(0); 3610 } 3611 3612 /*@ 3613 MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or 3614 U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U, 3615 3616 Neighbor-wise Collective on Mat 3617 3618 Input Parameters: 3619 + mat - the factored matrix 3620 - b - the right-hand-side vector 3621 3622 Output Parameter: 3623 . x - the result vector 3624 3625 Notes: 3626 MatSolve() should be used for most applications, as it performs 3627 a forward solve followed by a backward solve. 3628 3629 The vectors b and x cannot be the same, i.e., one cannot 3630 call MatForwardSolve(A,x,x). 3631 3632 For matrix in seqsbaij format with block size larger than 1, 3633 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3634 MatForwardSolve() solves U^T*D y = b, and 3635 MatBackwardSolve() solves U x = y. 3636 Thus they do not provide a symmetric preconditioner. 3637 3638 Most users should employ the simplified KSP interface for linear solvers 3639 instead of working directly with matrix algebra routines such as this. 3640 See, e.g., KSPCreate(). 3641 3642 Level: developer 3643 3644 .seealso: MatSolve(), MatBackwardSolve() 3645 @*/ 3646 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x) 3647 { 3648 PetscFunctionBegin; 3649 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3650 PetscValidType(mat,1); 3651 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3652 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3653 PetscCheckSameComm(mat,1,b,2); 3654 PetscCheckSameComm(mat,1,x,3); 3655 PetscCheckFalse(x == b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3656 PetscCheckFalse(mat->cmap->N != x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,x->map->N); 3657 PetscCheckFalse(mat->rmap->N != b->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,b->map->N); 3658 PetscCheckFalse(mat->rmap->n != b->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,b->map->n); 3659 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3660 MatCheckPreallocated(mat,1); 3661 3662 PetscCheck(mat->ops->forwardsolve,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3663 CHKERRQ(PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0)); 3664 CHKERRQ((*mat->ops->forwardsolve)(mat,b,x)); 3665 CHKERRQ(PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0)); 3666 CHKERRQ(PetscObjectStateIncrease((PetscObject)x)); 3667 PetscFunctionReturn(0); 3668 } 3669 3670 /*@ 3671 MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU. 3672 D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U, 3673 3674 Neighbor-wise Collective on Mat 3675 3676 Input Parameters: 3677 + mat - the factored matrix 3678 - b - the right-hand-side vector 3679 3680 Output Parameter: 3681 . x - the result vector 3682 3683 Notes: 3684 MatSolve() should be used for most applications, as it performs 3685 a forward solve followed by a backward solve. 3686 3687 The vectors b and x cannot be the same. I.e., one cannot 3688 call MatBackwardSolve(A,x,x). 3689 3690 For matrix in seqsbaij format with block size larger than 1, 3691 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3692 MatForwardSolve() solves U^T*D y = b, and 3693 MatBackwardSolve() solves U x = y. 3694 Thus they do not provide a symmetric preconditioner. 3695 3696 Most users should employ the simplified KSP interface for linear solvers 3697 instead of working directly with matrix algebra routines such as this. 3698 See, e.g., KSPCreate(). 3699 3700 Level: developer 3701 3702 .seealso: MatSolve(), MatForwardSolve() 3703 @*/ 3704 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x) 3705 { 3706 PetscFunctionBegin; 3707 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3708 PetscValidType(mat,1); 3709 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3710 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3711 PetscCheckSameComm(mat,1,b,2); 3712 PetscCheckSameComm(mat,1,x,3); 3713 PetscCheckFalse(x == b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3714 PetscCheckFalse(mat->cmap->N != x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,x->map->N); 3715 PetscCheckFalse(mat->rmap->N != b->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,b->map->N); 3716 PetscCheckFalse(mat->rmap->n != b->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,b->map->n); 3717 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3718 MatCheckPreallocated(mat,1); 3719 3720 PetscCheck(mat->ops->backwardsolve,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3721 CHKERRQ(PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0)); 3722 CHKERRQ((*mat->ops->backwardsolve)(mat,b,x)); 3723 CHKERRQ(PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0)); 3724 CHKERRQ(PetscObjectStateIncrease((PetscObject)x)); 3725 PetscFunctionReturn(0); 3726 } 3727 3728 /*@ 3729 MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix. 3730 3731 Neighbor-wise Collective on Mat 3732 3733 Input Parameters: 3734 + mat - the factored matrix 3735 . b - the right-hand-side vector 3736 - y - the vector to be added to 3737 3738 Output Parameter: 3739 . x - the result vector 3740 3741 Notes: 3742 The vectors b and x cannot be the same. I.e., one cannot 3743 call MatSolveAdd(A,x,y,x). 3744 3745 Most users should employ the simplified KSP interface for linear solvers 3746 instead of working directly with matrix algebra routines such as this. 3747 See, e.g., KSPCreate(). 3748 3749 Level: developer 3750 3751 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd() 3752 @*/ 3753 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x) 3754 { 3755 PetscScalar one = 1.0; 3756 Vec tmp; 3757 3758 PetscFunctionBegin; 3759 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3760 PetscValidType(mat,1); 3761 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 3762 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3763 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 3764 PetscCheckSameComm(mat,1,b,2); 3765 PetscCheckSameComm(mat,1,y,3); 3766 PetscCheckSameComm(mat,1,x,4); 3767 PetscCheckFalse(x == b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3768 PetscCheckFalse(mat->cmap->N != x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,x->map->N); 3769 PetscCheckFalse(mat->rmap->N != b->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,b->map->N); 3770 PetscCheckFalse(mat->rmap->N != y->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,y->map->N); 3771 PetscCheckFalse(mat->rmap->n != b->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,b->map->n); 3772 PetscCheckFalse(x->map->n != y->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %" PetscInt_FMT " %" PetscInt_FMT,x->map->n,y->map->n); 3773 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3774 MatCheckPreallocated(mat,1); 3775 3776 CHKERRQ(PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y)); 3777 if (mat->factorerrortype) { 3778 3779 CHKERRQ(PetscInfo(mat,"MatFactorError %d\n",mat->factorerrortype)); 3780 CHKERRQ(VecSetInf(x)); 3781 } else if (mat->ops->solveadd) { 3782 CHKERRQ((*mat->ops->solveadd)(mat,b,y,x)); 3783 } else { 3784 /* do the solve then the add manually */ 3785 if (x != y) { 3786 CHKERRQ(MatSolve(mat,b,x)); 3787 CHKERRQ(VecAXPY(x,one,y)); 3788 } else { 3789 CHKERRQ(VecDuplicate(x,&tmp)); 3790 CHKERRQ(PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp)); 3791 CHKERRQ(VecCopy(x,tmp)); 3792 CHKERRQ(MatSolve(mat,b,x)); 3793 CHKERRQ(VecAXPY(x,one,tmp)); 3794 CHKERRQ(VecDestroy(&tmp)); 3795 } 3796 } 3797 CHKERRQ(PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y)); 3798 CHKERRQ(PetscObjectStateIncrease((PetscObject)x)); 3799 PetscFunctionReturn(0); 3800 } 3801 3802 /*@ 3803 MatSolveTranspose - Solves A' x = b, given a factored matrix. 3804 3805 Neighbor-wise Collective on Mat 3806 3807 Input Parameters: 3808 + mat - the factored matrix 3809 - b - the right-hand-side vector 3810 3811 Output Parameter: 3812 . x - the result vector 3813 3814 Notes: 3815 The vectors b and x cannot be the same. I.e., one cannot 3816 call MatSolveTranspose(A,x,x). 3817 3818 Most users should employ the simplified KSP interface for linear solvers 3819 instead of working directly with matrix algebra routines such as this. 3820 See, e.g., KSPCreate(). 3821 3822 Level: developer 3823 3824 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd() 3825 @*/ 3826 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x) 3827 { 3828 PetscErrorCode (*f)(Mat,Vec,Vec) = (!mat->ops->solvetranspose && mat->symmetric) ? mat->ops->solve : mat->ops->solvetranspose; 3829 3830 PetscFunctionBegin; 3831 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3832 PetscValidType(mat,1); 3833 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3834 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3835 PetscCheckSameComm(mat,1,b,2); 3836 PetscCheckSameComm(mat,1,x,3); 3837 PetscCheckFalse(x == b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3838 PetscCheckFalse(mat->rmap->N != x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,x->map->N); 3839 PetscCheckFalse(mat->cmap->N != b->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,b->map->N); 3840 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3841 MatCheckPreallocated(mat,1); 3842 CHKERRQ(PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0)); 3843 if (mat->factorerrortype) { 3844 CHKERRQ(PetscInfo(mat,"MatFactorError %d\n",mat->factorerrortype)); 3845 CHKERRQ(VecSetInf(x)); 3846 } else { 3847 PetscCheck(f,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name); 3848 CHKERRQ((*f)(mat,b,x)); 3849 } 3850 CHKERRQ(PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0)); 3851 CHKERRQ(PetscObjectStateIncrease((PetscObject)x)); 3852 PetscFunctionReturn(0); 3853 } 3854 3855 /*@ 3856 MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a 3857 factored matrix. 3858 3859 Neighbor-wise Collective on Mat 3860 3861 Input Parameters: 3862 + mat - the factored matrix 3863 . b - the right-hand-side vector 3864 - y - the vector to be added to 3865 3866 Output Parameter: 3867 . x - the result vector 3868 3869 Notes: 3870 The vectors b and x cannot be the same. I.e., one cannot 3871 call MatSolveTransposeAdd(A,x,y,x). 3872 3873 Most users should employ the simplified KSP interface for linear solvers 3874 instead of working directly with matrix algebra routines such as this. 3875 See, e.g., KSPCreate(). 3876 3877 Level: developer 3878 3879 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose() 3880 @*/ 3881 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x) 3882 { 3883 PetscScalar one = 1.0; 3884 Vec tmp; 3885 PetscErrorCode (*f)(Mat,Vec,Vec,Vec) = (!mat->ops->solvetransposeadd && mat->symmetric) ? mat->ops->solveadd : mat->ops->solvetransposeadd; 3886 3887 PetscFunctionBegin; 3888 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3889 PetscValidType(mat,1); 3890 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 3891 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3892 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 3893 PetscCheckSameComm(mat,1,b,2); 3894 PetscCheckSameComm(mat,1,y,3); 3895 PetscCheckSameComm(mat,1,x,4); 3896 PetscCheckFalse(x == b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3897 PetscCheckFalse(mat->rmap->N != x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,x->map->N); 3898 PetscCheckFalse(mat->cmap->N != b->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,b->map->N); 3899 PetscCheckFalse(mat->cmap->N != y->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,y->map->N); 3900 PetscCheckFalse(x->map->n != y->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %" PetscInt_FMT " %" PetscInt_FMT,x->map->n,y->map->n); 3901 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3902 MatCheckPreallocated(mat,1); 3903 3904 CHKERRQ(PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y)); 3905 if (mat->factorerrortype) { 3906 CHKERRQ(PetscInfo(mat,"MatFactorError %d\n",mat->factorerrortype)); 3907 CHKERRQ(VecSetInf(x)); 3908 } else if (f) { 3909 CHKERRQ((*f)(mat,b,y,x)); 3910 } else { 3911 /* do the solve then the add manually */ 3912 if (x != y) { 3913 CHKERRQ(MatSolveTranspose(mat,b,x)); 3914 CHKERRQ(VecAXPY(x,one,y)); 3915 } else { 3916 CHKERRQ(VecDuplicate(x,&tmp)); 3917 CHKERRQ(PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp)); 3918 CHKERRQ(VecCopy(x,tmp)); 3919 CHKERRQ(MatSolveTranspose(mat,b,x)); 3920 CHKERRQ(VecAXPY(x,one,tmp)); 3921 CHKERRQ(VecDestroy(&tmp)); 3922 } 3923 } 3924 CHKERRQ(PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y)); 3925 CHKERRQ(PetscObjectStateIncrease((PetscObject)x)); 3926 PetscFunctionReturn(0); 3927 } 3928 /* ----------------------------------------------------------------*/ 3929 3930 /*@ 3931 MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps. 3932 3933 Neighbor-wise Collective on Mat 3934 3935 Input Parameters: 3936 + mat - the matrix 3937 . b - the right hand side 3938 . omega - the relaxation factor 3939 . flag - flag indicating the type of SOR (see below) 3940 . shift - diagonal shift 3941 . its - the number of iterations 3942 - lits - the number of local iterations 3943 3944 Output Parameter: 3945 . x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess) 3946 3947 SOR Flags: 3948 + SOR_FORWARD_SWEEP - forward SOR 3949 . SOR_BACKWARD_SWEEP - backward SOR 3950 . SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR) 3951 . SOR_LOCAL_FORWARD_SWEEP - local forward SOR 3952 . SOR_LOCAL_BACKWARD_SWEEP - local forward SOR 3953 . SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR 3954 . SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies 3955 upper/lower triangular part of matrix to 3956 vector (with omega) 3957 - SOR_ZERO_INITIAL_GUESS - zero initial guess 3958 3959 Notes: 3960 SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and 3961 SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings 3962 on each processor. 3963 3964 Application programmers will not generally use MatSOR() directly, 3965 but instead will employ the KSP/PC interface. 3966 3967 Notes: 3968 for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing 3969 3970 Notes for Advanced Users: 3971 The flags are implemented as bitwise inclusive or operations. 3972 For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP) 3973 to specify a zero initial guess for SSOR. 3974 3975 Most users should employ the simplified KSP interface for linear solvers 3976 instead of working directly with matrix algebra routines such as this. 3977 See, e.g., KSPCreate(). 3978 3979 Vectors x and b CANNOT be the same 3980 3981 Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes 3982 3983 Level: developer 3984 3985 @*/ 3986 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x) 3987 { 3988 PetscFunctionBegin; 3989 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3990 PetscValidType(mat,1); 3991 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3992 PetscValidHeaderSpecific(x,VEC_CLASSID,8); 3993 PetscCheckSameComm(mat,1,b,2); 3994 PetscCheckSameComm(mat,1,x,8); 3995 PetscCheck(mat->ops->sor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3996 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3997 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3998 PetscCheckFalse(mat->cmap->N != x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,x->map->N); 3999 PetscCheckFalse(mat->rmap->N != b->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,b->map->N); 4000 PetscCheckFalse(mat->rmap->n != b->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,b->map->n); 4001 PetscCheckFalse(its <= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %" PetscInt_FMT " positive",its); 4002 PetscCheckFalse(lits <= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %" PetscInt_FMT " positive",lits); 4003 PetscCheckFalse(b == x,PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same"); 4004 4005 MatCheckPreallocated(mat,1); 4006 CHKERRQ(PetscLogEventBegin(MAT_SOR,mat,b,x,0)); 4007 CHKERRQ((*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x)); 4008 CHKERRQ(PetscLogEventEnd(MAT_SOR,mat,b,x,0)); 4009 CHKERRQ(PetscObjectStateIncrease((PetscObject)x)); 4010 PetscFunctionReturn(0); 4011 } 4012 4013 /* 4014 Default matrix copy routine. 4015 */ 4016 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str) 4017 { 4018 PetscInt i,rstart = 0,rend = 0,nz; 4019 const PetscInt *cwork; 4020 const PetscScalar *vwork; 4021 4022 PetscFunctionBegin; 4023 if (B->assembled) { 4024 CHKERRQ(MatZeroEntries(B)); 4025 } 4026 if (str == SAME_NONZERO_PATTERN) { 4027 CHKERRQ(MatGetOwnershipRange(A,&rstart,&rend)); 4028 for (i=rstart; i<rend; i++) { 4029 CHKERRQ(MatGetRow(A,i,&nz,&cwork,&vwork)); 4030 CHKERRQ(MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES)); 4031 CHKERRQ(MatRestoreRow(A,i,&nz,&cwork,&vwork)); 4032 } 4033 } else { 4034 CHKERRQ(MatAYPX(B,0.0,A,str)); 4035 } 4036 CHKERRQ(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY)); 4037 CHKERRQ(MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY)); 4038 PetscFunctionReturn(0); 4039 } 4040 4041 /*@ 4042 MatCopy - Copies a matrix to another matrix. 4043 4044 Collective on Mat 4045 4046 Input Parameters: 4047 + A - the matrix 4048 - str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN 4049 4050 Output Parameter: 4051 . B - where the copy is put 4052 4053 Notes: 4054 If you use SAME_NONZERO_PATTERN then the two matrices must have the same nonzero pattern or the routine will crash. 4055 4056 MatCopy() copies the matrix entries of a matrix to another existing 4057 matrix (after first zeroing the second matrix). A related routine is 4058 MatConvert(), which first creates a new matrix and then copies the data. 4059 4060 Level: intermediate 4061 4062 .seealso: MatConvert(), MatDuplicate() 4063 @*/ 4064 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str) 4065 { 4066 PetscInt i; 4067 4068 PetscFunctionBegin; 4069 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4070 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4071 PetscValidType(A,1); 4072 PetscValidType(B,2); 4073 PetscCheckSameComm(A,1,B,2); 4074 MatCheckPreallocated(B,2); 4075 PetscCheck(A->assembled,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4076 PetscCheck(!A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4077 PetscCheckFalse(A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim (%" PetscInt_FMT ",%" PetscInt_FMT ") (%" PetscInt_FMT ",%" PetscInt_FMT ")",A->rmap->N,B->rmap->N,A->cmap->N,B->cmap->N); 4078 MatCheckPreallocated(A,1); 4079 if (A == B) PetscFunctionReturn(0); 4080 4081 CHKERRQ(PetscLogEventBegin(MAT_Copy,A,B,0,0)); 4082 if (A->ops->copy) { 4083 CHKERRQ((*A->ops->copy)(A,B,str)); 4084 } else { /* generic conversion */ 4085 CHKERRQ(MatCopy_Basic(A,B,str)); 4086 } 4087 4088 B->stencil.dim = A->stencil.dim; 4089 B->stencil.noc = A->stencil.noc; 4090 for (i=0; i<=A->stencil.dim; i++) { 4091 B->stencil.dims[i] = A->stencil.dims[i]; 4092 B->stencil.starts[i] = A->stencil.starts[i]; 4093 } 4094 4095 CHKERRQ(PetscLogEventEnd(MAT_Copy,A,B,0,0)); 4096 CHKERRQ(PetscObjectStateIncrease((PetscObject)B)); 4097 PetscFunctionReturn(0); 4098 } 4099 4100 /*@C 4101 MatConvert - Converts a matrix to another matrix, either of the same 4102 or different type. 4103 4104 Collective on Mat 4105 4106 Input Parameters: 4107 + mat - the matrix 4108 . newtype - new matrix type. Use MATSAME to create a new matrix of the 4109 same type as the original matrix. 4110 - reuse - denotes if the destination matrix is to be created or reused. 4111 Use MAT_INPLACE_MATRIX for inplace conversion (that is when you want the input mat to be changed to contain the matrix in the new format), otherwise use 4112 MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX (can only be used after the first call was made with MAT_INITIAL_MATRIX, causes the matrix space in M to be reused). 4113 4114 Output Parameter: 4115 . M - pointer to place new matrix 4116 4117 Notes: 4118 MatConvert() first creates a new matrix and then copies the data from 4119 the first matrix. A related routine is MatCopy(), which copies the matrix 4120 entries of one matrix to another already existing matrix context. 4121 4122 Cannot be used to convert a sequential matrix to parallel or parallel to sequential, 4123 the MPI communicator of the generated matrix is always the same as the communicator 4124 of the input matrix. 4125 4126 Level: intermediate 4127 4128 .seealso: MatCopy(), MatDuplicate() 4129 @*/ 4130 PetscErrorCode MatConvert(Mat mat,MatType newtype,MatReuse reuse,Mat *M) 4131 { 4132 PetscBool sametype,issame,flg,issymmetric,ishermitian; 4133 char convname[256],mtype[256]; 4134 Mat B; 4135 4136 PetscFunctionBegin; 4137 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4138 PetscValidType(mat,1); 4139 PetscValidPointer(M,4); 4140 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4141 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4142 MatCheckPreallocated(mat,1); 4143 4144 CHKERRQ(PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,sizeof(mtype),&flg)); 4145 if (flg) newtype = mtype; 4146 4147 CHKERRQ(PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype)); 4148 CHKERRQ(PetscStrcmp(newtype,"same",&issame)); 4149 PetscCheckFalse((reuse == MAT_INPLACE_MATRIX) && (mat != *M),PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix"); 4150 PetscCheckFalse((reuse == MAT_REUSE_MATRIX) && (mat == *M),PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_REUSE_MATRIX means reuse matrix in final argument, perhaps you mean MAT_INPLACE_MATRIX"); 4151 4152 if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) { 4153 CHKERRQ(PetscInfo(mat,"Early return for inplace %s %d %d\n",((PetscObject)mat)->type_name,sametype,issame)); 4154 PetscFunctionReturn(0); 4155 } 4156 4157 /* Cache Mat options because some converter use MatHeaderReplace */ 4158 issymmetric = mat->symmetric; 4159 ishermitian = mat->hermitian; 4160 4161 if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) { 4162 CHKERRQ(PetscInfo(mat,"Calling duplicate for initial matrix %s %d %d\n",((PetscObject)mat)->type_name,sametype,issame)); 4163 CHKERRQ((*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M)); 4164 } else { 4165 PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL; 4166 const char *prefix[3] = {"seq","mpi",""}; 4167 PetscInt i; 4168 /* 4169 Order of precedence: 4170 0) See if newtype is a superclass of the current matrix. 4171 1) See if a specialized converter is known to the current matrix. 4172 2) See if a specialized converter is known to the desired matrix class. 4173 3) See if a good general converter is registered for the desired class 4174 (as of 6/27/03 only MATMPIADJ falls into this category). 4175 4) See if a good general converter is known for the current matrix. 4176 5) Use a really basic converter. 4177 */ 4178 4179 /* 0) See if newtype is a superclass of the current matrix. 4180 i.e mat is mpiaij and newtype is aij */ 4181 for (i=0; i<2; i++) { 4182 CHKERRQ(PetscStrncpy(convname,prefix[i],sizeof(convname))); 4183 CHKERRQ(PetscStrlcat(convname,newtype,sizeof(convname))); 4184 CHKERRQ(PetscStrcmp(convname,((PetscObject)mat)->type_name,&flg)); 4185 CHKERRQ(PetscInfo(mat,"Check superclass %s %s -> %d\n",convname,((PetscObject)mat)->type_name,flg)); 4186 if (flg) { 4187 if (reuse == MAT_INPLACE_MATRIX) { 4188 CHKERRQ(PetscInfo(mat,"Early return\n")); 4189 PetscFunctionReturn(0); 4190 } else if (reuse == MAT_INITIAL_MATRIX && mat->ops->duplicate) { 4191 CHKERRQ(PetscInfo(mat,"Calling MatDuplicate\n")); 4192 CHKERRQ((*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M)); 4193 PetscFunctionReturn(0); 4194 } else if (reuse == MAT_REUSE_MATRIX && mat->ops->copy) { 4195 CHKERRQ(PetscInfo(mat,"Calling MatCopy\n")); 4196 CHKERRQ(MatCopy(mat,*M,SAME_NONZERO_PATTERN)); 4197 PetscFunctionReturn(0); 4198 } 4199 } 4200 } 4201 /* 1) See if a specialized converter is known to the current matrix and the desired class */ 4202 for (i=0; i<3; i++) { 4203 CHKERRQ(PetscStrncpy(convname,"MatConvert_",sizeof(convname))); 4204 CHKERRQ(PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname))); 4205 CHKERRQ(PetscStrlcat(convname,"_",sizeof(convname))); 4206 CHKERRQ(PetscStrlcat(convname,prefix[i],sizeof(convname))); 4207 CHKERRQ(PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname))); 4208 CHKERRQ(PetscStrlcat(convname,"_C",sizeof(convname))); 4209 CHKERRQ(PetscObjectQueryFunction((PetscObject)mat,convname,&conv)); 4210 CHKERRQ(PetscInfo(mat,"Check specialized (1) %s (%s) -> %d\n",convname,((PetscObject)mat)->type_name,!!conv)); 4211 if (conv) goto foundconv; 4212 } 4213 4214 /* 2) See if a specialized converter is known to the desired matrix class. */ 4215 CHKERRQ(MatCreate(PetscObjectComm((PetscObject)mat),&B)); 4216 CHKERRQ(MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N)); 4217 CHKERRQ(MatSetType(B,newtype)); 4218 for (i=0; i<3; i++) { 4219 CHKERRQ(PetscStrncpy(convname,"MatConvert_",sizeof(convname))); 4220 CHKERRQ(PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname))); 4221 CHKERRQ(PetscStrlcat(convname,"_",sizeof(convname))); 4222 CHKERRQ(PetscStrlcat(convname,prefix[i],sizeof(convname))); 4223 CHKERRQ(PetscStrlcat(convname,newtype,sizeof(convname))); 4224 CHKERRQ(PetscStrlcat(convname,"_C",sizeof(convname))); 4225 CHKERRQ(PetscObjectQueryFunction((PetscObject)B,convname,&conv)); 4226 CHKERRQ(PetscInfo(mat,"Check specialized (2) %s (%s) -> %d\n",convname,((PetscObject)B)->type_name,!!conv)); 4227 if (conv) { 4228 CHKERRQ(MatDestroy(&B)); 4229 goto foundconv; 4230 } 4231 } 4232 4233 /* 3) See if a good general converter is registered for the desired class */ 4234 conv = B->ops->convertfrom; 4235 CHKERRQ(PetscInfo(mat,"Check convertfrom (%s) -> %d\n",((PetscObject)B)->type_name,!!conv)); 4236 CHKERRQ(MatDestroy(&B)); 4237 if (conv) goto foundconv; 4238 4239 /* 4) See if a good general converter is known for the current matrix */ 4240 if (mat->ops->convert) conv = mat->ops->convert; 4241 CHKERRQ(PetscInfo(mat,"Check general convert (%s) -> %d\n",((PetscObject)mat)->type_name,!!conv)); 4242 if (conv) goto foundconv; 4243 4244 /* 5) Use a really basic converter. */ 4245 CHKERRQ(PetscInfo(mat,"Using MatConvert_Basic\n")); 4246 conv = MatConvert_Basic; 4247 4248 foundconv: 4249 CHKERRQ(PetscLogEventBegin(MAT_Convert,mat,0,0,0)); 4250 CHKERRQ((*conv)(mat,newtype,reuse,M)); 4251 if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) { 4252 /* the block sizes must be same if the mappings are copied over */ 4253 (*M)->rmap->bs = mat->rmap->bs; 4254 (*M)->cmap->bs = mat->cmap->bs; 4255 CHKERRQ(PetscObjectReference((PetscObject)mat->rmap->mapping)); 4256 CHKERRQ(PetscObjectReference((PetscObject)mat->cmap->mapping)); 4257 (*M)->rmap->mapping = mat->rmap->mapping; 4258 (*M)->cmap->mapping = mat->cmap->mapping; 4259 } 4260 (*M)->stencil.dim = mat->stencil.dim; 4261 (*M)->stencil.noc = mat->stencil.noc; 4262 for (i=0; i<=mat->stencil.dim; i++) { 4263 (*M)->stencil.dims[i] = mat->stencil.dims[i]; 4264 (*M)->stencil.starts[i] = mat->stencil.starts[i]; 4265 } 4266 CHKERRQ(PetscLogEventEnd(MAT_Convert,mat,0,0,0)); 4267 } 4268 CHKERRQ(PetscObjectStateIncrease((PetscObject)*M)); 4269 4270 /* Copy Mat options */ 4271 if (issymmetric) { 4272 CHKERRQ(MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE)); 4273 } 4274 if (ishermitian) { 4275 CHKERRQ(MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE)); 4276 } 4277 PetscFunctionReturn(0); 4278 } 4279 4280 /*@C 4281 MatFactorGetSolverType - Returns name of the package providing the factorization routines 4282 4283 Not Collective 4284 4285 Input Parameter: 4286 . mat - the matrix, must be a factored matrix 4287 4288 Output Parameter: 4289 . type - the string name of the package (do not free this string) 4290 4291 Notes: 4292 In Fortran you pass in a empty string and the package name will be copied into it. 4293 (Make sure the string is long enough) 4294 4295 Level: intermediate 4296 4297 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor() 4298 @*/ 4299 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type) 4300 { 4301 PetscErrorCode (*conv)(Mat,MatSolverType*); 4302 4303 PetscFunctionBegin; 4304 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4305 PetscValidType(mat,1); 4306 PetscValidPointer(type,2); 4307 PetscCheck(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 4308 CHKERRQ(PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv)); 4309 if (conv) CHKERRQ((*conv)(mat,type)); 4310 else *type = MATSOLVERPETSC; 4311 PetscFunctionReturn(0); 4312 } 4313 4314 typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType; 4315 struct _MatSolverTypeForSpecifcType { 4316 MatType mtype; 4317 /* no entry for MAT_FACTOR_NONE */ 4318 PetscErrorCode (*createfactor[MAT_FACTOR_NUM_TYPES-1])(Mat,MatFactorType,Mat*); 4319 MatSolverTypeForSpecifcType next; 4320 }; 4321 4322 typedef struct _MatSolverTypeHolder* MatSolverTypeHolder; 4323 struct _MatSolverTypeHolder { 4324 char *name; 4325 MatSolverTypeForSpecifcType handlers; 4326 MatSolverTypeHolder next; 4327 }; 4328 4329 static MatSolverTypeHolder MatSolverTypeHolders = NULL; 4330 4331 /*@C 4332 MatSolverTypeRegister - Registers a MatSolverType that works for a particular matrix type 4333 4334 Input Parameters: 4335 + package - name of the package, for example petsc or superlu 4336 . mtype - the matrix type that works with this package 4337 . ftype - the type of factorization supported by the package 4338 - createfactor - routine that will create the factored matrix ready to be used 4339 4340 Level: intermediate 4341 4342 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor() 4343 @*/ 4344 PetscErrorCode MatSolverTypeRegister(MatSolverType package,MatType mtype,MatFactorType ftype,PetscErrorCode (*createfactor)(Mat,MatFactorType,Mat*)) 4345 { 4346 MatSolverTypeHolder next = MatSolverTypeHolders,prev = NULL; 4347 PetscBool flg; 4348 MatSolverTypeForSpecifcType inext,iprev = NULL; 4349 4350 PetscFunctionBegin; 4351 CHKERRQ(MatInitializePackage()); 4352 if (!next) { 4353 CHKERRQ(PetscNew(&MatSolverTypeHolders)); 4354 CHKERRQ(PetscStrallocpy(package,&MatSolverTypeHolders->name)); 4355 CHKERRQ(PetscNew(&MatSolverTypeHolders->handlers)); 4356 CHKERRQ(PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype)); 4357 MatSolverTypeHolders->handlers->createfactor[(int)ftype-1] = createfactor; 4358 PetscFunctionReturn(0); 4359 } 4360 while (next) { 4361 CHKERRQ(PetscStrcasecmp(package,next->name,&flg)); 4362 if (flg) { 4363 PetscCheck(next->handlers,PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers"); 4364 inext = next->handlers; 4365 while (inext) { 4366 CHKERRQ(PetscStrcasecmp(mtype,inext->mtype,&flg)); 4367 if (flg) { 4368 inext->createfactor[(int)ftype-1] = createfactor; 4369 PetscFunctionReturn(0); 4370 } 4371 iprev = inext; 4372 inext = inext->next; 4373 } 4374 CHKERRQ(PetscNew(&iprev->next)); 4375 CHKERRQ(PetscStrallocpy(mtype,(char **)&iprev->next->mtype)); 4376 iprev->next->createfactor[(int)ftype-1] = createfactor; 4377 PetscFunctionReturn(0); 4378 } 4379 prev = next; 4380 next = next->next; 4381 } 4382 CHKERRQ(PetscNew(&prev->next)); 4383 CHKERRQ(PetscStrallocpy(package,&prev->next->name)); 4384 CHKERRQ(PetscNew(&prev->next->handlers)); 4385 CHKERRQ(PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype)); 4386 prev->next->handlers->createfactor[(int)ftype-1] = createfactor; 4387 PetscFunctionReturn(0); 4388 } 4389 4390 /*@C 4391 MatSolveTypeGet - Gets the function that creates the factor matrix if it exist 4392 4393 Input Parameters: 4394 + type - name of the package, for example petsc or superlu 4395 . ftype - the type of factorization supported by the type 4396 - mtype - the matrix type that works with this type 4397 4398 Output Parameters: 4399 + foundtype - PETSC_TRUE if the type was registered 4400 . foundmtype - PETSC_TRUE if the type supports the requested mtype 4401 - createfactor - routine that will create the factored matrix ready to be used or NULL if not found 4402 4403 Level: intermediate 4404 4405 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatSolverTypeRegister(), MatGetFactor() 4406 @*/ 4407 PetscErrorCode MatSolverTypeGet(MatSolverType type,MatType mtype,MatFactorType ftype,PetscBool *foundtype,PetscBool *foundmtype,PetscErrorCode (**createfactor)(Mat,MatFactorType,Mat*)) 4408 { 4409 MatSolverTypeHolder next = MatSolverTypeHolders; 4410 PetscBool flg; 4411 MatSolverTypeForSpecifcType inext; 4412 4413 PetscFunctionBegin; 4414 if (foundtype) *foundtype = PETSC_FALSE; 4415 if (foundmtype) *foundmtype = PETSC_FALSE; 4416 if (createfactor) *createfactor = NULL; 4417 4418 if (type) { 4419 while (next) { 4420 CHKERRQ(PetscStrcasecmp(type,next->name,&flg)); 4421 if (flg) { 4422 if (foundtype) *foundtype = PETSC_TRUE; 4423 inext = next->handlers; 4424 while (inext) { 4425 CHKERRQ(PetscStrbeginswith(mtype,inext->mtype,&flg)); 4426 if (flg) { 4427 if (foundmtype) *foundmtype = PETSC_TRUE; 4428 if (createfactor) *createfactor = inext->createfactor[(int)ftype-1]; 4429 PetscFunctionReturn(0); 4430 } 4431 inext = inext->next; 4432 } 4433 } 4434 next = next->next; 4435 } 4436 } else { 4437 while (next) { 4438 inext = next->handlers; 4439 while (inext) { 4440 CHKERRQ(PetscStrcmp(mtype,inext->mtype,&flg)); 4441 if (flg && inext->createfactor[(int)ftype-1]) { 4442 if (foundtype) *foundtype = PETSC_TRUE; 4443 if (foundmtype) *foundmtype = PETSC_TRUE; 4444 if (createfactor) *createfactor = inext->createfactor[(int)ftype-1]; 4445 PetscFunctionReturn(0); 4446 } 4447 inext = inext->next; 4448 } 4449 next = next->next; 4450 } 4451 /* try with base classes inext->mtype */ 4452 next = MatSolverTypeHolders; 4453 while (next) { 4454 inext = next->handlers; 4455 while (inext) { 4456 CHKERRQ(PetscStrbeginswith(mtype,inext->mtype,&flg)); 4457 if (flg && inext->createfactor[(int)ftype-1]) { 4458 if (foundtype) *foundtype = PETSC_TRUE; 4459 if (foundmtype) *foundmtype = PETSC_TRUE; 4460 if (createfactor) *createfactor = inext->createfactor[(int)ftype-1]; 4461 PetscFunctionReturn(0); 4462 } 4463 inext = inext->next; 4464 } 4465 next = next->next; 4466 } 4467 } 4468 PetscFunctionReturn(0); 4469 } 4470 4471 PetscErrorCode MatSolverTypeDestroy(void) 4472 { 4473 MatSolverTypeHolder next = MatSolverTypeHolders,prev; 4474 MatSolverTypeForSpecifcType inext,iprev; 4475 4476 PetscFunctionBegin; 4477 while (next) { 4478 CHKERRQ(PetscFree(next->name)); 4479 inext = next->handlers; 4480 while (inext) { 4481 CHKERRQ(PetscFree(inext->mtype)); 4482 iprev = inext; 4483 inext = inext->next; 4484 CHKERRQ(PetscFree(iprev)); 4485 } 4486 prev = next; 4487 next = next->next; 4488 CHKERRQ(PetscFree(prev)); 4489 } 4490 MatSolverTypeHolders = NULL; 4491 PetscFunctionReturn(0); 4492 } 4493 4494 /*@C 4495 MatFactorGetCanUseOrdering - Indicates if the factorization can use the ordering provided in MatLUFactorSymbolic(), MatCholeskyFactorSymbolic() 4496 4497 Logically Collective on Mat 4498 4499 Input Parameters: 4500 . mat - the matrix 4501 4502 Output Parameters: 4503 . flg - PETSC_TRUE if uses the ordering 4504 4505 Notes: 4506 Most internal PETSc factorizations use the ordering passed to the factorization routine but external 4507 packages do not, thus we want to skip generating the ordering when it is not needed or used. 4508 4509 Level: developer 4510 4511 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor(), MatLUFactorSymbolic(), MatCholeskyFactorSymbolic() 4512 @*/ 4513 PetscErrorCode MatFactorGetCanUseOrdering(Mat mat, PetscBool *flg) 4514 { 4515 PetscFunctionBegin; 4516 *flg = mat->canuseordering; 4517 PetscFunctionReturn(0); 4518 } 4519 4520 /*@C 4521 MatFactorGetPreferredOrdering - The preferred ordering for a particular matrix factor object 4522 4523 Logically Collective on Mat 4524 4525 Input Parameters: 4526 . mat - the matrix 4527 4528 Output Parameters: 4529 . otype - the preferred type 4530 4531 Level: developer 4532 4533 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor(), MatLUFactorSymbolic(), MatCholeskyFactorSymbolic() 4534 @*/ 4535 PetscErrorCode MatFactorGetPreferredOrdering(Mat mat, MatFactorType ftype, MatOrderingType *otype) 4536 { 4537 PetscFunctionBegin; 4538 *otype = mat->preferredordering[ftype]; 4539 PetscCheckFalse(!*otype,PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatFactor did not have a preferred ordering"); 4540 PetscFunctionReturn(0); 4541 } 4542 4543 /*@C 4544 MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic() 4545 4546 Collective on Mat 4547 4548 Input Parameters: 4549 + mat - the matrix 4550 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4551 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4552 4553 Output Parameters: 4554 . f - the factor matrix used with MatXXFactorSymbolic() calls 4555 4556 Notes: 4557 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4558 such as pastix, superlu, mumps etc. 4559 4560 PETSc must have been ./configure to use the external solver, using the option --download-package 4561 4562 Developer Notes: 4563 This should actually be called MatCreateFactor() since it creates a new factor object 4564 4565 Level: intermediate 4566 4567 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatFactorGetCanUseOrdering(), MatSolverTypeRegister() 4568 @*/ 4569 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f) 4570 { 4571 PetscBool foundtype,foundmtype; 4572 PetscErrorCode (*conv)(Mat,MatFactorType,Mat*); 4573 4574 PetscFunctionBegin; 4575 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4576 PetscValidType(mat,1); 4577 4578 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4579 MatCheckPreallocated(mat,1); 4580 4581 CHKERRQ(MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundtype,&foundmtype,&conv)); 4582 if (!foundtype) { 4583 if (type) { 4584 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver type %s for factorization type %s and matrix type %s. Perhaps you must ./configure with --download-%s",type,MatFactorTypes[ftype],((PetscObject)mat)->type_name,type); 4585 } else { 4586 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver type for factorization type %s and matrix type %s.",MatFactorTypes[ftype],((PetscObject)mat)->type_name); 4587 } 4588 } 4589 PetscCheck(foundmtype,PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name); 4590 PetscCheck(conv,PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support factorization type %s for matrix type %s",type,MatFactorTypes[ftype],((PetscObject)mat)->type_name); 4591 4592 CHKERRQ((*conv)(mat,ftype,f)); 4593 PetscFunctionReturn(0); 4594 } 4595 4596 /*@C 4597 MatGetFactorAvailable - Returns a a flag if matrix supports particular type and factor type 4598 4599 Not Collective 4600 4601 Input Parameters: 4602 + mat - the matrix 4603 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4604 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4605 4606 Output Parameter: 4607 . flg - PETSC_TRUE if the factorization is available 4608 4609 Notes: 4610 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4611 such as pastix, superlu, mumps etc. 4612 4613 PETSc must have been ./configure to use the external solver, using the option --download-package 4614 4615 Developer Notes: 4616 This should actually be called MatCreateFactorAvailable() since MatGetFactor() creates a new factor object 4617 4618 Level: intermediate 4619 4620 .seealso: MatCopy(), MatDuplicate(), MatGetFactor(), MatSolverTypeRegister() 4621 @*/ 4622 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool *flg) 4623 { 4624 PetscErrorCode (*gconv)(Mat,MatFactorType,Mat*); 4625 4626 PetscFunctionBegin; 4627 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4628 PetscValidType(mat,1); 4629 PetscValidBoolPointer(flg,4); 4630 4631 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4632 MatCheckPreallocated(mat,1); 4633 4634 CHKERRQ(MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv)); 4635 *flg = gconv ? PETSC_TRUE : PETSC_FALSE; 4636 PetscFunctionReturn(0); 4637 } 4638 4639 /*@ 4640 MatDuplicate - Duplicates a matrix including the non-zero structure. 4641 4642 Collective on Mat 4643 4644 Input Parameters: 4645 + mat - the matrix 4646 - op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN. 4647 See the manual page for MatDuplicateOption for an explanation of these options. 4648 4649 Output Parameter: 4650 . M - pointer to place new matrix 4651 4652 Level: intermediate 4653 4654 Notes: 4655 You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN. 4656 May be called with an unassembled input Mat if MAT_DO_NOT_COPY_VALUES is used, in which case the output Mat is unassembled as well. 4657 When original mat is a product of matrix operation, e.g., an output of MatMatMult() or MatCreateSubMatrix(), only the simple matrix data structure of mat is duplicated and the internal data structures created for the reuse of previous matrix operations are not duplicated. User should not use MatDuplicate() to create new matrix M if M is intended to be reused as the product of matrix operation. 4658 4659 .seealso: MatCopy(), MatConvert(), MatDuplicateOption 4660 @*/ 4661 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M) 4662 { 4663 Mat B; 4664 VecType vtype; 4665 PetscInt i; 4666 PetscObject dm; 4667 void (*viewf)(void); 4668 4669 PetscFunctionBegin; 4670 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4671 PetscValidType(mat,1); 4672 PetscValidPointer(M,3); 4673 PetscCheckFalse(op == MAT_COPY_VALUES && !mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix"); 4674 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4675 MatCheckPreallocated(mat,1); 4676 4677 *M = NULL; 4678 PetscCheck(mat->ops->duplicate,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for matrix type %s",((PetscObject)mat)->type_name); 4679 CHKERRQ(PetscLogEventBegin(MAT_Convert,mat,0,0,0)); 4680 CHKERRQ((*mat->ops->duplicate)(mat,op,M)); 4681 CHKERRQ(PetscLogEventEnd(MAT_Convert,mat,0,0,0)); 4682 B = *M; 4683 4684 CHKERRQ(MatGetOperation(mat,MATOP_VIEW,&viewf)); 4685 if (viewf) { 4686 CHKERRQ(MatSetOperation(B,MATOP_VIEW,viewf)); 4687 } 4688 CHKERRQ(MatGetVecType(mat,&vtype)); 4689 CHKERRQ(MatSetVecType(B,vtype)); 4690 4691 B->stencil.dim = mat->stencil.dim; 4692 B->stencil.noc = mat->stencil.noc; 4693 for (i=0; i<=mat->stencil.dim; i++) { 4694 B->stencil.dims[i] = mat->stencil.dims[i]; 4695 B->stencil.starts[i] = mat->stencil.starts[i]; 4696 } 4697 4698 B->nooffproczerorows = mat->nooffproczerorows; 4699 B->nooffprocentries = mat->nooffprocentries; 4700 4701 CHKERRQ(PetscObjectQuery((PetscObject) mat, "__PETSc_dm", &dm)); 4702 if (dm) { 4703 CHKERRQ(PetscObjectCompose((PetscObject) B, "__PETSc_dm", dm)); 4704 } 4705 CHKERRQ(PetscObjectStateIncrease((PetscObject)B)); 4706 PetscFunctionReturn(0); 4707 } 4708 4709 /*@ 4710 MatGetDiagonal - Gets the diagonal of a matrix. 4711 4712 Logically Collective on Mat 4713 4714 Input Parameters: 4715 + mat - the matrix 4716 - v - the vector for storing the diagonal 4717 4718 Output Parameter: 4719 . v - the diagonal of the matrix 4720 4721 Level: intermediate 4722 4723 Note: 4724 Currently only correct in parallel for square matrices. 4725 4726 .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs() 4727 @*/ 4728 PetscErrorCode MatGetDiagonal(Mat mat,Vec v) 4729 { 4730 PetscFunctionBegin; 4731 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4732 PetscValidType(mat,1); 4733 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4734 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4735 PetscCheck(mat->ops->getdiagonal,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4736 MatCheckPreallocated(mat,1); 4737 4738 CHKERRQ((*mat->ops->getdiagonal)(mat,v)); 4739 CHKERRQ(PetscObjectStateIncrease((PetscObject)v)); 4740 PetscFunctionReturn(0); 4741 } 4742 4743 /*@C 4744 MatGetRowMin - Gets the minimum value (of the real part) of each 4745 row of the matrix 4746 4747 Logically Collective on Mat 4748 4749 Input Parameter: 4750 . mat - the matrix 4751 4752 Output Parameters: 4753 + v - the vector for storing the maximums 4754 - idx - the indices of the column found for each row (optional) 4755 4756 Level: intermediate 4757 4758 Notes: 4759 The result of this call are the same as if one converted the matrix to dense format 4760 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4761 4762 This code is only implemented for a couple of matrix formats. 4763 4764 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), 4765 MatGetRowMax() 4766 @*/ 4767 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[]) 4768 { 4769 PetscFunctionBegin; 4770 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4771 PetscValidType(mat,1); 4772 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4773 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4774 4775 if (!mat->cmap->N) { 4776 CHKERRQ(VecSet(v,PETSC_MAX_REAL)); 4777 if (idx) { 4778 PetscInt i,m = mat->rmap->n; 4779 for (i=0; i<m; i++) idx[i] = -1; 4780 } 4781 } else { 4782 PetscCheck(mat->ops->getrowmin,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4783 MatCheckPreallocated(mat,1); 4784 } 4785 CHKERRQ((*mat->ops->getrowmin)(mat,v,idx)); 4786 CHKERRQ(PetscObjectStateIncrease((PetscObject)v)); 4787 PetscFunctionReturn(0); 4788 } 4789 4790 /*@C 4791 MatGetRowMinAbs - Gets the minimum value (in absolute value) of each 4792 row of the matrix 4793 4794 Logically Collective on Mat 4795 4796 Input Parameter: 4797 . mat - the matrix 4798 4799 Output Parameters: 4800 + v - the vector for storing the minimums 4801 - idx - the indices of the column found for each row (or NULL if not needed) 4802 4803 Level: intermediate 4804 4805 Notes: 4806 if a row is completely empty or has only 0.0 values then the idx[] value for that 4807 row is 0 (the first column). 4808 4809 This code is only implemented for a couple of matrix formats. 4810 4811 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin() 4812 @*/ 4813 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[]) 4814 { 4815 PetscFunctionBegin; 4816 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4817 PetscValidType(mat,1); 4818 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4819 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4820 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4821 4822 if (!mat->cmap->N) { 4823 CHKERRQ(VecSet(v,0.0)); 4824 if (idx) { 4825 PetscInt i,m = mat->rmap->n; 4826 for (i=0; i<m; i++) idx[i] = -1; 4827 } 4828 } else { 4829 PetscCheck(mat->ops->getrowminabs,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4830 MatCheckPreallocated(mat,1); 4831 if (idx) CHKERRQ(PetscArrayzero(idx,mat->rmap->n)); 4832 CHKERRQ((*mat->ops->getrowminabs)(mat,v,idx)); 4833 } 4834 CHKERRQ(PetscObjectStateIncrease((PetscObject)v)); 4835 PetscFunctionReturn(0); 4836 } 4837 4838 /*@C 4839 MatGetRowMax - Gets the maximum value (of the real part) of each 4840 row of the matrix 4841 4842 Logically Collective on Mat 4843 4844 Input Parameter: 4845 . mat - the matrix 4846 4847 Output Parameters: 4848 + v - the vector for storing the maximums 4849 - idx - the indices of the column found for each row (optional) 4850 4851 Level: intermediate 4852 4853 Notes: 4854 The result of this call are the same as if one converted the matrix to dense format 4855 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4856 4857 This code is only implemented for a couple of matrix formats. 4858 4859 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), MatGetRowMin() 4860 @*/ 4861 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[]) 4862 { 4863 PetscFunctionBegin; 4864 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4865 PetscValidType(mat,1); 4866 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4867 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4868 4869 if (!mat->cmap->N) { 4870 CHKERRQ(VecSet(v,PETSC_MIN_REAL)); 4871 if (idx) { 4872 PetscInt i,m = mat->rmap->n; 4873 for (i=0; i<m; i++) idx[i] = -1; 4874 } 4875 } else { 4876 PetscCheck(mat->ops->getrowmax,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4877 MatCheckPreallocated(mat,1); 4878 CHKERRQ((*mat->ops->getrowmax)(mat,v,idx)); 4879 } 4880 CHKERRQ(PetscObjectStateIncrease((PetscObject)v)); 4881 PetscFunctionReturn(0); 4882 } 4883 4884 /*@C 4885 MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each 4886 row of the matrix 4887 4888 Logically Collective on Mat 4889 4890 Input Parameter: 4891 . mat - the matrix 4892 4893 Output Parameters: 4894 + v - the vector for storing the maximums 4895 - idx - the indices of the column found for each row (or NULL if not needed) 4896 4897 Level: intermediate 4898 4899 Notes: 4900 if a row is completely empty or has only 0.0 values then the idx[] value for that 4901 row is 0 (the first column). 4902 4903 This code is only implemented for a couple of matrix formats. 4904 4905 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin() 4906 @*/ 4907 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[]) 4908 { 4909 PetscFunctionBegin; 4910 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4911 PetscValidType(mat,1); 4912 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4913 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4914 4915 if (!mat->cmap->N) { 4916 CHKERRQ(VecSet(v,0.0)); 4917 if (idx) { 4918 PetscInt i,m = mat->rmap->n; 4919 for (i=0; i<m; i++) idx[i] = -1; 4920 } 4921 } else { 4922 PetscCheck(mat->ops->getrowmaxabs,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4923 MatCheckPreallocated(mat,1); 4924 if (idx) CHKERRQ(PetscArrayzero(idx,mat->rmap->n)); 4925 CHKERRQ((*mat->ops->getrowmaxabs)(mat,v,idx)); 4926 } 4927 CHKERRQ(PetscObjectStateIncrease((PetscObject)v)); 4928 PetscFunctionReturn(0); 4929 } 4930 4931 /*@ 4932 MatGetRowSum - Gets the sum of each row of the matrix 4933 4934 Logically or Neighborhood Collective on Mat 4935 4936 Input Parameters: 4937 . mat - the matrix 4938 4939 Output Parameter: 4940 . v - the vector for storing the sum of rows 4941 4942 Level: intermediate 4943 4944 Notes: 4945 This code is slow since it is not currently specialized for different formats 4946 4947 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin() 4948 @*/ 4949 PetscErrorCode MatGetRowSum(Mat mat, Vec v) 4950 { 4951 Vec ones; 4952 4953 PetscFunctionBegin; 4954 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4955 PetscValidType(mat,1); 4956 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4957 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4958 MatCheckPreallocated(mat,1); 4959 CHKERRQ(MatCreateVecs(mat,&ones,NULL)); 4960 CHKERRQ(VecSet(ones,1.)); 4961 CHKERRQ(MatMult(mat,ones,v)); 4962 CHKERRQ(VecDestroy(&ones)); 4963 PetscFunctionReturn(0); 4964 } 4965 4966 /*@ 4967 MatTranspose - Computes an in-place or out-of-place transpose of a matrix. 4968 4969 Collective on Mat 4970 4971 Input Parameters: 4972 + mat - the matrix to transpose 4973 - reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX 4974 4975 Output Parameter: 4976 . B - the transpose 4977 4978 Notes: 4979 If you use MAT_INPLACE_MATRIX then you must pass in &mat for B 4980 4981 MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used 4982 4983 Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed. 4984 4985 Level: intermediate 4986 4987 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse 4988 @*/ 4989 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B) 4990 { 4991 PetscFunctionBegin; 4992 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4993 PetscValidType(mat,1); 4994 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4995 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4996 PetscCheck(mat->ops->transpose,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4997 PetscCheckFalse(reuse == MAT_INPLACE_MATRIX && mat != *B,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first"); 4998 PetscCheckFalse(reuse == MAT_REUSE_MATRIX && mat == *B,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX"); 4999 MatCheckPreallocated(mat,1); 5000 5001 CHKERRQ(PetscLogEventBegin(MAT_Transpose,mat,0,0,0)); 5002 CHKERRQ((*mat->ops->transpose)(mat,reuse,B)); 5003 CHKERRQ(PetscLogEventEnd(MAT_Transpose,mat,0,0,0)); 5004 if (B) CHKERRQ(PetscObjectStateIncrease((PetscObject)*B)); 5005 PetscFunctionReturn(0); 5006 } 5007 5008 /*@ 5009 MatIsTranspose - Test whether a matrix is another one's transpose, 5010 or its own, in which case it tests symmetry. 5011 5012 Collective on Mat 5013 5014 Input Parameters: 5015 + A - the matrix to test 5016 - B - the matrix to test against, this can equal the first parameter 5017 5018 Output Parameters: 5019 . flg - the result 5020 5021 Notes: 5022 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 5023 has a running time of the order of the number of nonzeros; the parallel 5024 test involves parallel copies of the block-offdiagonal parts of the matrix. 5025 5026 Level: intermediate 5027 5028 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian() 5029 @*/ 5030 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 5031 { 5032 PetscErrorCode (*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 5033 5034 PetscFunctionBegin; 5035 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5036 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5037 PetscValidBoolPointer(flg,4); 5038 CHKERRQ(PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f)); 5039 CHKERRQ(PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g)); 5040 *flg = PETSC_FALSE; 5041 if (f && g) { 5042 PetscCheck(f == g,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test"); 5043 CHKERRQ((*f)(A,B,tol,flg)); 5044 } else { 5045 MatType mattype; 5046 5047 CHKERRQ(MatGetType(f ? B : A,&mattype)); 5048 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for transpose",mattype); 5049 } 5050 PetscFunctionReturn(0); 5051 } 5052 5053 /*@ 5054 MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate. 5055 5056 Collective on Mat 5057 5058 Input Parameters: 5059 + mat - the matrix to transpose and complex conjugate 5060 - reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX 5061 5062 Output Parameter: 5063 . B - the Hermitian 5064 5065 Level: intermediate 5066 5067 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse 5068 @*/ 5069 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B) 5070 { 5071 PetscFunctionBegin; 5072 CHKERRQ(MatTranspose(mat,reuse,B)); 5073 #if defined(PETSC_USE_COMPLEX) 5074 CHKERRQ(MatConjugate(*B)); 5075 #endif 5076 PetscFunctionReturn(0); 5077 } 5078 5079 /*@ 5080 MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose, 5081 5082 Collective on Mat 5083 5084 Input Parameters: 5085 + A - the matrix to test 5086 - B - the matrix to test against, this can equal the first parameter 5087 5088 Output Parameters: 5089 . flg - the result 5090 5091 Notes: 5092 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 5093 has a running time of the order of the number of nonzeros; the parallel 5094 test involves parallel copies of the block-offdiagonal parts of the matrix. 5095 5096 Level: intermediate 5097 5098 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose() 5099 @*/ 5100 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 5101 { 5102 PetscErrorCode (*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 5103 5104 PetscFunctionBegin; 5105 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5106 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5107 PetscValidBoolPointer(flg,4); 5108 CHKERRQ(PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f)); 5109 CHKERRQ(PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g)); 5110 if (f && g) { 5111 PetscCheck(f != g,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test"); 5112 CHKERRQ((*f)(A,B,tol,flg)); 5113 } 5114 PetscFunctionReturn(0); 5115 } 5116 5117 /*@ 5118 MatPermute - Creates a new matrix with rows and columns permuted from the 5119 original. 5120 5121 Collective on Mat 5122 5123 Input Parameters: 5124 + mat - the matrix to permute 5125 . row - row permutation, each processor supplies only the permutation for its rows 5126 - col - column permutation, each processor supplies only the permutation for its columns 5127 5128 Output Parameters: 5129 . B - the permuted matrix 5130 5131 Level: advanced 5132 5133 Note: 5134 The index sets map from row/col of permuted matrix to row/col of original matrix. 5135 The index sets should be on the same communicator as Mat and have the same local sizes. 5136 5137 Developer Note: 5138 If you want to implement MatPermute for a matrix type, and your approach doesn't 5139 exploit the fact that row and col are permutations, consider implementing the 5140 more general MatCreateSubMatrix() instead. 5141 5142 .seealso: MatGetOrdering(), ISAllGather() 5143 5144 @*/ 5145 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B) 5146 { 5147 PetscFunctionBegin; 5148 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5149 PetscValidType(mat,1); 5150 PetscValidHeaderSpecific(row,IS_CLASSID,2); 5151 PetscValidHeaderSpecific(col,IS_CLASSID,3); 5152 PetscValidPointer(B,4); 5153 PetscCheckSameComm(mat,1,row,2); 5154 if (row != col) PetscCheckSameComm(row,2,col,3); 5155 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5156 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5157 PetscCheckFalse(!mat->ops->permute && !mat->ops->createsubmatrix,PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name); 5158 MatCheckPreallocated(mat,1); 5159 5160 if (mat->ops->permute) { 5161 CHKERRQ((*mat->ops->permute)(mat,row,col,B)); 5162 CHKERRQ(PetscObjectStateIncrease((PetscObject)*B)); 5163 } else { 5164 CHKERRQ(MatCreateSubMatrix(mat, row, col, MAT_INITIAL_MATRIX, B)); 5165 } 5166 PetscFunctionReturn(0); 5167 } 5168 5169 /*@ 5170 MatEqual - Compares two matrices. 5171 5172 Collective on Mat 5173 5174 Input Parameters: 5175 + A - the first matrix 5176 - B - the second matrix 5177 5178 Output Parameter: 5179 . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise. 5180 5181 Level: intermediate 5182 5183 @*/ 5184 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool *flg) 5185 { 5186 PetscFunctionBegin; 5187 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5188 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5189 PetscValidType(A,1); 5190 PetscValidType(B,2); 5191 PetscValidBoolPointer(flg,3); 5192 PetscCheckSameComm(A,1,B,2); 5193 MatCheckPreallocated(A,1); 5194 MatCheckPreallocated(B,2); 5195 PetscCheck(A->assembled,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5196 PetscCheck(B->assembled,PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5197 PetscCheckFalse(A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT,A->rmap->N,B->rmap->N,A->cmap->N,B->cmap->N); 5198 if (A->ops->equal && A->ops->equal == B->ops->equal) { 5199 CHKERRQ((*A->ops->equal)(A,B,flg)); 5200 } else { 5201 CHKERRQ(MatMultEqual(A,B,10,flg)); 5202 } 5203 PetscFunctionReturn(0); 5204 } 5205 5206 /*@ 5207 MatDiagonalScale - Scales a matrix on the left and right by diagonal 5208 matrices that are stored as vectors. Either of the two scaling 5209 matrices can be NULL. 5210 5211 Collective on Mat 5212 5213 Input Parameters: 5214 + mat - the matrix to be scaled 5215 . l - the left scaling vector (or NULL) 5216 - r - the right scaling vector (or NULL) 5217 5218 Notes: 5219 MatDiagonalScale() computes A = LAR, where 5220 L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector) 5221 The L scales the rows of the matrix, the R scales the columns of the matrix. 5222 5223 Level: intermediate 5224 5225 .seealso: MatScale(), MatShift(), MatDiagonalSet() 5226 @*/ 5227 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r) 5228 { 5229 PetscFunctionBegin; 5230 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5231 PetscValidType(mat,1); 5232 if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);} 5233 if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);} 5234 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5235 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5236 MatCheckPreallocated(mat,1); 5237 if (!l && !r) PetscFunctionReturn(0); 5238 5239 PetscCheckFalse(!mat->ops->diagonalscale,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5240 CHKERRQ(PetscLogEventBegin(MAT_Scale,mat,0,0,0)); 5241 CHKERRQ((*mat->ops->diagonalscale)(mat,l,r)); 5242 CHKERRQ(PetscLogEventEnd(MAT_Scale,mat,0,0,0)); 5243 CHKERRQ(PetscObjectStateIncrease((PetscObject)mat)); 5244 if (l != r && mat->symmetric) mat->symmetric = PETSC_FALSE; 5245 PetscFunctionReturn(0); 5246 } 5247 5248 /*@ 5249 MatScale - Scales all elements of a matrix by a given number. 5250 5251 Logically Collective on Mat 5252 5253 Input Parameters: 5254 + mat - the matrix to be scaled 5255 - a - the scaling value 5256 5257 Output Parameter: 5258 . mat - the scaled matrix 5259 5260 Level: intermediate 5261 5262 .seealso: MatDiagonalScale() 5263 @*/ 5264 PetscErrorCode MatScale(Mat mat,PetscScalar a) 5265 { 5266 PetscFunctionBegin; 5267 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5268 PetscValidType(mat,1); 5269 PetscCheckFalse(a != (PetscScalar)1.0 && !mat->ops->scale,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5270 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5271 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5272 PetscValidLogicalCollectiveScalar(mat,a,2); 5273 MatCheckPreallocated(mat,1); 5274 5275 CHKERRQ(PetscLogEventBegin(MAT_Scale,mat,0,0,0)); 5276 if (a != (PetscScalar)1.0) { 5277 CHKERRQ((*mat->ops->scale)(mat,a)); 5278 CHKERRQ(PetscObjectStateIncrease((PetscObject)mat)); 5279 } 5280 CHKERRQ(PetscLogEventEnd(MAT_Scale,mat,0,0,0)); 5281 PetscFunctionReturn(0); 5282 } 5283 5284 /*@ 5285 MatNorm - Calculates various norms of a matrix. 5286 5287 Collective on Mat 5288 5289 Input Parameters: 5290 + mat - the matrix 5291 - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY 5292 5293 Output Parameter: 5294 . nrm - the resulting norm 5295 5296 Level: intermediate 5297 5298 @*/ 5299 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm) 5300 { 5301 PetscFunctionBegin; 5302 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5303 PetscValidType(mat,1); 5304 PetscValidRealPointer(nrm,3); 5305 5306 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5307 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5308 PetscCheck(mat->ops->norm,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5309 MatCheckPreallocated(mat,1); 5310 5311 CHKERRQ((*mat->ops->norm)(mat,type,nrm)); 5312 PetscFunctionReturn(0); 5313 } 5314 5315 /* 5316 This variable is used to prevent counting of MatAssemblyBegin() that 5317 are called from within a MatAssemblyEnd(). 5318 */ 5319 static PetscInt MatAssemblyEnd_InUse = 0; 5320 /*@ 5321 MatAssemblyBegin - Begins assembling the matrix. This routine should 5322 be called after completing all calls to MatSetValues(). 5323 5324 Collective on Mat 5325 5326 Input Parameters: 5327 + mat - the matrix 5328 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5329 5330 Notes: 5331 MatSetValues() generally caches the values. The matrix is ready to 5332 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5333 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5334 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5335 using the matrix. 5336 5337 ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the 5338 same flag of MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY for all processes. Thus you CANNOT locally change from ADD_VALUES to INSERT_VALUES, that is 5339 a global collective operation requring all processes that share the matrix. 5340 5341 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5342 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5343 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5344 5345 Level: beginner 5346 5347 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled() 5348 @*/ 5349 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type) 5350 { 5351 PetscFunctionBegin; 5352 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5353 PetscValidType(mat,1); 5354 MatCheckPreallocated(mat,1); 5355 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?"); 5356 if (mat->assembled) { 5357 mat->was_assembled = PETSC_TRUE; 5358 mat->assembled = PETSC_FALSE; 5359 } 5360 5361 if (!MatAssemblyEnd_InUse) { 5362 CHKERRQ(PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0)); 5363 if (mat->ops->assemblybegin) CHKERRQ((*mat->ops->assemblybegin)(mat,type)); 5364 CHKERRQ(PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0)); 5365 } else if (mat->ops->assemblybegin) { 5366 CHKERRQ((*mat->ops->assemblybegin)(mat,type)); 5367 } 5368 PetscFunctionReturn(0); 5369 } 5370 5371 /*@ 5372 MatAssembled - Indicates if a matrix has been assembled and is ready for 5373 use; for example, in matrix-vector product. 5374 5375 Not Collective 5376 5377 Input Parameter: 5378 . mat - the matrix 5379 5380 Output Parameter: 5381 . assembled - PETSC_TRUE or PETSC_FALSE 5382 5383 Level: advanced 5384 5385 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin() 5386 @*/ 5387 PetscErrorCode MatAssembled(Mat mat,PetscBool *assembled) 5388 { 5389 PetscFunctionBegin; 5390 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5391 PetscValidPointer(assembled,2); 5392 *assembled = mat->assembled; 5393 PetscFunctionReturn(0); 5394 } 5395 5396 /*@ 5397 MatAssemblyEnd - Completes assembling the matrix. This routine should 5398 be called after MatAssemblyBegin(). 5399 5400 Collective on Mat 5401 5402 Input Parameters: 5403 + mat - the matrix 5404 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5405 5406 Options Database Keys: 5407 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly() 5408 . -mat_view ::ascii_info_detail - Prints more detailed info 5409 . -mat_view - Prints matrix in ASCII format 5410 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 5411 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 5412 . -display <name> - Sets display name (default is host) 5413 . -draw_pause <sec> - Sets number of seconds to pause after display 5414 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab) 5415 . -viewer_socket_machine <machine> - Machine to use for socket 5416 . -viewer_socket_port <port> - Port number to use for socket 5417 - -mat_view binary:filename[:append] - Save matrix to file in binary format 5418 5419 Notes: 5420 MatSetValues() generally caches the values. The matrix is ready to 5421 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5422 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5423 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5424 using the matrix. 5425 5426 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5427 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5428 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5429 5430 Level: beginner 5431 5432 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen() 5433 @*/ 5434 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type) 5435 { 5436 static PetscInt inassm = 0; 5437 PetscBool flg = PETSC_FALSE; 5438 5439 PetscFunctionBegin; 5440 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5441 PetscValidType(mat,1); 5442 5443 inassm++; 5444 MatAssemblyEnd_InUse++; 5445 if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */ 5446 CHKERRQ(PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0)); 5447 if (mat->ops->assemblyend) { 5448 CHKERRQ((*mat->ops->assemblyend)(mat,type)); 5449 } 5450 CHKERRQ(PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0)); 5451 } else if (mat->ops->assemblyend) { 5452 CHKERRQ((*mat->ops->assemblyend)(mat,type)); 5453 } 5454 5455 /* Flush assembly is not a true assembly */ 5456 if (type != MAT_FLUSH_ASSEMBLY) { 5457 mat->num_ass++; 5458 mat->assembled = PETSC_TRUE; 5459 mat->ass_nonzerostate = mat->nonzerostate; 5460 } 5461 5462 mat->insertmode = NOT_SET_VALUES; 5463 MatAssemblyEnd_InUse--; 5464 CHKERRQ(PetscObjectStateIncrease((PetscObject)mat)); 5465 if (!mat->symmetric_eternal) { 5466 mat->symmetric_set = PETSC_FALSE; 5467 mat->hermitian_set = PETSC_FALSE; 5468 mat->structurally_symmetric_set = PETSC_FALSE; 5469 } 5470 if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) { 5471 CHKERRQ(MatViewFromOptions(mat,NULL,"-mat_view")); 5472 5473 if (mat->checksymmetryonassembly) { 5474 CHKERRQ(MatIsSymmetric(mat,mat->checksymmetrytol,&flg)); 5475 if (flg) { 5476 CHKERRQ(PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol)); 5477 } else { 5478 CHKERRQ(PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol)); 5479 } 5480 } 5481 if (mat->nullsp && mat->checknullspaceonassembly) { 5482 CHKERRQ(MatNullSpaceTest(mat->nullsp,mat,NULL)); 5483 } 5484 } 5485 inassm--; 5486 PetscFunctionReturn(0); 5487 } 5488 5489 /*@ 5490 MatSetOption - Sets a parameter option for a matrix. Some options 5491 may be specific to certain storage formats. Some options 5492 determine how values will be inserted (or added). Sorted, 5493 row-oriented input will generally assemble the fastest. The default 5494 is row-oriented. 5495 5496 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5497 5498 Input Parameters: 5499 + mat - the matrix 5500 . option - the option, one of those listed below (and possibly others), 5501 - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5502 5503 Options Describing Matrix Structure: 5504 + MAT_SPD - symmetric positive definite 5505 . MAT_SYMMETRIC - symmetric in terms of both structure and value 5506 . MAT_HERMITIAN - transpose is the complex conjugation 5507 . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure 5508 - MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag 5509 you set to be kept with all future use of the matrix 5510 including after MatAssemblyBegin/End() which could 5511 potentially change the symmetry structure, i.e. you 5512 KNOW the matrix will ALWAYS have the property you set. 5513 Note that setting this flag alone implies nothing about whether the matrix is symmetric/Hermitian; 5514 the relevant flags must be set independently. 5515 5516 Options For Use with MatSetValues(): 5517 Insert a logically dense subblock, which can be 5518 . MAT_ROW_ORIENTED - row-oriented (default) 5519 5520 Note these options reflect the data you pass in with MatSetValues(); it has 5521 nothing to do with how the data is stored internally in the matrix 5522 data structure. 5523 5524 When (re)assembling a matrix, we can restrict the input for 5525 efficiency/debugging purposes. These options include 5526 + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow) 5527 . MAT_FORCE_DIAGONAL_ENTRIES - forces diagonal entries to be allocated 5528 . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries 5529 . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry 5530 . MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly 5531 . MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if 5532 any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves 5533 performance for very large process counts. 5534 - MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset 5535 of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly 5536 functions, instead sending only neighbor messages. 5537 5538 Notes: 5539 Except for MAT_UNUSED_NONZERO_LOCATION_ERR and MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg! 5540 5541 Some options are relevant only for particular matrix types and 5542 are thus ignored by others. Other options are not supported by 5543 certain matrix types and will generate an error message if set. 5544 5545 If using a Fortran 77 module to compute a matrix, one may need to 5546 use the column-oriented option (or convert to the row-oriented 5547 format). 5548 5549 MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion 5550 that would generate a new entry in the nonzero structure is instead 5551 ignored. Thus, if memory has not alredy been allocated for this particular 5552 data, then the insertion is ignored. For dense matrices, in which 5553 the entire array is allocated, no entries are ever ignored. 5554 Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5555 5556 MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5557 that would generate a new entry in the nonzero structure instead produces 5558 an error. (Currently supported for AIJ and BAIJ formats only.) If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5559 5560 MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5561 that would generate a new entry that has not been preallocated will 5562 instead produce an error. (Currently supported for AIJ and BAIJ formats 5563 only.) This is a useful flag when debugging matrix memory preallocation. 5564 If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5565 5566 MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for 5567 other processors should be dropped, rather than stashed. 5568 This is useful if you know that the "owning" processor is also 5569 always generating the correct matrix entries, so that PETSc need 5570 not transfer duplicate entries generated on another processor. 5571 5572 MAT_USE_HASH_TABLE indicates that a hash table be used to improve the 5573 searches during matrix assembly. When this flag is set, the hash table 5574 is created during the first Matrix Assembly. This hash table is 5575 used the next time through, during MatSetVaules()/MatSetVaulesBlocked() 5576 to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag 5577 should be used with MAT_USE_HASH_TABLE flag. This option is currently 5578 supported by MATMPIBAIJ format only. 5579 5580 MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries 5581 are kept in the nonzero structure 5582 5583 MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating 5584 a zero location in the matrix 5585 5586 MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types 5587 5588 MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the 5589 zero row routines and thus improves performance for very large process counts. 5590 5591 MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular 5592 part of the matrix (since they should match the upper triangular part). 5593 5594 MAT_SORTED_FULL - each process provides exactly its local rows; all column indices for a given row are passed in a 5595 single call to MatSetValues(), preallocation is perfect, row oriented, INSERT_VALUES is used. Common 5596 with finite difference schemes with non-periodic boundary conditions. 5597 5598 Level: intermediate 5599 5600 .seealso: MatOption, Mat 5601 5602 @*/ 5603 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg) 5604 { 5605 PetscFunctionBegin; 5606 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5607 if (op > 0) { 5608 PetscValidLogicalCollectiveEnum(mat,op,2); 5609 PetscValidLogicalCollectiveBool(mat,flg,3); 5610 } 5611 5612 PetscCheckFalse(((int) op) <= MAT_OPTION_MIN || ((int) op) >= MAT_OPTION_MAX,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Options %d is out of range",(int)op); 5613 5614 switch (op) { 5615 case MAT_FORCE_DIAGONAL_ENTRIES: 5616 mat->force_diagonals = flg; 5617 PetscFunctionReturn(0); 5618 case MAT_NO_OFF_PROC_ENTRIES: 5619 mat->nooffprocentries = flg; 5620 PetscFunctionReturn(0); 5621 case MAT_SUBSET_OFF_PROC_ENTRIES: 5622 mat->assembly_subset = flg; 5623 if (!mat->assembly_subset) { /* See the same logic in VecAssembly wrt VEC_SUBSET_OFF_PROC_ENTRIES */ 5624 #if !defined(PETSC_HAVE_MPIUNI) 5625 CHKERRQ(MatStashScatterDestroy_BTS(&mat->stash)); 5626 #endif 5627 mat->stash.first_assembly_done = PETSC_FALSE; 5628 } 5629 PetscFunctionReturn(0); 5630 case MAT_NO_OFF_PROC_ZERO_ROWS: 5631 mat->nooffproczerorows = flg; 5632 PetscFunctionReturn(0); 5633 case MAT_SPD: 5634 mat->spd_set = PETSC_TRUE; 5635 mat->spd = flg; 5636 if (flg) { 5637 mat->symmetric = PETSC_TRUE; 5638 mat->structurally_symmetric = PETSC_TRUE; 5639 mat->symmetric_set = PETSC_TRUE; 5640 mat->structurally_symmetric_set = PETSC_TRUE; 5641 } 5642 break; 5643 case MAT_SYMMETRIC: 5644 mat->symmetric = flg; 5645 if (flg) mat->structurally_symmetric = PETSC_TRUE; 5646 mat->symmetric_set = PETSC_TRUE; 5647 mat->structurally_symmetric_set = flg; 5648 #if !defined(PETSC_USE_COMPLEX) 5649 mat->hermitian = flg; 5650 mat->hermitian_set = PETSC_TRUE; 5651 #endif 5652 break; 5653 case MAT_HERMITIAN: 5654 mat->hermitian = flg; 5655 if (flg) mat->structurally_symmetric = PETSC_TRUE; 5656 mat->hermitian_set = PETSC_TRUE; 5657 mat->structurally_symmetric_set = flg; 5658 #if !defined(PETSC_USE_COMPLEX) 5659 mat->symmetric = flg; 5660 mat->symmetric_set = PETSC_TRUE; 5661 #endif 5662 break; 5663 case MAT_STRUCTURALLY_SYMMETRIC: 5664 mat->structurally_symmetric = flg; 5665 mat->structurally_symmetric_set = PETSC_TRUE; 5666 break; 5667 case MAT_SYMMETRY_ETERNAL: 5668 mat->symmetric_eternal = flg; 5669 break; 5670 case MAT_STRUCTURE_ONLY: 5671 mat->structure_only = flg; 5672 break; 5673 case MAT_SORTED_FULL: 5674 mat->sortedfull = flg; 5675 break; 5676 default: 5677 break; 5678 } 5679 if (mat->ops->setoption) { 5680 CHKERRQ((*mat->ops->setoption)(mat,op,flg)); 5681 } 5682 PetscFunctionReturn(0); 5683 } 5684 5685 /*@ 5686 MatGetOption - Gets a parameter option that has been set for a matrix. 5687 5688 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5689 5690 Input Parameters: 5691 + mat - the matrix 5692 - option - the option, this only responds to certain options, check the code for which ones 5693 5694 Output Parameter: 5695 . flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5696 5697 Notes: 5698 Can only be called after MatSetSizes() and MatSetType() have been set. 5699 5700 Level: intermediate 5701 5702 .seealso: MatOption, MatSetOption() 5703 5704 @*/ 5705 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg) 5706 { 5707 PetscFunctionBegin; 5708 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5709 PetscValidType(mat,1); 5710 5711 PetscCheckFalse(((int) op) <= MAT_OPTION_MIN || ((int) op) >= MAT_OPTION_MAX,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Options %d is out of range",(int)op); 5712 PetscCheckFalse(!((PetscObject)mat)->type_name,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_TYPENOTSET,"Cannot get options until type and size have been set, see MatSetType() and MatSetSizes()"); 5713 5714 switch (op) { 5715 case MAT_NO_OFF_PROC_ENTRIES: 5716 *flg = mat->nooffprocentries; 5717 break; 5718 case MAT_NO_OFF_PROC_ZERO_ROWS: 5719 *flg = mat->nooffproczerorows; 5720 break; 5721 case MAT_SYMMETRIC: 5722 *flg = mat->symmetric; 5723 break; 5724 case MAT_HERMITIAN: 5725 *flg = mat->hermitian; 5726 break; 5727 case MAT_STRUCTURALLY_SYMMETRIC: 5728 *flg = mat->structurally_symmetric; 5729 break; 5730 case MAT_SYMMETRY_ETERNAL: 5731 *flg = mat->symmetric_eternal; 5732 break; 5733 case MAT_SPD: 5734 *flg = mat->spd; 5735 break; 5736 default: 5737 break; 5738 } 5739 PetscFunctionReturn(0); 5740 } 5741 5742 /*@ 5743 MatZeroEntries - Zeros all entries of a matrix. For sparse matrices 5744 this routine retains the old nonzero structure. 5745 5746 Logically Collective on Mat 5747 5748 Input Parameters: 5749 . mat - the matrix 5750 5751 Level: intermediate 5752 5753 Notes: 5754 If the matrix was not preallocated then a default, likely poor preallocation will be set in the matrix, so this should be called after the preallocation phase. 5755 See the Performance chapter of the users manual for information on preallocating matrices. 5756 5757 .seealso: MatZeroRows() 5758 @*/ 5759 PetscErrorCode MatZeroEntries(Mat mat) 5760 { 5761 PetscFunctionBegin; 5762 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5763 PetscValidType(mat,1); 5764 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5765 PetscCheckFalse(mat->insertmode != NOT_SET_VALUES,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for matrices where you have set values but not yet assembled"); 5766 PetscCheck(mat->ops->zeroentries,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5767 MatCheckPreallocated(mat,1); 5768 5769 CHKERRQ(PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0)); 5770 CHKERRQ((*mat->ops->zeroentries)(mat)); 5771 CHKERRQ(PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0)); 5772 CHKERRQ(PetscObjectStateIncrease((PetscObject)mat)); 5773 PetscFunctionReturn(0); 5774 } 5775 5776 /*@ 5777 MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal) 5778 of a set of rows and columns of a matrix. 5779 5780 Collective on Mat 5781 5782 Input Parameters: 5783 + mat - the matrix 5784 . numRows - the number of rows to remove 5785 . rows - the global row indices 5786 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5787 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5788 - b - optional vector of right hand side, that will be adjusted by provided solution 5789 5790 Notes: 5791 This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5792 5793 The user can set a value in the diagonal entry (or for the AIJ and 5794 row formats can optionally remove the main diagonal entry from the 5795 nonzero structure as well, by passing 0.0 as the final argument). 5796 5797 For the parallel case, all processes that share the matrix (i.e., 5798 those in the communicator used for matrix creation) MUST call this 5799 routine, regardless of whether any rows being zeroed are owned by 5800 them. 5801 5802 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5803 list only rows local to itself). 5804 5805 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 5806 5807 Level: intermediate 5808 5809 .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5810 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5811 @*/ 5812 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5813 { 5814 PetscFunctionBegin; 5815 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5816 PetscValidType(mat,1); 5817 if (numRows) PetscValidIntPointer(rows,3); 5818 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5819 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5820 PetscCheck(mat->ops->zerorowscolumns,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5821 MatCheckPreallocated(mat,1); 5822 5823 CHKERRQ((*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b)); 5824 CHKERRQ(MatViewFromOptions(mat,NULL,"-mat_view")); 5825 CHKERRQ(PetscObjectStateIncrease((PetscObject)mat)); 5826 PetscFunctionReturn(0); 5827 } 5828 5829 /*@ 5830 MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal) 5831 of a set of rows and columns of a matrix. 5832 5833 Collective on Mat 5834 5835 Input Parameters: 5836 + mat - the matrix 5837 . is - the rows to zero 5838 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5839 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5840 - b - optional vector of right hand side, that will be adjusted by provided solution 5841 5842 Notes: 5843 This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5844 5845 The user can set a value in the diagonal entry (or for the AIJ and 5846 row formats can optionally remove the main diagonal entry from the 5847 nonzero structure as well, by passing 0.0 as the final argument). 5848 5849 For the parallel case, all processes that share the matrix (i.e., 5850 those in the communicator used for matrix creation) MUST call this 5851 routine, regardless of whether any rows being zeroed are owned by 5852 them. 5853 5854 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5855 list only rows local to itself). 5856 5857 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 5858 5859 Level: intermediate 5860 5861 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5862 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil() 5863 @*/ 5864 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 5865 { 5866 PetscInt numRows; 5867 const PetscInt *rows; 5868 5869 PetscFunctionBegin; 5870 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5871 PetscValidHeaderSpecific(is,IS_CLASSID,2); 5872 PetscValidType(mat,1); 5873 PetscValidType(is,2); 5874 CHKERRQ(ISGetLocalSize(is,&numRows)); 5875 CHKERRQ(ISGetIndices(is,&rows)); 5876 CHKERRQ(MatZeroRowsColumns(mat,numRows,rows,diag,x,b)); 5877 CHKERRQ(ISRestoreIndices(is,&rows)); 5878 PetscFunctionReturn(0); 5879 } 5880 5881 /*@ 5882 MatZeroRows - Zeros all entries (except possibly the main diagonal) 5883 of a set of rows of a matrix. 5884 5885 Collective on Mat 5886 5887 Input Parameters: 5888 + mat - the matrix 5889 . numRows - the number of rows to remove 5890 . rows - the global row indices 5891 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5892 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5893 - b - optional vector of right hand side, that will be adjusted by provided solution 5894 5895 Notes: 5896 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5897 but does not release memory. For the dense and block diagonal 5898 formats this does not alter the nonzero structure. 5899 5900 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5901 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5902 merely zeroed. 5903 5904 The user can set a value in the diagonal entry (or for the AIJ and 5905 row formats can optionally remove the main diagonal entry from the 5906 nonzero structure as well, by passing 0.0 as the final argument). 5907 5908 For the parallel case, all processes that share the matrix (i.e., 5909 those in the communicator used for matrix creation) MUST call this 5910 routine, regardless of whether any rows being zeroed are owned by 5911 them. 5912 5913 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5914 list only rows local to itself). 5915 5916 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 5917 owns that are to be zeroed. This saves a global synchronization in the implementation. 5918 5919 Level: intermediate 5920 5921 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5922 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5923 @*/ 5924 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5925 { 5926 PetscFunctionBegin; 5927 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5928 PetscValidType(mat,1); 5929 if (numRows) PetscValidIntPointer(rows,3); 5930 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5931 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5932 PetscCheck(mat->ops->zerorows,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5933 MatCheckPreallocated(mat,1); 5934 5935 CHKERRQ((*mat->ops->zerorows)(mat,numRows,rows,diag,x,b)); 5936 CHKERRQ(MatViewFromOptions(mat,NULL,"-mat_view")); 5937 CHKERRQ(PetscObjectStateIncrease((PetscObject)mat)); 5938 PetscFunctionReturn(0); 5939 } 5940 5941 /*@ 5942 MatZeroRowsIS - Zeros all entries (except possibly the main diagonal) 5943 of a set of rows of a matrix. 5944 5945 Collective on Mat 5946 5947 Input Parameters: 5948 + mat - the matrix 5949 . is - index set of rows to remove (if NULL then no row is removed) 5950 . diag - value put in all diagonals of eliminated rows 5951 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5952 - b - optional vector of right hand side, that will be adjusted by provided solution 5953 5954 Notes: 5955 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5956 but does not release memory. For the dense and block diagonal 5957 formats this does not alter the nonzero structure. 5958 5959 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5960 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5961 merely zeroed. 5962 5963 The user can set a value in the diagonal entry (or for the AIJ and 5964 row formats can optionally remove the main diagonal entry from the 5965 nonzero structure as well, by passing 0.0 as the final argument). 5966 5967 For the parallel case, all processes that share the matrix (i.e., 5968 those in the communicator used for matrix creation) MUST call this 5969 routine, regardless of whether any rows being zeroed are owned by 5970 them. 5971 5972 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5973 list only rows local to itself). 5974 5975 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 5976 owns that are to be zeroed. This saves a global synchronization in the implementation. 5977 5978 Level: intermediate 5979 5980 .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5981 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5982 @*/ 5983 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 5984 { 5985 PetscInt numRows = 0; 5986 const PetscInt *rows = NULL; 5987 5988 PetscFunctionBegin; 5989 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5990 PetscValidType(mat,1); 5991 if (is) { 5992 PetscValidHeaderSpecific(is,IS_CLASSID,2); 5993 CHKERRQ(ISGetLocalSize(is,&numRows)); 5994 CHKERRQ(ISGetIndices(is,&rows)); 5995 } 5996 CHKERRQ(MatZeroRows(mat,numRows,rows,diag,x,b)); 5997 if (is) { 5998 CHKERRQ(ISRestoreIndices(is,&rows)); 5999 } 6000 PetscFunctionReturn(0); 6001 } 6002 6003 /*@ 6004 MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal) 6005 of a set of rows of a matrix. These rows must be local to the process. 6006 6007 Collective on Mat 6008 6009 Input Parameters: 6010 + mat - the matrix 6011 . numRows - the number of rows to remove 6012 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 6013 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6014 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6015 - b - optional vector of right hand side, that will be adjusted by provided solution 6016 6017 Notes: 6018 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 6019 but does not release memory. For the dense and block diagonal 6020 formats this does not alter the nonzero structure. 6021 6022 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6023 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6024 merely zeroed. 6025 6026 The user can set a value in the diagonal entry (or for the AIJ and 6027 row formats can optionally remove the main diagonal entry from the 6028 nonzero structure as well, by passing 0.0 as the final argument). 6029 6030 For the parallel case, all processes that share the matrix (i.e., 6031 those in the communicator used for matrix creation) MUST call this 6032 routine, regardless of whether any rows being zeroed are owned by 6033 them. 6034 6035 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6036 list only rows local to itself). 6037 6038 The grid coordinates are across the entire grid, not just the local portion 6039 6040 In Fortran idxm and idxn should be declared as 6041 $ MatStencil idxm(4,m) 6042 and the values inserted using 6043 $ idxm(MatStencil_i,1) = i 6044 $ idxm(MatStencil_j,1) = j 6045 $ idxm(MatStencil_k,1) = k 6046 $ idxm(MatStencil_c,1) = c 6047 etc 6048 6049 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6050 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6051 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6052 DM_BOUNDARY_PERIODIC boundary type. 6053 6054 For indices that don't mean anything for your case (like the k index when working in 2d) or the c index when you have 6055 a single value per point) you can skip filling those indices. 6056 6057 Level: intermediate 6058 6059 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6060 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6061 @*/ 6062 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 6063 { 6064 PetscInt dim = mat->stencil.dim; 6065 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 6066 PetscInt *dims = mat->stencil.dims+1; 6067 PetscInt *starts = mat->stencil.starts; 6068 PetscInt *dxm = (PetscInt*) rows; 6069 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6070 6071 PetscFunctionBegin; 6072 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6073 PetscValidType(mat,1); 6074 if (numRows) PetscValidPointer(rows,3); 6075 6076 CHKERRQ(PetscMalloc1(numRows, &jdxm)); 6077 for (i = 0; i < numRows; ++i) { 6078 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6079 for (j = 0; j < 3-sdim; ++j) dxm++; 6080 /* Local index in X dir */ 6081 tmp = *dxm++ - starts[0]; 6082 /* Loop over remaining dimensions */ 6083 for (j = 0; j < dim-1; ++j) { 6084 /* If nonlocal, set index to be negative */ 6085 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6086 /* Update local index */ 6087 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6088 } 6089 /* Skip component slot if necessary */ 6090 if (mat->stencil.noc) dxm++; 6091 /* Local row number */ 6092 if (tmp >= 0) { 6093 jdxm[numNewRows++] = tmp; 6094 } 6095 } 6096 CHKERRQ(MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b)); 6097 CHKERRQ(PetscFree(jdxm)); 6098 PetscFunctionReturn(0); 6099 } 6100 6101 /*@ 6102 MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal) 6103 of a set of rows and columns of a matrix. 6104 6105 Collective on Mat 6106 6107 Input Parameters: 6108 + mat - the matrix 6109 . numRows - the number of rows/columns to remove 6110 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 6111 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6112 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6113 - b - optional vector of right hand side, that will be adjusted by provided solution 6114 6115 Notes: 6116 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 6117 but does not release memory. For the dense and block diagonal 6118 formats this does not alter the nonzero structure. 6119 6120 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6121 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6122 merely zeroed. 6123 6124 The user can set a value in the diagonal entry (or for the AIJ and 6125 row formats can optionally remove the main diagonal entry from the 6126 nonzero structure as well, by passing 0.0 as the final argument). 6127 6128 For the parallel case, all processes that share the matrix (i.e., 6129 those in the communicator used for matrix creation) MUST call this 6130 routine, regardless of whether any rows being zeroed are owned by 6131 them. 6132 6133 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6134 list only rows local to itself, but the row/column numbers are given in local numbering). 6135 6136 The grid coordinates are across the entire grid, not just the local portion 6137 6138 In Fortran idxm and idxn should be declared as 6139 $ MatStencil idxm(4,m) 6140 and the values inserted using 6141 $ idxm(MatStencil_i,1) = i 6142 $ idxm(MatStencil_j,1) = j 6143 $ idxm(MatStencil_k,1) = k 6144 $ idxm(MatStencil_c,1) = c 6145 etc 6146 6147 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6148 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6149 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6150 DM_BOUNDARY_PERIODIC boundary type. 6151 6152 For indices that don't mean anything for your case (like the k index when working in 2d) or the c index when you have 6153 a single value per point) you can skip filling those indices. 6154 6155 Level: intermediate 6156 6157 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6158 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows() 6159 @*/ 6160 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 6161 { 6162 PetscInt dim = mat->stencil.dim; 6163 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 6164 PetscInt *dims = mat->stencil.dims+1; 6165 PetscInt *starts = mat->stencil.starts; 6166 PetscInt *dxm = (PetscInt*) rows; 6167 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6168 6169 PetscFunctionBegin; 6170 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6171 PetscValidType(mat,1); 6172 if (numRows) PetscValidPointer(rows,3); 6173 6174 CHKERRQ(PetscMalloc1(numRows, &jdxm)); 6175 for (i = 0; i < numRows; ++i) { 6176 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6177 for (j = 0; j < 3-sdim; ++j) dxm++; 6178 /* Local index in X dir */ 6179 tmp = *dxm++ - starts[0]; 6180 /* Loop over remaining dimensions */ 6181 for (j = 0; j < dim-1; ++j) { 6182 /* If nonlocal, set index to be negative */ 6183 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6184 /* Update local index */ 6185 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6186 } 6187 /* Skip component slot if necessary */ 6188 if (mat->stencil.noc) dxm++; 6189 /* Local row number */ 6190 if (tmp >= 0) { 6191 jdxm[numNewRows++] = tmp; 6192 } 6193 } 6194 CHKERRQ(MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b)); 6195 CHKERRQ(PetscFree(jdxm)); 6196 PetscFunctionReturn(0); 6197 } 6198 6199 /*@C 6200 MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal) 6201 of a set of rows of a matrix; using local numbering of rows. 6202 6203 Collective on Mat 6204 6205 Input Parameters: 6206 + mat - the matrix 6207 . numRows - the number of rows to remove 6208 . rows - the local row indices 6209 . diag - value put in all diagonals of eliminated rows 6210 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6211 - b - optional vector of right hand side, that will be adjusted by provided solution 6212 6213 Notes: 6214 Before calling MatZeroRowsLocal(), the user must first set the 6215 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6216 6217 For the AIJ matrix formats this removes the old nonzero structure, 6218 but does not release memory. For the dense and block diagonal 6219 formats this does not alter the nonzero structure. 6220 6221 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6222 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6223 merely zeroed. 6224 6225 The user can set a value in the diagonal entry (or for the AIJ and 6226 row formats can optionally remove the main diagonal entry from the 6227 nonzero structure as well, by passing 0.0 as the final argument). 6228 6229 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6230 owns that are to be zeroed. This saves a global synchronization in the implementation. 6231 6232 Level: intermediate 6233 6234 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(), 6235 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6236 @*/ 6237 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6238 { 6239 PetscFunctionBegin; 6240 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6241 PetscValidType(mat,1); 6242 if (numRows) PetscValidIntPointer(rows,3); 6243 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6244 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6245 MatCheckPreallocated(mat,1); 6246 6247 if (mat->ops->zerorowslocal) { 6248 CHKERRQ((*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b)); 6249 } else { 6250 IS is, newis; 6251 const PetscInt *newRows; 6252 6253 PetscCheck(mat->rmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6254 CHKERRQ(ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is)); 6255 CHKERRQ(ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis)); 6256 CHKERRQ(ISGetIndices(newis,&newRows)); 6257 CHKERRQ((*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b)); 6258 CHKERRQ(ISRestoreIndices(newis,&newRows)); 6259 CHKERRQ(ISDestroy(&newis)); 6260 CHKERRQ(ISDestroy(&is)); 6261 } 6262 CHKERRQ(PetscObjectStateIncrease((PetscObject)mat)); 6263 PetscFunctionReturn(0); 6264 } 6265 6266 /*@ 6267 MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal) 6268 of a set of rows of a matrix; using local numbering of rows. 6269 6270 Collective on Mat 6271 6272 Input Parameters: 6273 + mat - the matrix 6274 . is - index set of rows to remove 6275 . diag - value put in all diagonals of eliminated rows 6276 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6277 - b - optional vector of right hand side, that will be adjusted by provided solution 6278 6279 Notes: 6280 Before calling MatZeroRowsLocalIS(), the user must first set the 6281 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6282 6283 For the AIJ matrix formats this removes the old nonzero structure, 6284 but does not release memory. For the dense and block diagonal 6285 formats this does not alter the nonzero structure. 6286 6287 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6288 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6289 merely zeroed. 6290 6291 The user can set a value in the diagonal entry (or for the AIJ and 6292 row formats can optionally remove the main diagonal entry from the 6293 nonzero structure as well, by passing 0.0 as the final argument). 6294 6295 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6296 owns that are to be zeroed. This saves a global synchronization in the implementation. 6297 6298 Level: intermediate 6299 6300 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6301 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6302 @*/ 6303 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6304 { 6305 PetscInt numRows; 6306 const PetscInt *rows; 6307 6308 PetscFunctionBegin; 6309 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6310 PetscValidType(mat,1); 6311 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6312 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6313 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6314 MatCheckPreallocated(mat,1); 6315 6316 CHKERRQ(ISGetLocalSize(is,&numRows)); 6317 CHKERRQ(ISGetIndices(is,&rows)); 6318 CHKERRQ(MatZeroRowsLocal(mat,numRows,rows,diag,x,b)); 6319 CHKERRQ(ISRestoreIndices(is,&rows)); 6320 PetscFunctionReturn(0); 6321 } 6322 6323 /*@ 6324 MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal) 6325 of a set of rows and columns of a matrix; using local numbering of rows. 6326 6327 Collective on Mat 6328 6329 Input Parameters: 6330 + mat - the matrix 6331 . numRows - the number of rows to remove 6332 . rows - the global row indices 6333 . diag - value put in all diagonals of eliminated rows 6334 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6335 - b - optional vector of right hand side, that will be adjusted by provided solution 6336 6337 Notes: 6338 Before calling MatZeroRowsColumnsLocal(), the user must first set the 6339 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6340 6341 The user can set a value in the diagonal entry (or for the AIJ and 6342 row formats can optionally remove the main diagonal entry from the 6343 nonzero structure as well, by passing 0.0 as the final argument). 6344 6345 Level: intermediate 6346 6347 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6348 MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6349 @*/ 6350 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6351 { 6352 IS is, newis; 6353 const PetscInt *newRows; 6354 6355 PetscFunctionBegin; 6356 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6357 PetscValidType(mat,1); 6358 if (numRows) PetscValidIntPointer(rows,3); 6359 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6360 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6361 MatCheckPreallocated(mat,1); 6362 6363 PetscCheck(mat->cmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6364 CHKERRQ(ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is)); 6365 CHKERRQ(ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis)); 6366 CHKERRQ(ISGetIndices(newis,&newRows)); 6367 CHKERRQ((*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b)); 6368 CHKERRQ(ISRestoreIndices(newis,&newRows)); 6369 CHKERRQ(ISDestroy(&newis)); 6370 CHKERRQ(ISDestroy(&is)); 6371 CHKERRQ(PetscObjectStateIncrease((PetscObject)mat)); 6372 PetscFunctionReturn(0); 6373 } 6374 6375 /*@ 6376 MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal) 6377 of a set of rows and columns of a matrix; using local numbering of rows. 6378 6379 Collective on Mat 6380 6381 Input Parameters: 6382 + mat - the matrix 6383 . is - index set of rows to remove 6384 . diag - value put in all diagonals of eliminated rows 6385 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6386 - b - optional vector of right hand side, that will be adjusted by provided solution 6387 6388 Notes: 6389 Before calling MatZeroRowsColumnsLocalIS(), the user must first set the 6390 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6391 6392 The user can set a value in the diagonal entry (or for the AIJ and 6393 row formats can optionally remove the main diagonal entry from the 6394 nonzero structure as well, by passing 0.0 as the final argument). 6395 6396 Level: intermediate 6397 6398 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6399 MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6400 @*/ 6401 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6402 { 6403 PetscInt numRows; 6404 const PetscInt *rows; 6405 6406 PetscFunctionBegin; 6407 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6408 PetscValidType(mat,1); 6409 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6410 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6411 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6412 MatCheckPreallocated(mat,1); 6413 6414 CHKERRQ(ISGetLocalSize(is,&numRows)); 6415 CHKERRQ(ISGetIndices(is,&rows)); 6416 CHKERRQ(MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b)); 6417 CHKERRQ(ISRestoreIndices(is,&rows)); 6418 PetscFunctionReturn(0); 6419 } 6420 6421 /*@C 6422 MatGetSize - Returns the numbers of rows and columns in a matrix. 6423 6424 Not Collective 6425 6426 Input Parameter: 6427 . mat - the matrix 6428 6429 Output Parameters: 6430 + m - the number of global rows 6431 - n - the number of global columns 6432 6433 Note: both output parameters can be NULL on input. 6434 6435 Level: beginner 6436 6437 .seealso: MatGetLocalSize() 6438 @*/ 6439 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n) 6440 { 6441 PetscFunctionBegin; 6442 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6443 if (m) *m = mat->rmap->N; 6444 if (n) *n = mat->cmap->N; 6445 PetscFunctionReturn(0); 6446 } 6447 6448 /*@C 6449 MatGetLocalSize - Returns the number of local rows and local columns 6450 of a matrix, that is the local size of the left and right vectors as returned by MatCreateVecs(). 6451 6452 Not Collective 6453 6454 Input Parameter: 6455 . mat - the matrix 6456 6457 Output Parameters: 6458 + m - the number of local rows 6459 - n - the number of local columns 6460 6461 Note: both output parameters can be NULL on input. 6462 6463 Level: beginner 6464 6465 .seealso: MatGetSize() 6466 @*/ 6467 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n) 6468 { 6469 PetscFunctionBegin; 6470 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6471 if (m) PetscValidIntPointer(m,2); 6472 if (n) PetscValidIntPointer(n,3); 6473 if (m) *m = mat->rmap->n; 6474 if (n) *n = mat->cmap->n; 6475 PetscFunctionReturn(0); 6476 } 6477 6478 /*@C 6479 MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by 6480 this processor. (The columns of the "diagonal block") 6481 6482 Not Collective, unless matrix has not been allocated, then collective on Mat 6483 6484 Input Parameter: 6485 . mat - the matrix 6486 6487 Output Parameters: 6488 + m - the global index of the first local column 6489 - n - one more than the global index of the last local column 6490 6491 Notes: 6492 both output parameters can be NULL on input. 6493 6494 Level: developer 6495 6496 .seealso: MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn() 6497 6498 @*/ 6499 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n) 6500 { 6501 PetscFunctionBegin; 6502 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6503 PetscValidType(mat,1); 6504 if (m) PetscValidIntPointer(m,2); 6505 if (n) PetscValidIntPointer(n,3); 6506 MatCheckPreallocated(mat,1); 6507 if (m) *m = mat->cmap->rstart; 6508 if (n) *n = mat->cmap->rend; 6509 PetscFunctionReturn(0); 6510 } 6511 6512 /*@C 6513 MatGetOwnershipRange - Returns the range of matrix rows owned by 6514 this processor, assuming that the matrix is laid out with the first 6515 n1 rows on the first processor, the next n2 rows on the second, etc. 6516 For certain parallel layouts this range may not be well defined. 6517 6518 Not Collective 6519 6520 Input Parameter: 6521 . mat - the matrix 6522 6523 Output Parameters: 6524 + m - the global index of the first local row 6525 - n - one more than the global index of the last local row 6526 6527 Note: Both output parameters can be NULL on input. 6528 $ This function requires that the matrix be preallocated. If you have not preallocated, consider using 6529 $ PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N) 6530 $ and then MPI_Scan() to calculate prefix sums of the local sizes. 6531 6532 Level: beginner 6533 6534 .seealso: MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock() 6535 6536 @*/ 6537 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n) 6538 { 6539 PetscFunctionBegin; 6540 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6541 PetscValidType(mat,1); 6542 if (m) PetscValidIntPointer(m,2); 6543 if (n) PetscValidIntPointer(n,3); 6544 MatCheckPreallocated(mat,1); 6545 if (m) *m = mat->rmap->rstart; 6546 if (n) *n = mat->rmap->rend; 6547 PetscFunctionReturn(0); 6548 } 6549 6550 /*@C 6551 MatGetOwnershipRanges - Returns the range of matrix rows owned by 6552 each process 6553 6554 Not Collective, unless matrix has not been allocated, then collective on Mat 6555 6556 Input Parameters: 6557 . mat - the matrix 6558 6559 Output Parameters: 6560 . ranges - start of each processors portion plus one more than the total length at the end 6561 6562 Level: beginner 6563 6564 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn() 6565 6566 @*/ 6567 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges) 6568 { 6569 PetscFunctionBegin; 6570 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6571 PetscValidType(mat,1); 6572 MatCheckPreallocated(mat,1); 6573 CHKERRQ(PetscLayoutGetRanges(mat->rmap,ranges)); 6574 PetscFunctionReturn(0); 6575 } 6576 6577 /*@C 6578 MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by 6579 this processor. (The columns of the "diagonal blocks" for each process) 6580 6581 Not Collective, unless matrix has not been allocated, then collective on Mat 6582 6583 Input Parameters: 6584 . mat - the matrix 6585 6586 Output Parameters: 6587 . ranges - start of each processors portion plus one more then the total length at the end 6588 6589 Level: beginner 6590 6591 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges() 6592 6593 @*/ 6594 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges) 6595 { 6596 PetscFunctionBegin; 6597 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6598 PetscValidType(mat,1); 6599 MatCheckPreallocated(mat,1); 6600 CHKERRQ(PetscLayoutGetRanges(mat->cmap,ranges)); 6601 PetscFunctionReturn(0); 6602 } 6603 6604 /*@C 6605 MatGetOwnershipIS - Get row and column ownership as index sets 6606 6607 Not Collective 6608 6609 Input Parameter: 6610 . A - matrix 6611 6612 Output Parameters: 6613 + rows - rows in which this process owns elements 6614 - cols - columns in which this process owns elements 6615 6616 Level: intermediate 6617 6618 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL, MATSCALAPACK 6619 @*/ 6620 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols) 6621 { 6622 PetscErrorCode (*f)(Mat,IS*,IS*); 6623 6624 PetscFunctionBegin; 6625 MatCheckPreallocated(A,1); 6626 CHKERRQ(PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f)); 6627 if (f) { 6628 CHKERRQ((*f)(A,rows,cols)); 6629 } else { /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */ 6630 if (rows) CHKERRQ(ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows)); 6631 if (cols) CHKERRQ(ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols)); 6632 } 6633 PetscFunctionReturn(0); 6634 } 6635 6636 /*@C 6637 MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix. 6638 Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric() 6639 to complete the factorization. 6640 6641 Collective on Mat 6642 6643 Input Parameters: 6644 + mat - the matrix 6645 . row - row permutation 6646 . column - column permutation 6647 - info - structure containing 6648 $ levels - number of levels of fill. 6649 $ expected fill - as ratio of original fill. 6650 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 6651 missing diagonal entries) 6652 6653 Output Parameters: 6654 . fact - new matrix that has been symbolically factored 6655 6656 Notes: 6657 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 6658 6659 Most users should employ the simplified KSP interface for linear solvers 6660 instead of working directly with matrix algebra routines such as this. 6661 See, e.g., KSPCreate(). 6662 6663 Level: developer 6664 6665 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 6666 MatGetOrdering(), MatFactorInfo 6667 6668 Note: this uses the definition of level of fill as in Y. Saad, 2003 6669 6670 Developer Note: fortran interface is not autogenerated as the f90 6671 interface definition cannot be generated correctly [due to MatFactorInfo] 6672 6673 References: 6674 . * - Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6675 @*/ 6676 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 6677 { 6678 PetscFunctionBegin; 6679 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 6680 PetscValidType(mat,2); 6681 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,3); 6682 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,4); 6683 PetscValidPointer(info,5); 6684 PetscValidPointer(fact,1); 6685 PetscCheckFalse(info->levels < 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %" PetscInt_FMT,(PetscInt)info->levels); 6686 PetscCheckFalse(info->fill < 1.0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6687 if (!fact->ops->ilufactorsymbolic) { 6688 MatSolverType stype; 6689 CHKERRQ(MatFactorGetSolverType(fact,&stype)); 6690 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver type %s",((PetscObject)mat)->type_name,stype); 6691 } 6692 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6693 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6694 MatCheckPreallocated(mat,2); 6695 6696 if (!fact->trivialsymbolic) CHKERRQ(PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0)); 6697 CHKERRQ((fact->ops->ilufactorsymbolic)(fact,mat,row,col,info)); 6698 if (!fact->trivialsymbolic) CHKERRQ(PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0)); 6699 PetscFunctionReturn(0); 6700 } 6701 6702 /*@C 6703 MatICCFactorSymbolic - Performs symbolic incomplete 6704 Cholesky factorization for a symmetric matrix. Use 6705 MatCholeskyFactorNumeric() to complete the factorization. 6706 6707 Collective on Mat 6708 6709 Input Parameters: 6710 + mat - the matrix 6711 . perm - row and column permutation 6712 - info - structure containing 6713 $ levels - number of levels of fill. 6714 $ expected fill - as ratio of original fill. 6715 6716 Output Parameter: 6717 . fact - the factored matrix 6718 6719 Notes: 6720 Most users should employ the KSP interface for linear solvers 6721 instead of working directly with matrix algebra routines such as this. 6722 See, e.g., KSPCreate(). 6723 6724 Level: developer 6725 6726 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo 6727 6728 Note: this uses the definition of level of fill as in Y. Saad, 2003 6729 6730 Developer Note: fortran interface is not autogenerated as the f90 6731 interface definition cannot be generated correctly [due to MatFactorInfo] 6732 6733 References: 6734 . * - Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6735 @*/ 6736 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 6737 { 6738 PetscFunctionBegin; 6739 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 6740 PetscValidType(mat,2); 6741 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,3); 6742 PetscValidPointer(info,4); 6743 PetscValidPointer(fact,1); 6744 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6745 PetscCheckFalse(info->levels < 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %" PetscInt_FMT,(PetscInt) info->levels); 6746 PetscCheckFalse(info->fill < 1.0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6747 if (!(fact)->ops->iccfactorsymbolic) { 6748 MatSolverType stype; 6749 CHKERRQ(MatFactorGetSolverType(fact,&stype)); 6750 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver type %s",((PetscObject)mat)->type_name,stype); 6751 } 6752 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6753 MatCheckPreallocated(mat,2); 6754 6755 if (!fact->trivialsymbolic) CHKERRQ(PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0)); 6756 CHKERRQ((fact->ops->iccfactorsymbolic)(fact,mat,perm,info)); 6757 if (!fact->trivialsymbolic) CHKERRQ(PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0)); 6758 PetscFunctionReturn(0); 6759 } 6760 6761 /*@C 6762 MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat 6763 points to an array of valid matrices, they may be reused to store the new 6764 submatrices. 6765 6766 Collective on Mat 6767 6768 Input Parameters: 6769 + mat - the matrix 6770 . n - the number of submatrixes to be extracted (on this processor, may be zero) 6771 . irow, icol - index sets of rows and columns to extract 6772 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6773 6774 Output Parameter: 6775 . submat - the array of submatrices 6776 6777 Notes: 6778 MatCreateSubMatrices() can extract ONLY sequential submatrices 6779 (from both sequential and parallel matrices). Use MatCreateSubMatrix() 6780 to extract a parallel submatrix. 6781 6782 Some matrix types place restrictions on the row and column 6783 indices, such as that they be sorted or that they be equal to each other. 6784 6785 The index sets may not have duplicate entries. 6786 6787 When extracting submatrices from a parallel matrix, each processor can 6788 form a different submatrix by setting the rows and columns of its 6789 individual index sets according to the local submatrix desired. 6790 6791 When finished using the submatrices, the user should destroy 6792 them with MatDestroySubMatrices(). 6793 6794 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 6795 original matrix has not changed from that last call to MatCreateSubMatrices(). 6796 6797 This routine creates the matrices in submat; you should NOT create them before 6798 calling it. It also allocates the array of matrix pointers submat. 6799 6800 For BAIJ matrices the index sets must respect the block structure, that is if they 6801 request one row/column in a block, they must request all rows/columns that are in 6802 that block. For example, if the block size is 2 you cannot request just row 0 and 6803 column 0. 6804 6805 Fortran Note: 6806 The Fortran interface is slightly different from that given below; it 6807 requires one to pass in as submat a Mat (integer) array of size at least n+1. 6808 6809 Level: advanced 6810 6811 .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse 6812 @*/ 6813 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 6814 { 6815 PetscInt i; 6816 PetscBool eq; 6817 6818 PetscFunctionBegin; 6819 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6820 PetscValidType(mat,1); 6821 if (n) { 6822 PetscValidPointer(irow,3); 6823 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 6824 PetscValidPointer(icol,4); 6825 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 6826 } 6827 PetscValidPointer(submat,6); 6828 if (n && scall == MAT_REUSE_MATRIX) { 6829 PetscValidPointer(*submat,6); 6830 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 6831 } 6832 PetscCheck(mat->ops->createsubmatrices,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6833 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6834 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6835 MatCheckPreallocated(mat,1); 6836 6837 CHKERRQ(PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0)); 6838 CHKERRQ((*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat)); 6839 CHKERRQ(PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0)); 6840 for (i=0; i<n; i++) { 6841 (*submat)[i]->factortype = MAT_FACTOR_NONE; /* in case in place factorization was previously done on submatrix */ 6842 CHKERRQ(ISEqualUnsorted(irow[i],icol[i],&eq)); 6843 if (eq) { 6844 CHKERRQ(MatPropagateSymmetryOptions(mat,(*submat)[i])); 6845 } 6846 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 6847 if (mat->boundtocpu && mat->bindingpropagates) { 6848 CHKERRQ(MatBindToCPU((*submat)[i],PETSC_TRUE)); 6849 CHKERRQ(MatSetBindingPropagates((*submat)[i],PETSC_TRUE)); 6850 } 6851 #endif 6852 } 6853 PetscFunctionReturn(0); 6854 } 6855 6856 /*@C 6857 MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms). 6858 6859 Collective on Mat 6860 6861 Input Parameters: 6862 + mat - the matrix 6863 . n - the number of submatrixes to be extracted 6864 . irow, icol - index sets of rows and columns to extract 6865 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6866 6867 Output Parameter: 6868 . submat - the array of submatrices 6869 6870 Level: advanced 6871 6872 .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse 6873 @*/ 6874 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 6875 { 6876 PetscInt i; 6877 PetscBool eq; 6878 6879 PetscFunctionBegin; 6880 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6881 PetscValidType(mat,1); 6882 if (n) { 6883 PetscValidPointer(irow,3); 6884 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 6885 PetscValidPointer(icol,4); 6886 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 6887 } 6888 PetscValidPointer(submat,6); 6889 if (n && scall == MAT_REUSE_MATRIX) { 6890 PetscValidPointer(*submat,6); 6891 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 6892 } 6893 PetscCheck(mat->ops->createsubmatricesmpi,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6894 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6895 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6896 MatCheckPreallocated(mat,1); 6897 6898 CHKERRQ(PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0)); 6899 CHKERRQ((*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat)); 6900 CHKERRQ(PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0)); 6901 for (i=0; i<n; i++) { 6902 CHKERRQ(ISEqualUnsorted(irow[i],icol[i],&eq)); 6903 if (eq) { 6904 CHKERRQ(MatPropagateSymmetryOptions(mat,(*submat)[i])); 6905 } 6906 } 6907 PetscFunctionReturn(0); 6908 } 6909 6910 /*@C 6911 MatDestroyMatrices - Destroys an array of matrices. 6912 6913 Collective on Mat 6914 6915 Input Parameters: 6916 + n - the number of local matrices 6917 - mat - the matrices (note that this is a pointer to the array of matrices) 6918 6919 Level: advanced 6920 6921 Notes: 6922 Frees not only the matrices, but also the array that contains the matrices 6923 In Fortran will not free the array. 6924 6925 .seealso: MatCreateSubMatrices() MatDestroySubMatrices() 6926 @*/ 6927 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[]) 6928 { 6929 PetscInt i; 6930 6931 PetscFunctionBegin; 6932 if (!*mat) PetscFunctionReturn(0); 6933 PetscCheckFalse(n < 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %" PetscInt_FMT,n); 6934 PetscValidPointer(mat,2); 6935 6936 for (i=0; i<n; i++) { 6937 CHKERRQ(MatDestroy(&(*mat)[i])); 6938 } 6939 6940 /* memory is allocated even if n = 0 */ 6941 CHKERRQ(PetscFree(*mat)); 6942 PetscFunctionReturn(0); 6943 } 6944 6945 /*@C 6946 MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices(). 6947 6948 Collective on Mat 6949 6950 Input Parameters: 6951 + n - the number of local matrices 6952 - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling 6953 sequence of MatCreateSubMatrices()) 6954 6955 Level: advanced 6956 6957 Notes: 6958 Frees not only the matrices, but also the array that contains the matrices 6959 In Fortran will not free the array. 6960 6961 .seealso: MatCreateSubMatrices() 6962 @*/ 6963 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[]) 6964 { 6965 Mat mat0; 6966 6967 PetscFunctionBegin; 6968 if (!*mat) PetscFunctionReturn(0); 6969 /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */ 6970 PetscCheckFalse(n < 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %" PetscInt_FMT,n); 6971 PetscValidPointer(mat,2); 6972 6973 mat0 = (*mat)[0]; 6974 if (mat0 && mat0->ops->destroysubmatrices) { 6975 CHKERRQ((mat0->ops->destroysubmatrices)(n,mat)); 6976 } else { 6977 CHKERRQ(MatDestroyMatrices(n,mat)); 6978 } 6979 PetscFunctionReturn(0); 6980 } 6981 6982 /*@C 6983 MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix. 6984 6985 Collective on Mat 6986 6987 Input Parameters: 6988 . mat - the matrix 6989 6990 Output Parameter: 6991 . matstruct - the sequential matrix with the nonzero structure of mat 6992 6993 Level: intermediate 6994 6995 .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices() 6996 @*/ 6997 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct) 6998 { 6999 PetscFunctionBegin; 7000 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7001 PetscValidPointer(matstruct,2); 7002 7003 PetscValidType(mat,1); 7004 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7005 MatCheckPreallocated(mat,1); 7006 7007 PetscCheck(mat->ops->getseqnonzerostructure,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s",((PetscObject)mat)->type_name); 7008 CHKERRQ(PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0)); 7009 CHKERRQ((*mat->ops->getseqnonzerostructure)(mat,matstruct)); 7010 CHKERRQ(PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0)); 7011 PetscFunctionReturn(0); 7012 } 7013 7014 /*@C 7015 MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure(). 7016 7017 Collective on Mat 7018 7019 Input Parameters: 7020 . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling 7021 sequence of MatGetSequentialNonzeroStructure()) 7022 7023 Level: advanced 7024 7025 Notes: 7026 Frees not only the matrices, but also the array that contains the matrices 7027 7028 .seealso: MatGetSeqNonzeroStructure() 7029 @*/ 7030 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat) 7031 { 7032 PetscFunctionBegin; 7033 PetscValidPointer(mat,1); 7034 CHKERRQ(MatDestroy(mat)); 7035 PetscFunctionReturn(0); 7036 } 7037 7038 /*@ 7039 MatIncreaseOverlap - Given a set of submatrices indicated by index sets, 7040 replaces the index sets by larger ones that represent submatrices with 7041 additional overlap. 7042 7043 Collective on Mat 7044 7045 Input Parameters: 7046 + mat - the matrix 7047 . n - the number of index sets 7048 . is - the array of index sets (these index sets will changed during the call) 7049 - ov - the additional overlap requested 7050 7051 Options Database: 7052 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7053 7054 Level: developer 7055 7056 Developer Note: 7057 Any implementation must preserve block sizes. That is: if the row block size and the column block size of mat are equal to bs, then the output index sets must be compatible with bs. 7058 7059 .seealso: MatCreateSubMatrices() 7060 @*/ 7061 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov) 7062 { 7063 PetscInt i,bs,cbs; 7064 7065 PetscFunctionBegin; 7066 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7067 PetscValidType(mat,1); 7068 PetscCheckFalse(n < 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %" PetscInt_FMT,n); 7069 if (n) { 7070 PetscValidPointer(is,3); 7071 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 7072 PetscValidLogicalCollectiveInt(*is,n,2); 7073 } 7074 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7075 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7076 MatCheckPreallocated(mat,1); 7077 7078 if (!ov) PetscFunctionReturn(0); 7079 PetscCheck(mat->ops->increaseoverlap,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7080 CHKERRQ(PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0)); 7081 CHKERRQ((*mat->ops->increaseoverlap)(mat,n,is,ov)); 7082 CHKERRQ(PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0)); 7083 CHKERRQ(MatGetBlockSizes(mat,&bs,&cbs)); 7084 if (bs == cbs) { 7085 for (i=0; i<n; i++) { 7086 CHKERRQ(ISSetBlockSize(is[i],bs)); 7087 } 7088 } 7089 PetscFunctionReturn(0); 7090 } 7091 7092 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt); 7093 7094 /*@ 7095 MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across 7096 a sub communicator, replaces the index sets by larger ones that represent submatrices with 7097 additional overlap. 7098 7099 Collective on Mat 7100 7101 Input Parameters: 7102 + mat - the matrix 7103 . n - the number of index sets 7104 . is - the array of index sets (these index sets will changed during the call) 7105 - ov - the additional overlap requested 7106 7107 Options Database: 7108 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7109 7110 Level: developer 7111 7112 .seealso: MatCreateSubMatrices() 7113 @*/ 7114 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov) 7115 { 7116 PetscInt i; 7117 7118 PetscFunctionBegin; 7119 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7120 PetscValidType(mat,1); 7121 PetscCheckFalse(n < 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %" PetscInt_FMT,n); 7122 if (n) { 7123 PetscValidPointer(is,3); 7124 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 7125 } 7126 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7127 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7128 MatCheckPreallocated(mat,1); 7129 if (!ov) PetscFunctionReturn(0); 7130 CHKERRQ(PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0)); 7131 for (i=0; i<n; i++) { 7132 CHKERRQ(MatIncreaseOverlapSplit_Single(mat,&is[i],ov)); 7133 } 7134 CHKERRQ(PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0)); 7135 PetscFunctionReturn(0); 7136 } 7137 7138 /*@ 7139 MatGetBlockSize - Returns the matrix block size. 7140 7141 Not Collective 7142 7143 Input Parameter: 7144 . mat - the matrix 7145 7146 Output Parameter: 7147 . bs - block size 7148 7149 Notes: 7150 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7151 7152 If the block size has not been set yet this routine returns 1. 7153 7154 Level: intermediate 7155 7156 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes() 7157 @*/ 7158 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs) 7159 { 7160 PetscFunctionBegin; 7161 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7162 PetscValidIntPointer(bs,2); 7163 *bs = PetscAbs(mat->rmap->bs); 7164 PetscFunctionReturn(0); 7165 } 7166 7167 /*@ 7168 MatGetBlockSizes - Returns the matrix block row and column sizes. 7169 7170 Not Collective 7171 7172 Input Parameter: 7173 . mat - the matrix 7174 7175 Output Parameters: 7176 + rbs - row block size 7177 - cbs - column block size 7178 7179 Notes: 7180 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7181 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7182 7183 If a block size has not been set yet this routine returns 1. 7184 7185 Level: intermediate 7186 7187 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes() 7188 @*/ 7189 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs) 7190 { 7191 PetscFunctionBegin; 7192 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7193 if (rbs) PetscValidIntPointer(rbs,2); 7194 if (cbs) PetscValidIntPointer(cbs,3); 7195 if (rbs) *rbs = PetscAbs(mat->rmap->bs); 7196 if (cbs) *cbs = PetscAbs(mat->cmap->bs); 7197 PetscFunctionReturn(0); 7198 } 7199 7200 /*@ 7201 MatSetBlockSize - Sets the matrix block size. 7202 7203 Logically Collective on Mat 7204 7205 Input Parameters: 7206 + mat - the matrix 7207 - bs - block size 7208 7209 Notes: 7210 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7211 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7212 7213 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size 7214 is compatible with the matrix local sizes. 7215 7216 Level: intermediate 7217 7218 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes() 7219 @*/ 7220 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs) 7221 { 7222 PetscFunctionBegin; 7223 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7224 PetscValidLogicalCollectiveInt(mat,bs,2); 7225 CHKERRQ(MatSetBlockSizes(mat,bs,bs)); 7226 PetscFunctionReturn(0); 7227 } 7228 7229 /*@ 7230 MatSetVariableBlockSizes - Sets diagonal point-blocks of the matrix that need not be of the same size 7231 7232 Logically Collective on Mat 7233 7234 Input Parameters: 7235 + mat - the matrix 7236 . nblocks - the number of blocks on this process 7237 - bsizes - the block sizes 7238 7239 Notes: 7240 Currently used by PCVPBJACOBI for AIJ matrices 7241 7242 Each variable point-block set of degrees of freedom must live on a single MPI rank. That is a point block cannot straddle two MPI ranks. 7243 7244 Level: intermediate 7245 7246 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatGetVariableBlockSizes(), PCVPBJACOBI 7247 @*/ 7248 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes) 7249 { 7250 PetscInt i,ncnt = 0, nlocal; 7251 7252 PetscFunctionBegin; 7253 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7254 PetscCheckFalse(nblocks < 0,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero"); 7255 CHKERRQ(MatGetLocalSize(mat,&nlocal,NULL)); 7256 for (i=0; i<nblocks; i++) ncnt += bsizes[i]; 7257 PetscCheckFalse(ncnt != nlocal,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Sum of local block sizes %" PetscInt_FMT " does not equal local size of matrix %" PetscInt_FMT,ncnt,nlocal); 7258 CHKERRQ(PetscFree(mat->bsizes)); 7259 mat->nblocks = nblocks; 7260 CHKERRQ(PetscMalloc1(nblocks,&mat->bsizes)); 7261 CHKERRQ(PetscArraycpy(mat->bsizes,bsizes,nblocks)); 7262 PetscFunctionReturn(0); 7263 } 7264 7265 /*@C 7266 MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size 7267 7268 Logically Collective on Mat 7269 7270 Input Parameter: 7271 . mat - the matrix 7272 7273 Output Parameters: 7274 + nblocks - the number of blocks on this process 7275 - bsizes - the block sizes 7276 7277 Notes: Currently not supported from Fortran 7278 7279 Level: intermediate 7280 7281 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatSetVariableBlockSizes() 7282 @*/ 7283 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes) 7284 { 7285 PetscFunctionBegin; 7286 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7287 *nblocks = mat->nblocks; 7288 *bsizes = mat->bsizes; 7289 PetscFunctionReturn(0); 7290 } 7291 7292 /*@ 7293 MatSetBlockSizes - Sets the matrix block row and column sizes. 7294 7295 Logically Collective on Mat 7296 7297 Input Parameters: 7298 + mat - the matrix 7299 . rbs - row block size 7300 - cbs - column block size 7301 7302 Notes: 7303 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7304 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7305 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7306 7307 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes 7308 are compatible with the matrix local sizes. 7309 7310 The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs(). 7311 7312 Level: intermediate 7313 7314 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes() 7315 @*/ 7316 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs) 7317 { 7318 PetscFunctionBegin; 7319 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7320 PetscValidLogicalCollectiveInt(mat,rbs,2); 7321 PetscValidLogicalCollectiveInt(mat,cbs,3); 7322 if (mat->ops->setblocksizes) { 7323 CHKERRQ((*mat->ops->setblocksizes)(mat,rbs,cbs)); 7324 } 7325 if (mat->rmap->refcnt) { 7326 ISLocalToGlobalMapping l2g = NULL; 7327 PetscLayout nmap = NULL; 7328 7329 CHKERRQ(PetscLayoutDuplicate(mat->rmap,&nmap)); 7330 if (mat->rmap->mapping) { 7331 CHKERRQ(ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g)); 7332 } 7333 CHKERRQ(PetscLayoutDestroy(&mat->rmap)); 7334 mat->rmap = nmap; 7335 mat->rmap->mapping = l2g; 7336 } 7337 if (mat->cmap->refcnt) { 7338 ISLocalToGlobalMapping l2g = NULL; 7339 PetscLayout nmap = NULL; 7340 7341 CHKERRQ(PetscLayoutDuplicate(mat->cmap,&nmap)); 7342 if (mat->cmap->mapping) { 7343 CHKERRQ(ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g)); 7344 } 7345 CHKERRQ(PetscLayoutDestroy(&mat->cmap)); 7346 mat->cmap = nmap; 7347 mat->cmap->mapping = l2g; 7348 } 7349 CHKERRQ(PetscLayoutSetBlockSize(mat->rmap,rbs)); 7350 CHKERRQ(PetscLayoutSetBlockSize(mat->cmap,cbs)); 7351 PetscFunctionReturn(0); 7352 } 7353 7354 /*@ 7355 MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices 7356 7357 Logically Collective on Mat 7358 7359 Input Parameters: 7360 + mat - the matrix 7361 . fromRow - matrix from which to copy row block size 7362 - fromCol - matrix from which to copy column block size (can be same as fromRow) 7363 7364 Level: developer 7365 7366 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes() 7367 @*/ 7368 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol) 7369 { 7370 PetscFunctionBegin; 7371 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7372 PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2); 7373 PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3); 7374 if (fromRow->rmap->bs > 0) CHKERRQ(PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs)); 7375 if (fromCol->cmap->bs > 0) CHKERRQ(PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs)); 7376 PetscFunctionReturn(0); 7377 } 7378 7379 /*@ 7380 MatResidual - Default routine to calculate the residual. 7381 7382 Collective on Mat 7383 7384 Input Parameters: 7385 + mat - the matrix 7386 . b - the right-hand-side 7387 - x - the approximate solution 7388 7389 Output Parameter: 7390 . r - location to store the residual 7391 7392 Level: developer 7393 7394 .seealso: PCMGSetResidual() 7395 @*/ 7396 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r) 7397 { 7398 PetscFunctionBegin; 7399 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7400 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 7401 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 7402 PetscValidHeaderSpecific(r,VEC_CLASSID,4); 7403 PetscValidType(mat,1); 7404 MatCheckPreallocated(mat,1); 7405 CHKERRQ(PetscLogEventBegin(MAT_Residual,mat,0,0,0)); 7406 if (!mat->ops->residual) { 7407 CHKERRQ(MatMult(mat,x,r)); 7408 CHKERRQ(VecAYPX(r,-1.0,b)); 7409 } else { 7410 CHKERRQ((*mat->ops->residual)(mat,b,x,r)); 7411 } 7412 CHKERRQ(PetscLogEventEnd(MAT_Residual,mat,0,0,0)); 7413 PetscFunctionReturn(0); 7414 } 7415 7416 /*@C 7417 MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices. 7418 7419 Collective on Mat 7420 7421 Input Parameters: 7422 + mat - the matrix 7423 . shift - 0 or 1 indicating we want the indices starting at 0 or 1 7424 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized 7425 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7426 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7427 always used. 7428 7429 Output Parameters: 7430 + n - number of rows in the (possibly compressed) matrix 7431 . ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix 7432 . ja - the column indices 7433 - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers 7434 are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set 7435 7436 Level: developer 7437 7438 Notes: 7439 You CANNOT change any of the ia[] or ja[] values. 7440 7441 Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values. 7442 7443 Fortran Notes: 7444 In Fortran use 7445 $ 7446 $ PetscInt ia(1), ja(1) 7447 $ PetscOffset iia, jja 7448 $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr) 7449 $ ! Access the ith and jth entries via ia(iia + i) and ja(jja + j) 7450 7451 or 7452 $ 7453 $ PetscInt, pointer :: ia(:),ja(:) 7454 $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr) 7455 $ ! Access the ith and jth entries via ia(i) and ja(j) 7456 7457 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray() 7458 @*/ 7459 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7460 { 7461 PetscFunctionBegin; 7462 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7463 PetscValidType(mat,1); 7464 PetscValidIntPointer(n,5); 7465 if (ia) PetscValidIntPointer(ia,6); 7466 if (ja) PetscValidIntPointer(ja,7); 7467 PetscValidBoolPointer(done,8); 7468 MatCheckPreallocated(mat,1); 7469 if (!mat->ops->getrowij) *done = PETSC_FALSE; 7470 else { 7471 *done = PETSC_TRUE; 7472 CHKERRQ(PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0)); 7473 CHKERRQ((*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done)); 7474 CHKERRQ(PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0)); 7475 } 7476 PetscFunctionReturn(0); 7477 } 7478 7479 /*@C 7480 MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices. 7481 7482 Collective on Mat 7483 7484 Input Parameters: 7485 + mat - the matrix 7486 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7487 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7488 symmetrized 7489 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7490 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7491 always used. 7492 . n - number of columns in the (possibly compressed) matrix 7493 . ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix 7494 - ja - the row indices 7495 7496 Output Parameters: 7497 . done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned 7498 7499 Level: developer 7500 7501 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 7502 @*/ 7503 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7504 { 7505 PetscFunctionBegin; 7506 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7507 PetscValidType(mat,1); 7508 PetscValidIntPointer(n,5); 7509 if (ia) PetscValidIntPointer(ia,6); 7510 if (ja) PetscValidIntPointer(ja,7); 7511 PetscValidBoolPointer(done,8); 7512 MatCheckPreallocated(mat,1); 7513 if (!mat->ops->getcolumnij) *done = PETSC_FALSE; 7514 else { 7515 *done = PETSC_TRUE; 7516 CHKERRQ((*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done)); 7517 } 7518 PetscFunctionReturn(0); 7519 } 7520 7521 /*@C 7522 MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with 7523 MatGetRowIJ(). 7524 7525 Collective on Mat 7526 7527 Input Parameters: 7528 + mat - the matrix 7529 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7530 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7531 symmetrized 7532 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7533 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7534 always used. 7535 . n - size of (possibly compressed) matrix 7536 . ia - the row pointers 7537 - ja - the column indices 7538 7539 Output Parameters: 7540 . done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7541 7542 Note: 7543 This routine zeros out n, ia, and ja. This is to prevent accidental 7544 us of the array after it has been restored. If you pass NULL, it will 7545 not zero the pointers. Use of ia or ja after MatRestoreRowIJ() is invalid. 7546 7547 Level: developer 7548 7549 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 7550 @*/ 7551 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7552 { 7553 PetscFunctionBegin; 7554 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7555 PetscValidType(mat,1); 7556 if (ia) PetscValidIntPointer(ia,6); 7557 if (ja) PetscValidIntPointer(ja,7); 7558 PetscValidBoolPointer(done,8); 7559 MatCheckPreallocated(mat,1); 7560 7561 if (!mat->ops->restorerowij) *done = PETSC_FALSE; 7562 else { 7563 *done = PETSC_TRUE; 7564 CHKERRQ((*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done)); 7565 if (n) *n = 0; 7566 if (ia) *ia = NULL; 7567 if (ja) *ja = NULL; 7568 } 7569 PetscFunctionReturn(0); 7570 } 7571 7572 /*@C 7573 MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with 7574 MatGetColumnIJ(). 7575 7576 Collective on Mat 7577 7578 Input Parameters: 7579 + mat - the matrix 7580 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7581 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7582 symmetrized 7583 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7584 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7585 always used. 7586 7587 Output Parameters: 7588 + n - size of (possibly compressed) matrix 7589 . ia - the column pointers 7590 . ja - the row indices 7591 - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7592 7593 Level: developer 7594 7595 .seealso: MatGetColumnIJ(), MatRestoreRowIJ() 7596 @*/ 7597 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7598 { 7599 PetscFunctionBegin; 7600 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7601 PetscValidType(mat,1); 7602 if (ia) PetscValidIntPointer(ia,6); 7603 if (ja) PetscValidIntPointer(ja,7); 7604 PetscValidBoolPointer(done,8); 7605 MatCheckPreallocated(mat,1); 7606 7607 if (!mat->ops->restorecolumnij) *done = PETSC_FALSE; 7608 else { 7609 *done = PETSC_TRUE; 7610 CHKERRQ((*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done)); 7611 if (n) *n = 0; 7612 if (ia) *ia = NULL; 7613 if (ja) *ja = NULL; 7614 } 7615 PetscFunctionReturn(0); 7616 } 7617 7618 /*@C 7619 MatColoringPatch -Used inside matrix coloring routines that 7620 use MatGetRowIJ() and/or MatGetColumnIJ(). 7621 7622 Collective on Mat 7623 7624 Input Parameters: 7625 + mat - the matrix 7626 . ncolors - max color value 7627 . n - number of entries in colorarray 7628 - colorarray - array indicating color for each column 7629 7630 Output Parameters: 7631 . iscoloring - coloring generated using colorarray information 7632 7633 Level: developer 7634 7635 .seealso: MatGetRowIJ(), MatGetColumnIJ() 7636 7637 @*/ 7638 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring) 7639 { 7640 PetscFunctionBegin; 7641 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7642 PetscValidType(mat,1); 7643 PetscValidIntPointer(colorarray,4); 7644 PetscValidPointer(iscoloring,5); 7645 MatCheckPreallocated(mat,1); 7646 7647 if (!mat->ops->coloringpatch) { 7648 CHKERRQ(ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring)); 7649 } else { 7650 CHKERRQ((*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring)); 7651 } 7652 PetscFunctionReturn(0); 7653 } 7654 7655 /*@ 7656 MatSetUnfactored - Resets a factored matrix to be treated as unfactored. 7657 7658 Logically Collective on Mat 7659 7660 Input Parameter: 7661 . mat - the factored matrix to be reset 7662 7663 Notes: 7664 This routine should be used only with factored matrices formed by in-place 7665 factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE 7666 format). This option can save memory, for example, when solving nonlinear 7667 systems with a matrix-free Newton-Krylov method and a matrix-based, in-place 7668 ILU(0) preconditioner. 7669 7670 Note that one can specify in-place ILU(0) factorization by calling 7671 .vb 7672 PCType(pc,PCILU); 7673 PCFactorSeUseInPlace(pc); 7674 .ve 7675 or by using the options -pc_type ilu -pc_factor_in_place 7676 7677 In-place factorization ILU(0) can also be used as a local 7678 solver for the blocks within the block Jacobi or additive Schwarz 7679 methods (runtime option: -sub_pc_factor_in_place). See Users-Manual: ch_pc 7680 for details on setting local solver options. 7681 7682 Most users should employ the simplified KSP interface for linear solvers 7683 instead of working directly with matrix algebra routines such as this. 7684 See, e.g., KSPCreate(). 7685 7686 Level: developer 7687 7688 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace() 7689 7690 @*/ 7691 PetscErrorCode MatSetUnfactored(Mat mat) 7692 { 7693 PetscFunctionBegin; 7694 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7695 PetscValidType(mat,1); 7696 MatCheckPreallocated(mat,1); 7697 mat->factortype = MAT_FACTOR_NONE; 7698 if (!mat->ops->setunfactored) PetscFunctionReturn(0); 7699 CHKERRQ((*mat->ops->setunfactored)(mat)); 7700 PetscFunctionReturn(0); 7701 } 7702 7703 /*MC 7704 MatDenseGetArrayF90 - Accesses a matrix array from Fortran90. 7705 7706 Synopsis: 7707 MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7708 7709 Not collective 7710 7711 Input Parameter: 7712 . x - matrix 7713 7714 Output Parameters: 7715 + xx_v - the Fortran90 pointer to the array 7716 - ierr - error code 7717 7718 Example of Usage: 7719 .vb 7720 PetscScalar, pointer xx_v(:,:) 7721 .... 7722 call MatDenseGetArrayF90(x,xx_v,ierr) 7723 a = xx_v(3) 7724 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7725 .ve 7726 7727 Level: advanced 7728 7729 .seealso: MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90() 7730 7731 M*/ 7732 7733 /*MC 7734 MatDenseRestoreArrayF90 - Restores a matrix array that has been 7735 accessed with MatDenseGetArrayF90(). 7736 7737 Synopsis: 7738 MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7739 7740 Not collective 7741 7742 Input Parameters: 7743 + x - matrix 7744 - xx_v - the Fortran90 pointer to the array 7745 7746 Output Parameter: 7747 . ierr - error code 7748 7749 Example of Usage: 7750 .vb 7751 PetscScalar, pointer xx_v(:,:) 7752 .... 7753 call MatDenseGetArrayF90(x,xx_v,ierr) 7754 a = xx_v(3) 7755 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7756 .ve 7757 7758 Level: advanced 7759 7760 .seealso: MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90() 7761 7762 M*/ 7763 7764 /*MC 7765 MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90. 7766 7767 Synopsis: 7768 MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7769 7770 Not collective 7771 7772 Input Parameter: 7773 . x - matrix 7774 7775 Output Parameters: 7776 + xx_v - the Fortran90 pointer to the array 7777 - ierr - error code 7778 7779 Example of Usage: 7780 .vb 7781 PetscScalar, pointer xx_v(:) 7782 .... 7783 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 7784 a = xx_v(3) 7785 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 7786 .ve 7787 7788 Level: advanced 7789 7790 .seealso: MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90() 7791 7792 M*/ 7793 7794 /*MC 7795 MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been 7796 accessed with MatSeqAIJGetArrayF90(). 7797 7798 Synopsis: 7799 MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7800 7801 Not collective 7802 7803 Input Parameters: 7804 + x - matrix 7805 - xx_v - the Fortran90 pointer to the array 7806 7807 Output Parameter: 7808 . ierr - error code 7809 7810 Example of Usage: 7811 .vb 7812 PetscScalar, pointer xx_v(:) 7813 .... 7814 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 7815 a = xx_v(3) 7816 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 7817 .ve 7818 7819 Level: advanced 7820 7821 .seealso: MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90() 7822 7823 M*/ 7824 7825 /*@ 7826 MatCreateSubMatrix - Gets a single submatrix on the same number of processors 7827 as the original matrix. 7828 7829 Collective on Mat 7830 7831 Input Parameters: 7832 + mat - the original matrix 7833 . isrow - parallel IS containing the rows this processor should obtain 7834 . iscol - parallel IS containing all columns you wish to keep. Each process should list the columns that will be in IT's "diagonal part" in the new matrix. 7835 - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 7836 7837 Output Parameter: 7838 . newmat - the new submatrix, of the same type as the old 7839 7840 Level: advanced 7841 7842 Notes: 7843 The submatrix will be able to be multiplied with vectors using the same layout as iscol. 7844 7845 Some matrix types place restrictions on the row and column indices, such 7846 as that they be sorted or that they be equal to each other. 7847 7848 The index sets may not have duplicate entries. 7849 7850 The first time this is called you should use a cll of MAT_INITIAL_MATRIX, 7851 the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls 7852 to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX 7853 will reuse the matrix generated the first time. You should call MatDestroy() on newmat when 7854 you are finished using it. 7855 7856 The communicator of the newly obtained matrix is ALWAYS the same as the communicator of 7857 the input matrix. 7858 7859 If iscol is NULL then all columns are obtained (not supported in Fortran). 7860 7861 Example usage: 7862 Consider the following 8x8 matrix with 34 non-zero values, that is 7863 assembled across 3 processors. Let's assume that proc0 owns 3 rows, 7864 proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown 7865 as follows: 7866 7867 .vb 7868 1 2 0 | 0 3 0 | 0 4 7869 Proc0 0 5 6 | 7 0 0 | 8 0 7870 9 0 10 | 11 0 0 | 12 0 7871 ------------------------------------- 7872 13 0 14 | 15 16 17 | 0 0 7873 Proc1 0 18 0 | 19 20 21 | 0 0 7874 0 0 0 | 22 23 0 | 24 0 7875 ------------------------------------- 7876 Proc2 25 26 27 | 0 0 28 | 29 0 7877 30 0 0 | 31 32 33 | 0 34 7878 .ve 7879 7880 Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is 7881 7882 .vb 7883 2 0 | 0 3 0 | 0 7884 Proc0 5 6 | 7 0 0 | 8 7885 ------------------------------- 7886 Proc1 18 0 | 19 20 21 | 0 7887 ------------------------------- 7888 Proc2 26 27 | 0 0 28 | 29 7889 0 0 | 31 32 33 | 0 7890 .ve 7891 7892 .seealso: MatCreateSubMatrices(), MatCreateSubMatricesMPI(), MatCreateSubMatrixVirtual(), MatSubMatrixVirtualUpdate() 7893 @*/ 7894 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat) 7895 { 7896 PetscMPIInt size; 7897 Mat *local; 7898 IS iscoltmp; 7899 PetscBool flg; 7900 7901 PetscFunctionBegin; 7902 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7903 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 7904 if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 7905 PetscValidPointer(newmat,5); 7906 if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5); 7907 PetscValidType(mat,1); 7908 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7909 PetscCheckFalse(cll == MAT_IGNORE_MATRIX,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX"); 7910 7911 MatCheckPreallocated(mat,1); 7912 CHKERRMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 7913 7914 if (!iscol || isrow == iscol) { 7915 PetscBool stride; 7916 PetscMPIInt grabentirematrix = 0,grab; 7917 CHKERRQ(PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride)); 7918 if (stride) { 7919 PetscInt first,step,n,rstart,rend; 7920 CHKERRQ(ISStrideGetInfo(isrow,&first,&step)); 7921 if (step == 1) { 7922 CHKERRQ(MatGetOwnershipRange(mat,&rstart,&rend)); 7923 if (rstart == first) { 7924 CHKERRQ(ISGetLocalSize(isrow,&n)); 7925 if (n == rend-rstart) { 7926 grabentirematrix = 1; 7927 } 7928 } 7929 } 7930 } 7931 CHKERRMPI(MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat))); 7932 if (grab) { 7933 CHKERRQ(PetscInfo(mat,"Getting entire matrix as submatrix\n")); 7934 if (cll == MAT_INITIAL_MATRIX) { 7935 *newmat = mat; 7936 CHKERRQ(PetscObjectReference((PetscObject)mat)); 7937 } 7938 PetscFunctionReturn(0); 7939 } 7940 } 7941 7942 if (!iscol) { 7943 CHKERRQ(ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp)); 7944 } else { 7945 iscoltmp = iscol; 7946 } 7947 7948 /* if original matrix is on just one processor then use submatrix generated */ 7949 if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) { 7950 CHKERRQ(MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat)); 7951 goto setproperties; 7952 } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) { 7953 CHKERRQ(MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local)); 7954 *newmat = *local; 7955 CHKERRQ(PetscFree(local)); 7956 goto setproperties; 7957 } else if (!mat->ops->createsubmatrix) { 7958 /* Create a new matrix type that implements the operation using the full matrix */ 7959 CHKERRQ(PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0)); 7960 switch (cll) { 7961 case MAT_INITIAL_MATRIX: 7962 CHKERRQ(MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat)); 7963 break; 7964 case MAT_REUSE_MATRIX: 7965 CHKERRQ(MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp)); 7966 break; 7967 default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX"); 7968 } 7969 CHKERRQ(PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0)); 7970 goto setproperties; 7971 } 7972 7973 PetscCheck(mat->ops->createsubmatrix,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7974 CHKERRQ(PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0)); 7975 CHKERRQ((*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat)); 7976 CHKERRQ(PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0)); 7977 7978 setproperties: 7979 CHKERRQ(ISEqualUnsorted(isrow,iscoltmp,&flg)); 7980 if (flg) { 7981 CHKERRQ(MatPropagateSymmetryOptions(mat,*newmat)); 7982 } 7983 if (!iscol) CHKERRQ(ISDestroy(&iscoltmp)); 7984 if (*newmat && cll == MAT_INITIAL_MATRIX) CHKERRQ(PetscObjectStateIncrease((PetscObject)*newmat)); 7985 PetscFunctionReturn(0); 7986 } 7987 7988 /*@ 7989 MatPropagateSymmetryOptions - Propagates symmetry options set on a matrix to another matrix 7990 7991 Not Collective 7992 7993 Input Parameters: 7994 + A - the matrix we wish to propagate options from 7995 - B - the matrix we wish to propagate options to 7996 7997 Level: beginner 7998 7999 Notes: Propagates the options associated to MAT_SYMMETRY_ETERNAL, MAT_STRUCTURALLY_SYMMETRIC, MAT_HERMITIAN, MAT_SPD and MAT_SYMMETRIC 8000 8001 .seealso: MatSetOption() 8002 @*/ 8003 PetscErrorCode MatPropagateSymmetryOptions(Mat A, Mat B) 8004 { 8005 PetscFunctionBegin; 8006 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8007 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 8008 if (A->symmetric_eternal) { /* symmetric_eternal does not have a corresponding *set flag */ 8009 CHKERRQ(MatSetOption(B,MAT_SYMMETRY_ETERNAL,A->symmetric_eternal)); 8010 } 8011 if (A->structurally_symmetric_set) { 8012 CHKERRQ(MatSetOption(B,MAT_STRUCTURALLY_SYMMETRIC,A->structurally_symmetric)); 8013 } 8014 if (A->hermitian_set) { 8015 CHKERRQ(MatSetOption(B,MAT_HERMITIAN,A->hermitian)); 8016 } 8017 if (A->spd_set) { 8018 CHKERRQ(MatSetOption(B,MAT_SPD,A->spd)); 8019 } 8020 if (A->symmetric_set) { 8021 CHKERRQ(MatSetOption(B,MAT_SYMMETRIC,A->symmetric)); 8022 } 8023 PetscFunctionReturn(0); 8024 } 8025 8026 /*@ 8027 MatStashSetInitialSize - sets the sizes of the matrix stash, that is 8028 used during the assembly process to store values that belong to 8029 other processors. 8030 8031 Not Collective 8032 8033 Input Parameters: 8034 + mat - the matrix 8035 . size - the initial size of the stash. 8036 - bsize - the initial size of the block-stash(if used). 8037 8038 Options Database Keys: 8039 + -matstash_initial_size <size> or <size0,size1,...sizep-1> 8040 - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1> 8041 8042 Level: intermediate 8043 8044 Notes: 8045 The block-stash is used for values set with MatSetValuesBlocked() while 8046 the stash is used for values set with MatSetValues() 8047 8048 Run with the option -info and look for output of the form 8049 MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs. 8050 to determine the appropriate value, MM, to use for size and 8051 MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs. 8052 to determine the value, BMM to use for bsize 8053 8054 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo() 8055 8056 @*/ 8057 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize) 8058 { 8059 PetscFunctionBegin; 8060 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8061 PetscValidType(mat,1); 8062 CHKERRQ(MatStashSetInitialSize_Private(&mat->stash,size)); 8063 CHKERRQ(MatStashSetInitialSize_Private(&mat->bstash,bsize)); 8064 PetscFunctionReturn(0); 8065 } 8066 8067 /*@ 8068 MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 8069 the matrix 8070 8071 Neighbor-wise Collective on Mat 8072 8073 Input Parameters: 8074 + mat - the matrix 8075 . x,y - the vectors 8076 - w - where the result is stored 8077 8078 Level: intermediate 8079 8080 Notes: 8081 w may be the same vector as y. 8082 8083 This allows one to use either the restriction or interpolation (its transpose) 8084 matrix to do the interpolation 8085 8086 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 8087 8088 @*/ 8089 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w) 8090 { 8091 PetscInt M,N,Ny; 8092 8093 PetscFunctionBegin; 8094 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8095 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8096 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8097 PetscValidHeaderSpecific(w,VEC_CLASSID,4); 8098 CHKERRQ(MatGetSize(A,&M,&N)); 8099 CHKERRQ(VecGetSize(y,&Ny)); 8100 if (M == Ny) { 8101 CHKERRQ(MatMultAdd(A,x,y,w)); 8102 } else { 8103 CHKERRQ(MatMultTransposeAdd(A,x,y,w)); 8104 } 8105 PetscFunctionReturn(0); 8106 } 8107 8108 /*@ 8109 MatInterpolate - y = A*x or A'*x depending on the shape of 8110 the matrix 8111 8112 Neighbor-wise Collective on Mat 8113 8114 Input Parameters: 8115 + mat - the matrix 8116 - x,y - the vectors 8117 8118 Level: intermediate 8119 8120 Notes: 8121 This allows one to use either the restriction or interpolation (its transpose) 8122 matrix to do the interpolation 8123 8124 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 8125 8126 @*/ 8127 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y) 8128 { 8129 PetscInt M,N,Ny; 8130 8131 PetscFunctionBegin; 8132 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8133 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8134 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8135 CHKERRQ(MatGetSize(A,&M,&N)); 8136 CHKERRQ(VecGetSize(y,&Ny)); 8137 if (M == Ny) { 8138 CHKERRQ(MatMult(A,x,y)); 8139 } else { 8140 CHKERRQ(MatMultTranspose(A,x,y)); 8141 } 8142 PetscFunctionReturn(0); 8143 } 8144 8145 /*@ 8146 MatRestrict - y = A*x or A'*x 8147 8148 Neighbor-wise Collective on Mat 8149 8150 Input Parameters: 8151 + mat - the matrix 8152 - x,y - the vectors 8153 8154 Level: intermediate 8155 8156 Notes: 8157 This allows one to use either the restriction or interpolation (its transpose) 8158 matrix to do the restriction 8159 8160 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate() 8161 8162 @*/ 8163 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y) 8164 { 8165 PetscInt M,N,Ny; 8166 8167 PetscFunctionBegin; 8168 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8169 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8170 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8171 CHKERRQ(MatGetSize(A,&M,&N)); 8172 CHKERRQ(VecGetSize(y,&Ny)); 8173 if (M == Ny) { 8174 CHKERRQ(MatMult(A,x,y)); 8175 } else { 8176 CHKERRQ(MatMultTranspose(A,x,y)); 8177 } 8178 PetscFunctionReturn(0); 8179 } 8180 8181 /*@ 8182 MatMatInterpolateAdd - Y = W + A*X or W + A'*X 8183 8184 Neighbor-wise Collective on Mat 8185 8186 Input Parameters: 8187 + mat - the matrix 8188 - w, x - the input dense matrices 8189 8190 Output Parameters: 8191 . y - the output dense matrix 8192 8193 Level: intermediate 8194 8195 Notes: 8196 This allows one to use either the restriction or interpolation (its transpose) 8197 matrix to do the interpolation. y matrix can be reused if already created with the proper sizes, 8198 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8199 8200 .seealso: MatInterpolateAdd(), MatMatInterpolate(), MatMatRestrict() 8201 8202 @*/ 8203 PetscErrorCode MatMatInterpolateAdd(Mat A,Mat x,Mat w,Mat *y) 8204 { 8205 PetscInt M,N,Mx,Nx,Mo,My = 0,Ny = 0; 8206 PetscBool trans = PETSC_TRUE; 8207 MatReuse reuse = MAT_INITIAL_MATRIX; 8208 8209 PetscFunctionBegin; 8210 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8211 PetscValidHeaderSpecific(x,MAT_CLASSID,2); 8212 PetscValidType(x,2); 8213 if (w) PetscValidHeaderSpecific(w,MAT_CLASSID,3); 8214 if (*y) PetscValidHeaderSpecific(*y,MAT_CLASSID,4); 8215 CHKERRQ(MatGetSize(A,&M,&N)); 8216 CHKERRQ(MatGetSize(x,&Mx,&Nx)); 8217 if (N == Mx) trans = PETSC_FALSE; 8218 else PetscCheckFalse(M != Mx,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Size mismatch: A %" PetscInt_FMT "x%" PetscInt_FMT ", X %" PetscInt_FMT "x%" PetscInt_FMT,M,N,Mx,Nx); 8219 Mo = trans ? N : M; 8220 if (*y) { 8221 CHKERRQ(MatGetSize(*y,&My,&Ny)); 8222 if (Mo == My && Nx == Ny) { reuse = MAT_REUSE_MATRIX; } 8223 else { 8224 PetscCheckFalse(w && *y == w,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Cannot reuse y and w, size mismatch: A %" PetscInt_FMT "x%" PetscInt_FMT ", X %" PetscInt_FMT "x%" PetscInt_FMT ", Y %" PetscInt_FMT "x%" PetscInt_FMT,M,N,Mx,Nx,My,Ny); 8225 CHKERRQ(MatDestroy(y)); 8226 } 8227 } 8228 8229 if (w && *y == w) { /* this is to minimize changes in PCMG */ 8230 PetscBool flg; 8231 8232 CHKERRQ(PetscObjectQuery((PetscObject)*y,"__MatMatIntAdd_w",(PetscObject*)&w)); 8233 if (w) { 8234 PetscInt My,Ny,Mw,Nw; 8235 8236 CHKERRQ(PetscObjectTypeCompare((PetscObject)*y,((PetscObject)w)->type_name,&flg)); 8237 CHKERRQ(MatGetSize(*y,&My,&Ny)); 8238 CHKERRQ(MatGetSize(w,&Mw,&Nw)); 8239 if (!flg || My != Mw || Ny != Nw) w = NULL; 8240 } 8241 if (!w) { 8242 CHKERRQ(MatDuplicate(*y,MAT_COPY_VALUES,&w)); 8243 CHKERRQ(PetscObjectCompose((PetscObject)*y,"__MatMatIntAdd_w",(PetscObject)w)); 8244 CHKERRQ(PetscLogObjectParent((PetscObject)*y,(PetscObject)w)); 8245 CHKERRQ(PetscObjectDereference((PetscObject)w)); 8246 } else { 8247 CHKERRQ(MatCopy(*y,w,UNKNOWN_NONZERO_PATTERN)); 8248 } 8249 } 8250 if (!trans) { 8251 CHKERRQ(MatMatMult(A,x,reuse,PETSC_DEFAULT,y)); 8252 } else { 8253 CHKERRQ(MatTransposeMatMult(A,x,reuse,PETSC_DEFAULT,y)); 8254 } 8255 if (w) { 8256 CHKERRQ(MatAXPY(*y,1.0,w,UNKNOWN_NONZERO_PATTERN)); 8257 } 8258 PetscFunctionReturn(0); 8259 } 8260 8261 /*@ 8262 MatMatInterpolate - Y = A*X or A'*X 8263 8264 Neighbor-wise Collective on Mat 8265 8266 Input Parameters: 8267 + mat - the matrix 8268 - x - the input dense matrix 8269 8270 Output Parameters: 8271 . y - the output dense matrix 8272 8273 Level: intermediate 8274 8275 Notes: 8276 This allows one to use either the restriction or interpolation (its transpose) 8277 matrix to do the interpolation. y matrix can be reused if already created with the proper sizes, 8278 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8279 8280 .seealso: MatInterpolate(), MatRestrict(), MatMatRestrict() 8281 8282 @*/ 8283 PetscErrorCode MatMatInterpolate(Mat A,Mat x,Mat *y) 8284 { 8285 PetscFunctionBegin; 8286 CHKERRQ(MatMatInterpolateAdd(A,x,NULL,y)); 8287 PetscFunctionReturn(0); 8288 } 8289 8290 /*@ 8291 MatMatRestrict - Y = A*X or A'*X 8292 8293 Neighbor-wise Collective on Mat 8294 8295 Input Parameters: 8296 + mat - the matrix 8297 - x - the input dense matrix 8298 8299 Output Parameters: 8300 . y - the output dense matrix 8301 8302 Level: intermediate 8303 8304 Notes: 8305 This allows one to use either the restriction or interpolation (its transpose) 8306 matrix to do the restriction. y matrix can be reused if already created with the proper sizes, 8307 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8308 8309 .seealso: MatRestrict(), MatInterpolate(), MatMatInterpolate() 8310 @*/ 8311 PetscErrorCode MatMatRestrict(Mat A,Mat x,Mat *y) 8312 { 8313 PetscFunctionBegin; 8314 CHKERRQ(MatMatInterpolateAdd(A,x,NULL,y)); 8315 PetscFunctionReturn(0); 8316 } 8317 8318 /*@ 8319 MatGetNullSpace - retrieves the null space of a matrix. 8320 8321 Logically Collective on Mat 8322 8323 Input Parameters: 8324 + mat - the matrix 8325 - nullsp - the null space object 8326 8327 Level: developer 8328 8329 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace() 8330 @*/ 8331 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp) 8332 { 8333 PetscFunctionBegin; 8334 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8335 PetscValidPointer(nullsp,2); 8336 *nullsp = (mat->symmetric_set && mat->symmetric && !mat->nullsp) ? mat->transnullsp : mat->nullsp; 8337 PetscFunctionReturn(0); 8338 } 8339 8340 /*@ 8341 MatSetNullSpace - attaches a null space to a matrix. 8342 8343 Logically Collective on Mat 8344 8345 Input Parameters: 8346 + mat - the matrix 8347 - nullsp - the null space object 8348 8349 Level: advanced 8350 8351 Notes: 8352 This null space is used by the KSP linear solvers to solve singular systems. 8353 8354 Overwrites any previous null space that may have been attached. You can remove the null space from the matrix object by calling this routine with an nullsp of NULL 8355 8356 For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) the KSP residuals will not converge to 8357 to zero but the linear system will still be solved in a least squares sense. 8358 8359 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8360 the domain of a matrix A (from R^n to R^m (m rows, n columns) R^n = the direct sum of the null space of A, n(A), + the range of A^T, R(A^T). 8361 Similarly R^m = direct sum n(A^T) + R(A). Hence the linear system A x = b has a solution only if b in R(A) (or correspondingly b is orthogonal to 8362 n(A^T)) and if x is a solution then x + alpha n(A) is a solution for any alpha. The minimum norm solution is orthogonal to n(A). For problems without a solution 8363 the solution that minimizes the norm of the residual (the least squares solution) can be obtained by solving A x = \hat{b} where \hat{b} is b orthogonalized to the n(A^T). 8364 This \hat{b} can be obtained by calling MatNullSpaceRemove() with the null space of the transpose of the matrix. 8365 8366 If the matrix is known to be symmetric because it is an SBAIJ matrix or one as called MatSetOption(mat,MAT_SYMMETRIC or MAT_SYMMETRIC_ETERNAL,PETSC_TRUE); this 8367 routine also automatically calls MatSetTransposeNullSpace(). 8368 8369 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove(), 8370 KSPSetPCSide() 8371 @*/ 8372 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp) 8373 { 8374 PetscFunctionBegin; 8375 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8376 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8377 if (nullsp) CHKERRQ(PetscObjectReference((PetscObject)nullsp)); 8378 CHKERRQ(MatNullSpaceDestroy(&mat->nullsp)); 8379 mat->nullsp = nullsp; 8380 if (mat->symmetric_set && mat->symmetric) { 8381 CHKERRQ(MatSetTransposeNullSpace(mat,nullsp)); 8382 } 8383 PetscFunctionReturn(0); 8384 } 8385 8386 /*@ 8387 MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix. 8388 8389 Logically Collective on Mat 8390 8391 Input Parameters: 8392 + mat - the matrix 8393 - nullsp - the null space object 8394 8395 Level: developer 8396 8397 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace() 8398 @*/ 8399 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp) 8400 { 8401 PetscFunctionBegin; 8402 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8403 PetscValidType(mat,1); 8404 PetscValidPointer(nullsp,2); 8405 *nullsp = (mat->symmetric_set && mat->symmetric && !mat->transnullsp) ? mat->nullsp : mat->transnullsp; 8406 PetscFunctionReturn(0); 8407 } 8408 8409 /*@ 8410 MatSetTransposeNullSpace - attaches the null space of a transpose of a matrix to the matrix 8411 8412 Logically Collective on Mat 8413 8414 Input Parameters: 8415 + mat - the matrix 8416 - nullsp - the null space object 8417 8418 Level: advanced 8419 8420 Notes: 8421 This allows solving singular linear systems defined by the transpose of the matrix using KSP solvers with left preconditioning. 8422 8423 See MatSetNullSpace() 8424 8425 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove(), KSPSetPCSide() 8426 @*/ 8427 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp) 8428 { 8429 PetscFunctionBegin; 8430 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8431 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8432 if (nullsp) CHKERRQ(PetscObjectReference((PetscObject)nullsp)); 8433 CHKERRQ(MatNullSpaceDestroy(&mat->transnullsp)); 8434 mat->transnullsp = nullsp; 8435 PetscFunctionReturn(0); 8436 } 8437 8438 /*@ 8439 MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions 8440 This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix. 8441 8442 Logically Collective on Mat 8443 8444 Input Parameters: 8445 + mat - the matrix 8446 - nullsp - the null space object 8447 8448 Level: advanced 8449 8450 Notes: 8451 Overwrites any previous near null space that may have been attached 8452 8453 You can remove the null space by calling this routine with an nullsp of NULL 8454 8455 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace() 8456 @*/ 8457 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp) 8458 { 8459 PetscFunctionBegin; 8460 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8461 PetscValidType(mat,1); 8462 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8463 MatCheckPreallocated(mat,1); 8464 if (nullsp) CHKERRQ(PetscObjectReference((PetscObject)nullsp)); 8465 CHKERRQ(MatNullSpaceDestroy(&mat->nearnullsp)); 8466 mat->nearnullsp = nullsp; 8467 PetscFunctionReturn(0); 8468 } 8469 8470 /*@ 8471 MatGetNearNullSpace - Get null space attached with MatSetNearNullSpace() 8472 8473 Not Collective 8474 8475 Input Parameter: 8476 . mat - the matrix 8477 8478 Output Parameter: 8479 . nullsp - the null space object, NULL if not set 8480 8481 Level: developer 8482 8483 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate() 8484 @*/ 8485 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp) 8486 { 8487 PetscFunctionBegin; 8488 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8489 PetscValidType(mat,1); 8490 PetscValidPointer(nullsp,2); 8491 MatCheckPreallocated(mat,1); 8492 *nullsp = mat->nearnullsp; 8493 PetscFunctionReturn(0); 8494 } 8495 8496 /*@C 8497 MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix. 8498 8499 Collective on Mat 8500 8501 Input Parameters: 8502 + mat - the matrix 8503 . row - row/column permutation 8504 . fill - expected fill factor >= 1.0 8505 - level - level of fill, for ICC(k) 8506 8507 Notes: 8508 Probably really in-place only when level of fill is zero, otherwise allocates 8509 new space to store factored matrix and deletes previous memory. 8510 8511 Most users should employ the simplified KSP interface for linear solvers 8512 instead of working directly with matrix algebra routines such as this. 8513 See, e.g., KSPCreate(). 8514 8515 Level: developer 8516 8517 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 8518 8519 Developer Note: fortran interface is not autogenerated as the f90 8520 interface definition cannot be generated correctly [due to MatFactorInfo] 8521 8522 @*/ 8523 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info) 8524 { 8525 PetscFunctionBegin; 8526 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8527 PetscValidType(mat,1); 8528 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 8529 PetscValidPointer(info,3); 8530 PetscCheckFalse(mat->rmap->N != mat->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 8531 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8532 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8533 PetscCheck(mat->ops->iccfactor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8534 MatCheckPreallocated(mat,1); 8535 CHKERRQ((*mat->ops->iccfactor)(mat,row,info)); 8536 CHKERRQ(PetscObjectStateIncrease((PetscObject)mat)); 8537 PetscFunctionReturn(0); 8538 } 8539 8540 /*@ 8541 MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 8542 ghosted ones. 8543 8544 Not Collective 8545 8546 Input Parameters: 8547 + mat - the matrix 8548 - diag - the diagonal values, including ghost ones 8549 8550 Level: developer 8551 8552 Notes: 8553 Works only for MPIAIJ and MPIBAIJ matrices 8554 8555 .seealso: MatDiagonalScale() 8556 @*/ 8557 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag) 8558 { 8559 PetscMPIInt size; 8560 8561 PetscFunctionBegin; 8562 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8563 PetscValidHeaderSpecific(diag,VEC_CLASSID,2); 8564 PetscValidType(mat,1); 8565 8566 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled"); 8567 CHKERRQ(PetscLogEventBegin(MAT_Scale,mat,0,0,0)); 8568 CHKERRMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 8569 if (size == 1) { 8570 PetscInt n,m; 8571 CHKERRQ(VecGetSize(diag,&n)); 8572 CHKERRQ(MatGetSize(mat,NULL,&m)); 8573 if (m == n) { 8574 CHKERRQ(MatDiagonalScale(mat,NULL,diag)); 8575 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions"); 8576 } else { 8577 CHKERRQ(PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag))); 8578 } 8579 CHKERRQ(PetscLogEventEnd(MAT_Scale,mat,0,0,0)); 8580 CHKERRQ(PetscObjectStateIncrease((PetscObject)mat)); 8581 PetscFunctionReturn(0); 8582 } 8583 8584 /*@ 8585 MatGetInertia - Gets the inertia from a factored matrix 8586 8587 Collective on Mat 8588 8589 Input Parameter: 8590 . mat - the matrix 8591 8592 Output Parameters: 8593 + nneg - number of negative eigenvalues 8594 . nzero - number of zero eigenvalues 8595 - npos - number of positive eigenvalues 8596 8597 Level: advanced 8598 8599 Notes: 8600 Matrix must have been factored by MatCholeskyFactor() 8601 8602 @*/ 8603 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos) 8604 { 8605 PetscFunctionBegin; 8606 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8607 PetscValidType(mat,1); 8608 PetscCheck(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8609 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled"); 8610 PetscCheck(mat->ops->getinertia,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8611 CHKERRQ((*mat->ops->getinertia)(mat,nneg,nzero,npos)); 8612 PetscFunctionReturn(0); 8613 } 8614 8615 /* ----------------------------------------------------------------*/ 8616 /*@C 8617 MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors 8618 8619 Neighbor-wise Collective on Mats 8620 8621 Input Parameters: 8622 + mat - the factored matrix 8623 - b - the right-hand-side vectors 8624 8625 Output Parameter: 8626 . x - the result vectors 8627 8628 Notes: 8629 The vectors b and x cannot be the same. I.e., one cannot 8630 call MatSolves(A,x,x). 8631 8632 Notes: 8633 Most users should employ the simplified KSP interface for linear solvers 8634 instead of working directly with matrix algebra routines such as this. 8635 See, e.g., KSPCreate(). 8636 8637 Level: developer 8638 8639 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve() 8640 @*/ 8641 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x) 8642 { 8643 PetscFunctionBegin; 8644 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8645 PetscValidType(mat,1); 8646 PetscCheckFalse(x == b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 8647 PetscCheck(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8648 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 8649 8650 PetscCheck(mat->ops->solves,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8651 MatCheckPreallocated(mat,1); 8652 CHKERRQ(PetscLogEventBegin(MAT_Solves,mat,0,0,0)); 8653 CHKERRQ((*mat->ops->solves)(mat,b,x)); 8654 CHKERRQ(PetscLogEventEnd(MAT_Solves,mat,0,0,0)); 8655 PetscFunctionReturn(0); 8656 } 8657 8658 /*@ 8659 MatIsSymmetric - Test whether a matrix is symmetric 8660 8661 Collective on Mat 8662 8663 Input Parameters: 8664 + A - the matrix to test 8665 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose) 8666 8667 Output Parameters: 8668 . flg - the result 8669 8670 Notes: 8671 For real numbers MatIsSymmetric() and MatIsHermitian() return identical results 8672 8673 Level: intermediate 8674 8675 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown() 8676 @*/ 8677 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg) 8678 { 8679 PetscFunctionBegin; 8680 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8681 PetscValidBoolPointer(flg,3); 8682 8683 if (!A->symmetric_set) { 8684 if (!A->ops->issymmetric) { 8685 MatType mattype; 8686 CHKERRQ(MatGetType(A,&mattype)); 8687 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for symmetric",mattype); 8688 } 8689 CHKERRQ((*A->ops->issymmetric)(A,tol,flg)); 8690 if (!tol) { 8691 CHKERRQ(MatSetOption(A,MAT_SYMMETRIC,*flg)); 8692 } 8693 } else if (A->symmetric) { 8694 *flg = PETSC_TRUE; 8695 } else if (!tol) { 8696 *flg = PETSC_FALSE; 8697 } else { 8698 if (!A->ops->issymmetric) { 8699 MatType mattype; 8700 CHKERRQ(MatGetType(A,&mattype)); 8701 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for symmetric",mattype); 8702 } 8703 CHKERRQ((*A->ops->issymmetric)(A,tol,flg)); 8704 } 8705 PetscFunctionReturn(0); 8706 } 8707 8708 /*@ 8709 MatIsHermitian - Test whether a matrix is Hermitian 8710 8711 Collective on Mat 8712 8713 Input Parameters: 8714 + A - the matrix to test 8715 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian) 8716 8717 Output Parameters: 8718 . flg - the result 8719 8720 Level: intermediate 8721 8722 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), 8723 MatIsSymmetricKnown(), MatIsSymmetric() 8724 @*/ 8725 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg) 8726 { 8727 PetscFunctionBegin; 8728 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8729 PetscValidBoolPointer(flg,3); 8730 8731 if (!A->hermitian_set) { 8732 if (!A->ops->ishermitian) { 8733 MatType mattype; 8734 CHKERRQ(MatGetType(A,&mattype)); 8735 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for hermitian",mattype); 8736 } 8737 CHKERRQ((*A->ops->ishermitian)(A,tol,flg)); 8738 if (!tol) { 8739 CHKERRQ(MatSetOption(A,MAT_HERMITIAN,*flg)); 8740 } 8741 } else if (A->hermitian) { 8742 *flg = PETSC_TRUE; 8743 } else if (!tol) { 8744 *flg = PETSC_FALSE; 8745 } else { 8746 if (!A->ops->ishermitian) { 8747 MatType mattype; 8748 CHKERRQ(MatGetType(A,&mattype)); 8749 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for hermitian",mattype); 8750 } 8751 CHKERRQ((*A->ops->ishermitian)(A,tol,flg)); 8752 } 8753 PetscFunctionReturn(0); 8754 } 8755 8756 /*@ 8757 MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric. 8758 8759 Not Collective 8760 8761 Input Parameter: 8762 . A - the matrix to check 8763 8764 Output Parameters: 8765 + set - if the symmetric flag is set (this tells you if the next flag is valid) 8766 - flg - the result 8767 8768 Level: advanced 8769 8770 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric() 8771 if you want it explicitly checked 8772 8773 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 8774 @*/ 8775 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg) 8776 { 8777 PetscFunctionBegin; 8778 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8779 PetscValidPointer(set,2); 8780 PetscValidBoolPointer(flg,3); 8781 if (A->symmetric_set) { 8782 *set = PETSC_TRUE; 8783 *flg = A->symmetric; 8784 } else { 8785 *set = PETSC_FALSE; 8786 } 8787 PetscFunctionReturn(0); 8788 } 8789 8790 /*@ 8791 MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian. 8792 8793 Not Collective 8794 8795 Input Parameter: 8796 . A - the matrix to check 8797 8798 Output Parameters: 8799 + set - if the hermitian flag is set (this tells you if the next flag is valid) 8800 - flg - the result 8801 8802 Level: advanced 8803 8804 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian() 8805 if you want it explicitly checked 8806 8807 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 8808 @*/ 8809 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg) 8810 { 8811 PetscFunctionBegin; 8812 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8813 PetscValidPointer(set,2); 8814 PetscValidBoolPointer(flg,3); 8815 if (A->hermitian_set) { 8816 *set = PETSC_TRUE; 8817 *flg = A->hermitian; 8818 } else { 8819 *set = PETSC_FALSE; 8820 } 8821 PetscFunctionReturn(0); 8822 } 8823 8824 /*@ 8825 MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric 8826 8827 Collective on Mat 8828 8829 Input Parameter: 8830 . A - the matrix to test 8831 8832 Output Parameters: 8833 . flg - the result 8834 8835 Level: intermediate 8836 8837 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption() 8838 @*/ 8839 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg) 8840 { 8841 PetscFunctionBegin; 8842 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8843 PetscValidBoolPointer(flg,2); 8844 if (!A->structurally_symmetric_set) { 8845 PetscCheck(A->ops->isstructurallysymmetric,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix of type %s does not support checking for structural symmetric",((PetscObject)A)->type_name); 8846 CHKERRQ((*A->ops->isstructurallysymmetric)(A,flg)); 8847 CHKERRQ(MatSetOption(A,MAT_STRUCTURALLY_SYMMETRIC,*flg)); 8848 } else *flg = A->structurally_symmetric; 8849 PetscFunctionReturn(0); 8850 } 8851 8852 /*@ 8853 MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need 8854 to be communicated to other processors during the MatAssemblyBegin/End() process 8855 8856 Not collective 8857 8858 Input Parameter: 8859 . vec - the vector 8860 8861 Output Parameters: 8862 + nstash - the size of the stash 8863 . reallocs - the number of additional mallocs incurred. 8864 . bnstash - the size of the block stash 8865 - breallocs - the number of additional mallocs incurred.in the block stash 8866 8867 Level: advanced 8868 8869 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize() 8870 8871 @*/ 8872 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs) 8873 { 8874 PetscFunctionBegin; 8875 CHKERRQ(MatStashGetInfo_Private(&mat->stash,nstash,reallocs)); 8876 CHKERRQ(MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs)); 8877 PetscFunctionReturn(0); 8878 } 8879 8880 /*@C 8881 MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same 8882 parallel layout 8883 8884 Collective on Mat 8885 8886 Input Parameter: 8887 . mat - the matrix 8888 8889 Output Parameters: 8890 + right - (optional) vector that the matrix can be multiplied against 8891 - left - (optional) vector that the matrix vector product can be stored in 8892 8893 Notes: 8894 The blocksize of the returned vectors is determined by the row and column block sizes set with MatSetBlockSizes() or the single blocksize (same for both) set by MatSetBlockSize(). 8895 8896 Notes: 8897 These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed 8898 8899 Level: advanced 8900 8901 .seealso: MatCreate(), VecDestroy() 8902 @*/ 8903 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left) 8904 { 8905 PetscFunctionBegin; 8906 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8907 PetscValidType(mat,1); 8908 if (mat->ops->getvecs) { 8909 CHKERRQ((*mat->ops->getvecs)(mat,right,left)); 8910 } else { 8911 PetscInt rbs,cbs; 8912 CHKERRQ(MatGetBlockSizes(mat,&rbs,&cbs)); 8913 if (right) { 8914 PetscCheckFalse(mat->cmap->n < 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup"); 8915 CHKERRQ(VecCreate(PetscObjectComm((PetscObject)mat),right)); 8916 CHKERRQ(VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE)); 8917 CHKERRQ(VecSetBlockSize(*right,cbs)); 8918 CHKERRQ(VecSetType(*right,mat->defaultvectype)); 8919 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 8920 if (mat->boundtocpu && mat->bindingpropagates) { 8921 CHKERRQ(VecSetBindingPropagates(*right,PETSC_TRUE)); 8922 CHKERRQ(VecBindToCPU(*right,PETSC_TRUE)); 8923 } 8924 #endif 8925 CHKERRQ(PetscLayoutReference(mat->cmap,&(*right)->map)); 8926 } 8927 if (left) { 8928 PetscCheckFalse(mat->rmap->n < 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup"); 8929 CHKERRQ(VecCreate(PetscObjectComm((PetscObject)mat),left)); 8930 CHKERRQ(VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE)); 8931 CHKERRQ(VecSetBlockSize(*left,rbs)); 8932 CHKERRQ(VecSetType(*left,mat->defaultvectype)); 8933 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 8934 if (mat->boundtocpu && mat->bindingpropagates) { 8935 CHKERRQ(VecSetBindingPropagates(*left,PETSC_TRUE)); 8936 CHKERRQ(VecBindToCPU(*left,PETSC_TRUE)); 8937 } 8938 #endif 8939 CHKERRQ(PetscLayoutReference(mat->rmap,&(*left)->map)); 8940 } 8941 } 8942 PetscFunctionReturn(0); 8943 } 8944 8945 /*@C 8946 MatFactorInfoInitialize - Initializes a MatFactorInfo data structure 8947 with default values. 8948 8949 Not Collective 8950 8951 Input Parameters: 8952 . info - the MatFactorInfo data structure 8953 8954 Notes: 8955 The solvers are generally used through the KSP and PC objects, for example 8956 PCLU, PCILU, PCCHOLESKY, PCICC 8957 8958 Level: developer 8959 8960 .seealso: MatFactorInfo 8961 8962 Developer Note: fortran interface is not autogenerated as the f90 8963 interface definition cannot be generated correctly [due to MatFactorInfo] 8964 8965 @*/ 8966 8967 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info) 8968 { 8969 PetscFunctionBegin; 8970 CHKERRQ(PetscMemzero(info,sizeof(MatFactorInfo))); 8971 PetscFunctionReturn(0); 8972 } 8973 8974 /*@ 8975 MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed 8976 8977 Collective on Mat 8978 8979 Input Parameters: 8980 + mat - the factored matrix 8981 - is - the index set defining the Schur indices (0-based) 8982 8983 Notes: 8984 Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system. 8985 8986 You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call. 8987 8988 Level: developer 8989 8990 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(), 8991 MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement() 8992 8993 @*/ 8994 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is) 8995 { 8996 PetscErrorCode (*f)(Mat,IS); 8997 8998 PetscFunctionBegin; 8999 PetscValidType(mat,1); 9000 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9001 PetscValidType(is,2); 9002 PetscValidHeaderSpecific(is,IS_CLASSID,2); 9003 PetscCheckSameComm(mat,1,is,2); 9004 PetscCheck(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 9005 CHKERRQ(PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f)); 9006 PetscCheck(f,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"The selected MatSolverType does not support Schur complement computation. You should use MATSOLVERMUMPS or MATSOLVERMKL_PARDISO"); 9007 CHKERRQ(MatDestroy(&mat->schur)); 9008 CHKERRQ((*f)(mat,is)); 9009 PetscCheck(mat->schur,PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created"); 9010 PetscFunctionReturn(0); 9011 } 9012 9013 /*@ 9014 MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step 9015 9016 Logically Collective on Mat 9017 9018 Input Parameters: 9019 + F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface 9020 . S - location where to return the Schur complement, can be NULL 9021 - status - the status of the Schur complement matrix, can be NULL 9022 9023 Notes: 9024 You must call MatFactorSetSchurIS() before calling this routine. 9025 9026 The routine provides a copy of the Schur matrix stored within the solver data structures. 9027 The caller must destroy the object when it is no longer needed. 9028 If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse. 9029 9030 Use MatFactorGetSchurComplement() to get access to the Schur complement matrix inside the factored matrix instead of making a copy of it (which this function does) 9031 9032 Developer Notes: 9033 The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc 9034 matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix. 9035 9036 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 9037 9038 Level: advanced 9039 9040 References: 9041 9042 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus 9043 @*/ 9044 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 9045 { 9046 PetscFunctionBegin; 9047 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9048 if (S) PetscValidPointer(S,2); 9049 if (status) PetscValidPointer(status,3); 9050 if (S) { 9051 PetscErrorCode (*f)(Mat,Mat*); 9052 9053 CHKERRQ(PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f)); 9054 if (f) { 9055 CHKERRQ((*f)(F,S)); 9056 } else { 9057 CHKERRQ(MatDuplicate(F->schur,MAT_COPY_VALUES,S)); 9058 } 9059 } 9060 if (status) *status = F->schur_status; 9061 PetscFunctionReturn(0); 9062 } 9063 9064 /*@ 9065 MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix 9066 9067 Logically Collective on Mat 9068 9069 Input Parameters: 9070 + F - the factored matrix obtained by calling MatGetFactor() 9071 . *S - location where to return the Schur complement, can be NULL 9072 - status - the status of the Schur complement matrix, can be NULL 9073 9074 Notes: 9075 You must call MatFactorSetSchurIS() before calling this routine. 9076 9077 Schur complement mode is currently implemented for sequential matrices. 9078 The routine returns a the Schur Complement stored within the data strutures of the solver. 9079 If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement. 9080 The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed. 9081 9082 Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix 9083 9084 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 9085 9086 Level: advanced 9087 9088 References: 9089 9090 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus 9091 @*/ 9092 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 9093 { 9094 PetscFunctionBegin; 9095 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9096 if (S) PetscValidPointer(S,2); 9097 if (status) PetscValidPointer(status,3); 9098 if (S) *S = F->schur; 9099 if (status) *status = F->schur_status; 9100 PetscFunctionReturn(0); 9101 } 9102 9103 /*@ 9104 MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement 9105 9106 Logically Collective on Mat 9107 9108 Input Parameters: 9109 + F - the factored matrix obtained by calling MatGetFactor() 9110 . *S - location where the Schur complement is stored 9111 - status - the status of the Schur complement matrix (see MatFactorSchurStatus) 9112 9113 Notes: 9114 9115 Level: advanced 9116 9117 References: 9118 9119 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus 9120 @*/ 9121 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status) 9122 { 9123 PetscFunctionBegin; 9124 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9125 if (S) { 9126 PetscValidHeaderSpecific(*S,MAT_CLASSID,2); 9127 *S = NULL; 9128 } 9129 F->schur_status = status; 9130 CHKERRQ(MatFactorUpdateSchurStatus_Private(F)); 9131 PetscFunctionReturn(0); 9132 } 9133 9134 /*@ 9135 MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step 9136 9137 Logically Collective on Mat 9138 9139 Input Parameters: 9140 + F - the factored matrix obtained by calling MatGetFactor() 9141 . rhs - location where the right hand side of the Schur complement system is stored 9142 - sol - location where the solution of the Schur complement system has to be returned 9143 9144 Notes: 9145 The sizes of the vectors should match the size of the Schur complement 9146 9147 Must be called after MatFactorSetSchurIS() 9148 9149 Level: advanced 9150 9151 References: 9152 9153 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement() 9154 @*/ 9155 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol) 9156 { 9157 PetscFunctionBegin; 9158 PetscValidType(F,1); 9159 PetscValidType(rhs,2); 9160 PetscValidType(sol,3); 9161 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9162 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9163 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9164 PetscCheckSameComm(F,1,rhs,2); 9165 PetscCheckSameComm(F,1,sol,3); 9166 CHKERRQ(MatFactorFactorizeSchurComplement(F)); 9167 switch (F->schur_status) { 9168 case MAT_FACTOR_SCHUR_FACTORED: 9169 CHKERRQ(MatSolveTranspose(F->schur,rhs,sol)); 9170 break; 9171 case MAT_FACTOR_SCHUR_INVERTED: 9172 CHKERRQ(MatMultTranspose(F->schur,rhs,sol)); 9173 break; 9174 default: 9175 SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %d",F->schur_status); 9176 } 9177 PetscFunctionReturn(0); 9178 } 9179 9180 /*@ 9181 MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step 9182 9183 Logically Collective on Mat 9184 9185 Input Parameters: 9186 + F - the factored matrix obtained by calling MatGetFactor() 9187 . rhs - location where the right hand side of the Schur complement system is stored 9188 - sol - location where the solution of the Schur complement system has to be returned 9189 9190 Notes: 9191 The sizes of the vectors should match the size of the Schur complement 9192 9193 Must be called after MatFactorSetSchurIS() 9194 9195 Level: advanced 9196 9197 References: 9198 9199 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose() 9200 @*/ 9201 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol) 9202 { 9203 PetscFunctionBegin; 9204 PetscValidType(F,1); 9205 PetscValidType(rhs,2); 9206 PetscValidType(sol,3); 9207 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9208 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9209 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9210 PetscCheckSameComm(F,1,rhs,2); 9211 PetscCheckSameComm(F,1,sol,3); 9212 CHKERRQ(MatFactorFactorizeSchurComplement(F)); 9213 switch (F->schur_status) { 9214 case MAT_FACTOR_SCHUR_FACTORED: 9215 CHKERRQ(MatSolve(F->schur,rhs,sol)); 9216 break; 9217 case MAT_FACTOR_SCHUR_INVERTED: 9218 CHKERRQ(MatMult(F->schur,rhs,sol)); 9219 break; 9220 default: 9221 SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %d",F->schur_status); 9222 } 9223 PetscFunctionReturn(0); 9224 } 9225 9226 /*@ 9227 MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step 9228 9229 Logically Collective on Mat 9230 9231 Input Parameters: 9232 . F - the factored matrix obtained by calling MatGetFactor() 9233 9234 Notes: 9235 Must be called after MatFactorSetSchurIS(). 9236 9237 Call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it. 9238 9239 Level: advanced 9240 9241 References: 9242 9243 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement() 9244 @*/ 9245 PetscErrorCode MatFactorInvertSchurComplement(Mat F) 9246 { 9247 PetscFunctionBegin; 9248 PetscValidType(F,1); 9249 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9250 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0); 9251 CHKERRQ(MatFactorFactorizeSchurComplement(F)); 9252 CHKERRQ(MatFactorInvertSchurComplement_Private(F)); 9253 F->schur_status = MAT_FACTOR_SCHUR_INVERTED; 9254 PetscFunctionReturn(0); 9255 } 9256 9257 /*@ 9258 MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step 9259 9260 Logically Collective on Mat 9261 9262 Input Parameters: 9263 . F - the factored matrix obtained by calling MatGetFactor() 9264 9265 Notes: 9266 Must be called after MatFactorSetSchurIS(). 9267 9268 Level: advanced 9269 9270 References: 9271 9272 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement() 9273 @*/ 9274 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F) 9275 { 9276 PetscFunctionBegin; 9277 PetscValidType(F,1); 9278 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9279 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0); 9280 CHKERRQ(MatFactorFactorizeSchurComplement_Private(F)); 9281 F->schur_status = MAT_FACTOR_SCHUR_FACTORED; 9282 PetscFunctionReturn(0); 9283 } 9284 9285 /*@ 9286 MatPtAP - Creates the matrix product C = P^T * A * P 9287 9288 Neighbor-wise Collective on Mat 9289 9290 Input Parameters: 9291 + A - the matrix 9292 . P - the projection matrix 9293 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9294 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate 9295 if the result is a dense matrix this is irrelevant 9296 9297 Output Parameters: 9298 . C - the product matrix 9299 9300 Notes: 9301 C will be created and must be destroyed by the user with MatDestroy(). 9302 9303 For matrix types without special implementation the function fallbacks to MatMatMult() followed by MatTransposeMatMult(). 9304 9305 Level: intermediate 9306 9307 .seealso: MatMatMult(), MatRARt() 9308 @*/ 9309 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 9310 { 9311 PetscFunctionBegin; 9312 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*C,5); 9313 PetscCheckFalse(scall == MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9314 9315 if (scall == MAT_INITIAL_MATRIX) { 9316 CHKERRQ(MatProductCreate(A,P,NULL,C)); 9317 CHKERRQ(MatProductSetType(*C,MATPRODUCT_PtAP)); 9318 CHKERRQ(MatProductSetAlgorithm(*C,"default")); 9319 CHKERRQ(MatProductSetFill(*C,fill)); 9320 9321 (*C)->product->api_user = PETSC_TRUE; 9322 CHKERRQ(MatProductSetFromOptions(*C)); 9323 PetscCheckFalse(!(*C)->ops->productsymbolic,PetscObjectComm((PetscObject)(*C)),PETSC_ERR_SUP,"MatProduct %s not supported for A %s and P %s",MatProductTypes[MATPRODUCT_PtAP],((PetscObject)A)->type_name,((PetscObject)P)->type_name); 9324 CHKERRQ(MatProductSymbolic(*C)); 9325 } else { /* scall == MAT_REUSE_MATRIX */ 9326 CHKERRQ(MatProductReplaceMats(A,P,NULL,*C)); 9327 } 9328 9329 CHKERRQ(MatProductNumeric(*C)); 9330 if (A->symmetric) { 9331 if (A->spd) { 9332 CHKERRQ(MatSetOption(*C,MAT_SPD,PETSC_TRUE)); 9333 } else { 9334 CHKERRQ(MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE)); 9335 } 9336 } 9337 PetscFunctionReturn(0); 9338 } 9339 9340 /*@ 9341 MatRARt - Creates the matrix product C = R * A * R^T 9342 9343 Neighbor-wise Collective on Mat 9344 9345 Input Parameters: 9346 + A - the matrix 9347 . R - the projection matrix 9348 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9349 - fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate 9350 if the result is a dense matrix this is irrelevant 9351 9352 Output Parameters: 9353 . C - the product matrix 9354 9355 Notes: 9356 C will be created and must be destroyed by the user with MatDestroy(). 9357 9358 This routine is currently only implemented for pairs of AIJ matrices and classes 9359 which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes, 9360 parallel MatRARt is implemented via explicit transpose of R, which could be very expensive. 9361 We recommend using MatPtAP(). 9362 9363 Level: intermediate 9364 9365 .seealso: MatMatMult(), MatPtAP() 9366 @*/ 9367 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C) 9368 { 9369 PetscFunctionBegin; 9370 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*C,5); 9371 PetscCheckFalse(scall == MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9372 9373 if (scall == MAT_INITIAL_MATRIX) { 9374 CHKERRQ(MatProductCreate(A,R,NULL,C)); 9375 CHKERRQ(MatProductSetType(*C,MATPRODUCT_RARt)); 9376 CHKERRQ(MatProductSetAlgorithm(*C,"default")); 9377 CHKERRQ(MatProductSetFill(*C,fill)); 9378 9379 (*C)->product->api_user = PETSC_TRUE; 9380 CHKERRQ(MatProductSetFromOptions(*C)); 9381 PetscCheckFalse(!(*C)->ops->productsymbolic,PetscObjectComm((PetscObject)(*C)),PETSC_ERR_SUP,"MatProduct %s not supported for A %s and R %s",MatProductTypes[MATPRODUCT_RARt],((PetscObject)A)->type_name,((PetscObject)R)->type_name); 9382 CHKERRQ(MatProductSymbolic(*C)); 9383 } else { /* scall == MAT_REUSE_MATRIX */ 9384 CHKERRQ(MatProductReplaceMats(A,R,NULL,*C)); 9385 } 9386 9387 CHKERRQ(MatProductNumeric(*C)); 9388 if (A->symmetric_set && A->symmetric) { 9389 CHKERRQ(MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE)); 9390 } 9391 PetscFunctionReturn(0); 9392 } 9393 9394 static PetscErrorCode MatProduct_Private(Mat A,Mat B,MatReuse scall,PetscReal fill,MatProductType ptype, Mat *C) 9395 { 9396 PetscFunctionBegin; 9397 PetscCheckFalse(scall == MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9398 9399 if (scall == MAT_INITIAL_MATRIX) { 9400 CHKERRQ(PetscInfo(A,"Calling MatProduct API with MAT_INITIAL_MATRIX and product type %s\n",MatProductTypes[ptype])); 9401 CHKERRQ(MatProductCreate(A,B,NULL,C)); 9402 CHKERRQ(MatProductSetType(*C,ptype)); 9403 CHKERRQ(MatProductSetAlgorithm(*C,MATPRODUCTALGORITHMDEFAULT)); 9404 CHKERRQ(MatProductSetFill(*C,fill)); 9405 9406 (*C)->product->api_user = PETSC_TRUE; 9407 CHKERRQ(MatProductSetFromOptions(*C)); 9408 CHKERRQ(MatProductSymbolic(*C)); 9409 } else { /* scall == MAT_REUSE_MATRIX */ 9410 Mat_Product *product = (*C)->product; 9411 PetscBool isdense; 9412 9413 CHKERRQ(PetscObjectBaseTypeCompareAny((PetscObject)(*C),&isdense,MATSEQDENSE,MATMPIDENSE,"")); 9414 if (isdense && product && product->type != ptype) { 9415 CHKERRQ(MatProductClear(*C)); 9416 product = NULL; 9417 } 9418 CHKERRQ(PetscInfo(A,"Calling MatProduct API with MAT_REUSE_MATRIX %s product present and product type %s\n",product ? "with" : "without",MatProductTypes[ptype])); 9419 if (!product) { /* user provide the dense matrix *C without calling MatProductCreate() or reusing it from previous calls */ 9420 if (isdense) { 9421 CHKERRQ(MatProductCreate_Private(A,B,NULL,*C)); 9422 product = (*C)->product; 9423 product->fill = fill; 9424 product->api_user = PETSC_TRUE; 9425 product->clear = PETSC_TRUE; 9426 9427 CHKERRQ(MatProductSetType(*C,ptype)); 9428 CHKERRQ(MatProductSetFromOptions(*C)); 9429 PetscCheckFalse(!(*C)->ops->productsymbolic,PetscObjectComm((PetscObject)(*C)),PETSC_ERR_SUP,"MatProduct %s not supported for %s and %s",MatProductTypes[ptype],((PetscObject)A)->type_name,((PetscObject)B)->type_name); 9430 CHKERRQ(MatProductSymbolic(*C)); 9431 } else SETERRQ(PetscObjectComm((PetscObject)(*C)),PETSC_ERR_SUP,"Call MatProductCreate() first"); 9432 } else { /* user may change input matrices A or B when REUSE */ 9433 CHKERRQ(MatProductReplaceMats(A,B,NULL,*C)); 9434 } 9435 } 9436 CHKERRQ(MatProductNumeric(*C)); 9437 PetscFunctionReturn(0); 9438 } 9439 9440 /*@ 9441 MatMatMult - Performs Matrix-Matrix Multiplication C=A*B. 9442 9443 Neighbor-wise Collective on Mat 9444 9445 Input Parameters: 9446 + A - the left matrix 9447 . B - the right matrix 9448 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9449 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate 9450 if the result is a dense matrix this is irrelevant 9451 9452 Output Parameters: 9453 . C - the product matrix 9454 9455 Notes: 9456 Unless scall is MAT_REUSE_MATRIX C will be created. 9457 9458 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call and C was obtained from a previous 9459 call to this function with MAT_INITIAL_MATRIX. 9460 9461 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value actually needed. 9462 9463 If you have many matrices with the same non-zero structure to multiply, you should use MatProductCreate()/MatProductSymbolic()/MatProductReplaceMats(), and call MatProductNumeric() repeatedly. 9464 9465 In the special case where matrix B (and hence C) are dense you can create the correctly sized matrix C yourself and then call this routine with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse. 9466 9467 Example of Usage: 9468 .vb 9469 MatProductCreate(A,B,NULL,&C); 9470 MatProductSetType(C,MATPRODUCT_AB); 9471 MatProductSymbolic(C); 9472 MatProductNumeric(C); // compute C=A * B 9473 MatProductReplaceMats(A1,B1,NULL,C); // compute C=A1 * B1 9474 MatProductNumeric(C); 9475 MatProductReplaceMats(A2,NULL,NULL,C); // compute C=A2 * B1 9476 MatProductNumeric(C); 9477 .ve 9478 9479 Level: intermediate 9480 9481 .seealso: MatTransposeMatMult(), MatMatTransposeMult(), MatPtAP(), MatProductCreate(), MatProductSymbolic(), MatProductReplaceMats(), MatProductNumeric() 9482 @*/ 9483 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9484 { 9485 PetscFunctionBegin; 9486 CHKERRQ(MatProduct_Private(A,B,scall,fill,MATPRODUCT_AB,C)); 9487 PetscFunctionReturn(0); 9488 } 9489 9490 /*@ 9491 MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T. 9492 9493 Neighbor-wise Collective on Mat 9494 9495 Input Parameters: 9496 + A - the left matrix 9497 . B - the right matrix 9498 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9499 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9500 9501 Output Parameters: 9502 . C - the product matrix 9503 9504 Notes: 9505 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9506 9507 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9508 9509 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9510 actually needed. 9511 9512 This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class, 9513 and for pairs of MPIDense matrices. 9514 9515 Options Database Keys: 9516 . -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorthims for MPIDense matrices: the 9517 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity; 9518 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity. 9519 9520 Level: intermediate 9521 9522 .seealso: MatMatMult(), MatTransposeMatMult() MatPtAP() 9523 @*/ 9524 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9525 { 9526 PetscFunctionBegin; 9527 CHKERRQ(MatProduct_Private(A,B,scall,fill,MATPRODUCT_ABt,C)); 9528 PetscFunctionReturn(0); 9529 } 9530 9531 /*@ 9532 MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B. 9533 9534 Neighbor-wise Collective on Mat 9535 9536 Input Parameters: 9537 + A - the left matrix 9538 . B - the right matrix 9539 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9540 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9541 9542 Output Parameters: 9543 . C - the product matrix 9544 9545 Notes: 9546 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9547 9548 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call. 9549 9550 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9551 actually needed. 9552 9553 This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes 9554 which inherit from SeqAIJ. C will be of same type as the input matrices. 9555 9556 Level: intermediate 9557 9558 .seealso: MatMatMult(), MatMatTransposeMult(), MatPtAP() 9559 @*/ 9560 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9561 { 9562 PetscFunctionBegin; 9563 CHKERRQ(MatProduct_Private(A,B,scall,fill,MATPRODUCT_AtB,C)); 9564 PetscFunctionReturn(0); 9565 } 9566 9567 /*@ 9568 MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C. 9569 9570 Neighbor-wise Collective on Mat 9571 9572 Input Parameters: 9573 + A - the left matrix 9574 . B - the middle matrix 9575 . C - the right matrix 9576 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9577 - fill - expected fill as ratio of nnz(D)/(nnz(A) + nnz(B)+nnz(C)), use PETSC_DEFAULT if you do not have a good estimate 9578 if the result is a dense matrix this is irrelevant 9579 9580 Output Parameters: 9581 . D - the product matrix 9582 9583 Notes: 9584 Unless scall is MAT_REUSE_MATRIX D will be created. 9585 9586 MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call 9587 9588 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9589 actually needed. 9590 9591 If you have many matrices with the same non-zero structure to multiply, you 9592 should use MAT_REUSE_MATRIX in all calls but the first or 9593 9594 Level: intermediate 9595 9596 .seealso: MatMatMult, MatPtAP() 9597 @*/ 9598 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D) 9599 { 9600 PetscFunctionBegin; 9601 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*D,6); 9602 PetscCheckFalse(scall == MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9603 9604 if (scall == MAT_INITIAL_MATRIX) { 9605 CHKERRQ(MatProductCreate(A,B,C,D)); 9606 CHKERRQ(MatProductSetType(*D,MATPRODUCT_ABC)); 9607 CHKERRQ(MatProductSetAlgorithm(*D,"default")); 9608 CHKERRQ(MatProductSetFill(*D,fill)); 9609 9610 (*D)->product->api_user = PETSC_TRUE; 9611 CHKERRQ(MatProductSetFromOptions(*D)); 9612 PetscCheckFalse(!(*D)->ops->productsymbolic,PetscObjectComm((PetscObject)(*D)),PETSC_ERR_SUP,"MatProduct %s not supported for A %s, B %s and C %s",MatProductTypes[MATPRODUCT_ABC],((PetscObject)A)->type_name,((PetscObject)B)->type_name,((PetscObject)C)->type_name); 9613 CHKERRQ(MatProductSymbolic(*D)); 9614 } else { /* user may change input matrices when REUSE */ 9615 CHKERRQ(MatProductReplaceMats(A,B,C,*D)); 9616 } 9617 CHKERRQ(MatProductNumeric(*D)); 9618 PetscFunctionReturn(0); 9619 } 9620 9621 /*@ 9622 MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators. 9623 9624 Collective on Mat 9625 9626 Input Parameters: 9627 + mat - the matrix 9628 . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices) 9629 . subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used) 9630 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9631 9632 Output Parameter: 9633 . matredundant - redundant matrix 9634 9635 Notes: 9636 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 9637 original matrix has not changed from that last call to MatCreateRedundantMatrix(). 9638 9639 This routine creates the duplicated matrices in subcommunicators; you should NOT create them before 9640 calling it. 9641 9642 Level: advanced 9643 9644 .seealso: MatDestroy() 9645 @*/ 9646 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant) 9647 { 9648 MPI_Comm comm; 9649 PetscMPIInt size; 9650 PetscInt mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs; 9651 Mat_Redundant *redund=NULL; 9652 PetscSubcomm psubcomm=NULL; 9653 MPI_Comm subcomm_in=subcomm; 9654 Mat *matseq; 9655 IS isrow,iscol; 9656 PetscBool newsubcomm=PETSC_FALSE; 9657 9658 PetscFunctionBegin; 9659 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9660 if (nsubcomm && reuse == MAT_REUSE_MATRIX) { 9661 PetscValidPointer(*matredundant,5); 9662 PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5); 9663 } 9664 9665 CHKERRMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 9666 if (size == 1 || nsubcomm == 1) { 9667 if (reuse == MAT_INITIAL_MATRIX) { 9668 CHKERRQ(MatDuplicate(mat,MAT_COPY_VALUES,matredundant)); 9669 } else { 9670 PetscCheckFalse(*matredundant == mat,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix"); 9671 CHKERRQ(MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN)); 9672 } 9673 PetscFunctionReturn(0); 9674 } 9675 9676 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9677 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9678 MatCheckPreallocated(mat,1); 9679 9680 CHKERRQ(PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0)); 9681 if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */ 9682 /* create psubcomm, then get subcomm */ 9683 CHKERRQ(PetscObjectGetComm((PetscObject)mat,&comm)); 9684 CHKERRMPI(MPI_Comm_size(comm,&size)); 9685 PetscCheckFalse(nsubcomm < 1 || nsubcomm > size,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %d",size); 9686 9687 CHKERRQ(PetscSubcommCreate(comm,&psubcomm)); 9688 CHKERRQ(PetscSubcommSetNumber(psubcomm,nsubcomm)); 9689 CHKERRQ(PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS)); 9690 CHKERRQ(PetscSubcommSetFromOptions(psubcomm)); 9691 CHKERRQ(PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL)); 9692 newsubcomm = PETSC_TRUE; 9693 CHKERRQ(PetscSubcommDestroy(&psubcomm)); 9694 } 9695 9696 /* get isrow, iscol and a local sequential matrix matseq[0] */ 9697 if (reuse == MAT_INITIAL_MATRIX) { 9698 mloc_sub = PETSC_DECIDE; 9699 nloc_sub = PETSC_DECIDE; 9700 if (bs < 1) { 9701 CHKERRQ(PetscSplitOwnership(subcomm,&mloc_sub,&M)); 9702 CHKERRQ(PetscSplitOwnership(subcomm,&nloc_sub,&N)); 9703 } else { 9704 CHKERRQ(PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M)); 9705 CHKERRQ(PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N)); 9706 } 9707 CHKERRMPI(MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm)); 9708 rstart = rend - mloc_sub; 9709 CHKERRQ(ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow)); 9710 CHKERRQ(ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol)); 9711 } else { /* reuse == MAT_REUSE_MATRIX */ 9712 PetscCheckFalse(*matredundant == mat,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix"); 9713 /* retrieve subcomm */ 9714 CHKERRQ(PetscObjectGetComm((PetscObject)(*matredundant),&subcomm)); 9715 redund = (*matredundant)->redundant; 9716 isrow = redund->isrow; 9717 iscol = redund->iscol; 9718 matseq = redund->matseq; 9719 } 9720 CHKERRQ(MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq)); 9721 9722 /* get matredundant over subcomm */ 9723 if (reuse == MAT_INITIAL_MATRIX) { 9724 CHKERRQ(MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant)); 9725 9726 /* create a supporting struct and attach it to C for reuse */ 9727 CHKERRQ(PetscNewLog(*matredundant,&redund)); 9728 (*matredundant)->redundant = redund; 9729 redund->isrow = isrow; 9730 redund->iscol = iscol; 9731 redund->matseq = matseq; 9732 if (newsubcomm) { 9733 redund->subcomm = subcomm; 9734 } else { 9735 redund->subcomm = MPI_COMM_NULL; 9736 } 9737 } else { 9738 CHKERRQ(MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant)); 9739 } 9740 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 9741 if (matseq[0]->boundtocpu && matseq[0]->bindingpropagates) { 9742 CHKERRQ(MatBindToCPU(*matredundant,PETSC_TRUE)); 9743 CHKERRQ(MatSetBindingPropagates(*matredundant,PETSC_TRUE)); 9744 } 9745 #endif 9746 CHKERRQ(PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0)); 9747 PetscFunctionReturn(0); 9748 } 9749 9750 /*@C 9751 MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from 9752 a given 'mat' object. Each submatrix can span multiple procs. 9753 9754 Collective on Mat 9755 9756 Input Parameters: 9757 + mat - the matrix 9758 . subcomm - the subcommunicator obtained by com_split(comm) 9759 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9760 9761 Output Parameter: 9762 . subMat - 'parallel submatrices each spans a given subcomm 9763 9764 Notes: 9765 The submatrix partition across processors is dictated by 'subComm' a 9766 communicator obtained by com_split(comm). The comm_split 9767 is not restriced to be grouped with consecutive original ranks. 9768 9769 Due the comm_split() usage, the parallel layout of the submatrices 9770 map directly to the layout of the original matrix [wrt the local 9771 row,col partitioning]. So the original 'DiagonalMat' naturally maps 9772 into the 'DiagonalMat' of the subMat, hence it is used directly from 9773 the subMat. However the offDiagMat looses some columns - and this is 9774 reconstructed with MatSetValues() 9775 9776 Level: advanced 9777 9778 .seealso: MatCreateSubMatrices() 9779 @*/ 9780 PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat) 9781 { 9782 PetscMPIInt commsize,subCommSize; 9783 9784 PetscFunctionBegin; 9785 CHKERRMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize)); 9786 CHKERRMPI(MPI_Comm_size(subComm,&subCommSize)); 9787 PetscCheckFalse(subCommSize > commsize,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %d < SubCommZize %d",commsize,subCommSize); 9788 9789 PetscCheckFalse(scall == MAT_REUSE_MATRIX && *subMat == mat,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix"); 9790 CHKERRQ(PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0)); 9791 CHKERRQ((*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat)); 9792 CHKERRQ(PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0)); 9793 PetscFunctionReturn(0); 9794 } 9795 9796 /*@ 9797 MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering 9798 9799 Not Collective 9800 9801 Input Parameters: 9802 + mat - matrix to extract local submatrix from 9803 . isrow - local row indices for submatrix 9804 - iscol - local column indices for submatrix 9805 9806 Output Parameter: 9807 . submat - the submatrix 9808 9809 Level: intermediate 9810 9811 Notes: 9812 The submat should be returned with MatRestoreLocalSubMatrix(). 9813 9814 Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be 9815 the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's. 9816 9817 The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then 9818 MatSetValuesBlockedLocal() will also be implemented. 9819 9820 The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that 9821 matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided. 9822 9823 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping() 9824 @*/ 9825 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 9826 { 9827 PetscFunctionBegin; 9828 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9829 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 9830 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 9831 PetscCheckSameComm(isrow,2,iscol,3); 9832 PetscValidPointer(submat,4); 9833 PetscCheck(mat->rmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call"); 9834 9835 if (mat->ops->getlocalsubmatrix) { 9836 CHKERRQ((*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat)); 9837 } else { 9838 CHKERRQ(MatCreateLocalRef(mat,isrow,iscol,submat)); 9839 } 9840 PetscFunctionReturn(0); 9841 } 9842 9843 /*@ 9844 MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering 9845 9846 Not Collective 9847 9848 Input Parameters: 9849 + mat - matrix to extract local submatrix from 9850 . isrow - local row indices for submatrix 9851 . iscol - local column indices for submatrix 9852 - submat - the submatrix 9853 9854 Level: intermediate 9855 9856 .seealso: MatGetLocalSubMatrix() 9857 @*/ 9858 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 9859 { 9860 PetscFunctionBegin; 9861 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9862 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 9863 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 9864 PetscCheckSameComm(isrow,2,iscol,3); 9865 PetscValidPointer(submat,4); 9866 if (*submat) { 9867 PetscValidHeaderSpecific(*submat,MAT_CLASSID,4); 9868 } 9869 9870 if (mat->ops->restorelocalsubmatrix) { 9871 CHKERRQ((*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat)); 9872 } else { 9873 CHKERRQ(MatDestroy(submat)); 9874 } 9875 *submat = NULL; 9876 PetscFunctionReturn(0); 9877 } 9878 9879 /* --------------------------------------------------------*/ 9880 /*@ 9881 MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix 9882 9883 Collective on Mat 9884 9885 Input Parameter: 9886 . mat - the matrix 9887 9888 Output Parameter: 9889 . is - if any rows have zero diagonals this contains the list of them 9890 9891 Level: developer 9892 9893 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 9894 @*/ 9895 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is) 9896 { 9897 PetscFunctionBegin; 9898 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9899 PetscValidType(mat,1); 9900 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9901 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9902 9903 if (!mat->ops->findzerodiagonals) { 9904 Vec diag; 9905 const PetscScalar *a; 9906 PetscInt *rows; 9907 PetscInt rStart, rEnd, r, nrow = 0; 9908 9909 CHKERRQ(MatCreateVecs(mat, &diag, NULL)); 9910 CHKERRQ(MatGetDiagonal(mat, diag)); 9911 CHKERRQ(MatGetOwnershipRange(mat, &rStart, &rEnd)); 9912 CHKERRQ(VecGetArrayRead(diag, &a)); 9913 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow; 9914 CHKERRQ(PetscMalloc1(nrow, &rows)); 9915 nrow = 0; 9916 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart; 9917 CHKERRQ(VecRestoreArrayRead(diag, &a)); 9918 CHKERRQ(VecDestroy(&diag)); 9919 CHKERRQ(ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is)); 9920 } else { 9921 CHKERRQ((*mat->ops->findzerodiagonals)(mat, is)); 9922 } 9923 PetscFunctionReturn(0); 9924 } 9925 9926 /*@ 9927 MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size) 9928 9929 Collective on Mat 9930 9931 Input Parameter: 9932 . mat - the matrix 9933 9934 Output Parameter: 9935 . is - contains the list of rows with off block diagonal entries 9936 9937 Level: developer 9938 9939 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 9940 @*/ 9941 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is) 9942 { 9943 PetscFunctionBegin; 9944 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9945 PetscValidType(mat,1); 9946 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9947 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9948 9949 PetscCheck(mat->ops->findoffblockdiagonalentries,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a find off block diagonal entries defined",((PetscObject)mat)->type_name); 9950 CHKERRQ((*mat->ops->findoffblockdiagonalentries)(mat,is)); 9951 PetscFunctionReturn(0); 9952 } 9953 9954 /*@C 9955 MatInvertBlockDiagonal - Inverts the block diagonal entries. 9956 9957 Collective on Mat 9958 9959 Input Parameters: 9960 . mat - the matrix 9961 9962 Output Parameters: 9963 . values - the block inverses in column major order (FORTRAN-like) 9964 9965 Note: 9966 The size of the blocks is determined by the block size of the matrix. 9967 9968 Fortran Note: 9969 This routine is not available from Fortran. 9970 9971 Level: advanced 9972 9973 .seealso: MatInvertBockDiagonalMat() 9974 @*/ 9975 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values) 9976 { 9977 PetscFunctionBegin; 9978 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9979 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9980 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9981 PetscCheck(mat->ops->invertblockdiagonal,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for type %s",((PetscObject)mat)->type_name); 9982 CHKERRQ((*mat->ops->invertblockdiagonal)(mat,values)); 9983 PetscFunctionReturn(0); 9984 } 9985 9986 /*@C 9987 MatInvertVariableBlockDiagonal - Inverts the point block diagonal entries. 9988 9989 Collective on Mat 9990 9991 Input Parameters: 9992 + mat - the matrix 9993 . nblocks - the number of blocks 9994 - bsizes - the size of each block 9995 9996 Output Parameters: 9997 . values - the block inverses in column major order (FORTRAN-like) 9998 9999 Note: 10000 This routine is not available from Fortran. 10001 10002 Level: advanced 10003 10004 .seealso: MatInvertBockDiagonal() 10005 @*/ 10006 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values) 10007 { 10008 PetscFunctionBegin; 10009 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10010 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10011 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10012 PetscCheck(mat->ops->invertvariableblockdiagonal,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for type %s",((PetscObject)mat)->type_name); 10013 CHKERRQ((*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values)); 10014 PetscFunctionReturn(0); 10015 } 10016 10017 /*@ 10018 MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A 10019 10020 Collective on Mat 10021 10022 Input Parameters: 10023 . A - the matrix 10024 10025 Output Parameters: 10026 . C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set. 10027 10028 Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C 10029 10030 Level: advanced 10031 10032 .seealso: MatInvertBockDiagonal() 10033 @*/ 10034 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C) 10035 { 10036 const PetscScalar *vals; 10037 PetscInt *dnnz; 10038 PetscInt M,N,m,n,rstart,rend,bs,i,j; 10039 10040 PetscFunctionBegin; 10041 CHKERRQ(MatInvertBlockDiagonal(A,&vals)); 10042 CHKERRQ(MatGetBlockSize(A,&bs)); 10043 CHKERRQ(MatGetSize(A,&M,&N)); 10044 CHKERRQ(MatGetLocalSize(A,&m,&n)); 10045 CHKERRQ(MatSetSizes(C,m,n,M,N)); 10046 CHKERRQ(MatSetBlockSize(C,bs)); 10047 CHKERRQ(PetscMalloc1(m/bs,&dnnz)); 10048 for (j = 0; j < m/bs; j++) dnnz[j] = 1; 10049 CHKERRQ(MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL)); 10050 CHKERRQ(PetscFree(dnnz)); 10051 CHKERRQ(MatGetOwnershipRange(C,&rstart,&rend)); 10052 CHKERRQ(MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE)); 10053 for (i = rstart/bs; i < rend/bs; i++) { 10054 CHKERRQ(MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES)); 10055 } 10056 CHKERRQ(MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY)); 10057 CHKERRQ(MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY)); 10058 CHKERRQ(MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE)); 10059 PetscFunctionReturn(0); 10060 } 10061 10062 /*@C 10063 MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created 10064 via MatTransposeColoringCreate(). 10065 10066 Collective on MatTransposeColoring 10067 10068 Input Parameter: 10069 . c - coloring context 10070 10071 Level: intermediate 10072 10073 .seealso: MatTransposeColoringCreate() 10074 @*/ 10075 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c) 10076 { 10077 MatTransposeColoring matcolor=*c; 10078 10079 PetscFunctionBegin; 10080 if (!matcolor) PetscFunctionReturn(0); 10081 if (--((PetscObject)matcolor)->refct > 0) {matcolor = NULL; PetscFunctionReturn(0);} 10082 10083 CHKERRQ(PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow)); 10084 CHKERRQ(PetscFree(matcolor->rows)); 10085 CHKERRQ(PetscFree(matcolor->den2sp)); 10086 CHKERRQ(PetscFree(matcolor->colorforcol)); 10087 CHKERRQ(PetscFree(matcolor->columns)); 10088 if (matcolor->brows>0) { 10089 CHKERRQ(PetscFree(matcolor->lstart)); 10090 } 10091 CHKERRQ(PetscHeaderDestroy(c)); 10092 PetscFunctionReturn(0); 10093 } 10094 10095 /*@C 10096 MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which 10097 a MatTransposeColoring context has been created, computes a dense B^T by Apply 10098 MatTransposeColoring to sparse B. 10099 10100 Collective on MatTransposeColoring 10101 10102 Input Parameters: 10103 + B - sparse matrix B 10104 . Btdense - symbolic dense matrix B^T 10105 - coloring - coloring context created with MatTransposeColoringCreate() 10106 10107 Output Parameter: 10108 . Btdense - dense matrix B^T 10109 10110 Level: advanced 10111 10112 Notes: 10113 These are used internally for some implementations of MatRARt() 10114 10115 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp() 10116 10117 @*/ 10118 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense) 10119 { 10120 PetscFunctionBegin; 10121 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 10122 PetscValidHeaderSpecific(Btdense,MAT_CLASSID,3); 10123 PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,1); 10124 10125 PetscCheck(B->ops->transcoloringapplysptoden,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name); 10126 CHKERRQ((B->ops->transcoloringapplysptoden)(coloring,B,Btdense)); 10127 PetscFunctionReturn(0); 10128 } 10129 10130 /*@C 10131 MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which 10132 a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense 10133 in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix 10134 Csp from Cden. 10135 10136 Collective on MatTransposeColoring 10137 10138 Input Parameters: 10139 + coloring - coloring context created with MatTransposeColoringCreate() 10140 - Cden - matrix product of a sparse matrix and a dense matrix Btdense 10141 10142 Output Parameter: 10143 . Csp - sparse matrix 10144 10145 Level: advanced 10146 10147 Notes: 10148 These are used internally for some implementations of MatRARt() 10149 10150 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen() 10151 10152 @*/ 10153 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp) 10154 { 10155 PetscFunctionBegin; 10156 PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1); 10157 PetscValidHeaderSpecific(Cden,MAT_CLASSID,2); 10158 PetscValidHeaderSpecific(Csp,MAT_CLASSID,3); 10159 10160 PetscCheck(Csp->ops->transcoloringapplydentosp,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name); 10161 CHKERRQ((Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp)); 10162 CHKERRQ(MatAssemblyBegin(Csp,MAT_FINAL_ASSEMBLY)); 10163 CHKERRQ(MatAssemblyEnd(Csp,MAT_FINAL_ASSEMBLY)); 10164 PetscFunctionReturn(0); 10165 } 10166 10167 /*@C 10168 MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T. 10169 10170 Collective on Mat 10171 10172 Input Parameters: 10173 + mat - the matrix product C 10174 - iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring() 10175 10176 Output Parameter: 10177 . color - the new coloring context 10178 10179 Level: intermediate 10180 10181 .seealso: MatTransposeColoringDestroy(), MatTransColoringApplySpToDen(), 10182 MatTransColoringApplyDenToSp() 10183 @*/ 10184 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color) 10185 { 10186 MatTransposeColoring c; 10187 MPI_Comm comm; 10188 10189 PetscFunctionBegin; 10190 CHKERRQ(PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0)); 10191 CHKERRQ(PetscObjectGetComm((PetscObject)mat,&comm)); 10192 CHKERRQ(PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL)); 10193 10194 c->ctype = iscoloring->ctype; 10195 if (mat->ops->transposecoloringcreate) { 10196 CHKERRQ((*mat->ops->transposecoloringcreate)(mat,iscoloring,c)); 10197 } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for matrix type %s",((PetscObject)mat)->type_name); 10198 10199 *color = c; 10200 CHKERRQ(PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0)); 10201 PetscFunctionReturn(0); 10202 } 10203 10204 /*@ 10205 MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the 10206 matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the 10207 same, otherwise it will be larger 10208 10209 Not Collective 10210 10211 Input Parameter: 10212 . A - the matrix 10213 10214 Output Parameter: 10215 . state - the current state 10216 10217 Notes: 10218 You can only compare states from two different calls to the SAME matrix, you cannot compare calls between 10219 different matrices 10220 10221 Level: intermediate 10222 10223 @*/ 10224 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state) 10225 { 10226 PetscFunctionBegin; 10227 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10228 *state = mat->nonzerostate; 10229 PetscFunctionReturn(0); 10230 } 10231 10232 /*@ 10233 MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential 10234 matrices from each processor 10235 10236 Collective 10237 10238 Input Parameters: 10239 + comm - the communicators the parallel matrix will live on 10240 . seqmat - the input sequential matrices 10241 . n - number of local columns (or PETSC_DECIDE) 10242 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10243 10244 Output Parameter: 10245 . mpimat - the parallel matrix generated 10246 10247 Level: advanced 10248 10249 Notes: 10250 The number of columns of the matrix in EACH processor MUST be the same. 10251 10252 @*/ 10253 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat) 10254 { 10255 PetscFunctionBegin; 10256 PetscCheck(seqmat->ops->creatempimatconcatenateseqmat,PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name); 10257 PetscCheckFalse(reuse == MAT_REUSE_MATRIX && seqmat == *mpimat,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix"); 10258 10259 CHKERRQ(PetscLogEventBegin(MAT_Merge,seqmat,0,0,0)); 10260 CHKERRQ((*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat)); 10261 CHKERRQ(PetscLogEventEnd(MAT_Merge,seqmat,0,0,0)); 10262 PetscFunctionReturn(0); 10263 } 10264 10265 /*@ 10266 MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent 10267 ranks' ownership ranges. 10268 10269 Collective on A 10270 10271 Input Parameters: 10272 + A - the matrix to create subdomains from 10273 - N - requested number of subdomains 10274 10275 Output Parameters: 10276 + n - number of subdomains resulting on this rank 10277 - iss - IS list with indices of subdomains on this rank 10278 10279 Level: advanced 10280 10281 Notes: 10282 number of subdomains must be smaller than the communicator size 10283 @*/ 10284 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[]) 10285 { 10286 MPI_Comm comm,subcomm; 10287 PetscMPIInt size,rank,color; 10288 PetscInt rstart,rend,k; 10289 10290 PetscFunctionBegin; 10291 CHKERRQ(PetscObjectGetComm((PetscObject)A,&comm)); 10292 CHKERRMPI(MPI_Comm_size(comm,&size)); 10293 CHKERRMPI(MPI_Comm_rank(comm,&rank)); 10294 PetscCheck(N >= 1 && N < (PetscInt)size,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"number of subdomains must be > 0 and < %d, got N = %" PetscInt_FMT,size,N); 10295 *n = 1; 10296 k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */ 10297 color = rank/k; 10298 CHKERRMPI(MPI_Comm_split(comm,color,rank,&subcomm)); 10299 CHKERRQ(PetscMalloc1(1,iss)); 10300 CHKERRQ(MatGetOwnershipRange(A,&rstart,&rend)); 10301 CHKERRQ(ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0])); 10302 CHKERRMPI(MPI_Comm_free(&subcomm)); 10303 PetscFunctionReturn(0); 10304 } 10305 10306 /*@ 10307 MatGalerkin - Constructs the coarse grid problem via Galerkin projection. 10308 10309 If the interpolation and restriction operators are the same, uses MatPtAP. 10310 If they are not the same, use MatMatMatMult. 10311 10312 Once the coarse grid problem is constructed, correct for interpolation operators 10313 that are not of full rank, which can legitimately happen in the case of non-nested 10314 geometric multigrid. 10315 10316 Input Parameters: 10317 + restrct - restriction operator 10318 . dA - fine grid matrix 10319 . interpolate - interpolation operator 10320 . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10321 - fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate 10322 10323 Output Parameters: 10324 . A - the Galerkin coarse matrix 10325 10326 Options Database Key: 10327 . -pc_mg_galerkin <both,pmat,mat,none> - for what matrices the Galerkin process should be used 10328 10329 Level: developer 10330 10331 .seealso: MatPtAP(), MatMatMatMult() 10332 @*/ 10333 PetscErrorCode MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A) 10334 { 10335 IS zerorows; 10336 Vec diag; 10337 10338 PetscFunctionBegin; 10339 PetscCheckFalse(reuse == MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 10340 /* Construct the coarse grid matrix */ 10341 if (interpolate == restrct) { 10342 CHKERRQ(MatPtAP(dA,interpolate,reuse,fill,A)); 10343 } else { 10344 CHKERRQ(MatMatMatMult(restrct,dA,interpolate,reuse,fill,A)); 10345 } 10346 10347 /* If the interpolation matrix is not of full rank, A will have zero rows. 10348 This can legitimately happen in the case of non-nested geometric multigrid. 10349 In that event, we set the rows of the matrix to the rows of the identity, 10350 ignoring the equations (as the RHS will also be zero). */ 10351 10352 CHKERRQ(MatFindZeroRows(*A, &zerorows)); 10353 10354 if (zerorows != NULL) { /* if there are any zero rows */ 10355 CHKERRQ(MatCreateVecs(*A, &diag, NULL)); 10356 CHKERRQ(MatGetDiagonal(*A, diag)); 10357 CHKERRQ(VecISSet(diag, zerorows, 1.0)); 10358 CHKERRQ(MatDiagonalSet(*A, diag, INSERT_VALUES)); 10359 CHKERRQ(VecDestroy(&diag)); 10360 CHKERRQ(ISDestroy(&zerorows)); 10361 } 10362 PetscFunctionReturn(0); 10363 } 10364 10365 /*@C 10366 MatSetOperation - Allows user to set a matrix operation for any matrix type 10367 10368 Logically Collective on Mat 10369 10370 Input Parameters: 10371 + mat - the matrix 10372 . op - the name of the operation 10373 - f - the function that provides the operation 10374 10375 Level: developer 10376 10377 Usage: 10378 $ extern PetscErrorCode usermult(Mat,Vec,Vec); 10379 $ ierr = MatCreateXXX(comm,...&A); 10380 $ ierr = MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult); 10381 10382 Notes: 10383 See the file include/petscmat.h for a complete list of matrix 10384 operations, which all have the form MATOP_<OPERATION>, where 10385 <OPERATION> is the name (in all capital letters) of the 10386 user interface routine (e.g., MatMult() -> MATOP_MULT). 10387 10388 All user-provided functions (except for MATOP_DESTROY) should have the same calling 10389 sequence as the usual matrix interface routines, since they 10390 are intended to be accessed via the usual matrix interface 10391 routines, e.g., 10392 $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 10393 10394 In particular each function MUST return an error code of 0 on success and 10395 nonzero on failure. 10396 10397 This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type. 10398 10399 .seealso: MatGetOperation(), MatCreateShell(), MatShellSetContext(), MatShellSetOperation() 10400 @*/ 10401 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void)) 10402 { 10403 PetscFunctionBegin; 10404 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10405 if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) { 10406 mat->ops->viewnative = mat->ops->view; 10407 } 10408 (((void(**)(void))mat->ops)[op]) = f; 10409 PetscFunctionReturn(0); 10410 } 10411 10412 /*@C 10413 MatGetOperation - Gets a matrix operation for any matrix type. 10414 10415 Not Collective 10416 10417 Input Parameters: 10418 + mat - the matrix 10419 - op - the name of the operation 10420 10421 Output Parameter: 10422 . f - the function that provides the operation 10423 10424 Level: developer 10425 10426 Usage: 10427 $ PetscErrorCode (*usermult)(Mat,Vec,Vec); 10428 $ ierr = MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult); 10429 10430 Notes: 10431 See the file include/petscmat.h for a complete list of matrix 10432 operations, which all have the form MATOP_<OPERATION>, where 10433 <OPERATION> is the name (in all capital letters) of the 10434 user interface routine (e.g., MatMult() -> MATOP_MULT). 10435 10436 This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type. 10437 10438 .seealso: MatSetOperation(), MatCreateShell(), MatShellGetContext(), MatShellGetOperation() 10439 @*/ 10440 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void)) 10441 { 10442 PetscFunctionBegin; 10443 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10444 *f = (((void (**)(void))mat->ops)[op]); 10445 PetscFunctionReturn(0); 10446 } 10447 10448 /*@ 10449 MatHasOperation - Determines whether the given matrix supports the particular 10450 operation. 10451 10452 Not Collective 10453 10454 Input Parameters: 10455 + mat - the matrix 10456 - op - the operation, for example, MATOP_GET_DIAGONAL 10457 10458 Output Parameter: 10459 . has - either PETSC_TRUE or PETSC_FALSE 10460 10461 Level: advanced 10462 10463 Notes: 10464 See the file include/petscmat.h for a complete list of matrix 10465 operations, which all have the form MATOP_<OPERATION>, where 10466 <OPERATION> is the name (in all capital letters) of the 10467 user-level routine. E.g., MatNorm() -> MATOP_NORM. 10468 10469 .seealso: MatCreateShell() 10470 @*/ 10471 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has) 10472 { 10473 PetscFunctionBegin; 10474 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10475 PetscValidPointer(has,3); 10476 if (mat->ops->hasoperation) { 10477 CHKERRQ((*mat->ops->hasoperation)(mat,op,has)); 10478 } else { 10479 if (((void**)mat->ops)[op]) *has = PETSC_TRUE; 10480 else { 10481 *has = PETSC_FALSE; 10482 if (op == MATOP_CREATE_SUBMATRIX) { 10483 PetscMPIInt size; 10484 10485 CHKERRMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 10486 if (size == 1) { 10487 CHKERRQ(MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has)); 10488 } 10489 } 10490 } 10491 } 10492 PetscFunctionReturn(0); 10493 } 10494 10495 /*@ 10496 MatHasCongruentLayouts - Determines whether the rows and columns layouts 10497 of the matrix are congruent 10498 10499 Collective on mat 10500 10501 Input Parameters: 10502 . mat - the matrix 10503 10504 Output Parameter: 10505 . cong - either PETSC_TRUE or PETSC_FALSE 10506 10507 Level: beginner 10508 10509 Notes: 10510 10511 .seealso: MatCreate(), MatSetSizes() 10512 @*/ 10513 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong) 10514 { 10515 PetscFunctionBegin; 10516 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10517 PetscValidType(mat,1); 10518 PetscValidPointer(cong,2); 10519 if (!mat->rmap || !mat->cmap) { 10520 *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE; 10521 PetscFunctionReturn(0); 10522 } 10523 if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */ 10524 CHKERRQ(PetscLayoutSetUp(mat->rmap)); 10525 CHKERRQ(PetscLayoutSetUp(mat->cmap)); 10526 CHKERRQ(PetscLayoutCompare(mat->rmap,mat->cmap,cong)); 10527 if (*cong) mat->congruentlayouts = 1; 10528 else mat->congruentlayouts = 0; 10529 } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE; 10530 PetscFunctionReturn(0); 10531 } 10532 10533 PetscErrorCode MatSetInf(Mat A) 10534 { 10535 PetscFunctionBegin; 10536 PetscCheck(A->ops->setinf,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"No support for this operation for this matrix type"); 10537 CHKERRQ((*A->ops->setinf)(A)); 10538 PetscFunctionReturn(0); 10539 } 10540