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 PetscCall(PetscObjectGetComm((PetscObject)x,&comm)); 87 PetscCall(PetscRandomCreate(comm,&randObj)); 88 PetscCall(PetscRandomSetFromOptions(randObj)); 89 rctx = randObj; 90 } 91 PetscCall(PetscLogEventBegin(MAT_SetRandom,x,rctx,0,0)); 92 PetscCall((*x->ops->setrandom)(x,rctx)); 93 PetscCall(PetscLogEventEnd(MAT_SetRandom,x,rctx,0,0)); 94 95 PetscCall(MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY)); 96 PetscCall(MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY)); 97 PetscCall(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 `MatErrorCode` 154 @*/ 155 PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err) 156 { 157 PetscFunctionBegin; 158 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 159 PetscValidPointer(err,2); 160 *err = mat->factorerrortype; 161 PetscFunctionReturn(0); 162 } 163 164 /*@ 165 MatFactorClearError - clears the error code in a factorization 166 167 Logically Collective on Mat 168 169 Input Parameter: 170 . mat - the factored matrix 171 172 Level: developer 173 174 Notes: 175 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 176 177 .seealso: `MatZeroEntries()`, `MatFactor()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()`, `MatFactorGetError()`, `MatFactorGetErrorZeroPivot()`, 178 `MatGetErrorCode()`, `MatErrorCode` 179 @*/ 180 PetscErrorCode MatFactorClearError(Mat mat) 181 { 182 PetscFunctionBegin; 183 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 184 mat->factorerrortype = MAT_FACTOR_NOERROR; 185 mat->factorerror_zeropivot_value = 0.0; 186 mat->factorerror_zeropivot_row = 0; 187 PetscFunctionReturn(0); 188 } 189 190 PETSC_INTERN PetscErrorCode MatFindNonzeroRowsOrCols_Basic(Mat mat,PetscBool cols,PetscReal tol,IS *nonzero) 191 { 192 Vec r,l; 193 const PetscScalar *al; 194 PetscInt i,nz,gnz,N,n; 195 196 PetscFunctionBegin; 197 PetscCall(MatCreateVecs(mat,&r,&l)); 198 if (!cols) { /* nonzero rows */ 199 PetscCall(MatGetSize(mat,&N,NULL)); 200 PetscCall(MatGetLocalSize(mat,&n,NULL)); 201 PetscCall(VecSet(l,0.0)); 202 PetscCall(VecSetRandom(r,NULL)); 203 PetscCall(MatMult(mat,r,l)); 204 PetscCall(VecGetArrayRead(l,&al)); 205 } else { /* nonzero columns */ 206 PetscCall(MatGetSize(mat,NULL,&N)); 207 PetscCall(MatGetLocalSize(mat,NULL,&n)); 208 PetscCall(VecSet(r,0.0)); 209 PetscCall(VecSetRandom(l,NULL)); 210 PetscCall(MatMultTranspose(mat,l,r)); 211 PetscCall(VecGetArrayRead(r,&al)); 212 } 213 if (tol <= 0.0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++; } 214 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nz++; } 215 PetscCall(MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat))); 216 if (gnz != N) { 217 PetscInt *nzr; 218 PetscCall(PetscMalloc1(nz,&nzr)); 219 if (nz) { 220 if (tol < 0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; } 221 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nzr[nz++] = i; } 222 } 223 PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,nonzero)); 224 } else *nonzero = NULL; 225 if (!cols) { /* nonzero rows */ 226 PetscCall(VecRestoreArrayRead(l,&al)); 227 } else { 228 PetscCall(VecRestoreArrayRead(r,&al)); 229 } 230 PetscCall(VecDestroy(&l)); 231 PetscCall(VecDestroy(&r)); 232 PetscFunctionReturn(0); 233 } 234 235 /*@ 236 MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix 237 238 Input Parameter: 239 . A - the matrix 240 241 Output Parameter: 242 . keptrows - the rows that are not completely zero 243 244 Notes: 245 keptrows is set to NULL if all rows are nonzero. 246 247 Level: intermediate 248 249 @*/ 250 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows) 251 { 252 PetscFunctionBegin; 253 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 254 PetscValidType(mat,1); 255 PetscValidPointer(keptrows,2); 256 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 257 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 258 if (mat->ops->findnonzerorows) { 259 PetscCall((*mat->ops->findnonzerorows)(mat,keptrows)); 260 } else { 261 PetscCall(MatFindNonzeroRowsOrCols_Basic(mat,PETSC_FALSE,0.0,keptrows)); 262 } 263 PetscFunctionReturn(0); 264 } 265 266 /*@ 267 MatFindZeroRows - Locate all rows that are completely zero in the matrix 268 269 Input Parameter: 270 . A - the matrix 271 272 Output Parameter: 273 . zerorows - the rows that are completely zero 274 275 Notes: 276 zerorows is set to NULL if no rows are zero. 277 278 Level: intermediate 279 280 @*/ 281 PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows) 282 { 283 IS keptrows; 284 PetscInt m, n; 285 286 PetscFunctionBegin; 287 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 288 PetscValidType(mat,1); 289 PetscValidPointer(zerorows,2); 290 PetscCall(MatFindNonzeroRows(mat, &keptrows)); 291 /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows. 292 In keeping with this convention, we set zerorows to NULL if there are no zero 293 rows. */ 294 if (keptrows == NULL) { 295 *zerorows = NULL; 296 } else { 297 PetscCall(MatGetOwnershipRange(mat,&m,&n)); 298 PetscCall(ISComplement(keptrows,m,n,zerorows)); 299 PetscCall(ISDestroy(&keptrows)); 300 } 301 PetscFunctionReturn(0); 302 } 303 304 /*@ 305 MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling 306 307 Not Collective 308 309 Input Parameters: 310 . A - the matrix 311 312 Output Parameters: 313 . a - the diagonal part (which is a SEQUENTIAL matrix) 314 315 Notes: 316 See the manual page for `MatCreateAIJ()` for more information on the "diagonal part" of the matrix. 317 318 Use caution, as the reference count on the returned matrix is not incremented and it is used as part of the containing MPI Mat's normal operation. 319 320 Level: advanced 321 322 .seelaso: `MatCreateAIJ()` 323 @*/ 324 PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a) 325 { 326 PetscFunctionBegin; 327 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 328 PetscValidType(A,1); 329 PetscValidPointer(a,2); 330 PetscCheck(!A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 331 if (A->ops->getdiagonalblock) { 332 PetscCall((*A->ops->getdiagonalblock)(A,a)); 333 } else { 334 PetscMPIInt size; 335 336 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)A),&size)); 337 PetscCheck(size == 1,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not for parallel matrix type %s",((PetscObject)A)->type_name); 338 *a = A; 339 } 340 PetscFunctionReturn(0); 341 } 342 343 /*@ 344 MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries. 345 346 Collective on Mat 347 348 Input Parameters: 349 . mat - the matrix 350 351 Output Parameter: 352 . trace - the sum of the diagonal entries 353 354 Level: advanced 355 356 @*/ 357 PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace) 358 { 359 Vec diag; 360 361 PetscFunctionBegin; 362 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 363 PetscValidScalarPointer(trace,2); 364 PetscCall(MatCreateVecs(mat,&diag,NULL)); 365 PetscCall(MatGetDiagonal(mat,diag)); 366 PetscCall(VecSum(diag,trace)); 367 PetscCall(VecDestroy(&diag)); 368 PetscFunctionReturn(0); 369 } 370 371 /*@ 372 MatRealPart - Zeros out the imaginary part of the matrix 373 374 Logically Collective on Mat 375 376 Input Parameters: 377 . mat - the matrix 378 379 Level: advanced 380 381 .seealso: `MatImaginaryPart()` 382 @*/ 383 PetscErrorCode MatRealPart(Mat mat) 384 { 385 PetscFunctionBegin; 386 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 387 PetscValidType(mat,1); 388 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 389 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 390 PetscCheck(mat->ops->realpart,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 391 MatCheckPreallocated(mat,1); 392 PetscCall((*mat->ops->realpart)(mat)); 393 PetscFunctionReturn(0); 394 } 395 396 /*@C 397 MatGetGhosts - Get the global indices of all ghost nodes defined by the sparse matrix 398 399 Collective on Mat 400 401 Input Parameter: 402 . mat - the matrix 403 404 Output Parameters: 405 + nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block) 406 - ghosts - the global indices of the ghost points 407 408 Notes: 409 the nghosts and ghosts are suitable to pass into `VecCreateGhost()` 410 411 Level: advanced 412 413 @*/ 414 PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[]) 415 { 416 PetscFunctionBegin; 417 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 418 PetscValidType(mat,1); 419 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 420 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 421 if (mat->ops->getghosts) { 422 PetscCall((*mat->ops->getghosts)(mat,nghosts,ghosts)); 423 } else { 424 if (nghosts) *nghosts = 0; 425 if (ghosts) *ghosts = NULL; 426 } 427 PetscFunctionReturn(0); 428 } 429 430 /*@ 431 MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part 432 433 Logically Collective on Mat 434 435 Input Parameters: 436 . mat - the matrix 437 438 Level: advanced 439 440 .seealso: `MatRealPart()` 441 @*/ 442 PetscErrorCode MatImaginaryPart(Mat mat) 443 { 444 PetscFunctionBegin; 445 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 446 PetscValidType(mat,1); 447 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 448 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 449 PetscCheck(mat->ops->imaginarypart,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 450 MatCheckPreallocated(mat,1); 451 PetscCall((*mat->ops->imaginarypart)(mat)); 452 PetscFunctionReturn(0); 453 } 454 455 /*@ 456 MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices) 457 458 Not Collective 459 460 Input Parameter: 461 . mat - the matrix 462 463 Output Parameters: 464 + missing - is any diagonal missing 465 - dd - first diagonal entry that is missing (optional) on this process 466 467 Level: advanced 468 469 .seealso: `MatRealPart()` 470 @*/ 471 PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd) 472 { 473 PetscFunctionBegin; 474 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 475 PetscValidType(mat,1); 476 PetscValidBoolPointer(missing,2); 477 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix %s",((PetscObject)mat)->type_name); 478 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 479 PetscCheck(mat->ops->missingdiagonal,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 480 PetscCall((*mat->ops->missingdiagonal)(mat,missing,dd)); 481 PetscFunctionReturn(0); 482 } 483 484 /*@C 485 MatGetRow - Gets a row of a matrix. You MUST call `MatRestoreRow()` 486 for each row that you get to ensure that your application does 487 not bleed memory. 488 489 Not Collective 490 491 Input Parameters: 492 + mat - the matrix 493 - row - the row to get 494 495 Output Parameters: 496 + ncols - if not NULL, the number of nonzeros in the row 497 . cols - if not NULL, the column numbers 498 - vals - if not NULL, the values 499 500 Notes: 501 This routine is provided for people who need to have direct access 502 to the structure of a matrix. We hope that we provide enough 503 high-level matrix routines that few users will need it. 504 505 `MatGetRow()` always returns 0-based column indices, regardless of 506 whether the internal representation is 0-based (default) or 1-based. 507 508 For better efficiency, set cols and/or vals to NULL if you do 509 not wish to extract these quantities. 510 511 The user can only examine the values extracted with `MatGetRow()`; 512 the values cannot be altered. To change the matrix entries, one 513 must use `MatSetValues()`. 514 515 You can only have one call to `MatGetRow()` outstanding for a particular 516 matrix at a time, per processor. `MatGetRow()` can only obtain rows 517 associated with the given processor, it cannot get rows from the 518 other processors; for that we suggest using `MatCreateSubMatrices()`, then 519 MatGetRow() on the submatrix. The row index passed to `MatGetRow()` 520 is in the global number of rows. 521 522 Use `MatGetRowIJ()` and `MatRestoreRowIJ()` to access all the local indices of the sparse matrix. 523 524 Use `MatSeqAIJGetArray()` and similar functions to access the numerical values for certain matrix types directly. 525 526 Fortran Notes: 527 The calling sequence from Fortran is 528 .vb 529 MatGetRow(matrix,row,ncols,cols,values,ierr) 530 Mat matrix (input) 531 integer row (input) 532 integer ncols (output) 533 integer cols(maxcols) (output) 534 double precision (or double complex) values(maxcols) output 535 .ve 536 where maxcols >= maximum nonzeros in any row of the matrix. 537 538 Caution: 539 Do not try to change the contents of the output arrays (cols and vals). 540 In some cases, this may corrupt the matrix. 541 542 Level: advanced 543 544 .seealso: `MatRestoreRow()`, `MatSetValues()`, `MatGetValues()`, `MatCreateSubMatrices()`, `MatGetDiagonal()`, `MatGetRowIJ()`, `MatRestoreRowIJ()` 545 @*/ 546 PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 547 { 548 PetscInt incols; 549 550 PetscFunctionBegin; 551 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 552 PetscValidType(mat,1); 553 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 554 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 555 PetscCheck(mat->ops->getrow,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 556 MatCheckPreallocated(mat,1); 557 PetscCheck(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); 558 PetscCall(PetscLogEventBegin(MAT_GetRow,mat,0,0,0)); 559 PetscCall((*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals)); 560 if (ncols) *ncols = incols; 561 PetscCall(PetscLogEventEnd(MAT_GetRow,mat,0,0,0)); 562 PetscFunctionReturn(0); 563 } 564 565 /*@ 566 MatConjugate - replaces the matrix values with their complex conjugates 567 568 Logically Collective on Mat 569 570 Input Parameters: 571 . mat - the matrix 572 573 Level: advanced 574 575 .seealso: `VecConjugate()`, `MatTranspose()` 576 @*/ 577 PetscErrorCode MatConjugate(Mat mat) 578 { 579 PetscFunctionBegin; 580 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 581 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 582 if (PetscDefined(USE_COMPLEX)) { 583 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); 584 PetscCall((*mat->ops->conjugate)(mat)); 585 } 586 PetscFunctionReturn(0); 587 } 588 589 /*@C 590 MatRestoreRow - Frees any temporary space allocated by `MatGetRow()`. 591 592 Not Collective 593 594 Input Parameters: 595 + mat - the matrix 596 . row - the row to get 597 . ncols, cols - the number of nonzeros and their columns 598 - vals - if nonzero the column values 599 600 Notes: 601 This routine should be called after you have finished examining the entries. 602 603 This routine zeros out ncols, cols, and vals. This is to prevent accidental 604 us of the array after it has been restored. If you pass NULL, it will 605 not zero the pointers. Use of cols or vals after `MatRestoreRow()` is invalid. 606 607 Fortran Notes: 608 The calling sequence from Fortran is 609 .vb 610 MatRestoreRow(matrix,row,ncols,cols,values,ierr) 611 Mat matrix (input) 612 integer row (input) 613 integer ncols (output) 614 integer cols(maxcols) (output) 615 double precision (or double complex) values(maxcols) output 616 .ve 617 Where maxcols >= maximum nonzeros in any row of the matrix. 618 619 In Fortran `MatRestoreRow()` MUST be called after `MatGetRow()` 620 before another call to `MatGetRow()` can be made. 621 622 Level: advanced 623 624 .seealso: `MatGetRow()` 625 @*/ 626 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 627 { 628 PetscFunctionBegin; 629 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 630 if (ncols) PetscValidIntPointer(ncols,3); 631 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 632 if (!mat->ops->restorerow) PetscFunctionReturn(0); 633 PetscCall((*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals)); 634 if (ncols) *ncols = 0; 635 if (cols) *cols = NULL; 636 if (vals) *vals = NULL; 637 PetscFunctionReturn(0); 638 } 639 640 /*@ 641 MatGetRowUpperTriangular - Sets a flag to enable calls to `MatGetRow()` for matrix in `MATSBAIJ` format. 642 You should call `MatRestoreRowUpperTriangular()` after calling` MatGetRow()` and `MatRestoreRow()` to disable the flag. 643 644 Not Collective 645 646 Input Parameters: 647 . mat - the matrix 648 649 Notes: 650 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. 651 652 Level: advanced 653 654 .seealso: `MatRestoreRowUpperTriangular()` 655 @*/ 656 PetscErrorCode MatGetRowUpperTriangular(Mat mat) 657 { 658 PetscFunctionBegin; 659 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 660 PetscValidType(mat,1); 661 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 662 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 663 MatCheckPreallocated(mat,1); 664 if (!mat->ops->getrowuppertriangular) PetscFunctionReturn(0); 665 PetscCall((*mat->ops->getrowuppertriangular)(mat)); 666 PetscFunctionReturn(0); 667 } 668 669 /*@ 670 MatRestoreRowUpperTriangular - Disable calls to `MatGetRow()` for matrix in `MATSBAIJ` format. 671 672 Not Collective 673 674 Input Parameters: 675 . mat - the matrix 676 677 Notes: 678 This routine should be called after you have finished calls to `MatGetRow()` and `MatRestoreRow()`. 679 680 Level: advanced 681 682 .seealso: `MatGetRowUpperTriangular()` 683 @*/ 684 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat) 685 { 686 PetscFunctionBegin; 687 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 688 PetscValidType(mat,1); 689 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 690 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 691 MatCheckPreallocated(mat,1); 692 if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0); 693 PetscCall((*mat->ops->restorerowuppertriangular)(mat)); 694 PetscFunctionReturn(0); 695 } 696 697 /*@C 698 MatSetOptionsPrefix - Sets the prefix used for searching for all 699 Mat options in the database. 700 701 Logically Collective on Mat 702 703 Input Parameters: 704 + A - the Mat context 705 - prefix - the prefix to prepend to all option names 706 707 Notes: 708 A hyphen (-) must NOT be given at the beginning of the prefix name. 709 The first character of all runtime options is AUTOMATICALLY the hyphen. 710 711 This is NOT used for options for the factorization of the matrix. Normally the 712 prefix is automatically passed in from the PC calling the factorization. To set 713 it directly use `MatSetOptionsPrefixFactor()` 714 715 Level: advanced 716 717 .seealso: `MatSetFromOptions()`, `MatSetOptionsPrefixFactor()` 718 @*/ 719 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[]) 720 { 721 PetscFunctionBegin; 722 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 723 PetscCall(PetscObjectSetOptionsPrefix((PetscObject)A,prefix)); 724 PetscFunctionReturn(0); 725 } 726 727 /*@C 728 MatSetOptionsPrefixFactor - Sets the prefix used for searching for all Mat factor options in the database for 729 for matrices created with `MatGetFactor()` 730 731 Logically Collective on Mat 732 733 Input Parameters: 734 + A - the Mat context 735 - prefix - the prefix to prepend to all option names for the factored matrix 736 737 Notes: 738 A hyphen (-) must NOT be given at the beginning of the prefix name. 739 The first character of all runtime options is AUTOMATICALLY the hyphen. 740 741 Normally the prefix is automatically passed in from the PC calling the factorization. To set 742 it directly when not using `KSP`/`PC` use `MatSetOptionsPrefixFactor()` 743 744 Level: developer 745 746 .seealso: `MatSetFromOptions()`, `MatSetOptionsPrefix()`, `MatAppendOptionsPrefixFactor()` 747 @*/ 748 PetscErrorCode MatSetOptionsPrefixFactor(Mat A,const char prefix[]) 749 { 750 PetscFunctionBegin; 751 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 752 if (prefix) { 753 PetscValidCharPointer(prefix,2); 754 PetscCheck(prefix[0] != '-',PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Options prefix should not begin with a hyphen"); 755 if (prefix != A->factorprefix) { 756 PetscCall(PetscFree(A->factorprefix)); 757 PetscCall(PetscStrallocpy(prefix,&A->factorprefix)); 758 } 759 } else PetscCall(PetscFree(A->factorprefix)); 760 PetscFunctionReturn(0); 761 } 762 763 /*@C 764 MatAppendOptionsPrefixFactor - Appends to the prefix used for searching for all Mat factor options in the database for 765 for matrices created with `MatGetFactor()` 766 767 Logically Collective on Mat 768 769 Input Parameters: 770 + A - the Mat context 771 - prefix - the prefix to prepend to all option names for the factored matrix 772 773 Notes: 774 A hyphen (-) must NOT be given at the beginning of the prefix name. 775 The first character of all runtime options is AUTOMATICALLY the hyphen. 776 777 Normally the prefix is automatically passed in from the PC calling the factorization. To set 778 it directly when not using `KSP`/`PC` use `MatAppendOptionsPrefixFactor()` 779 780 Level: developer 781 .seealso: `PetscOptionsCreate()`, `PetscOptionsDestroy()`, `PetscObjectSetOptionsPrefix()`, `PetscObjectPrependOptionsPrefix()`, 782 `PetscObjectGetOptionsPrefix()`, `TSAppendOptionsPrefix()`, `SNESAppendOptionsPrefix()`, `KSPAppendOptionsPrefix()`, `MatSetOptionsPrefixFactor()`, 783 `MatSetOptionsPrefix()` 784 @*/ 785 PetscErrorCode MatAppendOptionsPrefixFactor(Mat A,const char prefix[]) 786 { 787 char *buf = A->factorprefix; 788 size_t len1,len2; 789 790 PetscFunctionBegin; 791 PetscValidHeader(A,1); 792 if (!prefix) PetscFunctionReturn(0); 793 if (!buf) { 794 PetscCall(MatSetOptionsPrefixFactor(A,prefix)); 795 PetscFunctionReturn(0); 796 } 797 PetscCheck(prefix[0] != '-',PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Options prefix should not begin with a hyphen"); 798 799 PetscCall(PetscStrlen(prefix,&len1)); 800 PetscCall(PetscStrlen(buf,&len2)); 801 PetscCall(PetscMalloc1(1+len1+len2,&A->factorprefix)); 802 PetscCall(PetscStrcpy(A->factorprefix,buf)); 803 PetscCall(PetscStrcat(A->factorprefix,prefix)); 804 PetscCall(PetscFree(buf)); 805 PetscFunctionReturn(0); 806 } 807 808 /*@C 809 MatAppendOptionsPrefix - Appends to the prefix used for searching for all 810 Mat options in the database. 811 812 Logically Collective on Mat 813 814 Input Parameters: 815 + A - the Mat context 816 - prefix - the prefix to prepend to all option names 817 818 Notes: 819 A hyphen (-) must NOT be given at the beginning of the prefix name. 820 The first character of all runtime options is AUTOMATICALLY the hyphen. 821 822 Level: advanced 823 824 .seealso: `MatGetOptionsPrefix()` 825 @*/ 826 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[]) 827 { 828 PetscFunctionBegin; 829 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 830 PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)A,prefix)); 831 PetscFunctionReturn(0); 832 } 833 834 /*@C 835 MatGetOptionsPrefix - Gets the prefix used for searching for all 836 Mat options in the database. 837 838 Not Collective 839 840 Input Parameter: 841 . A - the Mat context 842 843 Output Parameter: 844 . prefix - pointer to the prefix string used 845 846 Notes: 847 On the fortran side, the user should pass in a string 'prefix' of 848 sufficient length to hold the prefix. 849 850 Level: advanced 851 852 .seealso: `MatAppendOptionsPrefix()` 853 @*/ 854 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[]) 855 { 856 PetscFunctionBegin; 857 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 858 PetscValidPointer(prefix,2); 859 PetscCall(PetscObjectGetOptionsPrefix((PetscObject)A,prefix)); 860 PetscFunctionReturn(0); 861 } 862 863 /*@ 864 MatResetPreallocation - Reset mat to use the original nonzero pattern provided by users. 865 866 Collective on Mat 867 868 Input Parameters: 869 . A - the Mat context 870 871 Notes: 872 The allocated memory will be shrunk after calling `MatAssemblyBegin()` and `MatAssemblyEnd()` with `MAT_FINAL_ASSEMBLY`. 873 874 Users can reset the preallocation to access the original memory. 875 876 Currently only supported for `MATMPIAIJ` and `MATSEQAIJ` matrices. 877 878 Level: beginner 879 880 .seealso: `MatSeqAIJSetPreallocation()`, `MatMPIAIJSetPreallocation()`, `MatXAIJSetPreallocation()` 881 @*/ 882 PetscErrorCode MatResetPreallocation(Mat A) 883 { 884 PetscFunctionBegin; 885 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 886 PetscValidType(A,1); 887 PetscUseMethod(A,"MatResetPreallocation_C",(Mat),(A)); 888 PetscFunctionReturn(0); 889 } 890 891 /*@ 892 MatSetUp - Sets up the internal matrix data structures for later use. 893 894 Collective on Mat 895 896 Input Parameters: 897 . A - the Mat context 898 899 Notes: 900 If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used. 901 902 If a suitable preallocation routine is used, this function does not need to be called. 903 904 See the Performance chapter of the PETSc users manual for how to preallocate matrices 905 906 Level: beginner 907 908 .seealso: `MatCreate()`, `MatDestroy()` 909 @*/ 910 PetscErrorCode MatSetUp(Mat A) 911 { 912 PetscFunctionBegin; 913 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 914 if (!((PetscObject)A)->type_name) { 915 PetscMPIInt size; 916 917 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)A), &size)); 918 PetscCall(MatSetType(A, size == 1 ? MATSEQAIJ : MATMPIAIJ)); 919 } 920 if (!A->preallocated && A->ops->setup) { 921 PetscCall(PetscInfo(A,"Warning not preallocating matrix storage\n")); 922 PetscCall((*A->ops->setup)(A)); 923 } 924 PetscCall(PetscLayoutSetUp(A->rmap)); 925 PetscCall(PetscLayoutSetUp(A->cmap)); 926 A->preallocated = PETSC_TRUE; 927 PetscFunctionReturn(0); 928 } 929 930 #if defined(PETSC_HAVE_SAWS) 931 #include <petscviewersaws.h> 932 #endif 933 934 /*@C 935 MatViewFromOptions - View from Options 936 937 Collective on Mat 938 939 Input Parameters: 940 + A - the Mat context 941 . obj - Optional object 942 - name - command line option 943 944 Level: intermediate 945 .seealso: `Mat`, `MatView`, `PetscObjectViewFromOptions()`, `MatCreate()` 946 @*/ 947 PetscErrorCode MatViewFromOptions(Mat A,PetscObject obj,const char name[]) 948 { 949 PetscFunctionBegin; 950 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 951 PetscCall(PetscObjectViewFromOptions((PetscObject)A,obj,name)); 952 PetscFunctionReturn(0); 953 } 954 955 /*@C 956 MatView - Visualizes a matrix object. 957 958 Collective on Mat 959 960 Input Parameters: 961 + mat - the matrix 962 - viewer - visualization context 963 964 Notes: 965 The available visualization contexts include 966 + `PETSC_VIEWER_STDOUT_SELF` - for sequential matrices 967 . `PETSC_VIEWER_STDOUT_WORLD` - for parallel matrices created on `PETSC_COMM_WORLD` 968 . `PETSC_VIEWER_STDOUT_`(comm) - for matrices created on MPI communicator comm 969 - `PETSC_VIEWER_DRAW_WORLD` - graphical display of nonzero structure 970 971 The user can open alternative visualization contexts with 972 + `PetscViewerASCIIOpen()` - Outputs matrix to a specified file 973 . `PetscViewerBinaryOpen()` - Outputs matrix in binary to a 974 specified file; corresponding input uses MatLoad() 975 . `PetscViewerDrawOpen()` - Outputs nonzero matrix structure to 976 an X window display 977 - `PetscViewerSocketOpen()` - Outputs matrix to Socket viewer. 978 Currently only the sequential dense and AIJ 979 matrix types support the Socket viewer. 980 981 The user can call `PetscViewerPushFormat()` to specify the output 982 format of ASCII printed objects (when using `PETSC_VIEWER_STDOUT_SELF`, 983 `PETSC_VIEWER_STDOUT_WORLD` and `PetscViewerASCIIOpen()`). Available formats include 984 + `PETSC_VIEWER_DEFAULT` - default, prints matrix contents 985 . `PETSC_VIEWER_ASCII_MATLAB` - prints matrix contents in Matlab format 986 . `PETSC_VIEWER_ASCII_DENSE` - prints entire matrix including zeros 987 . `PETSC_VIEWER_ASCII_COMMON` - prints matrix contents, using a sparse 988 format common among all matrix types 989 . `PETSC_VIEWER_ASCII_IMPL` - prints matrix contents, using an implementation-specific 990 format (which is in many cases the same as the default) 991 . `PETSC_VIEWER_ASCII_INFO` - prints basic information about the matrix 992 size and structure (not the matrix entries) 993 - `PETSC_VIEWER_ASCII_INFO_DETAIL` - prints more detailed information about 994 the matrix structure 995 996 Options Database Keys: 997 + -mat_view ::ascii_info - Prints info on matrix at conclusion of `MatAssemblyEnd()` 998 . -mat_view ::ascii_info_detail - Prints more detailed info 999 . -mat_view - Prints matrix in ASCII format 1000 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 1001 . -mat_view draw - PetscDraws nonzero structure of matrix, using `MatView()` and `PetscDrawOpenX()`. 1002 . -display <name> - Sets display name (default is host) 1003 . -draw_pause <sec> - Sets number of seconds to pause after display 1004 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details) 1005 . -viewer_socket_machine <machine> - 1006 . -viewer_socket_port <port> - 1007 . -mat_view binary - save matrix to file in binary format 1008 - -viewer_binary_filename <name> - 1009 1010 Level: beginner 1011 1012 Notes: 1013 The ASCII viewers are only recommended for small matrices on at most a moderate number of processes, 1014 the program will seemingly hang and take hours for larger matrices, for larger matrices one should use the binary format. 1015 1016 In the debugger you can do "call MatView(mat,0)" to display the matrix. (The same holds for any PETSc object viewer). 1017 1018 See the manual page for `MatLoad()` for the exact format of the binary file when the binary 1019 viewer is used. 1020 1021 See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary 1022 viewer is used and lib/petsc/bin/PetscBinaryIO.py for loading them into Python. 1023 1024 One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure, 1025 and then use the following mouse functions. 1026 .vb 1027 left mouse: zoom in 1028 middle mouse: zoom out 1029 right mouse: continue with the simulation 1030 .ve 1031 1032 .seealso: `PetscViewerPushFormat()`, `PetscViewerASCIIOpen()`, `PetscViewerDrawOpen()`, 1033 `PetscViewerSocketOpen()`, `PetscViewerBinaryOpen()`, `MatLoad()` 1034 @*/ 1035 PetscErrorCode MatView(Mat mat,PetscViewer viewer) 1036 { 1037 PetscInt rows,cols,rbs,cbs; 1038 PetscBool isascii,isstring,issaws; 1039 PetscViewerFormat format; 1040 PetscMPIInt size; 1041 1042 PetscFunctionBegin; 1043 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1044 PetscValidType(mat,1); 1045 if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer)); 1046 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1047 PetscCheckSameComm(mat,1,viewer,2); 1048 MatCheckPreallocated(mat,1); 1049 1050 PetscCall(PetscViewerGetFormat(viewer,&format)); 1051 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 1052 if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0); 1053 1054 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring)); 1055 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii)); 1056 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws)); 1057 if ((!isascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) { 1058 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detail"); 1059 } 1060 1061 PetscCall(PetscLogEventBegin(MAT_View,mat,viewer,0,0)); 1062 if (isascii) { 1063 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix"); 1064 PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer)); 1065 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1066 MatNullSpace nullsp,transnullsp; 1067 1068 PetscCall(PetscViewerASCIIPushTab(viewer)); 1069 PetscCall(MatGetSize(mat,&rows,&cols)); 1070 PetscCall(MatGetBlockSizes(mat,&rbs,&cbs)); 1071 if (rbs != 1 || cbs != 1) { 1072 if (rbs != cbs) PetscCall(PetscViewerASCIIPrintf(viewer,"rows=%" PetscInt_FMT ", cols=%" PetscInt_FMT ", rbs=%" PetscInt_FMT ", cbs=%" PetscInt_FMT "\n",rows,cols,rbs,cbs)); 1073 else PetscCall(PetscViewerASCIIPrintf(viewer,"rows=%" PetscInt_FMT ", cols=%" PetscInt_FMT ", bs=%" PetscInt_FMT "\n",rows,cols,rbs)); 1074 } else PetscCall(PetscViewerASCIIPrintf(viewer,"rows=%" PetscInt_FMT ", cols=%" PetscInt_FMT "\n",rows,cols)); 1075 if (mat->factortype) { 1076 MatSolverType solver; 1077 PetscCall(MatFactorGetSolverType(mat,&solver)); 1078 PetscCall(PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver)); 1079 } 1080 if (mat->ops->getinfo) { 1081 MatInfo info; 1082 PetscCall(MatGetInfo(mat,MAT_GLOBAL_SUM,&info)); 1083 PetscCall(PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated)); 1084 if (!mat->factortype) PetscCall(PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls=%" PetscInt_FMT "\n",(PetscInt)info.mallocs)); 1085 } 1086 PetscCall(MatGetNullSpace(mat,&nullsp)); 1087 PetscCall(MatGetTransposeNullSpace(mat,&transnullsp)); 1088 if (nullsp) PetscCall(PetscViewerASCIIPrintf(viewer," has attached null space\n")); 1089 if (transnullsp && transnullsp != nullsp) PetscCall(PetscViewerASCIIPrintf(viewer," has attached transposed null space\n")); 1090 PetscCall(MatGetNearNullSpace(mat,&nullsp)); 1091 if (nullsp) PetscCall(PetscViewerASCIIPrintf(viewer," has attached near null space\n")); 1092 PetscCall(PetscViewerASCIIPushTab(viewer)); 1093 PetscCall(MatProductView(mat,viewer)); 1094 PetscCall(PetscViewerASCIIPopTab(viewer)); 1095 } 1096 } else if (issaws) { 1097 #if defined(PETSC_HAVE_SAWS) 1098 PetscMPIInt rank; 1099 1100 PetscCall(PetscObjectName((PetscObject)mat)); 1101 PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD,&rank)); 1102 if (!((PetscObject)mat)->amsmem && rank == 0) { 1103 PetscCall(PetscObjectViewSAWs((PetscObject)mat,viewer)); 1104 } 1105 #endif 1106 } else if (isstring) { 1107 const char *type; 1108 PetscCall(MatGetType(mat,&type)); 1109 PetscCall(PetscViewerStringSPrintf(viewer," MatType: %-7.7s",type)); 1110 if (mat->ops->view) PetscCall((*mat->ops->view)(mat,viewer)); 1111 } 1112 if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) { 1113 PetscCall(PetscViewerASCIIPushTab(viewer)); 1114 PetscCall((*mat->ops->viewnative)(mat,viewer)); 1115 PetscCall(PetscViewerASCIIPopTab(viewer)); 1116 } else if (mat->ops->view) { 1117 PetscCall(PetscViewerASCIIPushTab(viewer)); 1118 PetscCall((*mat->ops->view)(mat,viewer)); 1119 PetscCall(PetscViewerASCIIPopTab(viewer)); 1120 } 1121 if (isascii) { 1122 PetscCall(PetscViewerGetFormat(viewer,&format)); 1123 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1124 PetscCall(PetscViewerASCIIPopTab(viewer)); 1125 } 1126 } 1127 PetscCall(PetscLogEventEnd(MAT_View,mat,viewer,0,0)); 1128 PetscFunctionReturn(0); 1129 } 1130 1131 #if defined(PETSC_USE_DEBUG) 1132 #include <../src/sys/totalview/tv_data_display.h> 1133 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat) 1134 { 1135 TV_add_row("Local rows", "int", &mat->rmap->n); 1136 TV_add_row("Local columns", "int", &mat->cmap->n); 1137 TV_add_row("Global rows", "int", &mat->rmap->N); 1138 TV_add_row("Global columns", "int", &mat->cmap->N); 1139 TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name); 1140 return TV_format_OK; 1141 } 1142 #endif 1143 1144 /*@C 1145 MatLoad - Loads a matrix that has been stored in binary/HDF5 format 1146 with `MatView()`. The matrix format is determined from the options database. 1147 Generates a parallel MPI matrix if the communicator has more than one 1148 processor. The default matrix type is AIJ. 1149 1150 Collective on PetscViewer 1151 1152 Input Parameters: 1153 + mat - the newly loaded matrix, this needs to have been created with `MatCreate()` 1154 or some related function before a call to `MatLoad()` 1155 - viewer - binary/HDF5 file viewer 1156 1157 Options Database Keys: 1158 Used with block matrix formats (`MATSEQBAIJ`, ...) to specify 1159 block size 1160 . -matload_block_size <bs> - set block size 1161 1162 Level: beginner 1163 1164 Notes: 1165 If the Mat type has not yet been given then `MATAIJ` is used, call `MatSetFromOptions()` on the 1166 Mat before calling this routine if you wish to set it from the options database. 1167 1168 `MatLoad()` automatically loads into the options database any options 1169 given in the file filename.info where filename is the name of the file 1170 that was passed to the `PetscViewerBinaryOpen()`. The options in the info 1171 file will be ignored if you use the -viewer_binary_skip_info option. 1172 1173 If the type or size of mat is not set before a call to `MatLoad()`, PETSc 1174 sets the default matrix type AIJ and sets the local and global sizes. 1175 If type and/or size is already set, then the same are used. 1176 1177 In parallel, each processor can load a subset of rows (or the 1178 entire matrix). This routine is especially useful when a large 1179 matrix is stored on disk and only part of it is desired on each 1180 processor. For example, a parallel solver may access only some of 1181 the rows from each processor. The algorithm used here reads 1182 relatively small blocks of data rather than reading the entire 1183 matrix and then subsetting it. 1184 1185 Viewer's `PetscViewerType` must be either `PETSCVIEWERBINARY` or `PETSCVIEWERHDF5`. 1186 Such viewer can be created using `PetscViewerBinaryOpen()` or `PetscViewerHDF5Open()`, 1187 or the sequence like 1188 .vb 1189 `PetscViewer` v; 1190 `PetscViewerCreate`(`PETSC_COMM_WORLD`,&v); 1191 `PetscViewerSetType`(v,`PETSCVIEWERBINARY`); 1192 `PetscViewerSetFromOptions`(v); 1193 `PetscViewerFileSetMode`(v,`FILE_MODE_READ`); 1194 `PetscViewerFileSetName`(v,"datafile"); 1195 .ve 1196 The optional `PetscViewerSetFromOptions()` call allows overriding `PetscViewerSetType()` using the option 1197 $ -viewer_type {binary,hdf5} 1198 1199 See the example src/ksp/ksp/tutorials/ex27.c with the first approach, 1200 and src/mat/tutorials/ex10.c with the second approach. 1201 1202 Notes about the PETSc binary format: 1203 In case of `PETSCVIEWERBINARY`, a native PETSc binary format is used. Each of the blocks 1204 is read onto rank 0 and then shipped to its destination rank, one after another. 1205 Multiple objects, both matrices and vectors, can be stored within the same file. 1206 Their PetscObject name is ignored; they are loaded in the order of their storage. 1207 1208 Most users should not need to know the details of the binary storage 1209 format, since `MatLoad()` and `MatView()` completely hide these details. 1210 But for anyone who's interested, the standard binary matrix storage 1211 format is 1212 1213 $ PetscInt MAT_FILE_CLASSID 1214 $ PetscInt number of rows 1215 $ PetscInt number of columns 1216 $ PetscInt total number of nonzeros 1217 $ PetscInt *number nonzeros in each row 1218 $ PetscInt *column indices of all nonzeros (starting index is zero) 1219 $ PetscScalar *values of all nonzeros 1220 1221 PETSc automatically does the byte swapping for 1222 machines that store the bytes reversed, e.g. DEC alpha, freebsd, 1223 Linux, Microsoft Windows and the Intel Paragon; thus if you write your own binary 1224 read/write routines you have to swap the bytes; see `PetscBinaryRead()` 1225 and `PetscBinaryWrite()` to see how this may be done. 1226 1227 Notes about the HDF5 (MATLAB MAT-File Version 7.3) format: 1228 In case of `PETSCVIEWERHDF5`, a parallel HDF5 reader is used. 1229 Each processor's chunk is loaded independently by its owning rank. 1230 Multiple objects, both matrices and vectors, can be stored within the same file. 1231 They are looked up by their PetscObject name. 1232 1233 As the MATLAB MAT-File Version 7.3 format is also a HDF5 flavor, we decided to use 1234 by default the same structure and naming of the AIJ arrays and column count 1235 within the HDF5 file. This means that a MAT file saved with -v7.3 flag, e.g. 1236 $ save example.mat A b -v7.3 1237 can be directly read by this routine (see Reference 1 for details). 1238 Note that depending on your MATLAB version, this format might be a default, 1239 otherwise you can set it as default in Preferences. 1240 1241 Unless -nocompression flag is used to save the file in MATLAB, 1242 PETSc must be configured with ZLIB package. 1243 1244 See also examples src/mat/tutorials/ex10.c and src/ksp/ksp/tutorials/ex27.c 1245 1246 Current HDF5 (MAT-File) limitations: 1247 This reader currently supports only real `MATSEQAIJ`, `MATMPIAIJ`, `MATSEQDENSE` and `MATMPIDENSE` matrices. 1248 1249 Corresponding `MatView()` is not yet implemented. 1250 1251 The loaded matrix is actually a transpose of the original one in MATLAB, 1252 unless you push `PETSC_VIEWER_HDF5_MAT` format (see examples above). 1253 With this format, matrix is automatically transposed by PETSc, 1254 unless the matrix is marked as SPD or symmetric 1255 (see `MatSetOption()`, `MAT_SPD`, `MAT_SYMMETRIC`). 1256 1257 References: 1258 . * - MATLAB(R) Documentation, manual page of save(), https://www.mathworks.com/help/matlab/ref/save.html#btox10b-1-version 1259 1260 .seealso: `PetscViewerBinaryOpen()`, `PetscViewerSetType()`, `MatView()`, `VecLoad()` 1261 1262 @*/ 1263 PetscErrorCode MatLoad(Mat mat,PetscViewer viewer) 1264 { 1265 PetscBool flg; 1266 1267 PetscFunctionBegin; 1268 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1269 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1270 1271 if (!((PetscObject)mat)->type_name) PetscCall(MatSetType(mat,MATAIJ)); 1272 1273 flg = PETSC_FALSE; 1274 PetscCall(PetscOptionsGetBool(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matload_symmetric",&flg,NULL)); 1275 if (flg) { 1276 PetscCall(MatSetOption(mat,MAT_SYMMETRIC,PETSC_TRUE)); 1277 PetscCall(MatSetOption(mat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE)); 1278 } 1279 flg = PETSC_FALSE; 1280 PetscCall(PetscOptionsGetBool(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matload_spd",&flg,NULL)); 1281 if (flg) PetscCall(MatSetOption(mat,MAT_SPD,PETSC_TRUE)); 1282 1283 PetscCheck(mat->ops->load,PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type %s",((PetscObject)mat)->type_name); 1284 PetscCall(PetscLogEventBegin(MAT_Load,mat,viewer,0,0)); 1285 PetscCall((*mat->ops->load)(mat,viewer)); 1286 PetscCall(PetscLogEventEnd(MAT_Load,mat,viewer,0,0)); 1287 PetscFunctionReturn(0); 1288 } 1289 1290 static PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant) 1291 { 1292 Mat_Redundant *redund = *redundant; 1293 1294 PetscFunctionBegin; 1295 if (redund) { 1296 if (redund->matseq) { /* via MatCreateSubMatrices() */ 1297 PetscCall(ISDestroy(&redund->isrow)); 1298 PetscCall(ISDestroy(&redund->iscol)); 1299 PetscCall(MatDestroySubMatrices(1,&redund->matseq)); 1300 } else { 1301 PetscCall(PetscFree2(redund->send_rank,redund->recv_rank)); 1302 PetscCall(PetscFree(redund->sbuf_j)); 1303 PetscCall(PetscFree(redund->sbuf_a)); 1304 for (PetscInt i=0; i<redund->nrecvs; i++) { 1305 PetscCall(PetscFree(redund->rbuf_j[i])); 1306 PetscCall(PetscFree(redund->rbuf_a[i])); 1307 } 1308 PetscCall(PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a)); 1309 } 1310 1311 if (redund->subcomm) PetscCall(PetscCommDestroy(&redund->subcomm)); 1312 PetscCall(PetscFree(redund)); 1313 } 1314 PetscFunctionReturn(0); 1315 } 1316 1317 /*@C 1318 MatDestroy - Frees space taken by a matrix. 1319 1320 Collective on Mat 1321 1322 Input Parameter: 1323 . A - the matrix 1324 1325 Level: beginner 1326 1327 Developer Notes: 1328 Some special arrays of matrices are not destroyed in this routine but instead by the routines called by 1329 `MatDestroySubMatrices()`. Thus one must be sure that any changes here must also be made in those routines. 1330 MatHeaderMerge() and MatHeaderReplace() also manipulate the data in the `Mat` object and likely need changes 1331 if changes are needed here. 1332 @*/ 1333 PetscErrorCode MatDestroy(Mat *A) 1334 { 1335 PetscFunctionBegin; 1336 if (!*A) PetscFunctionReturn(0); 1337 PetscValidHeaderSpecific(*A,MAT_CLASSID,1); 1338 if (--((PetscObject)(*A))->refct > 0) {*A = NULL; PetscFunctionReturn(0);} 1339 1340 /* if memory was published with SAWs then destroy it */ 1341 PetscCall(PetscObjectSAWsViewOff((PetscObject)*A)); 1342 if ((*A)->ops->destroy) PetscCall((*(*A)->ops->destroy)(*A)); 1343 1344 PetscCall(PetscFree((*A)->factorprefix)); 1345 PetscCall(PetscFree((*A)->defaultvectype)); 1346 PetscCall(PetscFree((*A)->bsizes)); 1347 PetscCall(PetscFree((*A)->solvertype)); 1348 for (PetscInt i=0; i<MAT_FACTOR_NUM_TYPES; i++) PetscCall(PetscFree((*A)->preferredordering[i])); 1349 if ((*A)->redundant && (*A)->redundant->matseq[0] == *A) (*A)->redundant->matseq[0] = NULL; 1350 PetscCall(MatDestroy_Redundant(&(*A)->redundant)); 1351 PetscCall(MatProductClear(*A)); 1352 PetscCall(MatNullSpaceDestroy(&(*A)->nullsp)); 1353 PetscCall(MatNullSpaceDestroy(&(*A)->transnullsp)); 1354 PetscCall(MatNullSpaceDestroy(&(*A)->nearnullsp)); 1355 PetscCall(MatDestroy(&(*A)->schur)); 1356 PetscCall(PetscLayoutDestroy(&(*A)->rmap)); 1357 PetscCall(PetscLayoutDestroy(&(*A)->cmap)); 1358 PetscCall(PetscHeaderDestroy(A)); 1359 PetscFunctionReturn(0); 1360 } 1361 1362 /*@C 1363 MatSetValues - Inserts or adds a block of values into a matrix. 1364 These values may be cached, so `MatAssemblyBegin()` and `MatAssemblyEnd()` 1365 MUST be called after all calls to `MatSetValues()` have been completed. 1366 1367 Not Collective 1368 1369 Input Parameters: 1370 + mat - the matrix 1371 . v - a logically two-dimensional array of values 1372 . m, idxm - the number of rows and their global indices 1373 . n, idxn - the number of columns and their global indices 1374 - addv - either `ADD_VALUES` or `INSERT_VALUES`, where 1375 `ADD_VALUES` adds values to any existing entries, and 1376 `INSERT_VALUES` replaces existing entries with new values 1377 1378 Notes: 1379 If you create the matrix yourself (that is not with a call to `DMCreateMatrix()`) then you MUST call MatXXXXSetPreallocation() or 1380 `MatSetUp()` before using this routine 1381 1382 By default the values, v, are row-oriented. See `MatSetOption()` for other options. 1383 1384 Calls to `MatSetValues()` with the `INSERT_VALUES` and `ADD_VALUES` 1385 options cannot be mixed without intervening calls to the assembly 1386 routines. 1387 1388 `MatSetValues()` uses 0-based row and column numbers in Fortran 1389 as well as in C. 1390 1391 Negative indices may be passed in idxm and idxn, these rows and columns are 1392 simply ignored. This allows easily inserting element stiffness matrices 1393 with homogeneous Dirchlet boundary conditions that you don't want represented 1394 in the matrix. 1395 1396 Efficiency Alert: 1397 The routine `MatSetValuesBlocked()` may offer much better efficiency 1398 for users of block sparse formats (`MATSEQBAIJ` and `MATMPIBAIJ`). 1399 1400 Level: beginner 1401 1402 Developer Notes: 1403 This is labeled with C so does not automatically generate Fortran stubs and interfaces 1404 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 1405 1406 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 1407 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES` 1408 @*/ 1409 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1410 { 1411 PetscFunctionBeginHot; 1412 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1413 PetscValidType(mat,1); 1414 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1415 PetscValidIntPointer(idxm,3); 1416 PetscValidIntPointer(idxn,5); 1417 MatCheckPreallocated(mat,1); 1418 1419 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 1420 else PetscCheck(mat->insertmode == addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1421 1422 if (PetscDefined(USE_DEBUG)) { 1423 PetscInt i,j; 1424 1425 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1426 PetscCheck(mat->ops->setvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1427 1428 for (i=0; i<m; i++) { 1429 for (j=0; j<n; j++) { 1430 if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j])) 1431 #if defined(PETSC_USE_COMPLEX) 1432 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]); 1433 #else 1434 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]); 1435 #endif 1436 } 1437 } 1438 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); 1439 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); 1440 } 1441 1442 if (mat->assembled) { 1443 mat->was_assembled = PETSC_TRUE; 1444 mat->assembled = PETSC_FALSE; 1445 } 1446 PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 1447 PetscCall((*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv)); 1448 PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 1449 PetscFunctionReturn(0); 1450 } 1451 1452 /*@C 1453 MatSetValuesIS - Inserts or adds a block of values into a matrix using IS to indicate the rows and columns 1454 These values may be cached, so `MatAssemblyBegin()` and `MatAssemblyEnd()` 1455 MUST be called after all calls to `MatSetValues()` have been completed. 1456 1457 Not Collective 1458 1459 Input Parameters: 1460 + mat - the matrix 1461 . v - a logically two-dimensional array of values 1462 . ism - the rows to provide 1463 . isn - the columns to provide 1464 - addv - either `ADD_VALUES` or `INSERT_VALUES`, where 1465 `ADD_VALUES` adds values to any existing entries, and 1466 `INSERT_VALUES` replaces existing entries with new values 1467 1468 Notes: 1469 If you create the matrix yourself (that is not with a call to `DMCreateMatrix()`) then you MUST call MatXXXXSetPreallocation() or 1470 `MatSetUp()` before using this routine 1471 1472 By default the values, v, are row-oriented. See `MatSetOption()` for other options. 1473 1474 Calls to `MatSetValues()` with the `INSERT_VALUES` and `ADD_VALUES` 1475 options cannot be mixed without intervening calls to the assembly 1476 routines. 1477 1478 MatSetValues() uses 0-based row and column numbers in Fortran 1479 as well as in C. 1480 1481 Negative indices may be passed in ism and isn, these rows and columns are 1482 simply ignored. This allows easily inserting element stiffness matrices 1483 with homogeneous Dirchlet boundary conditions that you don't want represented 1484 in the matrix. 1485 1486 Efficiency Alert: 1487 The routine `MatSetValuesBlocked()` may offer much better efficiency 1488 for users of block sparse formats (`MATSEQBAIJ` and `MATMPIBAIJ`). 1489 1490 Level: beginner 1491 1492 Developer Notes: 1493 This is labeled with C so does not automatically generate Fortran stubs and interfaces 1494 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 1495 1496 This is currently not optimized for any particular IS type 1497 1498 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 1499 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()` 1500 @*/ 1501 PetscErrorCode MatSetValuesIS(Mat mat,IS ism,IS isn,const PetscScalar v[],InsertMode addv) 1502 { 1503 PetscInt m,n; 1504 const PetscInt *rows,*cols; 1505 1506 PetscFunctionBeginHot; 1507 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1508 PetscCall(ISGetIndices(ism,&rows)); 1509 PetscCall(ISGetIndices(isn,&cols)); 1510 PetscCall(ISGetLocalSize(ism,&m)); 1511 PetscCall(ISGetLocalSize(isn,&n)); 1512 PetscCall(MatSetValues(mat,m,rows,n,cols,v,addv)); 1513 PetscCall(ISRestoreIndices(ism,&rows)); 1514 PetscCall(ISRestoreIndices(isn,&cols)); 1515 PetscFunctionReturn(0); 1516 } 1517 1518 /*@ 1519 MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero 1520 values into a matrix 1521 1522 Not Collective 1523 1524 Input Parameters: 1525 + mat - the matrix 1526 . row - the (block) row to set 1527 - v - a logically two-dimensional array of values 1528 1529 Notes: 1530 By the values, v, are column-oriented (for the block version) and sorted 1531 1532 All the nonzeros in the row must be provided 1533 1534 The matrix must have previously had its column indices set 1535 1536 The row must belong to this process 1537 1538 Level: intermediate 1539 1540 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 1541 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()`, `MatSetValuesRow()`, `MatSetLocalToGlobalMapping()` 1542 @*/ 1543 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[]) 1544 { 1545 PetscInt globalrow; 1546 1547 PetscFunctionBegin; 1548 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1549 PetscValidType(mat,1); 1550 PetscValidScalarPointer(v,3); 1551 PetscCall(ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow)); 1552 PetscCall(MatSetValuesRow(mat,globalrow,v)); 1553 PetscFunctionReturn(0); 1554 } 1555 1556 /*@ 1557 MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero 1558 values into a matrix 1559 1560 Not Collective 1561 1562 Input Parameters: 1563 + mat - the matrix 1564 . row - the (block) row to set 1565 - 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 1566 1567 Notes: 1568 The values, v, are column-oriented for the block version. 1569 1570 All the nonzeros in the row must be provided 1571 1572 THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually `MatSetValues()` is used. 1573 1574 The row must belong to this process 1575 1576 Level: advanced 1577 1578 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 1579 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()` 1580 @*/ 1581 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[]) 1582 { 1583 PetscFunctionBeginHot; 1584 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1585 PetscValidType(mat,1); 1586 MatCheckPreallocated(mat,1); 1587 PetscValidScalarPointer(v,3); 1588 PetscCheck(mat->insertmode != ADD_VALUES,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values"); 1589 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1590 mat->insertmode = INSERT_VALUES; 1591 1592 if (mat->assembled) { 1593 mat->was_assembled = PETSC_TRUE; 1594 mat->assembled = PETSC_FALSE; 1595 } 1596 PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 1597 PetscCheck(mat->ops->setvaluesrow,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1598 PetscCall((*mat->ops->setvaluesrow)(mat,row,v)); 1599 PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 1600 PetscFunctionReturn(0); 1601 } 1602 1603 /*@ 1604 MatSetValuesStencil - Inserts or adds a block of values into a matrix. 1605 Using structured grid indexing 1606 1607 Not Collective 1608 1609 Input Parameters: 1610 + mat - the matrix 1611 . m - number of rows being entered 1612 . idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered 1613 . n - number of columns being entered 1614 . idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered 1615 . v - a logically two-dimensional array of values 1616 - addv - either ADD_VALUES or INSERT_VALUES, where 1617 ADD_VALUES adds values to any existing entries, and 1618 INSERT_VALUES replaces existing entries with new values 1619 1620 Notes: 1621 By default the values, v, are row-oriented. See `MatSetOption()` for other options. 1622 1623 Calls to `MatSetValuesStencil()` with the `INSERT_VALUES` and `ADD_VALUES` 1624 options cannot be mixed without intervening calls to the assembly 1625 routines. 1626 1627 The grid coordinates are across the entire grid, not just the local portion 1628 1629 `MatSetValuesStencil()` uses 0-based row and column numbers in Fortran 1630 as well as in C. 1631 1632 For setting/accessing vector values via array coordinates you can use the `DMDAVecGetArray()` routine 1633 1634 In order to use this routine you must either obtain the matrix with `DMCreateMatrix()` 1635 or call `MatSetLocalToGlobalMapping()` and `MatSetStencil()` first. 1636 1637 The columns and rows in the stencil passed in MUST be contained within the 1638 ghost region of the given process as set with DMDACreateXXX() or `MatSetStencil()`. For example, 1639 if you create a `DMDA` with an overlap of one grid level and on a particular process its first 1640 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1641 first i index you can use in your column and row indices in `MatSetStencil()` is 5. 1642 1643 In Fortran idxm and idxn should be declared as 1644 $ MatStencil idxm(4,m),idxn(4,n) 1645 and the values inserted using 1646 $ idxm(MatStencil_i,1) = i 1647 $ idxm(MatStencil_j,1) = j 1648 $ idxm(MatStencil_k,1) = k 1649 $ idxm(MatStencil_c,1) = c 1650 etc 1651 1652 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 1653 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 1654 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 1655 `DM_BOUNDARY_PERIODIC` boundary type. 1656 1657 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 1658 a single value per point) you can skip filling those indices. 1659 1660 Inspired by the structured grid interface to the HYPRE package 1661 (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods) 1662 1663 Efficiency Alert: 1664 The routine `MatSetValuesBlockedStencil()` may offer much better efficiency 1665 for users of block sparse formats (`MATSEQBAIJ` and `MATMPIBAIJ`). 1666 1667 Level: beginner 1668 1669 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()` 1670 `MatSetValues()`, `MatSetValuesBlockedStencil()`, `MatSetStencil()`, `DMCreateMatrix()`, `DMDAVecGetArray()`, `MatStencil` 1671 @*/ 1672 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1673 { 1674 PetscInt buf[8192],*bufm=NULL,*bufn=NULL,*jdxm,*jdxn; 1675 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1676 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1677 1678 PetscFunctionBegin; 1679 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1680 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1681 PetscValidType(mat,1); 1682 PetscValidPointer(idxm,3); 1683 PetscValidPointer(idxn,5); 1684 1685 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1686 jdxm = buf; jdxn = buf+m; 1687 } else { 1688 PetscCall(PetscMalloc2(m,&bufm,n,&bufn)); 1689 jdxm = bufm; jdxn = bufn; 1690 } 1691 for (i=0; i<m; i++) { 1692 for (j=0; j<3-sdim; j++) dxm++; 1693 tmp = *dxm++ - starts[0]; 1694 for (j=0; j<dim-1; j++) { 1695 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1696 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1697 } 1698 if (mat->stencil.noc) dxm++; 1699 jdxm[i] = tmp; 1700 } 1701 for (i=0; i<n; i++) { 1702 for (j=0; j<3-sdim; j++) dxn++; 1703 tmp = *dxn++ - starts[0]; 1704 for (j=0; j<dim-1; j++) { 1705 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1706 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1707 } 1708 if (mat->stencil.noc) dxn++; 1709 jdxn[i] = tmp; 1710 } 1711 PetscCall(MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv)); 1712 PetscCall(PetscFree2(bufm,bufn)); 1713 PetscFunctionReturn(0); 1714 } 1715 1716 /*@ 1717 MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix. 1718 Using structured grid indexing 1719 1720 Not Collective 1721 1722 Input Parameters: 1723 + mat - the matrix 1724 . m - number of rows being entered 1725 . idxm - grid coordinates for matrix rows being entered 1726 . n - number of columns being entered 1727 . idxn - grid coordinates for matrix columns being entered 1728 . v - a logically two-dimensional array of values 1729 - addv - either ADD_VALUES or INSERT_VALUES, where 1730 ADD_VALUES adds values to any existing entries, and 1731 INSERT_VALUES replaces existing entries with new values 1732 1733 Notes: 1734 By default the values, v, are row-oriented and unsorted. 1735 See MatSetOption() for other options. 1736 1737 Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES 1738 options cannot be mixed without intervening calls to the assembly 1739 routines. 1740 1741 The grid coordinates are across the entire grid, not just the local portion 1742 1743 MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran 1744 as well as in C. 1745 1746 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine 1747 1748 In order to use this routine you must either obtain the matrix with DMCreateMatrix() 1749 or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first. 1750 1751 The columns and rows in the stencil passed in MUST be contained within the 1752 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example, 1753 if you create a DMDA with an overlap of one grid level and on a particular process its first 1754 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1755 first i index you can use in your column and row indices in MatSetStencil() is 5. 1756 1757 In Fortran idxm and idxn should be declared as 1758 $ MatStencil idxm(4,m),idxn(4,n) 1759 and the values inserted using 1760 $ idxm(MatStencil_i,1) = i 1761 $ idxm(MatStencil_j,1) = j 1762 $ idxm(MatStencil_k,1) = k 1763 etc 1764 1765 Negative indices may be passed in idxm and idxn, these rows and columns are 1766 simply ignored. This allows easily inserting element stiffness matrices 1767 with homogeneous Dirchlet boundary conditions that you don't want represented 1768 in the matrix. 1769 1770 Inspired by the structured grid interface to the HYPRE package 1771 (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods) 1772 1773 Level: beginner 1774 1775 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()` 1776 `MatSetValues()`, `MatSetValuesStencil()`, `MatSetStencil()`, `DMCreateMatrix()`, `DMDAVecGetArray()`, `MatStencil`, 1777 `MatSetBlockSize()`, `MatSetLocalToGlobalMapping()` 1778 @*/ 1779 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1780 { 1781 PetscInt buf[8192],*bufm=NULL,*bufn=NULL,*jdxm,*jdxn; 1782 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1783 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1784 1785 PetscFunctionBegin; 1786 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1787 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1788 PetscValidType(mat,1); 1789 PetscValidPointer(idxm,3); 1790 PetscValidPointer(idxn,5); 1791 PetscValidScalarPointer(v,6); 1792 1793 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1794 jdxm = buf; jdxn = buf+m; 1795 } else { 1796 PetscCall(PetscMalloc2(m,&bufm,n,&bufn)); 1797 jdxm = bufm; jdxn = bufn; 1798 } 1799 for (i=0; i<m; i++) { 1800 for (j=0; j<3-sdim; j++) dxm++; 1801 tmp = *dxm++ - starts[0]; 1802 for (j=0; j<sdim-1; j++) { 1803 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1804 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1805 } 1806 dxm++; 1807 jdxm[i] = tmp; 1808 } 1809 for (i=0; i<n; i++) { 1810 for (j=0; j<3-sdim; j++) dxn++; 1811 tmp = *dxn++ - starts[0]; 1812 for (j=0; j<sdim-1; j++) { 1813 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1814 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1815 } 1816 dxn++; 1817 jdxn[i] = tmp; 1818 } 1819 PetscCall(MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv)); 1820 PetscCall(PetscFree2(bufm,bufn)); 1821 PetscFunctionReturn(0); 1822 } 1823 1824 /*@ 1825 MatSetStencil - Sets the grid information for setting values into a matrix via 1826 MatSetValuesStencil() 1827 1828 Not Collective 1829 1830 Input Parameters: 1831 + mat - the matrix 1832 . dim - dimension of the grid 1, 2, or 3 1833 . dims - number of grid points in x, y, and z direction, including ghost points on your processor 1834 . starts - starting point of ghost nodes on your processor in x, y, and z direction 1835 - dof - number of degrees of freedom per node 1836 1837 Inspired by the structured grid interface to the HYPRE package 1838 (www.llnl.gov/CASC/hyper) 1839 1840 For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the 1841 user. 1842 1843 Level: beginner 1844 1845 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()` 1846 `MatSetValues()`, `MatSetValuesBlockedStencil()`, `MatSetValuesStencil()` 1847 @*/ 1848 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof) 1849 { 1850 PetscFunctionBegin; 1851 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1852 PetscValidIntPointer(dims,3); 1853 PetscValidIntPointer(starts,4); 1854 1855 mat->stencil.dim = dim + (dof > 1); 1856 for (PetscInt i=0; i<dim; i++) { 1857 mat->stencil.dims[i] = dims[dim-i-1]; /* copy the values in backwards */ 1858 mat->stencil.starts[i] = starts[dim-i-1]; 1859 } 1860 mat->stencil.dims[dim] = dof; 1861 mat->stencil.starts[dim] = 0; 1862 mat->stencil.noc = (PetscBool)(dof == 1); 1863 PetscFunctionReturn(0); 1864 } 1865 1866 /*@C 1867 MatSetValuesBlocked - Inserts or adds a block of values into a matrix. 1868 1869 Not Collective 1870 1871 Input Parameters: 1872 + mat - the matrix 1873 . v - a logically two-dimensional array of values 1874 . m, idxm - the number of block rows and their global block indices 1875 . n, idxn - the number of block columns and their global block indices 1876 - addv - either ADD_VALUES or INSERT_VALUES, where 1877 ADD_VALUES adds values to any existing entries, and 1878 INSERT_VALUES replaces existing entries with new values 1879 1880 Notes: 1881 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call 1882 MatXXXXSetPreallocation() or MatSetUp() before using this routine. 1883 1884 The m and n count the NUMBER of blocks in the row direction and column direction, 1885 NOT the total number of rows/columns; for example, if the block size is 2 and 1886 you are passing in values for rows 2,3,4,5 then m would be 2 (not 4). 1887 The values in idxm would be 1 2; that is the first index for each block divided by 1888 the block size. 1889 1890 Note that you must call MatSetBlockSize() when constructing this matrix (before 1891 preallocating it). 1892 1893 By default the values, v, are row-oriented, so the layout of 1894 v is the same as for MatSetValues(). See MatSetOption() for other options. 1895 1896 Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES 1897 options cannot be mixed without intervening calls to the assembly 1898 routines. 1899 1900 MatSetValuesBlocked() uses 0-based row and column numbers in Fortran 1901 as well as in C. 1902 1903 Negative indices may be passed in idxm and idxn, these rows and columns are 1904 simply ignored. This allows easily inserting element stiffness matrices 1905 with homogeneous Dirchlet boundary conditions that you don't want represented 1906 in the matrix. 1907 1908 Each time an entry is set within a sparse matrix via MatSetValues(), 1909 internal searching must be done to determine where to place the 1910 data in the matrix storage space. By instead inserting blocks of 1911 entries via MatSetValuesBlocked(), the overhead of matrix assembly is 1912 reduced. 1913 1914 Example: 1915 $ Suppose m=n=2 and block size(bs) = 2 The array is 1916 $ 1917 $ 1 2 | 3 4 1918 $ 5 6 | 7 8 1919 $ - - - | - - - 1920 $ 9 10 | 11 12 1921 $ 13 14 | 15 16 1922 $ 1923 $ v[] should be passed in like 1924 $ v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] 1925 $ 1926 $ If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then 1927 $ v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16] 1928 1929 Level: intermediate 1930 1931 .seealso: `MatSetBlockSize()`, `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetValuesBlockedLocal()` 1932 @*/ 1933 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1934 { 1935 PetscFunctionBeginHot; 1936 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1937 PetscValidType(mat,1); 1938 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1939 PetscValidIntPointer(idxm,3); 1940 PetscValidIntPointer(idxn,5); 1941 MatCheckPreallocated(mat,1); 1942 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 1943 else PetscCheck(mat->insertmode == addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1944 if (PetscDefined(USE_DEBUG)) { 1945 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1946 PetscCheck(mat->ops->setvaluesblocked || mat->ops->setvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1947 } 1948 if (PetscDefined(USE_DEBUG)) { 1949 PetscInt rbs,cbs,M,N,i; 1950 PetscCall(MatGetBlockSizes(mat,&rbs,&cbs)); 1951 PetscCall(MatGetSize(mat,&M,&N)); 1952 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); 1953 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); 1954 } 1955 if (mat->assembled) { 1956 mat->was_assembled = PETSC_TRUE; 1957 mat->assembled = PETSC_FALSE; 1958 } 1959 PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 1960 if (mat->ops->setvaluesblocked) { 1961 PetscCall((*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv)); 1962 } else { 1963 PetscInt buf[8192],*bufr=NULL,*bufc=NULL,*iidxm,*iidxn; 1964 PetscInt i,j,bs,cbs; 1965 1966 PetscCall(MatGetBlockSizes(mat,&bs,&cbs)); 1967 if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1968 iidxm = buf; 1969 iidxn = buf + m*bs; 1970 } else { 1971 PetscCall(PetscMalloc2(m*bs,&bufr,n*cbs,&bufc)); 1972 iidxm = bufr; 1973 iidxn = bufc; 1974 } 1975 for (i=0; i<m; i++) { 1976 for (j=0; j<bs; j++) { 1977 iidxm[i*bs+j] = bs*idxm[i] + j; 1978 } 1979 } 1980 if (m != n || bs != cbs || idxm != idxn) { 1981 for (i=0; i<n; i++) { 1982 for (j=0; j<cbs; j++) { 1983 iidxn[i*cbs+j] = cbs*idxn[i] + j; 1984 } 1985 } 1986 } else iidxn = iidxm; 1987 PetscCall(MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv)); 1988 PetscCall(PetscFree2(bufr,bufc)); 1989 } 1990 PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 1991 PetscFunctionReturn(0); 1992 } 1993 1994 /*@C 1995 MatGetValues - Gets a block of values from a matrix. 1996 1997 Not Collective; can only return values that are owned by the give process 1998 1999 Input Parameters: 2000 + mat - the matrix 2001 . v - a logically two-dimensional array for storing the values 2002 . m, idxm - the number of rows and their global indices 2003 - n, idxn - the number of columns and their global indices 2004 2005 Notes: 2006 The user must allocate space (m*n PetscScalars) for the values, v. 2007 The values, v, are then returned in a row-oriented format, 2008 analogous to that used by default in MatSetValues(). 2009 2010 MatGetValues() uses 0-based row and column numbers in 2011 Fortran as well as in C. 2012 2013 MatGetValues() requires that the matrix has been assembled 2014 with MatAssemblyBegin()/MatAssemblyEnd(). Thus, calls to 2015 MatSetValues() and MatGetValues() CANNOT be made in succession 2016 without intermediate matrix assembly. 2017 2018 Negative row or column indices will be ignored and those locations in v[] will be 2019 left unchanged. 2020 2021 For the standard row-based matrix formats, idxm[] can only contain rows owned by the requesting MPI rank. 2022 That is, rows with global index greater than or equal to rstart and less than rend where rstart and rend are obtainable 2023 from MatGetOwnershipRange(mat,&rstart,&rend). 2024 2025 Level: advanced 2026 2027 .seealso: `MatGetRow()`, `MatCreateSubMatrices()`, `MatSetValues()`, `MatGetOwnershipRange()`, `MatGetValuesLocal()`, `MatGetValue()` 2028 @*/ 2029 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[]) 2030 { 2031 PetscFunctionBegin; 2032 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2033 PetscValidType(mat,1); 2034 if (!m || !n) PetscFunctionReturn(0); 2035 PetscValidIntPointer(idxm,3); 2036 PetscValidIntPointer(idxn,5); 2037 PetscValidScalarPointer(v,6); 2038 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2039 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2040 PetscCheck(mat->ops->getvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2041 MatCheckPreallocated(mat,1); 2042 2043 PetscCall(PetscLogEventBegin(MAT_GetValues,mat,0,0,0)); 2044 PetscCall((*mat->ops->getvalues)(mat,m,idxm,n,idxn,v)); 2045 PetscCall(PetscLogEventEnd(MAT_GetValues,mat,0,0,0)); 2046 PetscFunctionReturn(0); 2047 } 2048 2049 /*@C 2050 MatGetValuesLocal - retrieves values from certain locations in a matrix using the local numbering of the indices 2051 defined previously by MatSetLocalToGlobalMapping() 2052 2053 Not Collective 2054 2055 Input Parameters: 2056 + mat - the matrix 2057 . nrow, irow - number of rows and their local indices 2058 - ncol, icol - number of columns and their local indices 2059 2060 Output Parameter: 2061 . y - a logically two-dimensional array of values 2062 2063 Notes: 2064 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine. 2065 2066 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, 2067 are greater than or equal to rstart and less than rend where rstart and rend are obtainable from MatGetOwnershipRange(mat,&rstart,&rend). One can 2068 determine if the resulting global row associated with the local row r is owned by the requesting MPI rank by applying the ISLocalToGlobalMapping set 2069 with MatSetLocalToGlobalMapping(). 2070 2071 Developer Notes: 2072 This is labelled with C so does not automatically generate Fortran stubs and interfaces 2073 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2074 2075 Level: advanced 2076 2077 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetLocalToGlobalMapping()`, 2078 `MatSetValuesLocal()`, `MatGetValues()` 2079 @*/ 2080 PetscErrorCode MatGetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],PetscScalar y[]) 2081 { 2082 PetscFunctionBeginHot; 2083 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2084 PetscValidType(mat,1); 2085 MatCheckPreallocated(mat,1); 2086 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to retrieve */ 2087 PetscValidIntPointer(irow,3); 2088 PetscValidIntPointer(icol,5); 2089 if (PetscDefined(USE_DEBUG)) { 2090 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2091 PetscCheck(mat->ops->getvalueslocal || mat->ops->getvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2092 } 2093 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2094 PetscCall(PetscLogEventBegin(MAT_GetValues,mat,0,0,0)); 2095 if (mat->ops->getvalueslocal) { 2096 PetscCall((*mat->ops->getvalueslocal)(mat,nrow,irow,ncol,icol,y)); 2097 } else { 2098 PetscInt buf[8192],*bufr=NULL,*bufc=NULL,*irowm,*icolm; 2099 if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2100 irowm = buf; icolm = buf+nrow; 2101 } else { 2102 PetscCall(PetscMalloc2(nrow,&bufr,ncol,&bufc)); 2103 irowm = bufr; icolm = bufc; 2104 } 2105 PetscCheck(mat->rmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MatGetValuesLocal() cannot proceed without local-to-global row mapping (See MatSetLocalToGlobalMapping())."); 2106 PetscCheck(mat->cmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MatGetValuesLocal() cannot proceed without local-to-global column mapping (See MatSetLocalToGlobalMapping())."); 2107 PetscCall(ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm)); 2108 PetscCall(ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm)); 2109 PetscCall(MatGetValues(mat,nrow,irowm,ncol,icolm,y)); 2110 PetscCall(PetscFree2(bufr,bufc)); 2111 } 2112 PetscCall(PetscLogEventEnd(MAT_GetValues,mat,0,0,0)); 2113 PetscFunctionReturn(0); 2114 } 2115 2116 /*@ 2117 MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and 2118 the same size. Currently, this can only be called once and creates the given matrix. 2119 2120 Not Collective 2121 2122 Input Parameters: 2123 + mat - the matrix 2124 . nb - the number of blocks 2125 . bs - the number of rows (and columns) in each block 2126 . rows - a concatenation of the rows for each block 2127 - v - a concatenation of logically two-dimensional arrays of values 2128 2129 Notes: 2130 In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix. 2131 2132 Level: advanced 2133 2134 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 2135 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()` 2136 @*/ 2137 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[]) 2138 { 2139 PetscFunctionBegin; 2140 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2141 PetscValidType(mat,1); 2142 PetscValidIntPointer(rows,4); 2143 PetscValidScalarPointer(v,5); 2144 PetscAssert(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2145 2146 PetscCall(PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0)); 2147 if (mat->ops->setvaluesbatch) { 2148 PetscCall((*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v)); 2149 } else { 2150 for (PetscInt b = 0; b < nb; ++b) PetscCall(MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES)); 2151 } 2152 PetscCall(PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0)); 2153 PetscFunctionReturn(0); 2154 } 2155 2156 /*@ 2157 MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by 2158 the routine MatSetValuesLocal() to allow users to insert matrix entries 2159 using a local (per-processor) numbering. 2160 2161 Not Collective 2162 2163 Input Parameters: 2164 + x - the matrix 2165 . rmapping - row mapping created with ISLocalToGlobalMappingCreate() or ISLocalToGlobalMappingCreateIS() 2166 - cmapping - column mapping 2167 2168 Level: intermediate 2169 2170 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetValuesLocal()`, `MatGetValuesLocal()` 2171 @*/ 2172 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 2173 { 2174 PetscFunctionBegin; 2175 PetscValidHeaderSpecific(x,MAT_CLASSID,1); 2176 PetscValidType(x,1); 2177 if (rmapping) PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2); 2178 if (cmapping) PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3); 2179 if (x->ops->setlocaltoglobalmapping) { 2180 PetscCall((*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping)); 2181 } else { 2182 PetscCall(PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping)); 2183 PetscCall(PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping)); 2184 } 2185 PetscFunctionReturn(0); 2186 } 2187 2188 /*@ 2189 MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping() 2190 2191 Not Collective 2192 2193 Input Parameter: 2194 . A - the matrix 2195 2196 Output Parameters: 2197 + rmapping - row mapping 2198 - cmapping - column mapping 2199 2200 Level: advanced 2201 2202 .seealso: `MatSetValuesLocal()` 2203 @*/ 2204 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping) 2205 { 2206 PetscFunctionBegin; 2207 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2208 PetscValidType(A,1); 2209 if (rmapping) { 2210 PetscValidPointer(rmapping,2); 2211 *rmapping = A->rmap->mapping; 2212 } 2213 if (cmapping) { 2214 PetscValidPointer(cmapping,3); 2215 *cmapping = A->cmap->mapping; 2216 } 2217 PetscFunctionReturn(0); 2218 } 2219 2220 /*@ 2221 MatSetLayouts - Sets the PetscLayout objects for rows and columns of a matrix 2222 2223 Logically Collective on A 2224 2225 Input Parameters: 2226 + A - the matrix 2227 . rmap - row layout 2228 - cmap - column layout 2229 2230 Level: advanced 2231 2232 .seealso: `MatCreateVecs()`, `MatGetLocalToGlobalMapping()`, `MatGetLayouts()` 2233 @*/ 2234 PetscErrorCode MatSetLayouts(Mat A,PetscLayout rmap,PetscLayout cmap) 2235 { 2236 PetscFunctionBegin; 2237 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2238 PetscCall(PetscLayoutReference(rmap,&A->rmap)); 2239 PetscCall(PetscLayoutReference(cmap,&A->cmap)); 2240 PetscFunctionReturn(0); 2241 } 2242 2243 /*@ 2244 MatGetLayouts - Gets the PetscLayout objects for rows and columns 2245 2246 Not Collective 2247 2248 Input Parameter: 2249 . A - the matrix 2250 2251 Output Parameters: 2252 + rmap - row layout 2253 - cmap - column layout 2254 2255 Level: advanced 2256 2257 .seealso: `MatCreateVecs()`, `MatGetLocalToGlobalMapping()`, `MatSetLayouts()` 2258 @*/ 2259 PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap) 2260 { 2261 PetscFunctionBegin; 2262 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2263 PetscValidType(A,1); 2264 if (rmap) { 2265 PetscValidPointer(rmap,2); 2266 *rmap = A->rmap; 2267 } 2268 if (cmap) { 2269 PetscValidPointer(cmap,3); 2270 *cmap = A->cmap; 2271 } 2272 PetscFunctionReturn(0); 2273 } 2274 2275 /*@C 2276 MatSetValuesLocal - Inserts or adds values into certain locations of a matrix, 2277 using a local numbering of the nodes. 2278 2279 Not Collective 2280 2281 Input Parameters: 2282 + mat - the matrix 2283 . nrow, irow - number of rows and their local indices 2284 . ncol, icol - number of columns and their local indices 2285 . y - a logically two-dimensional array of values 2286 - addv - either INSERT_VALUES or ADD_VALUES, where 2287 ADD_VALUES adds values to any existing entries, and 2288 INSERT_VALUES replaces existing entries with new values 2289 2290 Notes: 2291 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2292 MatSetUp() before using this routine 2293 2294 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine 2295 2296 Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES 2297 options cannot be mixed without intervening calls to the assembly 2298 routines. 2299 2300 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2301 MUST be called after all calls to MatSetValuesLocal() have been completed. 2302 2303 Level: intermediate 2304 2305 Developer Notes: 2306 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2307 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2308 2309 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetLocalToGlobalMapping()`, 2310 `MatSetValueLocal()`, `MatGetValuesLocal()` 2311 @*/ 2312 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2313 { 2314 PetscFunctionBeginHot; 2315 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2316 PetscValidType(mat,1); 2317 MatCheckPreallocated(mat,1); 2318 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2319 PetscValidIntPointer(irow,3); 2320 PetscValidIntPointer(icol,5); 2321 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 2322 else PetscCheck(mat->insertmode == addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2323 if (PetscDefined(USE_DEBUG)) { 2324 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2325 PetscCheck(mat->ops->setvalueslocal || mat->ops->setvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2326 } 2327 2328 if (mat->assembled) { 2329 mat->was_assembled = PETSC_TRUE; 2330 mat->assembled = PETSC_FALSE; 2331 } 2332 PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 2333 if (mat->ops->setvalueslocal) { 2334 PetscCall((*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv)); 2335 } else { 2336 PetscInt buf[8192],*bufr=NULL,*bufc=NULL; 2337 const PetscInt *irowm,*icolm; 2338 2339 if ((!mat->rmap->mapping && !mat->cmap->mapping) || (nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2340 bufr = buf; 2341 bufc = buf + nrow; 2342 irowm = bufr; 2343 icolm = bufc; 2344 } else { 2345 PetscCall(PetscMalloc2(nrow,&bufr,ncol,&bufc)); 2346 irowm = bufr; 2347 icolm = bufc; 2348 } 2349 if (mat->rmap->mapping) PetscCall(ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,bufr)); 2350 else irowm = irow; 2351 if (mat->cmap->mapping) { 2352 if (mat->cmap->mapping != mat->rmap->mapping || ncol != nrow || icol != irow) { 2353 PetscCall(ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,bufc)); 2354 } else icolm = irowm; 2355 } else icolm = icol; 2356 PetscCall(MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv)); 2357 if (bufr != buf) PetscCall(PetscFree2(bufr,bufc)); 2358 } 2359 PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 2360 PetscFunctionReturn(0); 2361 } 2362 2363 /*@C 2364 MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix, 2365 using a local ordering of the nodes a block at a time. 2366 2367 Not Collective 2368 2369 Input Parameters: 2370 + x - the matrix 2371 . nrow, irow - number of rows and their local indices 2372 . ncol, icol - number of columns and their local indices 2373 . y - a logically two-dimensional array of values 2374 - addv - either INSERT_VALUES or ADD_VALUES, where 2375 ADD_VALUES adds values to any existing entries, and 2376 INSERT_VALUES replaces existing entries with new values 2377 2378 Notes: 2379 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2380 MatSetUp() before using this routine 2381 2382 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping() 2383 before using this routineBefore calling MatSetValuesLocal(), the user must first set the 2384 2385 Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES 2386 options cannot be mixed without intervening calls to the assembly 2387 routines. 2388 2389 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2390 MUST be called after all calls to MatSetValuesBlockedLocal() have been completed. 2391 2392 Level: intermediate 2393 2394 Developer Notes: 2395 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2396 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2397 2398 .seealso: `MatSetBlockSize()`, `MatSetLocalToGlobalMapping()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, 2399 `MatSetValuesLocal()`, `MatSetValuesBlocked()` 2400 @*/ 2401 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2402 { 2403 PetscFunctionBeginHot; 2404 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2405 PetscValidType(mat,1); 2406 MatCheckPreallocated(mat,1); 2407 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2408 PetscValidIntPointer(irow,3); 2409 PetscValidIntPointer(icol,5); 2410 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 2411 else PetscCheck(mat->insertmode == addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2412 if (PetscDefined(USE_DEBUG)) { 2413 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2414 PetscCheck(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); 2415 } 2416 2417 if (mat->assembled) { 2418 mat->was_assembled = PETSC_TRUE; 2419 mat->assembled = PETSC_FALSE; 2420 } 2421 if (PetscUnlikelyDebug(mat->rmap->mapping)) { /* Condition on the mapping existing, because MatSetValuesBlockedLocal_IS does not require it to be set. */ 2422 PetscInt irbs, rbs; 2423 PetscCall(MatGetBlockSizes(mat, &rbs, NULL)); 2424 PetscCall(ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&irbs)); 2425 PetscCheck(rbs == irbs,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different row block sizes! mat %" PetscInt_FMT ", row l2g map %" PetscInt_FMT,rbs,irbs); 2426 } 2427 if (PetscUnlikelyDebug(mat->cmap->mapping)) { 2428 PetscInt icbs, cbs; 2429 PetscCall(MatGetBlockSizes(mat,NULL,&cbs)); 2430 PetscCall(ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&icbs)); 2431 PetscCheck(cbs == icbs,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different col block sizes! mat %" PetscInt_FMT ", col l2g map %" PetscInt_FMT,cbs,icbs); 2432 } 2433 PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 2434 if (mat->ops->setvaluesblockedlocal) { 2435 PetscCall((*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv)); 2436 } else { 2437 PetscInt buf[8192],*bufr=NULL,*bufc=NULL; 2438 const PetscInt *irowm,*icolm; 2439 2440 if ((!mat->rmap->mapping && !mat->cmap->mapping) || (nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2441 bufr = buf; 2442 bufc = buf + nrow; 2443 irowm = bufr; 2444 icolm = bufc; 2445 } else { 2446 PetscCall(PetscMalloc2(nrow,&bufr,ncol,&bufc)); 2447 irowm = bufr; 2448 icolm = bufc; 2449 } 2450 if (mat->rmap->mapping) PetscCall(ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,bufr)); 2451 else irowm = irow; 2452 if (mat->cmap->mapping) { 2453 if (mat->cmap->mapping != mat->rmap->mapping || ncol != nrow || icol != irow) { 2454 PetscCall(ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,bufc)); 2455 } else icolm = irowm; 2456 } else icolm = icol; 2457 PetscCall(MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv)); 2458 if (bufr != buf) PetscCall(PetscFree2(bufr,bufc)); 2459 } 2460 PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 2461 PetscFunctionReturn(0); 2462 } 2463 2464 /*@ 2465 MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal 2466 2467 Collective on Mat 2468 2469 Input Parameters: 2470 + mat - the matrix 2471 - x - the vector to be multiplied 2472 2473 Output Parameters: 2474 . y - the result 2475 2476 Notes: 2477 The vectors x and y cannot be the same. I.e., one cannot 2478 call MatMult(A,y,y). 2479 2480 Level: developer 2481 2482 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 2483 @*/ 2484 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y) 2485 { 2486 PetscFunctionBegin; 2487 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2488 PetscValidType(mat,1); 2489 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2490 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2491 2492 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2493 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2494 PetscCheck(x != y,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2495 MatCheckPreallocated(mat,1); 2496 2497 PetscCheck(mat->ops->multdiagonalblock,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a multiply defined",((PetscObject)mat)->type_name); 2498 PetscCall((*mat->ops->multdiagonalblock)(mat,x,y)); 2499 PetscCall(PetscObjectStateIncrease((PetscObject)y)); 2500 PetscFunctionReturn(0); 2501 } 2502 2503 /* --------------------------------------------------------*/ 2504 /*@ 2505 MatMult - Computes the matrix-vector product, y = Ax. 2506 2507 Neighbor-wise Collective on Mat 2508 2509 Input Parameters: 2510 + mat - the matrix 2511 - x - the vector to be multiplied 2512 2513 Output Parameters: 2514 . y - the result 2515 2516 Notes: 2517 The vectors x and y cannot be the same. I.e., one cannot 2518 call MatMult(A,y,y). 2519 2520 Level: beginner 2521 2522 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 2523 @*/ 2524 PetscErrorCode MatMult(Mat mat,Vec x,Vec y) 2525 { 2526 PetscFunctionBegin; 2527 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2528 PetscValidType(mat,1); 2529 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2530 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2531 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2532 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2533 PetscCheck(x != y,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2534 PetscCheck(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); 2535 PetscCheck(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); 2536 PetscCheck(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); 2537 PetscCheck(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); 2538 PetscCall(VecSetErrorIfLocked(y,3)); 2539 if (mat->erroriffailure) PetscCall(VecValidValues(x,2,PETSC_TRUE)); 2540 MatCheckPreallocated(mat,1); 2541 2542 PetscCall(VecLockReadPush(x)); 2543 PetscCheck(mat->ops->mult,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a multiply defined",((PetscObject)mat)->type_name); 2544 PetscCall(PetscLogEventBegin(MAT_Mult,mat,x,y,0)); 2545 PetscCall((*mat->ops->mult)(mat,x,y)); 2546 PetscCall(PetscLogEventEnd(MAT_Mult,mat,x,y,0)); 2547 if (mat->erroriffailure) PetscCall(VecValidValues(y,3,PETSC_FALSE)); 2548 PetscCall(VecLockReadPop(x)); 2549 PetscFunctionReturn(0); 2550 } 2551 2552 /*@ 2553 MatMultTranspose - Computes matrix transpose times a vector y = A^T * x. 2554 2555 Neighbor-wise Collective on Mat 2556 2557 Input Parameters: 2558 + mat - the matrix 2559 - x - the vector to be multiplied 2560 2561 Output Parameters: 2562 . y - the result 2563 2564 Notes: 2565 The vectors x and y cannot be the same. I.e., one cannot 2566 call MatMultTranspose(A,y,y). 2567 2568 For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple, 2569 use MatMultHermitianTranspose() 2570 2571 Level: beginner 2572 2573 .seealso: `MatMult()`, `MatMultAdd()`, `MatMultTransposeAdd()`, `MatMultHermitianTranspose()`, `MatTranspose()` 2574 @*/ 2575 PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y) 2576 { 2577 PetscErrorCode (*op)(Mat,Vec,Vec) = NULL; 2578 2579 PetscFunctionBegin; 2580 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2581 PetscValidType(mat,1); 2582 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2583 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2584 2585 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2586 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2587 PetscCheck(x != y,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2588 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); 2589 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); 2590 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); 2591 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); 2592 if (mat->erroriffailure) PetscCall(VecValidValues(x,2,PETSC_TRUE)); 2593 MatCheckPreallocated(mat,1); 2594 2595 if (!mat->ops->multtranspose) { 2596 if (mat->symmetric == PETSC_BOOL3_TRUE && mat->ops->mult) op = mat->ops->mult; 2597 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); 2598 } else op = mat->ops->multtranspose; 2599 PetscCall(PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0)); 2600 PetscCall(VecLockReadPush(x)); 2601 PetscCall((*op)(mat,x,y)); 2602 PetscCall(VecLockReadPop(x)); 2603 PetscCall(PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0)); 2604 PetscCall(PetscObjectStateIncrease((PetscObject)y)); 2605 if (mat->erroriffailure) PetscCall(VecValidValues(y,3,PETSC_FALSE)); 2606 PetscFunctionReturn(0); 2607 } 2608 2609 /*@ 2610 MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector. 2611 2612 Neighbor-wise Collective on Mat 2613 2614 Input Parameters: 2615 + mat - the matrix 2616 - x - the vector to be multilplied 2617 2618 Output Parameters: 2619 . y - the result 2620 2621 Notes: 2622 The vectors x and y cannot be the same. I.e., one cannot 2623 call MatMultHermitianTranspose(A,y,y). 2624 2625 Also called the conjugate transpose, complex conjugate transpose, or adjoint. 2626 2627 For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical. 2628 2629 Level: beginner 2630 2631 .seealso: `MatMult()`, `MatMultAdd()`, `MatMultHermitianTransposeAdd()`, `MatMultTranspose()` 2632 @*/ 2633 PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y) 2634 { 2635 PetscFunctionBegin; 2636 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2637 PetscValidType(mat,1); 2638 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2639 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2640 2641 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2642 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2643 PetscCheck(x != y,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2644 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); 2645 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); 2646 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); 2647 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); 2648 MatCheckPreallocated(mat,1); 2649 2650 PetscCall(PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0)); 2651 #if defined(PETSC_USE_COMPLEX) 2652 if (mat->ops->multhermitiantranspose || (mat->hermitian == PETSC_BOOL3_TRUE && mat->ops->mult)) { 2653 PetscCall(VecLockReadPush(x)); 2654 if (mat->ops->multhermitiantranspose) { 2655 PetscCall((*mat->ops->multhermitiantranspose)(mat,x,y)); 2656 } else { 2657 PetscCall((*mat->ops->mult)(mat,x,y)); 2658 } 2659 PetscCall(VecLockReadPop(x)); 2660 } else { 2661 Vec w; 2662 PetscCall(VecDuplicate(x,&w)); 2663 PetscCall(VecCopy(x,w)); 2664 PetscCall(VecConjugate(w)); 2665 PetscCall(MatMultTranspose(mat,w,y)); 2666 PetscCall(VecDestroy(&w)); 2667 PetscCall(VecConjugate(y)); 2668 } 2669 PetscCall(PetscObjectStateIncrease((PetscObject)y)); 2670 #else 2671 PetscCall(MatMultTranspose(mat,x,y)); 2672 #endif 2673 PetscCall(PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0)); 2674 PetscFunctionReturn(0); 2675 } 2676 2677 /*@ 2678 MatMultAdd - Computes v3 = v2 + A * v1. 2679 2680 Neighbor-wise Collective on Mat 2681 2682 Input Parameters: 2683 + mat - the matrix 2684 - v1, v2 - the vectors 2685 2686 Output Parameters: 2687 . v3 - the result 2688 2689 Notes: 2690 The vectors v1 and v3 cannot be the same. I.e., one cannot 2691 call MatMultAdd(A,v1,v2,v1). 2692 2693 Level: beginner 2694 2695 .seealso: `MatMultTranspose()`, `MatMult()`, `MatMultTransposeAdd()` 2696 @*/ 2697 PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2698 { 2699 PetscFunctionBegin; 2700 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2701 PetscValidType(mat,1); 2702 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2703 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2704 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2705 2706 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2707 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2708 PetscCheck(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); 2709 /* PetscCheck(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); 2710 PetscCheck(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); */ 2711 PetscCheck(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); 2712 PetscCheck(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); 2713 PetscCheck(v1 != v3,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2714 MatCheckPreallocated(mat,1); 2715 2716 PetscCheck(mat->ops->multadd,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type %s",((PetscObject)mat)->type_name); 2717 PetscCall(PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3)); 2718 PetscCall(VecLockReadPush(v1)); 2719 PetscCall((*mat->ops->multadd)(mat,v1,v2,v3)); 2720 PetscCall(VecLockReadPop(v1)); 2721 PetscCall(PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3)); 2722 PetscCall(PetscObjectStateIncrease((PetscObject)v3)); 2723 PetscFunctionReturn(0); 2724 } 2725 2726 /*@ 2727 MatMultTransposeAdd - Computes v3 = v2 + A' * v1. 2728 2729 Neighbor-wise Collective on Mat 2730 2731 Input Parameters: 2732 + mat - the matrix 2733 - v1, v2 - the vectors 2734 2735 Output Parameters: 2736 . v3 - the result 2737 2738 Notes: 2739 The vectors v1 and v3 cannot be the same. I.e., one cannot 2740 call MatMultTransposeAdd(A,v1,v2,v1). 2741 2742 Level: beginner 2743 2744 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMult()` 2745 @*/ 2746 PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2747 { 2748 PetscErrorCode (*op)(Mat,Vec,Vec,Vec) = (!mat->ops->multtransposeadd && mat->symmetric) ? mat->ops->multadd : mat->ops->multtransposeadd; 2749 2750 PetscFunctionBegin; 2751 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2752 PetscValidType(mat,1); 2753 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2754 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2755 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2756 2757 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2758 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2759 PetscCheck(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); 2760 PetscCheck(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); 2761 PetscCheck(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); 2762 PetscCheck(v1 != v3,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2763 PetscCheck(op,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2764 MatCheckPreallocated(mat,1); 2765 2766 PetscCall(PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3)); 2767 PetscCall(VecLockReadPush(v1)); 2768 PetscCall((*op)(mat,v1,v2,v3)); 2769 PetscCall(VecLockReadPop(v1)); 2770 PetscCall(PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3)); 2771 PetscCall(PetscObjectStateIncrease((PetscObject)v3)); 2772 PetscFunctionReturn(0); 2773 } 2774 2775 /*@ 2776 MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1. 2777 2778 Neighbor-wise Collective on Mat 2779 2780 Input Parameters: 2781 + mat - the matrix 2782 - v1, v2 - the vectors 2783 2784 Output Parameters: 2785 . v3 - the result 2786 2787 Notes: 2788 The vectors v1 and v3 cannot be the same. I.e., one cannot 2789 call MatMultHermitianTransposeAdd(A,v1,v2,v1). 2790 2791 Level: beginner 2792 2793 .seealso: `MatMultHermitianTranspose()`, `MatMultTranspose()`, `MatMultAdd()`, `MatMult()` 2794 @*/ 2795 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2796 { 2797 PetscFunctionBegin; 2798 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2799 PetscValidType(mat,1); 2800 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2801 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2802 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2803 2804 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2805 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2806 PetscCheck(v1 != v3,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2807 PetscCheck(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); 2808 PetscCheck(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); 2809 PetscCheck(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); 2810 MatCheckPreallocated(mat,1); 2811 2812 PetscCall(PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3)); 2813 PetscCall(VecLockReadPush(v1)); 2814 if (mat->ops->multhermitiantransposeadd) { 2815 PetscCall((*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3)); 2816 } else { 2817 Vec w,z; 2818 PetscCall(VecDuplicate(v1,&w)); 2819 PetscCall(VecCopy(v1,w)); 2820 PetscCall(VecConjugate(w)); 2821 PetscCall(VecDuplicate(v3,&z)); 2822 PetscCall(MatMultTranspose(mat,w,z)); 2823 PetscCall(VecDestroy(&w)); 2824 PetscCall(VecConjugate(z)); 2825 if (v2 != v3) { 2826 PetscCall(VecWAXPY(v3,1.0,v2,z)); 2827 } else { 2828 PetscCall(VecAXPY(v3,1.0,z)); 2829 } 2830 PetscCall(VecDestroy(&z)); 2831 } 2832 PetscCall(VecLockReadPop(v1)); 2833 PetscCall(PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3)); 2834 PetscCall(PetscObjectStateIncrease((PetscObject)v3)); 2835 PetscFunctionReturn(0); 2836 } 2837 2838 /*@C 2839 MatGetFactorType - gets the type of factorization it is 2840 2841 Not Collective 2842 2843 Input Parameters: 2844 . mat - the matrix 2845 2846 Output Parameters: 2847 . t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT 2848 2849 Level: intermediate 2850 2851 .seealso: `MatFactorType`, `MatGetFactor()`, `MatSetFactorType()` 2852 @*/ 2853 PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t) 2854 { 2855 PetscFunctionBegin; 2856 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2857 PetscValidType(mat,1); 2858 PetscValidPointer(t,2); 2859 *t = mat->factortype; 2860 PetscFunctionReturn(0); 2861 } 2862 2863 /*@C 2864 MatSetFactorType - sets the type of factorization it is 2865 2866 Logically Collective on Mat 2867 2868 Input Parameters: 2869 + mat - the matrix 2870 - t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT 2871 2872 Level: intermediate 2873 2874 .seealso: `MatFactorType`, `MatGetFactor()`, `MatGetFactorType()` 2875 @*/ 2876 PetscErrorCode MatSetFactorType(Mat mat, MatFactorType t) 2877 { 2878 PetscFunctionBegin; 2879 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2880 PetscValidType(mat,1); 2881 mat->factortype = t; 2882 PetscFunctionReturn(0); 2883 } 2884 2885 /* ------------------------------------------------------------*/ 2886 /*@C 2887 MatGetInfo - Returns information about matrix storage (number of 2888 nonzeros, memory, etc.). 2889 2890 Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag 2891 2892 Input Parameter: 2893 . mat - the matrix 2894 2895 Output Parameters: 2896 + flag - flag indicating the type of parameters to be returned 2897 (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors, 2898 MAT_GLOBAL_SUM - sum over all processors) 2899 - info - matrix information context 2900 2901 Notes: 2902 The MatInfo context contains a variety of matrix data, including 2903 number of nonzeros allocated and used, number of mallocs during 2904 matrix assembly, etc. Additional information for factored matrices 2905 is provided (such as the fill ratio, number of mallocs during 2906 factorization, etc.). Much of this info is printed to PETSC_STDOUT 2907 when using the runtime options 2908 $ -info -mat_view ::ascii_info 2909 2910 Example for C/C++ Users: 2911 See the file ${PETSC_DIR}/include/petscmat.h for a complete list of 2912 data within the MatInfo context. For example, 2913 .vb 2914 MatInfo info; 2915 Mat A; 2916 double mal, nz_a, nz_u; 2917 2918 MatGetInfo(A,MAT_LOCAL,&info); 2919 mal = info.mallocs; 2920 nz_a = info.nz_allocated; 2921 .ve 2922 2923 Example for Fortran Users: 2924 Fortran users should declare info as a double precision 2925 array of dimension MAT_INFO_SIZE, and then extract the parameters 2926 of interest. See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h 2927 a complete list of parameter names. 2928 .vb 2929 double precision info(MAT_INFO_SIZE) 2930 double precision mal, nz_a 2931 Mat A 2932 integer ierr 2933 2934 call MatGetInfo(A,MAT_LOCAL,info,ierr) 2935 mal = info(MAT_INFO_MALLOCS) 2936 nz_a = info(MAT_INFO_NZ_ALLOCATED) 2937 .ve 2938 2939 Level: intermediate 2940 2941 Developer Note: fortran interface is not autogenerated as the f90 2942 interface definition cannot be generated correctly [due to MatInfo] 2943 2944 .seealso: `MatStashGetInfo()` 2945 2946 @*/ 2947 PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info) 2948 { 2949 PetscFunctionBegin; 2950 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2951 PetscValidType(mat,1); 2952 PetscValidPointer(info,3); 2953 PetscCheck(mat->ops->getinfo,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2954 MatCheckPreallocated(mat,1); 2955 PetscCall((*mat->ops->getinfo)(mat,flag,info)); 2956 PetscFunctionReturn(0); 2957 } 2958 2959 /* 2960 This is used by external packages where it is not easy to get the info from the actual 2961 matrix factorization. 2962 */ 2963 PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info) 2964 { 2965 PetscFunctionBegin; 2966 PetscCall(PetscMemzero(info,sizeof(MatInfo))); 2967 PetscFunctionReturn(0); 2968 } 2969 2970 /* ----------------------------------------------------------*/ 2971 2972 /*@C 2973 MatLUFactor - Performs in-place LU factorization of matrix. 2974 2975 Collective on Mat 2976 2977 Input Parameters: 2978 + mat - the matrix 2979 . row - row permutation 2980 . col - column permutation 2981 - info - options for factorization, includes 2982 $ fill - expected fill as ratio of original fill. 2983 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 2984 $ Run with the option -info to determine an optimal value to use 2985 2986 Notes: 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 This changes the state of the matrix to a factored matrix; it cannot be used 2992 for example with MatSetValues() unless one first calls MatSetUnfactored(). 2993 2994 Level: developer 2995 2996 .seealso: `MatLUFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()`, 2997 `MatGetOrdering()`, `MatSetUnfactored()`, `MatFactorInfo`, `MatGetFactor()` 2998 2999 Developer Note: fortran interface is not autogenerated as the f90 3000 interface definition cannot be generated correctly [due to MatFactorInfo] 3001 3002 @*/ 3003 PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 3004 { 3005 MatFactorInfo tinfo; 3006 3007 PetscFunctionBegin; 3008 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3009 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 3010 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 3011 if (info) PetscValidPointer(info,4); 3012 PetscValidType(mat,1); 3013 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3014 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3015 PetscCheck(mat->ops->lufactor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3016 MatCheckPreallocated(mat,1); 3017 if (!info) { 3018 PetscCall(MatFactorInfoInitialize(&tinfo)); 3019 info = &tinfo; 3020 } 3021 3022 PetscCall(PetscLogEventBegin(MAT_LUFactor,mat,row,col,0)); 3023 PetscCall((*mat->ops->lufactor)(mat,row,col,info)); 3024 PetscCall(PetscLogEventEnd(MAT_LUFactor,mat,row,col,0)); 3025 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 3026 PetscFunctionReturn(0); 3027 } 3028 3029 /*@C 3030 MatILUFactor - Performs in-place ILU factorization of matrix. 3031 3032 Collective on Mat 3033 3034 Input Parameters: 3035 + mat - the matrix 3036 . row - row permutation 3037 . col - column permutation 3038 - info - structure containing 3039 $ levels - number of levels of fill. 3040 $ expected fill - as ratio of original fill. 3041 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 3042 missing diagonal entries) 3043 3044 Notes: 3045 Probably really in-place only when level of fill is zero, otherwise allocates 3046 new space to store factored matrix and deletes previous memory. 3047 3048 Most users should employ the simplified KSP interface for linear solvers 3049 instead of working directly with matrix algebra routines such as this. 3050 See, e.g., KSPCreate(). 3051 3052 Level: developer 3053 3054 .seealso: `MatILUFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()`, `MatFactorInfo` 3055 3056 Developer Note: fortran interface is not autogenerated as the f90 3057 interface definition cannot be generated correctly [due to MatFactorInfo] 3058 3059 @*/ 3060 PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 3061 { 3062 PetscFunctionBegin; 3063 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3064 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 3065 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 3066 PetscValidPointer(info,4); 3067 PetscValidType(mat,1); 3068 PetscCheck(mat->rmap->N == mat->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 3069 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3070 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3071 PetscCheck(mat->ops->ilufactor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3072 MatCheckPreallocated(mat,1); 3073 3074 PetscCall(PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0)); 3075 PetscCall((*mat->ops->ilufactor)(mat,row,col,info)); 3076 PetscCall(PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0)); 3077 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 3078 PetscFunctionReturn(0); 3079 } 3080 3081 /*@C 3082 MatLUFactorSymbolic - Performs symbolic LU factorization of matrix. 3083 Call this routine before calling MatLUFactorNumeric(). 3084 3085 Collective on Mat 3086 3087 Input Parameters: 3088 + fact - the factor matrix obtained with MatGetFactor() 3089 . mat - the matrix 3090 . row, col - row and column permutations 3091 - info - options for factorization, includes 3092 $ fill - expected fill as ratio of original fill. 3093 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3094 $ Run with the option -info to determine an optimal value to use 3095 3096 Notes: 3097 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 3098 3099 Most users should employ the simplified KSP interface for linear solvers 3100 instead of working directly with matrix algebra routines such as this. 3101 See, e.g., KSPCreate(). 3102 3103 Level: developer 3104 3105 .seealso: `MatLUFactor()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()`, `MatFactorInfo`, `MatFactorInfoInitialize()` 3106 3107 Developer Note: fortran interface is not autogenerated as the f90 3108 interface definition cannot be generated correctly [due to MatFactorInfo] 3109 3110 @*/ 3111 PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 3112 { 3113 MatFactorInfo tinfo; 3114 3115 PetscFunctionBegin; 3116 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3117 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,3); 3118 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,4); 3119 if (info) PetscValidPointer(info,5); 3120 PetscValidType(mat,2); 3121 PetscValidPointer(fact,1); 3122 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3123 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3124 if (!(fact)->ops->lufactorsymbolic) { 3125 MatSolverType stype; 3126 PetscCall(MatFactorGetSolverType(fact,&stype)); 3127 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,stype); 3128 } 3129 MatCheckPreallocated(mat,2); 3130 if (!info) { 3131 PetscCall(MatFactorInfoInitialize(&tinfo)); 3132 info = &tinfo; 3133 } 3134 3135 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0)); 3136 PetscCall((fact->ops->lufactorsymbolic)(fact,mat,row,col,info)); 3137 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0)); 3138 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3139 PetscFunctionReturn(0); 3140 } 3141 3142 /*@C 3143 MatLUFactorNumeric - Performs numeric LU factorization of a matrix. 3144 Call this routine after first calling MatLUFactorSymbolic(). 3145 3146 Collective on Mat 3147 3148 Input Parameters: 3149 + fact - the factor matrix obtained with MatGetFactor() 3150 . mat - the matrix 3151 - info - options for factorization 3152 3153 Notes: 3154 See MatLUFactor() for in-place factorization. See 3155 MatCholeskyFactorNumeric() for the symmetric, positive definite case. 3156 3157 Most users should employ the simplified KSP interface for linear solvers 3158 instead of working directly with matrix algebra routines such as this. 3159 See, e.g., KSPCreate(). 3160 3161 Level: developer 3162 3163 .seealso: `MatLUFactorSymbolic()`, `MatLUFactor()`, `MatCholeskyFactor()` 3164 3165 Developer Note: fortran interface is not autogenerated as the f90 3166 interface definition cannot be generated correctly [due to MatFactorInfo] 3167 3168 @*/ 3169 PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3170 { 3171 MatFactorInfo tinfo; 3172 3173 PetscFunctionBegin; 3174 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3175 PetscValidType(mat,2); 3176 PetscValidPointer(fact,1); 3177 PetscValidHeaderSpecific(fact,MAT_CLASSID,1); 3178 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3179 PetscCheck(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); 3180 3181 PetscCheck((fact)->ops->lufactornumeric,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name); 3182 MatCheckPreallocated(mat,2); 3183 if (!info) { 3184 PetscCall(MatFactorInfoInitialize(&tinfo)); 3185 info = &tinfo; 3186 } 3187 3188 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0)); 3189 else PetscCall(PetscLogEventBegin(MAT_LUFactor,mat,fact,0,0)); 3190 PetscCall((fact->ops->lufactornumeric)(fact,mat,info)); 3191 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0)); 3192 else PetscCall(PetscLogEventEnd(MAT_LUFactor,mat,fact,0,0)); 3193 PetscCall(MatViewFromOptions(fact,NULL,"-mat_factor_view")); 3194 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3195 PetscFunctionReturn(0); 3196 } 3197 3198 /*@C 3199 MatCholeskyFactor - Performs in-place Cholesky factorization of a 3200 symmetric matrix. 3201 3202 Collective on Mat 3203 3204 Input Parameters: 3205 + mat - the matrix 3206 . perm - row and column permutations 3207 - f - expected fill as ratio of original fill 3208 3209 Notes: 3210 See MatLUFactor() for the nonsymmetric case. See also 3211 MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric(). 3212 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 Level: developer 3218 3219 .seealso: `MatLUFactor()`, `MatCholeskyFactorSymbolic()`, `MatCholeskyFactorNumeric()` 3220 `MatGetOrdering()` 3221 3222 Developer Note: fortran interface is not autogenerated as the f90 3223 interface definition cannot be generated correctly [due to MatFactorInfo] 3224 3225 @*/ 3226 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info) 3227 { 3228 MatFactorInfo tinfo; 3229 3230 PetscFunctionBegin; 3231 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3232 PetscValidType(mat,1); 3233 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2); 3234 if (info) PetscValidPointer(info,3); 3235 PetscCheck(mat->rmap->N == mat->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square"); 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 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); 3239 MatCheckPreallocated(mat,1); 3240 if (!info) { 3241 PetscCall(MatFactorInfoInitialize(&tinfo)); 3242 info = &tinfo; 3243 } 3244 3245 PetscCall(PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0)); 3246 PetscCall((*mat->ops->choleskyfactor)(mat,perm,info)); 3247 PetscCall(PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0)); 3248 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 3249 PetscFunctionReturn(0); 3250 } 3251 3252 /*@C 3253 MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization 3254 of a symmetric matrix. 3255 3256 Collective on Mat 3257 3258 Input Parameters: 3259 + fact - the factor matrix obtained with MatGetFactor() 3260 . mat - the matrix 3261 . perm - row and column permutations 3262 - info - options for factorization, includes 3263 $ fill - expected fill as ratio of original fill. 3264 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3265 $ Run with the option -info to determine an optimal value to use 3266 3267 Notes: 3268 See MatLUFactorSymbolic() for the nonsymmetric case. See also 3269 MatCholeskyFactor() and MatCholeskyFactorNumeric(). 3270 3271 Most users should employ the simplified KSP interface for linear solvers 3272 instead of working directly with matrix algebra routines such as this. 3273 See, e.g., KSPCreate(). 3274 3275 Level: developer 3276 3277 .seealso: `MatLUFactorSymbolic()`, `MatCholeskyFactor()`, `MatCholeskyFactorNumeric()` 3278 `MatGetOrdering()` 3279 3280 Developer Note: fortran interface is not autogenerated as the f90 3281 interface definition cannot be generated correctly [due to MatFactorInfo] 3282 3283 @*/ 3284 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 3285 { 3286 MatFactorInfo tinfo; 3287 3288 PetscFunctionBegin; 3289 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3290 PetscValidType(mat,2); 3291 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,3); 3292 if (info) PetscValidPointer(info,4); 3293 PetscValidPointer(fact,1); 3294 PetscCheck(mat->rmap->N == mat->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square"); 3295 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3296 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3297 if (!(fact)->ops->choleskyfactorsymbolic) { 3298 MatSolverType stype; 3299 PetscCall(MatFactorGetSolverType(fact,&stype)); 3300 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,stype); 3301 } 3302 MatCheckPreallocated(mat,2); 3303 if (!info) { 3304 PetscCall(MatFactorInfoInitialize(&tinfo)); 3305 info = &tinfo; 3306 } 3307 3308 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0)); 3309 PetscCall((fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info)); 3310 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0)); 3311 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3312 PetscFunctionReturn(0); 3313 } 3314 3315 /*@C 3316 MatCholeskyFactorNumeric - Performs numeric Cholesky factorization 3317 of a symmetric matrix. Call this routine after first calling 3318 MatCholeskyFactorSymbolic(). 3319 3320 Collective on Mat 3321 3322 Input Parameters: 3323 + fact - the factor matrix obtained with MatGetFactor() 3324 . mat - the initial matrix 3325 . info - options for factorization 3326 - fact - the symbolic factor of mat 3327 3328 Notes: 3329 Most users should employ the simplified KSP interface for linear solvers 3330 instead of working directly with matrix algebra routines such as this. 3331 See, e.g., KSPCreate(). 3332 3333 Level: developer 3334 3335 .seealso: `MatCholeskyFactorSymbolic()`, `MatCholeskyFactor()`, `MatLUFactorNumeric()` 3336 3337 Developer Note: fortran interface is not autogenerated as the f90 3338 interface definition cannot be generated correctly [due to MatFactorInfo] 3339 3340 @*/ 3341 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3342 { 3343 MatFactorInfo tinfo; 3344 3345 PetscFunctionBegin; 3346 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3347 PetscValidType(mat,2); 3348 PetscValidPointer(fact,1); 3349 PetscValidHeaderSpecific(fact,MAT_CLASSID,1); 3350 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3351 PetscCheck((fact)->ops->choleskyfactornumeric,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name); 3352 PetscCheck(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); 3353 MatCheckPreallocated(mat,2); 3354 if (!info) { 3355 PetscCall(MatFactorInfoInitialize(&tinfo)); 3356 info = &tinfo; 3357 } 3358 3359 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0)); 3360 else PetscCall(PetscLogEventBegin(MAT_CholeskyFactor,mat,fact,0,0)); 3361 PetscCall((fact->ops->choleskyfactornumeric)(fact,mat,info)); 3362 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0)); 3363 else PetscCall(PetscLogEventEnd(MAT_CholeskyFactor,mat,fact,0,0)); 3364 PetscCall(MatViewFromOptions(fact,NULL,"-mat_factor_view")); 3365 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3366 PetscFunctionReturn(0); 3367 } 3368 3369 /*@ 3370 MatQRFactor - Performs in-place QR factorization of matrix. 3371 3372 Collective on Mat 3373 3374 Input Parameters: 3375 + mat - the matrix 3376 . col - column permutation 3377 - info - options for factorization, includes 3378 $ fill - expected fill as ratio of original fill. 3379 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3380 $ Run with the option -info to determine an optimal value to use 3381 3382 Notes: 3383 Most users should employ the simplified KSP interface for linear solvers 3384 instead of working directly with matrix algebra routines such as this. 3385 See, e.g., KSPCreate(). 3386 3387 This changes the state of the matrix to a factored matrix; it cannot be used 3388 for example with MatSetValues() unless one first calls MatSetUnfactored(). 3389 3390 Level: developer 3391 3392 .seealso: `MatQRFactorSymbolic()`, `MatQRFactorNumeric()`, `MatLUFactor()`, 3393 `MatSetUnfactored()`, `MatFactorInfo`, `MatGetFactor()` 3394 3395 Developer Note: fortran interface is not autogenerated as the f90 3396 interface definition cannot be generated correctly [due to MatFactorInfo] 3397 3398 @*/ 3399 PetscErrorCode MatQRFactor(Mat mat, IS col, const MatFactorInfo *info) 3400 { 3401 PetscFunctionBegin; 3402 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3403 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,2); 3404 if (info) PetscValidPointer(info,3); 3405 PetscValidType(mat,1); 3406 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3407 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3408 MatCheckPreallocated(mat,1); 3409 PetscCall(PetscLogEventBegin(MAT_QRFactor,mat,col,0,0)); 3410 PetscUseMethod(mat,"MatQRFactor_C", (Mat,IS,const MatFactorInfo*), (mat, col, info)); 3411 PetscCall(PetscLogEventEnd(MAT_QRFactor,mat,col,0,0)); 3412 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 3413 PetscFunctionReturn(0); 3414 } 3415 3416 /*@ 3417 MatQRFactorSymbolic - Performs symbolic QR factorization of matrix. 3418 Call this routine before calling MatQRFactorNumeric(). 3419 3420 Collective on Mat 3421 3422 Input Parameters: 3423 + fact - the factor matrix obtained with MatGetFactor() 3424 . mat - the matrix 3425 . col - column permutation 3426 - info - options for factorization, includes 3427 $ fill - expected fill as ratio of original fill. 3428 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3429 $ Run with the option -info to determine an optimal value to use 3430 3431 Most users should employ the simplified KSP interface for linear solvers 3432 instead of working directly with matrix algebra routines such as this. 3433 See, e.g., KSPCreate(). 3434 3435 Level: developer 3436 3437 .seealso: `MatQRFactor()`, `MatQRFactorNumeric()`, `MatLUFactor()`, `MatFactorInfo`, `MatFactorInfoInitialize()` 3438 3439 Developer Note: fortran interface is not autogenerated as the f90 3440 interface definition cannot be generated correctly [due to MatFactorInfo] 3441 3442 @*/ 3443 PetscErrorCode MatQRFactorSymbolic(Mat fact,Mat mat,IS col,const MatFactorInfo *info) 3444 { 3445 MatFactorInfo tinfo; 3446 3447 PetscFunctionBegin; 3448 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3449 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 3450 if (info) PetscValidPointer(info,4); 3451 PetscValidType(mat,2); 3452 PetscValidPointer(fact,1); 3453 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3454 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3455 MatCheckPreallocated(mat,2); 3456 if (!info) { 3457 PetscCall(MatFactorInfoInitialize(&tinfo)); 3458 info = &tinfo; 3459 } 3460 3461 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_QRFactorSymbolic,fact,mat,col,0)); 3462 PetscUseMethod(fact,"MatQRFactorSymbolic_C", (Mat,Mat,IS,const MatFactorInfo*), (fact, mat, col, info)); 3463 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_QRFactorSymbolic,fact,mat,col,0)); 3464 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3465 PetscFunctionReturn(0); 3466 } 3467 3468 /*@ 3469 MatQRFactorNumeric - Performs numeric QR factorization of a matrix. 3470 Call this routine after first calling MatQRFactorSymbolic(). 3471 3472 Collective on Mat 3473 3474 Input Parameters: 3475 + fact - the factor matrix obtained with MatGetFactor() 3476 . mat - the matrix 3477 - info - options for factorization 3478 3479 Notes: 3480 See MatQRFactor() for in-place factorization. 3481 3482 Most users should employ the simplified KSP interface for linear solvers 3483 instead of working directly with matrix algebra routines such as this. 3484 See, e.g., KSPCreate(). 3485 3486 Level: developer 3487 3488 .seealso: `MatQRFactorSymbolic()`, `MatLUFactor()` 3489 3490 Developer Note: fortran interface is not autogenerated as the f90 3491 interface definition cannot be generated correctly [due to MatFactorInfo] 3492 3493 @*/ 3494 PetscErrorCode MatQRFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3495 { 3496 MatFactorInfo tinfo; 3497 3498 PetscFunctionBegin; 3499 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3500 PetscValidType(mat,2); 3501 PetscValidPointer(fact,1); 3502 PetscValidHeaderSpecific(fact,MAT_CLASSID,1); 3503 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3504 PetscCheck(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); 3505 3506 MatCheckPreallocated(mat,2); 3507 if (!info) { 3508 PetscCall(MatFactorInfoInitialize(&tinfo)); 3509 info = &tinfo; 3510 } 3511 3512 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_QRFactorNumeric,mat,fact,0,0)); 3513 else PetscCall(PetscLogEventBegin(MAT_QRFactor,mat,fact,0,0)); 3514 PetscUseMethod(fact,"MatQRFactorNumeric_C", (Mat,Mat,const MatFactorInfo*), (fact, mat, info)); 3515 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_QRFactorNumeric,mat,fact,0,0)); 3516 else PetscCall(PetscLogEventEnd(MAT_QRFactor,mat,fact,0,0)); 3517 PetscCall(MatViewFromOptions(fact,NULL,"-mat_factor_view")); 3518 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3519 PetscFunctionReturn(0); 3520 } 3521 3522 /* ----------------------------------------------------------------*/ 3523 /*@ 3524 MatSolve - Solves A x = b, given a factored matrix. 3525 3526 Neighbor-wise Collective on Mat 3527 3528 Input Parameters: 3529 + mat - the factored matrix 3530 - b - the right-hand-side vector 3531 3532 Output Parameter: 3533 . x - the result vector 3534 3535 Notes: 3536 The vectors b and x cannot be the same. I.e., one cannot 3537 call MatSolve(A,x,x). 3538 3539 Notes: 3540 Most users should employ the simplified KSP interface for linear solvers 3541 instead of working directly with matrix algebra routines such as this. 3542 See, e.g., KSPCreate(). 3543 3544 Level: developer 3545 3546 .seealso: `MatSolveAdd()`, `MatSolveTranspose()`, `MatSolveTransposeAdd()` 3547 @*/ 3548 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x) 3549 { 3550 PetscFunctionBegin; 3551 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3552 PetscValidType(mat,1); 3553 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3554 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3555 PetscCheckSameComm(mat,1,b,2); 3556 PetscCheckSameComm(mat,1,x,3); 3557 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3558 PetscCheck(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); 3559 PetscCheck(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); 3560 PetscCheck(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); 3561 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3562 MatCheckPreallocated(mat,1); 3563 3564 PetscCall(PetscLogEventBegin(MAT_Solve,mat,b,x,0)); 3565 if (mat->factorerrortype) { 3566 PetscCall(PetscInfo(mat,"MatFactorError %d\n",mat->factorerrortype)); 3567 PetscCall(VecSetInf(x)); 3568 } else { 3569 PetscCheck(mat->ops->solve,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3570 PetscCall((*mat->ops->solve)(mat,b,x)); 3571 } 3572 PetscCall(PetscLogEventEnd(MAT_Solve,mat,b,x,0)); 3573 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3574 PetscFunctionReturn(0); 3575 } 3576 3577 static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X,PetscBool trans) 3578 { 3579 Vec b,x; 3580 PetscInt N,i; 3581 PetscErrorCode (*f)(Mat,Vec,Vec); 3582 PetscBool Abound,Bneedconv = PETSC_FALSE,Xneedconv = PETSC_FALSE; 3583 3584 PetscFunctionBegin; 3585 if (A->factorerrortype) { 3586 PetscCall(PetscInfo(A,"MatFactorError %d\n",A->factorerrortype)); 3587 PetscCall(MatSetInf(X)); 3588 PetscFunctionReturn(0); 3589 } 3590 f = (!trans || (!A->ops->solvetranspose && A->symmetric)) ? A->ops->solve : A->ops->solvetranspose; 3591 PetscCheck(f,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 3592 PetscCall(MatBoundToCPU(A,&Abound)); 3593 if (!Abound) { 3594 PetscCall(PetscObjectTypeCompareAny((PetscObject)B,&Bneedconv,MATSEQDENSE,MATMPIDENSE,"")); 3595 PetscCall(PetscObjectTypeCompareAny((PetscObject)X,&Xneedconv,MATSEQDENSE,MATMPIDENSE,"")); 3596 } 3597 if (Bneedconv) { 3598 PetscCall(MatConvert(B,MATDENSECUDA,MAT_INPLACE_MATRIX,&B)); 3599 } 3600 if (Xneedconv) { 3601 PetscCall(MatConvert(X,MATDENSECUDA,MAT_INPLACE_MATRIX,&X)); 3602 } 3603 PetscCall(MatGetSize(B,NULL,&N)); 3604 for (i=0; i<N; i++) { 3605 PetscCall(MatDenseGetColumnVecRead(B,i,&b)); 3606 PetscCall(MatDenseGetColumnVecWrite(X,i,&x)); 3607 PetscCall((*f)(A,b,x)); 3608 PetscCall(MatDenseRestoreColumnVecWrite(X,i,&x)); 3609 PetscCall(MatDenseRestoreColumnVecRead(B,i,&b)); 3610 } 3611 if (Bneedconv) { 3612 PetscCall(MatConvert(B,MATDENSE,MAT_INPLACE_MATRIX,&B)); 3613 } 3614 if (Xneedconv) { 3615 PetscCall(MatConvert(X,MATDENSE,MAT_INPLACE_MATRIX,&X)); 3616 } 3617 PetscFunctionReturn(0); 3618 } 3619 3620 /*@ 3621 MatMatSolve - Solves A X = B, given a factored matrix. 3622 3623 Neighbor-wise Collective on Mat 3624 3625 Input Parameters: 3626 + A - the factored matrix 3627 - B - the right-hand-side matrix MATDENSE (or sparse -- when using MUMPS) 3628 3629 Output Parameter: 3630 . X - the result matrix (dense matrix) 3631 3632 Notes: 3633 If B is a MATDENSE matrix then one can call MatMatSolve(A,B,B) except with MKL_CPARDISO; 3634 otherwise, B and X cannot be the same. 3635 3636 Notes: 3637 Most users should usually employ the simplified KSP interface for linear solvers 3638 instead of working directly with matrix algebra routines such as this. 3639 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3640 at a time. 3641 3642 Level: developer 3643 3644 .seealso: `MatMatSolveTranspose()`, `MatLUFactor()`, `MatCholeskyFactor()` 3645 @*/ 3646 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X) 3647 { 3648 PetscFunctionBegin; 3649 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3650 PetscValidType(A,1); 3651 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3652 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3653 PetscCheckSameComm(A,1,B,2); 3654 PetscCheckSameComm(A,1,X,3); 3655 PetscCheck(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); 3656 PetscCheck(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); 3657 PetscCheck(X->cmap->N == B->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix"); 3658 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3659 PetscCheck(A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3660 MatCheckPreallocated(A,1); 3661 3662 PetscCall(PetscLogEventBegin(MAT_MatSolve,A,B,X,0)); 3663 if (!A->ops->matsolve) { 3664 PetscCall(PetscInfo(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name)); 3665 PetscCall(MatMatSolve_Basic(A,B,X,PETSC_FALSE)); 3666 } else { 3667 PetscCall((*A->ops->matsolve)(A,B,X)); 3668 } 3669 PetscCall(PetscLogEventEnd(MAT_MatSolve,A,B,X,0)); 3670 PetscCall(PetscObjectStateIncrease((PetscObject)X)); 3671 PetscFunctionReturn(0); 3672 } 3673 3674 /*@ 3675 MatMatSolveTranspose - Solves A^T X = B, given a factored matrix. 3676 3677 Neighbor-wise Collective on Mat 3678 3679 Input Parameters: 3680 + A - the factored matrix 3681 - B - the right-hand-side matrix (dense matrix) 3682 3683 Output Parameter: 3684 . X - the result matrix (dense matrix) 3685 3686 Notes: 3687 The matrices B and X cannot be the same. I.e., one cannot 3688 call MatMatSolveTranspose(A,X,X). 3689 3690 Notes: 3691 Most users should usually employ the simplified KSP interface for linear solvers 3692 instead of working directly with matrix algebra routines such as this. 3693 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3694 at a time. 3695 3696 When using SuperLU_Dist or MUMPS as a parallel solver, PETSc will use their functionality to solve multiple right hand sides simultaneously. 3697 3698 Level: developer 3699 3700 .seealso: `MatMatSolve()`, `MatLUFactor()`, `MatCholeskyFactor()` 3701 @*/ 3702 PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X) 3703 { 3704 PetscFunctionBegin; 3705 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3706 PetscValidType(A,1); 3707 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3708 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3709 PetscCheckSameComm(A,1,B,2); 3710 PetscCheckSameComm(A,1,X,3); 3711 PetscCheck(X != B,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3712 PetscCheck(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); 3713 PetscCheck(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); 3714 PetscCheck(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); 3715 PetscCheck(X->cmap->N >= B->cmap->N,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix"); 3716 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3717 PetscCheck(A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3718 MatCheckPreallocated(A,1); 3719 3720 PetscCall(PetscLogEventBegin(MAT_MatSolve,A,B,X,0)); 3721 if (!A->ops->matsolvetranspose) { 3722 PetscCall(PetscInfo(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name)); 3723 PetscCall(MatMatSolve_Basic(A,B,X,PETSC_TRUE)); 3724 } else { 3725 PetscCall((*A->ops->matsolvetranspose)(A,B,X)); 3726 } 3727 PetscCall(PetscLogEventEnd(MAT_MatSolve,A,B,X,0)); 3728 PetscCall(PetscObjectStateIncrease((PetscObject)X)); 3729 PetscFunctionReturn(0); 3730 } 3731 3732 /*@ 3733 MatMatTransposeSolve - Solves A X = B^T, given a factored matrix. 3734 3735 Neighbor-wise Collective on Mat 3736 3737 Input Parameters: 3738 + A - the factored matrix 3739 - Bt - the transpose of right-hand-side matrix 3740 3741 Output Parameter: 3742 . X - the result matrix (dense matrix) 3743 3744 Notes: 3745 Most users should usually 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(). However KSP can only solve for one vector (column of X) 3748 at a time. 3749 3750 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(). 3751 3752 Level: developer 3753 3754 .seealso: `MatMatSolve()`, `MatMatSolveTranspose()`, `MatLUFactor()`, `MatCholeskyFactor()` 3755 @*/ 3756 PetscErrorCode MatMatTransposeSolve(Mat A,Mat Bt,Mat X) 3757 { 3758 PetscFunctionBegin; 3759 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3760 PetscValidType(A,1); 3761 PetscValidHeaderSpecific(Bt,MAT_CLASSID,2); 3762 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3763 PetscCheckSameComm(A,1,Bt,2); 3764 PetscCheckSameComm(A,1,X,3); 3765 3766 PetscCheck(X != Bt,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3767 PetscCheck(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); 3768 PetscCheck(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); 3769 PetscCheck(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"); 3770 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3771 PetscCheck(A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3772 MatCheckPreallocated(A,1); 3773 3774 PetscCheck(A->ops->mattransposesolve,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 3775 PetscCall(PetscLogEventBegin(MAT_MatTrSolve,A,Bt,X,0)); 3776 PetscCall((*A->ops->mattransposesolve)(A,Bt,X)); 3777 PetscCall(PetscLogEventEnd(MAT_MatTrSolve,A,Bt,X,0)); 3778 PetscCall(PetscObjectStateIncrease((PetscObject)X)); 3779 PetscFunctionReturn(0); 3780 } 3781 3782 /*@ 3783 MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or 3784 U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U, 3785 3786 Neighbor-wise Collective on Mat 3787 3788 Input Parameters: 3789 + mat - the factored matrix 3790 - b - the right-hand-side vector 3791 3792 Output Parameter: 3793 . x - the result vector 3794 3795 Notes: 3796 MatSolve() should be used for most applications, as it performs 3797 a forward solve followed by a backward solve. 3798 3799 The vectors b and x cannot be the same, i.e., one cannot 3800 call MatForwardSolve(A,x,x). 3801 3802 For matrix in seqsbaij format with block size larger than 1, 3803 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3804 MatForwardSolve() solves U^T*D y = b, and 3805 MatBackwardSolve() solves U x = y. 3806 Thus they do not provide a symmetric preconditioner. 3807 3808 Most users should employ the simplified KSP interface for linear solvers 3809 instead of working directly with matrix algebra routines such as this. 3810 See, e.g., KSPCreate(). 3811 3812 Level: developer 3813 3814 .seealso: `MatSolve()`, `MatBackwardSolve()` 3815 @*/ 3816 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x) 3817 { 3818 PetscFunctionBegin; 3819 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3820 PetscValidType(mat,1); 3821 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3822 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3823 PetscCheckSameComm(mat,1,b,2); 3824 PetscCheckSameComm(mat,1,x,3); 3825 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3826 PetscCheck(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); 3827 PetscCheck(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); 3828 PetscCheck(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); 3829 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3830 MatCheckPreallocated(mat,1); 3831 3832 PetscCheck(mat->ops->forwardsolve,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3833 PetscCall(PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0)); 3834 PetscCall((*mat->ops->forwardsolve)(mat,b,x)); 3835 PetscCall(PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0)); 3836 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3837 PetscFunctionReturn(0); 3838 } 3839 3840 /*@ 3841 MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU. 3842 D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U, 3843 3844 Neighbor-wise Collective on Mat 3845 3846 Input Parameters: 3847 + mat - the factored matrix 3848 - b - the right-hand-side vector 3849 3850 Output Parameter: 3851 . x - the result vector 3852 3853 Notes: 3854 MatSolve() should be used for most applications, as it performs 3855 a forward solve followed by a backward solve. 3856 3857 The vectors b and x cannot be the same. I.e., one cannot 3858 call MatBackwardSolve(A,x,x). 3859 3860 For matrix in seqsbaij format with block size larger than 1, 3861 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3862 MatForwardSolve() solves U^T*D y = b, and 3863 MatBackwardSolve() solves U x = y. 3864 Thus they do not provide a symmetric preconditioner. 3865 3866 Most users should employ the simplified KSP interface for linear solvers 3867 instead of working directly with matrix algebra routines such as this. 3868 See, e.g., KSPCreate(). 3869 3870 Level: developer 3871 3872 .seealso: `MatSolve()`, `MatForwardSolve()` 3873 @*/ 3874 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x) 3875 { 3876 PetscFunctionBegin; 3877 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3878 PetscValidType(mat,1); 3879 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3880 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3881 PetscCheckSameComm(mat,1,b,2); 3882 PetscCheckSameComm(mat,1,x,3); 3883 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3884 PetscCheck(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); 3885 PetscCheck(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); 3886 PetscCheck(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); 3887 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3888 MatCheckPreallocated(mat,1); 3889 3890 PetscCheck(mat->ops->backwardsolve,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3891 PetscCall(PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0)); 3892 PetscCall((*mat->ops->backwardsolve)(mat,b,x)); 3893 PetscCall(PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0)); 3894 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3895 PetscFunctionReturn(0); 3896 } 3897 3898 /*@ 3899 MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix. 3900 3901 Neighbor-wise Collective on Mat 3902 3903 Input Parameters: 3904 + mat - the factored matrix 3905 . b - the right-hand-side vector 3906 - y - the vector to be added to 3907 3908 Output Parameter: 3909 . x - the result vector 3910 3911 Notes: 3912 The vectors b and x cannot be the same. I.e., one cannot 3913 call MatSolveAdd(A,x,y,x). 3914 3915 Most users should employ the simplified KSP interface for linear solvers 3916 instead of working directly with matrix algebra routines such as this. 3917 See, e.g., KSPCreate(). 3918 3919 Level: developer 3920 3921 .seealso: `MatSolve()`, `MatSolveTranspose()`, `MatSolveTransposeAdd()` 3922 @*/ 3923 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x) 3924 { 3925 PetscScalar one = 1.0; 3926 Vec tmp; 3927 3928 PetscFunctionBegin; 3929 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3930 PetscValidType(mat,1); 3931 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 3932 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3933 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 3934 PetscCheckSameComm(mat,1,b,2); 3935 PetscCheckSameComm(mat,1,y,3); 3936 PetscCheckSameComm(mat,1,x,4); 3937 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3938 PetscCheck(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); 3939 PetscCheck(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); 3940 PetscCheck(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); 3941 PetscCheck(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); 3942 PetscCheck(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); 3943 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3944 MatCheckPreallocated(mat,1); 3945 3946 PetscCall(PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y)); 3947 if (mat->factorerrortype) { 3948 3949 PetscCall(PetscInfo(mat,"MatFactorError %d\n",mat->factorerrortype)); 3950 PetscCall(VecSetInf(x)); 3951 } else if (mat->ops->solveadd) { 3952 PetscCall((*mat->ops->solveadd)(mat,b,y,x)); 3953 } else { 3954 /* do the solve then the add manually */ 3955 if (x != y) { 3956 PetscCall(MatSolve(mat,b,x)); 3957 PetscCall(VecAXPY(x,one,y)); 3958 } else { 3959 PetscCall(VecDuplicate(x,&tmp)); 3960 PetscCall(PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp)); 3961 PetscCall(VecCopy(x,tmp)); 3962 PetscCall(MatSolve(mat,b,x)); 3963 PetscCall(VecAXPY(x,one,tmp)); 3964 PetscCall(VecDestroy(&tmp)); 3965 } 3966 } 3967 PetscCall(PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y)); 3968 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3969 PetscFunctionReturn(0); 3970 } 3971 3972 /*@ 3973 MatSolveTranspose - Solves A' x = b, given a factored matrix. 3974 3975 Neighbor-wise Collective on Mat 3976 3977 Input Parameters: 3978 + mat - the factored matrix 3979 - b - the right-hand-side vector 3980 3981 Output Parameter: 3982 . x - the result vector 3983 3984 Notes: 3985 The vectors b and x cannot be the same. I.e., one cannot 3986 call MatSolveTranspose(A,x,x). 3987 3988 Most users should employ the simplified KSP interface for linear solvers 3989 instead of working directly with matrix algebra routines such as this. 3990 See, e.g., KSPCreate(). 3991 3992 Level: developer 3993 3994 .seealso: `MatSolve()`, `MatSolveAdd()`, `MatSolveTransposeAdd()` 3995 @*/ 3996 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x) 3997 { 3998 PetscErrorCode (*f)(Mat,Vec,Vec) = (!mat->ops->solvetranspose && mat->symmetric) ? mat->ops->solve : mat->ops->solvetranspose; 3999 4000 PetscFunctionBegin; 4001 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4002 PetscValidType(mat,1); 4003 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 4004 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 4005 PetscCheckSameComm(mat,1,b,2); 4006 PetscCheckSameComm(mat,1,x,3); 4007 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 4008 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); 4009 PetscCheck(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); 4010 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 4011 MatCheckPreallocated(mat,1); 4012 PetscCall(PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0)); 4013 if (mat->factorerrortype) { 4014 PetscCall(PetscInfo(mat,"MatFactorError %d\n",mat->factorerrortype)); 4015 PetscCall(VecSetInf(x)); 4016 } else { 4017 PetscCheck(f,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name); 4018 PetscCall((*f)(mat,b,x)); 4019 } 4020 PetscCall(PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0)); 4021 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 4022 PetscFunctionReturn(0); 4023 } 4024 4025 /*@ 4026 MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a 4027 factored matrix. 4028 4029 Neighbor-wise Collective on Mat 4030 4031 Input Parameters: 4032 + mat - the factored matrix 4033 . b - the right-hand-side vector 4034 - y - the vector to be added to 4035 4036 Output Parameter: 4037 . x - the result vector 4038 4039 Notes: 4040 The vectors b and x cannot be the same. I.e., one cannot 4041 call MatSolveTransposeAdd(A,x,y,x). 4042 4043 Most users should employ the simplified KSP interface for linear solvers 4044 instead of working directly with matrix algebra routines such as this. 4045 See, e.g., KSPCreate(). 4046 4047 Level: developer 4048 4049 .seealso: `MatSolve()`, `MatSolveAdd()`, `MatSolveTranspose()` 4050 @*/ 4051 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x) 4052 { 4053 PetscScalar one = 1.0; 4054 Vec tmp; 4055 PetscErrorCode (*f)(Mat,Vec,Vec,Vec) = (!mat->ops->solvetransposeadd && mat->symmetric) ? mat->ops->solveadd : mat->ops->solvetransposeadd; 4056 4057 PetscFunctionBegin; 4058 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4059 PetscValidType(mat,1); 4060 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 4061 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 4062 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 4063 PetscCheckSameComm(mat,1,b,2); 4064 PetscCheckSameComm(mat,1,y,3); 4065 PetscCheckSameComm(mat,1,x,4); 4066 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 4067 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); 4068 PetscCheck(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); 4069 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); 4070 PetscCheck(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); 4071 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 4072 MatCheckPreallocated(mat,1); 4073 4074 PetscCall(PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y)); 4075 if (mat->factorerrortype) { 4076 PetscCall(PetscInfo(mat,"MatFactorError %d\n",mat->factorerrortype)); 4077 PetscCall(VecSetInf(x)); 4078 } else if (f) { 4079 PetscCall((*f)(mat,b,y,x)); 4080 } else { 4081 /* do the solve then the add manually */ 4082 if (x != y) { 4083 PetscCall(MatSolveTranspose(mat,b,x)); 4084 PetscCall(VecAXPY(x,one,y)); 4085 } else { 4086 PetscCall(VecDuplicate(x,&tmp)); 4087 PetscCall(PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp)); 4088 PetscCall(VecCopy(x,tmp)); 4089 PetscCall(MatSolveTranspose(mat,b,x)); 4090 PetscCall(VecAXPY(x,one,tmp)); 4091 PetscCall(VecDestroy(&tmp)); 4092 } 4093 } 4094 PetscCall(PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y)); 4095 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 4096 PetscFunctionReturn(0); 4097 } 4098 /* ----------------------------------------------------------------*/ 4099 4100 /*@ 4101 MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps. 4102 4103 Neighbor-wise Collective on Mat 4104 4105 Input Parameters: 4106 + mat - the matrix 4107 . b - the right hand side 4108 . omega - the relaxation factor 4109 . flag - flag indicating the type of SOR (see below) 4110 . shift - diagonal shift 4111 . its - the number of iterations 4112 - lits - the number of local iterations 4113 4114 Output Parameter: 4115 . x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess) 4116 4117 SOR Flags: 4118 + SOR_FORWARD_SWEEP - forward SOR 4119 . SOR_BACKWARD_SWEEP - backward SOR 4120 . SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR) 4121 . SOR_LOCAL_FORWARD_SWEEP - local forward SOR 4122 . SOR_LOCAL_BACKWARD_SWEEP - local forward SOR 4123 . SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR 4124 . SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies 4125 upper/lower triangular part of matrix to 4126 vector (with omega) 4127 - SOR_ZERO_INITIAL_GUESS - zero initial guess 4128 4129 Notes: 4130 SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and 4131 SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings 4132 on each processor. 4133 4134 Application programmers will not generally use MatSOR() directly, 4135 but instead will employ the KSP/PC interface. 4136 4137 Notes: 4138 for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing 4139 4140 Notes for Advanced Users: 4141 The flags are implemented as bitwise inclusive or operations. 4142 For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP) 4143 to specify a zero initial guess for SSOR. 4144 4145 Most users should employ the simplified KSP interface for linear solvers 4146 instead of working directly with matrix algebra routines such as this. 4147 See, e.g., KSPCreate(). 4148 4149 Vectors x and b CANNOT be the same 4150 4151 Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes 4152 4153 Level: developer 4154 4155 @*/ 4156 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x) 4157 { 4158 PetscFunctionBegin; 4159 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4160 PetscValidType(mat,1); 4161 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 4162 PetscValidHeaderSpecific(x,VEC_CLASSID,8); 4163 PetscCheckSameComm(mat,1,b,2); 4164 PetscCheckSameComm(mat,1,x,8); 4165 PetscCheck(mat->ops->sor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4166 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4167 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4168 PetscCheck(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); 4169 PetscCheck(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); 4170 PetscCheck(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); 4171 PetscCheck(its > 0,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %" PetscInt_FMT " positive",its); 4172 PetscCheck(lits > 0,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %" PetscInt_FMT " positive",lits); 4173 PetscCheck(b != x,PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same"); 4174 4175 MatCheckPreallocated(mat,1); 4176 PetscCall(PetscLogEventBegin(MAT_SOR,mat,b,x,0)); 4177 PetscCall((*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x)); 4178 PetscCall(PetscLogEventEnd(MAT_SOR,mat,b,x,0)); 4179 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 4180 PetscFunctionReturn(0); 4181 } 4182 4183 /* 4184 Default matrix copy routine. 4185 */ 4186 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str) 4187 { 4188 PetscInt i,rstart = 0,rend = 0,nz; 4189 const PetscInt *cwork; 4190 const PetscScalar *vwork; 4191 4192 PetscFunctionBegin; 4193 if (B->assembled) PetscCall(MatZeroEntries(B)); 4194 if (str == SAME_NONZERO_PATTERN) { 4195 PetscCall(MatGetOwnershipRange(A,&rstart,&rend)); 4196 for (i=rstart; i<rend; i++) { 4197 PetscCall(MatGetRow(A,i,&nz,&cwork,&vwork)); 4198 PetscCall(MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES)); 4199 PetscCall(MatRestoreRow(A,i,&nz,&cwork,&vwork)); 4200 } 4201 } else { 4202 PetscCall(MatAYPX(B,0.0,A,str)); 4203 } 4204 PetscCall(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY)); 4205 PetscCall(MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY)); 4206 PetscFunctionReturn(0); 4207 } 4208 4209 /*@ 4210 MatCopy - Copies a matrix to another matrix. 4211 4212 Collective on Mat 4213 4214 Input Parameters: 4215 + A - the matrix 4216 - str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN 4217 4218 Output Parameter: 4219 . B - where the copy is put 4220 4221 Notes: 4222 If you use SAME_NONZERO_PATTERN then the two matrices must have the same nonzero pattern or the routine will crash. 4223 4224 MatCopy() copies the matrix entries of a matrix to another existing 4225 matrix (after first zeroing the second matrix). A related routine is 4226 MatConvert(), which first creates a new matrix and then copies the data. 4227 4228 Level: intermediate 4229 4230 .seealso: `MatConvert()`, `MatDuplicate()` 4231 @*/ 4232 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str) 4233 { 4234 PetscInt i; 4235 4236 PetscFunctionBegin; 4237 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4238 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4239 PetscValidType(A,1); 4240 PetscValidType(B,2); 4241 PetscCheckSameComm(A,1,B,2); 4242 MatCheckPreallocated(B,2); 4243 PetscCheck(A->assembled,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4244 PetscCheck(!A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4245 PetscCheck(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); 4246 MatCheckPreallocated(A,1); 4247 if (A == B) PetscFunctionReturn(0); 4248 4249 PetscCall(PetscLogEventBegin(MAT_Copy,A,B,0,0)); 4250 if (A->ops->copy) { 4251 PetscCall((*A->ops->copy)(A,B,str)); 4252 } else { /* generic conversion */ 4253 PetscCall(MatCopy_Basic(A,B,str)); 4254 } 4255 4256 B->stencil.dim = A->stencil.dim; 4257 B->stencil.noc = A->stencil.noc; 4258 for (i=0; i<=A->stencil.dim; i++) { 4259 B->stencil.dims[i] = A->stencil.dims[i]; 4260 B->stencil.starts[i] = A->stencil.starts[i]; 4261 } 4262 4263 PetscCall(PetscLogEventEnd(MAT_Copy,A,B,0,0)); 4264 PetscCall(PetscObjectStateIncrease((PetscObject)B)); 4265 PetscFunctionReturn(0); 4266 } 4267 4268 /*@C 4269 MatConvert - Converts a matrix to another matrix, either of the same 4270 or different type. 4271 4272 Collective on Mat 4273 4274 Input Parameters: 4275 + mat - the matrix 4276 . newtype - new matrix type. Use MATSAME to create a new matrix of the 4277 same type as the original matrix. 4278 - reuse - denotes if the destination matrix is to be created or reused. 4279 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 4280 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). 4281 4282 Output Parameter: 4283 . M - pointer to place new matrix 4284 4285 Notes: 4286 MatConvert() first creates a new matrix and then copies the data from 4287 the first matrix. A related routine is MatCopy(), which copies the matrix 4288 entries of one matrix to another already existing matrix context. 4289 4290 Cannot be used to convert a sequential matrix to parallel or parallel to sequential, 4291 the MPI communicator of the generated matrix is always the same as the communicator 4292 of the input matrix. 4293 4294 Level: intermediate 4295 4296 .seealso: `MatCopy()`, `MatDuplicate()` 4297 @*/ 4298 PetscErrorCode MatConvert(Mat mat,MatType newtype,MatReuse reuse,Mat *M) 4299 { 4300 PetscBool sametype,issame,flg; 4301 PetscBool3 issymmetric,ishermitian; 4302 char convname[256],mtype[256]; 4303 Mat B; 4304 4305 PetscFunctionBegin; 4306 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4307 PetscValidType(mat,1); 4308 PetscValidPointer(M,4); 4309 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4310 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4311 MatCheckPreallocated(mat,1); 4312 4313 PetscCall(PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,sizeof(mtype),&flg)); 4314 if (flg) newtype = mtype; 4315 4316 PetscCall(PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype)); 4317 PetscCall(PetscStrcmp(newtype,"same",&issame)); 4318 PetscCheck(!(reuse == MAT_INPLACE_MATRIX) || !(mat != *M),PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix"); 4319 PetscCheck(!(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"); 4320 4321 if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) { 4322 PetscCall(PetscInfo(mat,"Early return for inplace %s %d %d\n",((PetscObject)mat)->type_name,sametype,issame)); 4323 PetscFunctionReturn(0); 4324 } 4325 4326 /* Cache Mat options because some converters use MatHeaderReplace */ 4327 issymmetric = mat->symmetric; 4328 ishermitian = mat->hermitian; 4329 4330 if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) { 4331 PetscCall(PetscInfo(mat,"Calling duplicate for initial matrix %s %d %d\n",((PetscObject)mat)->type_name,sametype,issame)); 4332 PetscCall((*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M)); 4333 } else { 4334 PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL; 4335 const char *prefix[3] = {"seq","mpi",""}; 4336 PetscInt i; 4337 /* 4338 Order of precedence: 4339 0) See if newtype is a superclass of the current matrix. 4340 1) See if a specialized converter is known to the current matrix. 4341 2) See if a specialized converter is known to the desired matrix class. 4342 3) See if a good general converter is registered for the desired class 4343 (as of 6/27/03 only MATMPIADJ falls into this category). 4344 4) See if a good general converter is known for the current matrix. 4345 5) Use a really basic converter. 4346 */ 4347 4348 /* 0) See if newtype is a superclass of the current matrix. 4349 i.e mat is mpiaij and newtype is aij */ 4350 for (i=0; i<2; i++) { 4351 PetscCall(PetscStrncpy(convname,prefix[i],sizeof(convname))); 4352 PetscCall(PetscStrlcat(convname,newtype,sizeof(convname))); 4353 PetscCall(PetscStrcmp(convname,((PetscObject)mat)->type_name,&flg)); 4354 PetscCall(PetscInfo(mat,"Check superclass %s %s -> %d\n",convname,((PetscObject)mat)->type_name,flg)); 4355 if (flg) { 4356 if (reuse == MAT_INPLACE_MATRIX) { 4357 PetscCall(PetscInfo(mat,"Early return\n")); 4358 PetscFunctionReturn(0); 4359 } else if (reuse == MAT_INITIAL_MATRIX && mat->ops->duplicate) { 4360 PetscCall(PetscInfo(mat,"Calling MatDuplicate\n")); 4361 PetscCall((*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M)); 4362 PetscFunctionReturn(0); 4363 } else if (reuse == MAT_REUSE_MATRIX && mat->ops->copy) { 4364 PetscCall(PetscInfo(mat,"Calling MatCopy\n")); 4365 PetscCall(MatCopy(mat,*M,SAME_NONZERO_PATTERN)); 4366 PetscFunctionReturn(0); 4367 } 4368 } 4369 } 4370 /* 1) See if a specialized converter is known to the current matrix and the desired class */ 4371 for (i=0; i<3; i++) { 4372 PetscCall(PetscStrncpy(convname,"MatConvert_",sizeof(convname))); 4373 PetscCall(PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname))); 4374 PetscCall(PetscStrlcat(convname,"_",sizeof(convname))); 4375 PetscCall(PetscStrlcat(convname,prefix[i],sizeof(convname))); 4376 PetscCall(PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname))); 4377 PetscCall(PetscStrlcat(convname,"_C",sizeof(convname))); 4378 PetscCall(PetscObjectQueryFunction((PetscObject)mat,convname,&conv)); 4379 PetscCall(PetscInfo(mat,"Check specialized (1) %s (%s) -> %d\n",convname,((PetscObject)mat)->type_name,!!conv)); 4380 if (conv) goto foundconv; 4381 } 4382 4383 /* 2) See if a specialized converter is known to the desired matrix class. */ 4384 PetscCall(MatCreate(PetscObjectComm((PetscObject)mat),&B)); 4385 PetscCall(MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N)); 4386 PetscCall(MatSetType(B,newtype)); 4387 for (i=0; i<3; i++) { 4388 PetscCall(PetscStrncpy(convname,"MatConvert_",sizeof(convname))); 4389 PetscCall(PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname))); 4390 PetscCall(PetscStrlcat(convname,"_",sizeof(convname))); 4391 PetscCall(PetscStrlcat(convname,prefix[i],sizeof(convname))); 4392 PetscCall(PetscStrlcat(convname,newtype,sizeof(convname))); 4393 PetscCall(PetscStrlcat(convname,"_C",sizeof(convname))); 4394 PetscCall(PetscObjectQueryFunction((PetscObject)B,convname,&conv)); 4395 PetscCall(PetscInfo(mat,"Check specialized (2) %s (%s) -> %d\n",convname,((PetscObject)B)->type_name,!!conv)); 4396 if (conv) { 4397 PetscCall(MatDestroy(&B)); 4398 goto foundconv; 4399 } 4400 } 4401 4402 /* 3) See if a good general converter is registered for the desired class */ 4403 conv = B->ops->convertfrom; 4404 PetscCall(PetscInfo(mat,"Check convertfrom (%s) -> %d\n",((PetscObject)B)->type_name,!!conv)); 4405 PetscCall(MatDestroy(&B)); 4406 if (conv) goto foundconv; 4407 4408 /* 4) See if a good general converter is known for the current matrix */ 4409 if (mat->ops->convert) conv = mat->ops->convert; 4410 PetscCall(PetscInfo(mat,"Check general convert (%s) -> %d\n",((PetscObject)mat)->type_name,!!conv)); 4411 if (conv) goto foundconv; 4412 4413 /* 5) Use a really basic converter. */ 4414 PetscCall(PetscInfo(mat,"Using MatConvert_Basic\n")); 4415 conv = MatConvert_Basic; 4416 4417 foundconv: 4418 PetscCall(PetscLogEventBegin(MAT_Convert,mat,0,0,0)); 4419 PetscCall((*conv)(mat,newtype,reuse,M)); 4420 if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) { 4421 /* the block sizes must be same if the mappings are copied over */ 4422 (*M)->rmap->bs = mat->rmap->bs; 4423 (*M)->cmap->bs = mat->cmap->bs; 4424 PetscCall(PetscObjectReference((PetscObject)mat->rmap->mapping)); 4425 PetscCall(PetscObjectReference((PetscObject)mat->cmap->mapping)); 4426 (*M)->rmap->mapping = mat->rmap->mapping; 4427 (*M)->cmap->mapping = mat->cmap->mapping; 4428 } 4429 (*M)->stencil.dim = mat->stencil.dim; 4430 (*M)->stencil.noc = mat->stencil.noc; 4431 for (i=0; i<=mat->stencil.dim; i++) { 4432 (*M)->stencil.dims[i] = mat->stencil.dims[i]; 4433 (*M)->stencil.starts[i] = mat->stencil.starts[i]; 4434 } 4435 PetscCall(PetscLogEventEnd(MAT_Convert,mat,0,0,0)); 4436 } 4437 PetscCall(PetscObjectStateIncrease((PetscObject)*M)); 4438 4439 /* Copy Mat options */ 4440 if (issymmetric == PETSC_BOOL3_TRUE) PetscCall(MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE)); 4441 else if (issymmetric == PETSC_BOOL3_FALSE) PetscCall(MatSetOption(*M,MAT_SYMMETRIC,PETSC_FALSE)); 4442 if (ishermitian == PETSC_BOOL3_TRUE) PetscCall(MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE)); 4443 else if (ishermitian == PETSC_BOOL3_FALSE) PetscCall(MatSetOption(*M,MAT_HERMITIAN,PETSC_FALSE)); 4444 PetscFunctionReturn(0); 4445 } 4446 4447 /*@C 4448 MatFactorGetSolverType - Returns name of the package providing the factorization routines 4449 4450 Not Collective 4451 4452 Input Parameter: 4453 . mat - the matrix, must be a factored matrix 4454 4455 Output Parameter: 4456 . type - the string name of the package (do not free this string) 4457 4458 Notes: 4459 In Fortran you pass in a empty string and the package name will be copied into it. 4460 (Make sure the string is long enough) 4461 4462 Level: intermediate 4463 4464 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()` 4465 @*/ 4466 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type) 4467 { 4468 PetscErrorCode (*conv)(Mat,MatSolverType*); 4469 4470 PetscFunctionBegin; 4471 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4472 PetscValidType(mat,1); 4473 PetscValidPointer(type,2); 4474 PetscCheck(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 4475 PetscCall(PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv)); 4476 if (conv) PetscCall((*conv)(mat,type)); 4477 else *type = MATSOLVERPETSC; 4478 PetscFunctionReturn(0); 4479 } 4480 4481 typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType; 4482 struct _MatSolverTypeForSpecifcType { 4483 MatType mtype; 4484 /* no entry for MAT_FACTOR_NONE */ 4485 PetscErrorCode (*createfactor[MAT_FACTOR_NUM_TYPES-1])(Mat,MatFactorType,Mat*); 4486 MatSolverTypeForSpecifcType next; 4487 }; 4488 4489 typedef struct _MatSolverTypeHolder* MatSolverTypeHolder; 4490 struct _MatSolverTypeHolder { 4491 char *name; 4492 MatSolverTypeForSpecifcType handlers; 4493 MatSolverTypeHolder next; 4494 }; 4495 4496 static MatSolverTypeHolder MatSolverTypeHolders = NULL; 4497 4498 /*@C 4499 MatSolverTypeRegister - Registers a MatSolverType that works for a particular matrix type 4500 4501 Input Parameters: 4502 + package - name of the package, for example petsc or superlu 4503 . mtype - the matrix type that works with this package 4504 . ftype - the type of factorization supported by the package 4505 - createfactor - routine that will create the factored matrix ready to be used 4506 4507 Level: intermediate 4508 4509 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()` 4510 @*/ 4511 PetscErrorCode MatSolverTypeRegister(MatSolverType package,MatType mtype,MatFactorType ftype,PetscErrorCode (*createfactor)(Mat,MatFactorType,Mat*)) 4512 { 4513 MatSolverTypeHolder next = MatSolverTypeHolders,prev = NULL; 4514 PetscBool flg; 4515 MatSolverTypeForSpecifcType inext,iprev = NULL; 4516 4517 PetscFunctionBegin; 4518 PetscCall(MatInitializePackage()); 4519 if (!next) { 4520 PetscCall(PetscNew(&MatSolverTypeHolders)); 4521 PetscCall(PetscStrallocpy(package,&MatSolverTypeHolders->name)); 4522 PetscCall(PetscNew(&MatSolverTypeHolders->handlers)); 4523 PetscCall(PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype)); 4524 MatSolverTypeHolders->handlers->createfactor[(int)ftype-1] = createfactor; 4525 PetscFunctionReturn(0); 4526 } 4527 while (next) { 4528 PetscCall(PetscStrcasecmp(package,next->name,&flg)); 4529 if (flg) { 4530 PetscCheck(next->handlers,PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers"); 4531 inext = next->handlers; 4532 while (inext) { 4533 PetscCall(PetscStrcasecmp(mtype,inext->mtype,&flg)); 4534 if (flg) { 4535 inext->createfactor[(int)ftype-1] = createfactor; 4536 PetscFunctionReturn(0); 4537 } 4538 iprev = inext; 4539 inext = inext->next; 4540 } 4541 PetscCall(PetscNew(&iprev->next)); 4542 PetscCall(PetscStrallocpy(mtype,(char **)&iprev->next->mtype)); 4543 iprev->next->createfactor[(int)ftype-1] = createfactor; 4544 PetscFunctionReturn(0); 4545 } 4546 prev = next; 4547 next = next->next; 4548 } 4549 PetscCall(PetscNew(&prev->next)); 4550 PetscCall(PetscStrallocpy(package,&prev->next->name)); 4551 PetscCall(PetscNew(&prev->next->handlers)); 4552 PetscCall(PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype)); 4553 prev->next->handlers->createfactor[(int)ftype-1] = createfactor; 4554 PetscFunctionReturn(0); 4555 } 4556 4557 /*@C 4558 MatSolverTypeGet - Gets the function that creates the factor matrix if it exist 4559 4560 Input Parameters: 4561 + type - name of the package, for example petsc or superlu 4562 . ftype - the type of factorization supported by the type 4563 - mtype - the matrix type that works with this type 4564 4565 Output Parameters: 4566 + foundtype - PETSC_TRUE if the type was registered 4567 . foundmtype - PETSC_TRUE if the type supports the requested mtype 4568 - createfactor - routine that will create the factored matrix ready to be used or NULL if not found 4569 4570 Level: intermediate 4571 4572 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatSolverTypeRegister()`, `MatGetFactor()` 4573 @*/ 4574 PetscErrorCode MatSolverTypeGet(MatSolverType type,MatType mtype,MatFactorType ftype,PetscBool *foundtype,PetscBool *foundmtype,PetscErrorCode (**createfactor)(Mat,MatFactorType,Mat*)) 4575 { 4576 MatSolverTypeHolder next = MatSolverTypeHolders; 4577 PetscBool flg; 4578 MatSolverTypeForSpecifcType inext; 4579 4580 PetscFunctionBegin; 4581 if (foundtype) *foundtype = PETSC_FALSE; 4582 if (foundmtype) *foundmtype = PETSC_FALSE; 4583 if (createfactor) *createfactor = NULL; 4584 4585 if (type) { 4586 while (next) { 4587 PetscCall(PetscStrcasecmp(type,next->name,&flg)); 4588 if (flg) { 4589 if (foundtype) *foundtype = PETSC_TRUE; 4590 inext = next->handlers; 4591 while (inext) { 4592 PetscCall(PetscStrbeginswith(mtype,inext->mtype,&flg)); 4593 if (flg) { 4594 if (foundmtype) *foundmtype = PETSC_TRUE; 4595 if (createfactor) *createfactor = inext->createfactor[(int)ftype-1]; 4596 PetscFunctionReturn(0); 4597 } 4598 inext = inext->next; 4599 } 4600 } 4601 next = next->next; 4602 } 4603 } else { 4604 while (next) { 4605 inext = next->handlers; 4606 while (inext) { 4607 PetscCall(PetscStrcmp(mtype,inext->mtype,&flg)); 4608 if (flg && inext->createfactor[(int)ftype-1]) { 4609 if (foundtype) *foundtype = PETSC_TRUE; 4610 if (foundmtype) *foundmtype = PETSC_TRUE; 4611 if (createfactor) *createfactor = inext->createfactor[(int)ftype-1]; 4612 PetscFunctionReturn(0); 4613 } 4614 inext = inext->next; 4615 } 4616 next = next->next; 4617 } 4618 /* try with base classes inext->mtype */ 4619 next = MatSolverTypeHolders; 4620 while (next) { 4621 inext = next->handlers; 4622 while (inext) { 4623 PetscCall(PetscStrbeginswith(mtype,inext->mtype,&flg)); 4624 if (flg && inext->createfactor[(int)ftype-1]) { 4625 if (foundtype) *foundtype = PETSC_TRUE; 4626 if (foundmtype) *foundmtype = PETSC_TRUE; 4627 if (createfactor) *createfactor = inext->createfactor[(int)ftype-1]; 4628 PetscFunctionReturn(0); 4629 } 4630 inext = inext->next; 4631 } 4632 next = next->next; 4633 } 4634 } 4635 PetscFunctionReturn(0); 4636 } 4637 4638 PetscErrorCode MatSolverTypeDestroy(void) 4639 { 4640 MatSolverTypeHolder next = MatSolverTypeHolders,prev; 4641 MatSolverTypeForSpecifcType inext,iprev; 4642 4643 PetscFunctionBegin; 4644 while (next) { 4645 PetscCall(PetscFree(next->name)); 4646 inext = next->handlers; 4647 while (inext) { 4648 PetscCall(PetscFree(inext->mtype)); 4649 iprev = inext; 4650 inext = inext->next; 4651 PetscCall(PetscFree(iprev)); 4652 } 4653 prev = next; 4654 next = next->next; 4655 PetscCall(PetscFree(prev)); 4656 } 4657 MatSolverTypeHolders = NULL; 4658 PetscFunctionReturn(0); 4659 } 4660 4661 /*@C 4662 MatFactorGetCanUseOrdering - Indicates if the factorization can use the ordering provided in MatLUFactorSymbolic(), MatCholeskyFactorSymbolic() 4663 4664 Logically Collective on Mat 4665 4666 Input Parameters: 4667 . mat - the matrix 4668 4669 Output Parameters: 4670 . flg - PETSC_TRUE if uses the ordering 4671 4672 Notes: 4673 Most internal PETSc factorizations use the ordering passed to the factorization routine but external 4674 packages do not, thus we want to skip generating the ordering when it is not needed or used. 4675 4676 Level: developer 4677 4678 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()` 4679 @*/ 4680 PetscErrorCode MatFactorGetCanUseOrdering(Mat mat, PetscBool *flg) 4681 { 4682 PetscFunctionBegin; 4683 *flg = mat->canuseordering; 4684 PetscFunctionReturn(0); 4685 } 4686 4687 /*@C 4688 MatFactorGetPreferredOrdering - The preferred ordering for a particular matrix factor object 4689 4690 Logically Collective on Mat 4691 4692 Input Parameters: 4693 . mat - the matrix 4694 4695 Output Parameters: 4696 . otype - the preferred type 4697 4698 Level: developer 4699 4700 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()` 4701 @*/ 4702 PetscErrorCode MatFactorGetPreferredOrdering(Mat mat, MatFactorType ftype, MatOrderingType *otype) 4703 { 4704 PetscFunctionBegin; 4705 *otype = mat->preferredordering[ftype]; 4706 PetscCheck(*otype,PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatFactor did not have a preferred ordering"); 4707 PetscFunctionReturn(0); 4708 } 4709 4710 /*@C 4711 MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic() 4712 4713 Collective on Mat 4714 4715 Input Parameters: 4716 + mat - the matrix 4717 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4718 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4719 4720 Output Parameters: 4721 . f - the factor matrix used with MatXXFactorSymbolic() calls 4722 4723 Options Database Key: 4724 . -mat_factor_bind_factorization <host, device> - Where to do matrix factorization? Default is device (might consume more device memory. 4725 One can choose host to save device memory). Currently only supported with SEQAIJCUSPARSE matrices. 4726 4727 Notes: 4728 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4729 such as pastix, superlu, mumps etc. 4730 4731 PETSc must have been ./configure to use the external solver, using the option --download-package 4732 4733 Some of the packages have options for controlling the factorization, these are in the form -prefix_mat_packagename_packageoption 4734 where prefix is normally obtained from the calling `KSP`/`PC`. If `MatGetFactor()` is called directly one can set 4735 call `MatSetOptionsPrefixFactor()` on the originating matrix or `MatSetOptionsPrefix()` on the resulting factor matrix. 4736 4737 Developer Notes: 4738 This should actually be called MatCreateFactor() since it creates a new factor object 4739 4740 Level: intermediate 4741 4742 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatFactorGetCanUseOrdering()`, `MatSolverTypeRegister()` 4743 @*/ 4744 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f) 4745 { 4746 PetscBool foundtype,foundmtype; 4747 PetscErrorCode (*conv)(Mat,MatFactorType,Mat*); 4748 4749 PetscFunctionBegin; 4750 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4751 PetscValidType(mat,1); 4752 4753 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4754 MatCheckPreallocated(mat,1); 4755 4756 PetscCall(MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundtype,&foundmtype,&conv)); 4757 if (!foundtype) { 4758 if (type) { 4759 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); 4760 } else { 4761 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); 4762 } 4763 } 4764 PetscCheck(foundmtype,PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name); 4765 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); 4766 4767 PetscCall((*conv)(mat,ftype,f)); 4768 if (mat->factorprefix) PetscCall(MatSetOptionsPrefix(*f,mat->factorprefix)); 4769 PetscFunctionReturn(0); 4770 } 4771 4772 /*@C 4773 MatGetFactorAvailable - Returns a a flag if matrix supports particular type and factor type 4774 4775 Not Collective 4776 4777 Input Parameters: 4778 + mat - the matrix 4779 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4780 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4781 4782 Output Parameter: 4783 . flg - PETSC_TRUE if the factorization is available 4784 4785 Notes: 4786 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4787 such as pastix, superlu, mumps etc. 4788 4789 PETSc must have been ./configure to use the external solver, using the option --download-package 4790 4791 Developer Notes: 4792 This should actually be called MatCreateFactorAvailable() since MatGetFactor() creates a new factor object 4793 4794 Level: intermediate 4795 4796 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactor()`, `MatSolverTypeRegister()` 4797 @*/ 4798 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool *flg) 4799 { 4800 PetscErrorCode (*gconv)(Mat,MatFactorType,Mat*); 4801 4802 PetscFunctionBegin; 4803 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4804 PetscValidType(mat,1); 4805 PetscValidBoolPointer(flg,4); 4806 4807 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4808 MatCheckPreallocated(mat,1); 4809 4810 PetscCall(MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv)); 4811 *flg = gconv ? PETSC_TRUE : PETSC_FALSE; 4812 PetscFunctionReturn(0); 4813 } 4814 4815 /*@ 4816 MatDuplicate - Duplicates a matrix including the non-zero structure. 4817 4818 Collective on Mat 4819 4820 Input Parameters: 4821 + mat - the matrix 4822 - op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN. 4823 See the manual page for MatDuplicateOption for an explanation of these options. 4824 4825 Output Parameter: 4826 . M - pointer to place new matrix 4827 4828 Level: intermediate 4829 4830 Notes: 4831 You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN. 4832 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. 4833 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. 4834 4835 .seealso: `MatCopy()`, `MatConvert()`, `MatDuplicateOption` 4836 @*/ 4837 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M) 4838 { 4839 Mat B; 4840 VecType vtype; 4841 PetscInt i; 4842 PetscObject dm; 4843 void (*viewf)(void); 4844 4845 PetscFunctionBegin; 4846 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4847 PetscValidType(mat,1); 4848 PetscValidPointer(M,3); 4849 PetscCheck(op != MAT_COPY_VALUES || mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix"); 4850 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4851 MatCheckPreallocated(mat,1); 4852 4853 *M = NULL; 4854 PetscCheck(mat->ops->duplicate,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for matrix type %s",((PetscObject)mat)->type_name); 4855 PetscCall(PetscLogEventBegin(MAT_Convert,mat,0,0,0)); 4856 PetscCall((*mat->ops->duplicate)(mat,op,M)); 4857 PetscCall(PetscLogEventEnd(MAT_Convert,mat,0,0,0)); 4858 B = *M; 4859 4860 PetscCall(MatGetOperation(mat,MATOP_VIEW,&viewf)); 4861 if (viewf) PetscCall(MatSetOperation(B,MATOP_VIEW,viewf)); 4862 PetscCall(MatGetVecType(mat,&vtype)); 4863 PetscCall(MatSetVecType(B,vtype)); 4864 4865 B->stencil.dim = mat->stencil.dim; 4866 B->stencil.noc = mat->stencil.noc; 4867 for (i=0; i<=mat->stencil.dim; i++) { 4868 B->stencil.dims[i] = mat->stencil.dims[i]; 4869 B->stencil.starts[i] = mat->stencil.starts[i]; 4870 } 4871 4872 B->nooffproczerorows = mat->nooffproczerorows; 4873 B->nooffprocentries = mat->nooffprocentries; 4874 4875 PetscCall(PetscObjectQuery((PetscObject) mat, "__PETSc_dm", &dm)); 4876 if (dm) { 4877 PetscCall(PetscObjectCompose((PetscObject) B, "__PETSc_dm", dm)); 4878 } 4879 PetscCall(PetscObjectStateIncrease((PetscObject)B)); 4880 PetscFunctionReturn(0); 4881 } 4882 4883 /*@ 4884 MatGetDiagonal - Gets the diagonal of a matrix. 4885 4886 Logically Collective on Mat 4887 4888 Input Parameters: 4889 + mat - the matrix 4890 - v - the vector for storing the diagonal 4891 4892 Output Parameter: 4893 . v - the diagonal of the matrix 4894 4895 Level: intermediate 4896 4897 Note: 4898 Currently only correct in parallel for square matrices. 4899 4900 .seealso: `MatGetRow()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMaxAbs()` 4901 @*/ 4902 PetscErrorCode MatGetDiagonal(Mat mat,Vec v) 4903 { 4904 PetscFunctionBegin; 4905 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4906 PetscValidType(mat,1); 4907 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4908 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4909 PetscCheck(mat->ops->getdiagonal,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4910 MatCheckPreallocated(mat,1); 4911 4912 PetscCall((*mat->ops->getdiagonal)(mat,v)); 4913 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 4914 PetscFunctionReturn(0); 4915 } 4916 4917 /*@C 4918 MatGetRowMin - Gets the minimum value (of the real part) of each 4919 row of the matrix 4920 4921 Logically Collective on Mat 4922 4923 Input Parameter: 4924 . mat - the matrix 4925 4926 Output Parameters: 4927 + v - the vector for storing the maximums 4928 - idx - the indices of the column found for each row (optional) 4929 4930 Level: intermediate 4931 4932 Notes: 4933 The result of this call are the same as if one converted the matrix to dense format 4934 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4935 4936 This code is only implemented for a couple of matrix formats. 4937 4938 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMaxAbs()`, 4939 `MatGetRowMax()` 4940 @*/ 4941 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[]) 4942 { 4943 PetscFunctionBegin; 4944 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4945 PetscValidType(mat,1); 4946 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4947 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4948 4949 if (!mat->cmap->N) { 4950 PetscCall(VecSet(v,PETSC_MAX_REAL)); 4951 if (idx) { 4952 PetscInt i,m = mat->rmap->n; 4953 for (i=0; i<m; i++) idx[i] = -1; 4954 } 4955 } else { 4956 PetscCheck(mat->ops->getrowmin,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4957 MatCheckPreallocated(mat,1); 4958 } 4959 PetscCall((*mat->ops->getrowmin)(mat,v,idx)); 4960 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 4961 PetscFunctionReturn(0); 4962 } 4963 4964 /*@C 4965 MatGetRowMinAbs - Gets the minimum value (in absolute value) of each 4966 row of the matrix 4967 4968 Logically Collective on Mat 4969 4970 Input Parameter: 4971 . mat - the matrix 4972 4973 Output Parameters: 4974 + v - the vector for storing the minimums 4975 - idx - the indices of the column found for each row (or NULL if not needed) 4976 4977 Level: intermediate 4978 4979 Notes: 4980 if a row is completely empty or has only 0.0 values then the idx[] value for that 4981 row is 0 (the first column). 4982 4983 This code is only implemented for a couple of matrix formats. 4984 4985 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMax()`, `MatGetRowMaxAbs()`, `MatGetRowMin()` 4986 @*/ 4987 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[]) 4988 { 4989 PetscFunctionBegin; 4990 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4991 PetscValidType(mat,1); 4992 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4993 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4994 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4995 4996 if (!mat->cmap->N) { 4997 PetscCall(VecSet(v,0.0)); 4998 if (idx) { 4999 PetscInt i,m = mat->rmap->n; 5000 for (i=0; i<m; i++) idx[i] = -1; 5001 } 5002 } else { 5003 PetscCheck(mat->ops->getrowminabs,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5004 MatCheckPreallocated(mat,1); 5005 if (idx) PetscCall(PetscArrayzero(idx,mat->rmap->n)); 5006 PetscCall((*mat->ops->getrowminabs)(mat,v,idx)); 5007 } 5008 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 5009 PetscFunctionReturn(0); 5010 } 5011 5012 /*@C 5013 MatGetRowMax - Gets the maximum value (of the real part) of each 5014 row of the matrix 5015 5016 Logically Collective on Mat 5017 5018 Input Parameter: 5019 . mat - the matrix 5020 5021 Output Parameters: 5022 + v - the vector for storing the maximums 5023 - idx - the indices of the column found for each row (optional) 5024 5025 Level: intermediate 5026 5027 Notes: 5028 The result of this call are the same as if one converted the matrix to dense format 5029 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 5030 5031 This code is only implemented for a couple of matrix formats. 5032 5033 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMaxAbs()`, `MatGetRowMin()` 5034 @*/ 5035 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[]) 5036 { 5037 PetscFunctionBegin; 5038 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5039 PetscValidType(mat,1); 5040 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 5041 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5042 5043 if (!mat->cmap->N) { 5044 PetscCall(VecSet(v,PETSC_MIN_REAL)); 5045 if (idx) { 5046 PetscInt i,m = mat->rmap->n; 5047 for (i=0; i<m; i++) idx[i] = -1; 5048 } 5049 } else { 5050 PetscCheck(mat->ops->getrowmax,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5051 MatCheckPreallocated(mat,1); 5052 PetscCall((*mat->ops->getrowmax)(mat,v,idx)); 5053 } 5054 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 5055 PetscFunctionReturn(0); 5056 } 5057 5058 /*@C 5059 MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each 5060 row of the matrix 5061 5062 Logically Collective on Mat 5063 5064 Input Parameter: 5065 . mat - the matrix 5066 5067 Output Parameters: 5068 + v - the vector for storing the maximums 5069 - idx - the indices of the column found for each row (or NULL if not needed) 5070 5071 Level: intermediate 5072 5073 Notes: 5074 if a row is completely empty or has only 0.0 values then the idx[] value for that 5075 row is 0 (the first column). 5076 5077 This code is only implemented for a couple of matrix formats. 5078 5079 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMax()`, `MatGetRowMin()` 5080 @*/ 5081 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[]) 5082 { 5083 PetscFunctionBegin; 5084 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5085 PetscValidType(mat,1); 5086 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 5087 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5088 5089 if (!mat->cmap->N) { 5090 PetscCall(VecSet(v,0.0)); 5091 if (idx) { 5092 PetscInt i,m = mat->rmap->n; 5093 for (i=0; i<m; i++) idx[i] = -1; 5094 } 5095 } else { 5096 PetscCheck(mat->ops->getrowmaxabs,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5097 MatCheckPreallocated(mat,1); 5098 if (idx) PetscCall(PetscArrayzero(idx,mat->rmap->n)); 5099 PetscCall((*mat->ops->getrowmaxabs)(mat,v,idx)); 5100 } 5101 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 5102 PetscFunctionReturn(0); 5103 } 5104 5105 /*@ 5106 MatGetRowSum - Gets the sum of each row of the matrix 5107 5108 Logically or Neighborhood Collective on Mat 5109 5110 Input Parameters: 5111 . mat - the matrix 5112 5113 Output Parameter: 5114 . v - the vector for storing the sum of rows 5115 5116 Level: intermediate 5117 5118 Notes: 5119 This code is slow since it is not currently specialized for different formats 5120 5121 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMax()`, `MatGetRowMin()` 5122 @*/ 5123 PetscErrorCode MatGetRowSum(Mat mat, Vec v) 5124 { 5125 Vec ones; 5126 5127 PetscFunctionBegin; 5128 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5129 PetscValidType(mat,1); 5130 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 5131 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5132 MatCheckPreallocated(mat,1); 5133 PetscCall(MatCreateVecs(mat,&ones,NULL)); 5134 PetscCall(VecSet(ones,1.)); 5135 PetscCall(MatMult(mat,ones,v)); 5136 PetscCall(VecDestroy(&ones)); 5137 PetscFunctionReturn(0); 5138 } 5139 5140 /*@ 5141 MatTransposeSetPrecursor - Set the matrix from which the second matrix will receive numerical transpose data with a call to `MatTranspose`(A,`MAT_REUSE_MATRIX`,&B) 5142 when B was not obtained with `MatTranspose`(A,`MAT_INITIAL_MATRIX`,&B) 5143 5144 Collective on Mat 5145 5146 Input Parameter: 5147 . mat - the matrix to provide the transpose 5148 5149 Output Parameter: 5150 . mat - the matrix to contain the transpose; it MUST have the nonzero structure of the transpose of A or the code will crash or generate incorrect results 5151 5152 Level: advanced 5153 5154 Note: 5155 Normally he use of `MatTranspose`(A,`MAT_REUSE_MATRIX`,&B) requires that B was obtained with a call to `MatTranspose`(A,`MAT_INITIAL_MATRIX`,&B). This 5156 routine allows bypassing that call. 5157 5158 .seealso: `MatTransposeSymbolic()`, `MatTranspose()`, `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse`, `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, `MAT_INPLACE_MATRIX` 5159 @*/ 5160 PetscErrorCode MatTransposeSetPrecursor(Mat mat,Mat B) 5161 { 5162 PetscContainer rB = NULL; 5163 MatParentState *rb = NULL; 5164 5165 PetscFunctionBegin; 5166 PetscCall(PetscNew(&rb)); 5167 rb->id = ((PetscObject)mat)->id; 5168 rb->state = 0; 5169 PetscCall(MatGetNonzeroState(mat,&rb->nonzerostate)); 5170 PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)B),&rB)); 5171 PetscCall(PetscContainerSetPointer(rB,rb)); 5172 PetscCall(PetscContainerSetUserDestroy(rB,PetscContainerUserDestroyDefault)); 5173 PetscCall(PetscObjectCompose((PetscObject)B,"MatTransposeParent",(PetscObject)rB)); 5174 PetscCall(PetscObjectDereference((PetscObject)rB)); 5175 PetscFunctionReturn(0); 5176 } 5177 5178 /*@ 5179 MatTranspose - Computes an in-place or out-of-place transpose of a matrix. 5180 5181 Collective on Mat 5182 5183 Input Parameters: 5184 + mat - the matrix to transpose 5185 - reuse - either `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, or `MAT_INPLACE_MATRIX` 5186 5187 Output Parameter: 5188 . B - the transpose 5189 5190 Notes: 5191 If you use `MAT_INPLACE_MATRIX` then you must pass in &mat for B 5192 5193 `MAT_REUSE_MATRIX` uses the B matrix obtained from a previous call to this function with `MAT_INITIAL_MATRIX`. If you already have a matrix to contain the 5194 transpose, call `MatTransposeSetPrecursor`(mat,B) before calling this routine. 5195 5196 If the nonzero structure of mat changed from the previous call to this function with the same matrices an error will be generated for some matrix types. 5197 5198 Consider using `MatCreateTranspose()` instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed. 5199 5200 If mat is unchanged from the last call this function returns immediately without recomputing the result 5201 5202 If you only need the symbolic transpose, and not the numerical values, use `MatTransposeSymbolic()` 5203 5204 Level: intermediate 5205 5206 .seealso: `MatTransposeSetPrecursor()`, `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse`, `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, `MAT_INPLACE_MATRIX`, 5207 `MatTransposeSymbolic()` 5208 @*/ 5209 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B) 5210 { 5211 PetscContainer rB = NULL; 5212 MatParentState *rb = NULL; 5213 5214 PetscFunctionBegin; 5215 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5216 PetscValidType(mat,1); 5217 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5218 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5219 PetscCheck(mat->ops->transpose,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5220 PetscCheck(reuse != MAT_INPLACE_MATRIX || mat == *B,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first"); 5221 PetscCheck(reuse != MAT_REUSE_MATRIX || mat != *B,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX"); 5222 MatCheckPreallocated(mat,1); 5223 if (reuse == MAT_REUSE_MATRIX) { 5224 PetscCall(PetscObjectQuery((PetscObject)*B,"MatTransposeParent",(PetscObject*)&rB)); 5225 PetscCheck(rB,PetscObjectComm((PetscObject)*B),PETSC_ERR_ARG_WRONG,"Reuse matrix used was not generated from call to MatTranspose(). Suggest MatTransposeSetPrecursor()."); 5226 PetscCall(PetscContainerGetPointer(rB,(void**)&rb)); 5227 PetscCheck(rb->id == ((PetscObject)mat)->id,PetscObjectComm((PetscObject)*B),PETSC_ERR_ARG_WRONG,"Reuse matrix used was not generated from input matrix"); 5228 if (rb->state == ((PetscObject)mat)->state) PetscFunctionReturn(0); 5229 } 5230 5231 PetscCall(PetscLogEventBegin(MAT_Transpose,mat,0,0,0)); 5232 PetscCall((*mat->ops->transpose)(mat,reuse,B)); 5233 PetscCall(PetscLogEventEnd(MAT_Transpose,mat,0,0,0)); 5234 PetscCall(PetscObjectStateIncrease((PetscObject)*B)); 5235 5236 if (reuse == MAT_INITIAL_MATRIX) PetscCall(MatTransposeSetPrecursor(mat,*B)); 5237 if (reuse != MAT_INPLACE_MATRIX) { 5238 PetscCall(PetscObjectQuery((PetscObject)*B,"MatTransposeParent",(PetscObject*)&rB)); 5239 PetscCall(PetscContainerGetPointer(rB,(void**)&rb)); 5240 rb->state = ((PetscObject)mat)->state; 5241 rb->nonzerostate = mat->nonzerostate; 5242 } 5243 PetscFunctionReturn(0); 5244 } 5245 5246 /*@ 5247 MatTransposeSymbolic - Computes the symbolic part of the transpose of a matrix. 5248 5249 Collective on Mat 5250 5251 Input Parameters: 5252 . A - the matrix to transpose 5253 5254 Output Parameter: 5255 . B - the transpose. This is a complete matrix but the numerical portion is invalid. One can call `MatTranspose`(A,MAT_REUSE_MATRIX,&B) to compute the 5256 numerical portion. 5257 5258 Level: intermediate 5259 5260 Note: 5261 This is not supported for many matrix types, use `MatTranspose()` in those cases 5262 5263 .seealso: `MatTransposeSetPrecursor()`, `MatTranspose()`, `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse`, `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, `MAT_INPLACE_MATRIX` 5264 @*/ 5265 PetscErrorCode MatTransposeSymbolic(Mat A,Mat *B) 5266 { 5267 PetscFunctionBegin; 5268 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5269 PetscValidType(A,1); 5270 PetscCheck(A->assembled,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5271 PetscCheck(!A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5272 PetscCheck(A->ops->transposesymbolic,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 5273 PetscCall(PetscLogEventBegin(MAT_Transpose,A,0,0,0)); 5274 PetscCall((*A->ops->transposesymbolic)(A,B)); 5275 PetscCall(PetscLogEventEnd(MAT_Transpose,A,0,0,0)); 5276 5277 PetscCall(MatTransposeSetPrecursor(A,*B)); 5278 PetscFunctionReturn(0); 5279 } 5280 5281 PetscErrorCode MatTransposeCheckNonzeroState_Private(Mat A,Mat B) 5282 { 5283 PetscContainer rB; 5284 MatParentState *rb; 5285 5286 PetscFunctionBegin; 5287 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5288 PetscValidType(A,1); 5289 PetscCheck(A->assembled,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5290 PetscCheck(!A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5291 PetscCall(PetscObjectQuery((PetscObject)B,"MatTransposeParent",(PetscObject*)&rB)); 5292 PetscCheck(rB,PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONG,"Reuse matrix used was not generated from call to MatTranspose()"); 5293 PetscCall(PetscContainerGetPointer(rB,(void**)&rb)); 5294 PetscCheck(rb->id == ((PetscObject)A)->id,PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONG,"Reuse matrix used was not generated from input matrix"); 5295 PetscCheck(rb->nonzerostate == A->nonzerostate,PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Reuse matrix has changed nonzero structure"); 5296 PetscFunctionReturn(0); 5297 } 5298 5299 /*@ 5300 MatIsTranspose - Test whether a matrix is another one's transpose, 5301 or its own, in which case it tests symmetry. 5302 5303 Collective on Mat 5304 5305 Input Parameters: 5306 + A - the matrix to test 5307 - B - the matrix to test against, this can equal the first parameter 5308 5309 Output Parameters: 5310 . flg - the result 5311 5312 Notes: 5313 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 5314 has a running time of the order of the number of nonzeros; the parallel 5315 test involves parallel copies of the block-offdiagonal parts of the matrix. 5316 5317 Level: intermediate 5318 5319 .seealso: `MatTranspose()`, `MatIsSymmetric()`, `MatIsHermitian()` 5320 @*/ 5321 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 5322 { 5323 PetscErrorCode (*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 5324 5325 PetscFunctionBegin; 5326 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5327 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5328 PetscValidBoolPointer(flg,4); 5329 PetscCall(PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f)); 5330 PetscCall(PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g)); 5331 *flg = PETSC_FALSE; 5332 if (f && g) { 5333 PetscCheck(f == g,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test"); 5334 PetscCall((*f)(A,B,tol,flg)); 5335 } else { 5336 MatType mattype; 5337 5338 PetscCall(MatGetType(f ? B : A,&mattype)); 5339 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for transpose",mattype); 5340 } 5341 PetscFunctionReturn(0); 5342 } 5343 5344 /*@ 5345 MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate. 5346 5347 Collective on Mat 5348 5349 Input Parameters: 5350 + mat - the matrix to transpose and complex conjugate 5351 - reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX 5352 5353 Output Parameter: 5354 . B - the Hermitian 5355 5356 Level: intermediate 5357 5358 .seealso: `MatTranspose()`, `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse` 5359 @*/ 5360 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B) 5361 { 5362 PetscFunctionBegin; 5363 PetscCall(MatTranspose(mat,reuse,B)); 5364 #if defined(PETSC_USE_COMPLEX) 5365 PetscCall(MatConjugate(*B)); 5366 #endif 5367 PetscFunctionReturn(0); 5368 } 5369 5370 /*@ 5371 MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose, 5372 5373 Collective on Mat 5374 5375 Input Parameters: 5376 + A - the matrix to test 5377 - B - the matrix to test against, this can equal the first parameter 5378 5379 Output Parameters: 5380 . flg - the result 5381 5382 Notes: 5383 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 5384 has a running time of the order of the number of nonzeros; the parallel 5385 test involves parallel copies of the block-offdiagonal parts of the matrix. 5386 5387 Level: intermediate 5388 5389 .seealso: `MatTranspose()`, `MatIsSymmetric()`, `MatIsHermitian()`, `MatIsTranspose()` 5390 @*/ 5391 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 5392 { 5393 PetscErrorCode (*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 5394 5395 PetscFunctionBegin; 5396 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5397 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5398 PetscValidBoolPointer(flg,4); 5399 PetscCall(PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f)); 5400 PetscCall(PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g)); 5401 if (f && g) { 5402 PetscCheck(f != g,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test"); 5403 PetscCall((*f)(A,B,tol,flg)); 5404 } 5405 PetscFunctionReturn(0); 5406 } 5407 5408 /*@ 5409 MatPermute - Creates a new matrix with rows and columns permuted from the 5410 original. 5411 5412 Collective on Mat 5413 5414 Input Parameters: 5415 + mat - the matrix to permute 5416 . row - row permutation, each processor supplies only the permutation for its rows 5417 - col - column permutation, each processor supplies only the permutation for its columns 5418 5419 Output Parameters: 5420 . B - the permuted matrix 5421 5422 Level: advanced 5423 5424 Note: 5425 The index sets map from row/col of permuted matrix to row/col of original matrix. 5426 The index sets should be on the same communicator as Mat and have the same local sizes. 5427 5428 Developer Note: 5429 If you want to implement MatPermute for a matrix type, and your approach doesn't 5430 exploit the fact that row and col are permutations, consider implementing the 5431 more general MatCreateSubMatrix() instead. 5432 5433 .seealso: `MatGetOrdering()`, `ISAllGather()` 5434 5435 @*/ 5436 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B) 5437 { 5438 PetscFunctionBegin; 5439 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5440 PetscValidType(mat,1); 5441 PetscValidHeaderSpecific(row,IS_CLASSID,2); 5442 PetscValidHeaderSpecific(col,IS_CLASSID,3); 5443 PetscValidPointer(B,4); 5444 PetscCheckSameComm(mat,1,row,2); 5445 if (row != col) PetscCheckSameComm(row,2,col,3); 5446 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5447 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5448 PetscCheck(mat->ops->permute || mat->ops->createsubmatrix,PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name); 5449 MatCheckPreallocated(mat,1); 5450 5451 if (mat->ops->permute) { 5452 PetscCall((*mat->ops->permute)(mat,row,col,B)); 5453 PetscCall(PetscObjectStateIncrease((PetscObject)*B)); 5454 } else { 5455 PetscCall(MatCreateSubMatrix(mat, row, col, MAT_INITIAL_MATRIX, B)); 5456 } 5457 PetscFunctionReturn(0); 5458 } 5459 5460 /*@ 5461 MatEqual - Compares two matrices. 5462 5463 Collective on Mat 5464 5465 Input Parameters: 5466 + A - the first matrix 5467 - B - the second matrix 5468 5469 Output Parameter: 5470 . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise. 5471 5472 Level: intermediate 5473 5474 @*/ 5475 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool *flg) 5476 { 5477 PetscFunctionBegin; 5478 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5479 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5480 PetscValidType(A,1); 5481 PetscValidType(B,2); 5482 PetscValidBoolPointer(flg,3); 5483 PetscCheckSameComm(A,1,B,2); 5484 MatCheckPreallocated(A,1); 5485 MatCheckPreallocated(B,2); 5486 PetscCheck(A->assembled,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5487 PetscCheck(B->assembled,PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5488 PetscCheck(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); 5489 if (A->ops->equal && A->ops->equal == B->ops->equal) { 5490 PetscCall((*A->ops->equal)(A,B,flg)); 5491 } else { 5492 PetscCall(MatMultEqual(A,B,10,flg)); 5493 } 5494 PetscFunctionReturn(0); 5495 } 5496 5497 /*@ 5498 MatDiagonalScale - Scales a matrix on the left and right by diagonal 5499 matrices that are stored as vectors. Either of the two scaling 5500 matrices can be NULL. 5501 5502 Collective on Mat 5503 5504 Input Parameters: 5505 + mat - the matrix to be scaled 5506 . l - the left scaling vector (or NULL) 5507 - r - the right scaling vector (or NULL) 5508 5509 Notes: 5510 MatDiagonalScale() computes A = LAR, where 5511 L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector) 5512 The L scales the rows of the matrix, the R scales the columns of the matrix. 5513 5514 Level: intermediate 5515 5516 .seealso: `MatScale()`, `MatShift()`, `MatDiagonalSet()` 5517 @*/ 5518 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r) 5519 { 5520 PetscFunctionBegin; 5521 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5522 PetscValidType(mat,1); 5523 if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);} 5524 if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);} 5525 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5526 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5527 MatCheckPreallocated(mat,1); 5528 if (!l && !r) PetscFunctionReturn(0); 5529 5530 PetscCheck(mat->ops->diagonalscale,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5531 PetscCall(PetscLogEventBegin(MAT_Scale,mat,0,0,0)); 5532 PetscCall((*mat->ops->diagonalscale)(mat,l,r)); 5533 PetscCall(PetscLogEventEnd(MAT_Scale,mat,0,0,0)); 5534 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5535 if (l != r) mat->symmetric = PETSC_BOOL3_FALSE; 5536 PetscFunctionReturn(0); 5537 } 5538 5539 /*@ 5540 MatScale - Scales all elements of a matrix by a given number. 5541 5542 Logically Collective on Mat 5543 5544 Input Parameters: 5545 + mat - the matrix to be scaled 5546 - a - the scaling value 5547 5548 Output Parameter: 5549 . mat - the scaled matrix 5550 5551 Level: intermediate 5552 5553 .seealso: `MatDiagonalScale()` 5554 @*/ 5555 PetscErrorCode MatScale(Mat mat,PetscScalar a) 5556 { 5557 PetscFunctionBegin; 5558 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5559 PetscValidType(mat,1); 5560 PetscCheck(a == (PetscScalar)1.0 || mat->ops->scale,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5561 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5562 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5563 PetscValidLogicalCollectiveScalar(mat,a,2); 5564 MatCheckPreallocated(mat,1); 5565 5566 PetscCall(PetscLogEventBegin(MAT_Scale,mat,0,0,0)); 5567 if (a != (PetscScalar)1.0) { 5568 PetscCall((*mat->ops->scale)(mat,a)); 5569 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5570 } 5571 PetscCall(PetscLogEventEnd(MAT_Scale,mat,0,0,0)); 5572 PetscFunctionReturn(0); 5573 } 5574 5575 /*@ 5576 MatNorm - Calculates various norms of a matrix. 5577 5578 Collective on Mat 5579 5580 Input Parameters: 5581 + mat - the matrix 5582 - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY 5583 5584 Output Parameter: 5585 . nrm - the resulting norm 5586 5587 Level: intermediate 5588 5589 @*/ 5590 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm) 5591 { 5592 PetscFunctionBegin; 5593 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5594 PetscValidType(mat,1); 5595 PetscValidRealPointer(nrm,3); 5596 5597 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5598 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5599 PetscCheck(mat->ops->norm,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5600 MatCheckPreallocated(mat,1); 5601 5602 PetscCall((*mat->ops->norm)(mat,type,nrm)); 5603 PetscFunctionReturn(0); 5604 } 5605 5606 /* 5607 This variable is used to prevent counting of MatAssemblyBegin() that 5608 are called from within a MatAssemblyEnd(). 5609 */ 5610 static PetscInt MatAssemblyEnd_InUse = 0; 5611 /*@ 5612 MatAssemblyBegin - Begins assembling the matrix. This routine should 5613 be called after completing all calls to MatSetValues(). 5614 5615 Collective on Mat 5616 5617 Input Parameters: 5618 + mat - the matrix 5619 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5620 5621 Notes: 5622 MatSetValues() generally caches the values. The matrix is ready to 5623 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5624 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5625 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5626 using the matrix. 5627 5628 ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the 5629 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 5630 a global collective operation requring all processes that share the matrix. 5631 5632 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5633 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5634 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5635 5636 Level: beginner 5637 5638 .seealso: `MatAssemblyEnd()`, `MatSetValues()`, `MatAssembled()` 5639 @*/ 5640 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type) 5641 { 5642 PetscFunctionBegin; 5643 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5644 PetscValidType(mat,1); 5645 MatCheckPreallocated(mat,1); 5646 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?"); 5647 if (mat->assembled) { 5648 mat->was_assembled = PETSC_TRUE; 5649 mat->assembled = PETSC_FALSE; 5650 } 5651 5652 if (!MatAssemblyEnd_InUse) { 5653 PetscCall(PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0)); 5654 if (mat->ops->assemblybegin) PetscCall((*mat->ops->assemblybegin)(mat,type)); 5655 PetscCall(PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0)); 5656 } else if (mat->ops->assemblybegin) PetscCall((*mat->ops->assemblybegin)(mat,type)); 5657 PetscFunctionReturn(0); 5658 } 5659 5660 /*@ 5661 MatAssembled - Indicates if a matrix has been assembled and is ready for 5662 use; for example, in matrix-vector product. 5663 5664 Not Collective 5665 5666 Input Parameter: 5667 . mat - the matrix 5668 5669 Output Parameter: 5670 . assembled - PETSC_TRUE or PETSC_FALSE 5671 5672 Level: advanced 5673 5674 .seealso: `MatAssemblyEnd()`, `MatSetValues()`, `MatAssemblyBegin()` 5675 @*/ 5676 PetscErrorCode MatAssembled(Mat mat,PetscBool *assembled) 5677 { 5678 PetscFunctionBegin; 5679 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5680 PetscValidBoolPointer(assembled,2); 5681 *assembled = mat->assembled; 5682 PetscFunctionReturn(0); 5683 } 5684 5685 /*@ 5686 MatAssemblyEnd - Completes assembling the matrix. This routine should 5687 be called after MatAssemblyBegin(). 5688 5689 Collective on Mat 5690 5691 Input Parameters: 5692 + mat - the matrix 5693 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5694 5695 Options Database Keys: 5696 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly() 5697 . -mat_view ::ascii_info_detail - Prints more detailed info 5698 . -mat_view - Prints matrix in ASCII format 5699 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 5700 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 5701 . -display <name> - Sets display name (default is host) 5702 . -draw_pause <sec> - Sets number of seconds to pause after display 5703 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab) 5704 . -viewer_socket_machine <machine> - Machine to use for socket 5705 . -viewer_socket_port <port> - Port number to use for socket 5706 - -mat_view binary:filename[:append] - Save matrix to file in binary format 5707 5708 Notes: 5709 MatSetValues() generally caches the values. The matrix is ready to 5710 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5711 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5712 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5713 using the matrix. 5714 5715 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5716 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5717 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5718 5719 Level: beginner 5720 5721 .seealso: `MatAssemblyBegin()`, `MatSetValues()`, `PetscDrawOpenX()`, `PetscDrawCreate()`, `MatView()`, `MatAssembled()`, `PetscViewerSocketOpen()` 5722 @*/ 5723 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type) 5724 { 5725 static PetscInt inassm = 0; 5726 PetscBool flg = PETSC_FALSE; 5727 5728 PetscFunctionBegin; 5729 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5730 PetscValidType(mat,1); 5731 5732 inassm++; 5733 MatAssemblyEnd_InUse++; 5734 if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */ 5735 PetscCall(PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0)); 5736 if (mat->ops->assemblyend) PetscCall((*mat->ops->assemblyend)(mat,type)); 5737 PetscCall(PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0)); 5738 } else if (mat->ops->assemblyend) PetscCall((*mat->ops->assemblyend)(mat,type)); 5739 5740 /* Flush assembly is not a true assembly */ 5741 if (type != MAT_FLUSH_ASSEMBLY) { 5742 if (mat->num_ass) { 5743 if (!mat->symmetry_eternal) { 5744 mat->symmetric = PETSC_BOOL3_UNKNOWN; 5745 mat->hermitian = PETSC_BOOL3_UNKNOWN; 5746 } 5747 if (!mat->structural_symmetry_eternal && mat->ass_nonzerostate != mat->nonzerostate) { 5748 mat->structurally_symmetric = PETSC_BOOL3_UNKNOWN; 5749 } 5750 if (!mat->spd_eternal) mat->spd = PETSC_BOOL3_UNKNOWN; 5751 } 5752 mat->num_ass++; 5753 mat->assembled = PETSC_TRUE; 5754 mat->ass_nonzerostate = mat->nonzerostate; 5755 } 5756 5757 mat->insertmode = NOT_SET_VALUES; 5758 MatAssemblyEnd_InUse--; 5759 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5760 if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) { 5761 PetscCall(MatViewFromOptions(mat,NULL,"-mat_view")); 5762 5763 if (mat->checksymmetryonassembly) { 5764 PetscCall(MatIsSymmetric(mat,mat->checksymmetrytol,&flg)); 5765 if (flg) { 5766 PetscCall(PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol)); 5767 } else { 5768 PetscCall(PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol)); 5769 } 5770 } 5771 if (mat->nullsp && mat->checknullspaceonassembly) { 5772 PetscCall(MatNullSpaceTest(mat->nullsp,mat,NULL)); 5773 } 5774 } 5775 inassm--; 5776 PetscFunctionReturn(0); 5777 } 5778 5779 /*@ 5780 MatSetOption - Sets a parameter option for a matrix. Some options 5781 may be specific to certain storage formats. Some options 5782 determine how values will be inserted (or added). Sorted, 5783 row-oriented input will generally assemble the fastest. The default 5784 is row-oriented. 5785 5786 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5787 5788 Input Parameters: 5789 + mat - the matrix 5790 . option - the option, one of those listed below (and possibly others), 5791 - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5792 5793 Options Describing Matrix Structure: 5794 + MAT_SPD - symmetric positive definite 5795 . MAT_SYMMETRIC - symmetric in terms of both structure and value 5796 . MAT_HERMITIAN - transpose is the complex conjugation 5797 . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure 5798 - MAT_SYMMETRY_ETERNAL - indicates the symmetry (or Hermitian structure) or its absence will persist through any changes to the matrix 5799 - MAT_STRUCTURAL_SYMMETRY_ETERNAL - indicates the structural symmetry or its absence will persist through any changes to the matrix 5800 5801 These are not really options of the matrix, they are knowledge about the structure of the matrix that users may provide so that they 5802 do not need to be computed (usually at a high cost) 5803 5804 Options For Use with MatSetValues(): 5805 Insert a logically dense subblock, which can be 5806 . MAT_ROW_ORIENTED - row-oriented (default) 5807 5808 Note these options reflect the data you pass in with MatSetValues(); it has 5809 nothing to do with how the data is stored internally in the matrix 5810 data structure. 5811 5812 When (re)assembling a matrix, we can restrict the input for 5813 efficiency/debugging purposes. These options include 5814 + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow) 5815 . MAT_FORCE_DIAGONAL_ENTRIES - forces diagonal entries to be allocated 5816 . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries 5817 . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry 5818 . MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly 5819 . MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if 5820 any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves 5821 performance for very large process counts. 5822 - MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset 5823 of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly 5824 functions, instead sending only neighbor messages. 5825 5826 Notes: 5827 Except for MAT_UNUSED_NONZERO_LOCATION_ERR and MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg! 5828 5829 Some options are relevant only for particular matrix types and 5830 are thus ignored by others. Other options are not supported by 5831 certain matrix types and will generate an error message if set. 5832 5833 If using a Fortran 77 module to compute a matrix, one may need to 5834 use the column-oriented option (or convert to the row-oriented 5835 format). 5836 5837 MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion 5838 that would generate a new entry in the nonzero structure is instead 5839 ignored. Thus, if memory has not alredy been allocated for this particular 5840 data, then the insertion is ignored. For dense matrices, in which 5841 the entire array is allocated, no entries are ever ignored. 5842 Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5843 5844 MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5845 that would generate a new entry in the nonzero structure instead produces 5846 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 5847 5848 MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5849 that would generate a new entry that has not been preallocated will 5850 instead produce an error. (Currently supported for AIJ and BAIJ formats 5851 only.) This is a useful flag when debugging matrix memory preallocation. 5852 If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5853 5854 MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for 5855 other processors should be dropped, rather than stashed. 5856 This is useful if you know that the "owning" processor is also 5857 always generating the correct matrix entries, so that PETSc need 5858 not transfer duplicate entries generated on another processor. 5859 5860 MAT_USE_HASH_TABLE indicates that a hash table be used to improve the 5861 searches during matrix assembly. When this flag is set, the hash table 5862 is created during the first Matrix Assembly. This hash table is 5863 used the next time through, during MatSetVaules()/MatSetVaulesBlocked() 5864 to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag 5865 should be used with MAT_USE_HASH_TABLE flag. This option is currently 5866 supported by MATMPIBAIJ format only. 5867 5868 MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries 5869 are kept in the nonzero structure 5870 5871 MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating 5872 a zero location in the matrix 5873 5874 MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types 5875 5876 MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the 5877 zero row routines and thus improves performance for very large process counts. 5878 5879 MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular 5880 part of the matrix (since they should match the upper triangular part). 5881 5882 MAT_SORTED_FULL - each process provides exactly its local rows; all column indices for a given row are passed in a 5883 single call to MatSetValues(), preallocation is perfect, row oriented, INSERT_VALUES is used. Common 5884 with finite difference schemes with non-periodic boundary conditions. 5885 5886 Level: intermediate 5887 5888 .seealso: `MatOption`, `Mat`, `MatGetOption()` 5889 5890 @*/ 5891 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg) 5892 { 5893 PetscFunctionBegin; 5894 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5895 if (op > 0) { 5896 PetscValidLogicalCollectiveEnum(mat,op,2); 5897 PetscValidLogicalCollectiveBool(mat,flg,3); 5898 } 5899 5900 PetscCheck(((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); 5901 5902 switch (op) { 5903 case MAT_FORCE_DIAGONAL_ENTRIES: 5904 mat->force_diagonals = flg; 5905 PetscFunctionReturn(0); 5906 case MAT_NO_OFF_PROC_ENTRIES: 5907 mat->nooffprocentries = flg; 5908 PetscFunctionReturn(0); 5909 case MAT_SUBSET_OFF_PROC_ENTRIES: 5910 mat->assembly_subset = flg; 5911 if (!mat->assembly_subset) { /* See the same logic in VecAssembly wrt VEC_SUBSET_OFF_PROC_ENTRIES */ 5912 #if !defined(PETSC_HAVE_MPIUNI) 5913 PetscCall(MatStashScatterDestroy_BTS(&mat->stash)); 5914 #endif 5915 mat->stash.first_assembly_done = PETSC_FALSE; 5916 } 5917 PetscFunctionReturn(0); 5918 case MAT_NO_OFF_PROC_ZERO_ROWS: 5919 mat->nooffproczerorows = flg; 5920 PetscFunctionReturn(0); 5921 case MAT_SPD: 5922 if (flg) { 5923 mat->spd = PETSC_BOOL3_TRUE; 5924 mat->symmetric = PETSC_BOOL3_TRUE; 5925 mat->structurally_symmetric = PETSC_BOOL3_TRUE; 5926 } else { 5927 mat->spd = PETSC_BOOL3_FALSE; 5928 } 5929 break; 5930 case MAT_SYMMETRIC: 5931 mat->symmetric = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5932 if (flg) mat->structurally_symmetric = PETSC_BOOL3_TRUE; 5933 #if !defined(PETSC_USE_COMPLEX) 5934 mat->hermitian = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5935 #endif 5936 break; 5937 case MAT_HERMITIAN: 5938 mat->hermitian = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5939 if (flg) mat->structurally_symmetric = PETSC_BOOL3_TRUE; 5940 #if !defined(PETSC_USE_COMPLEX) 5941 mat->symmetric = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5942 #endif 5943 break; 5944 case MAT_STRUCTURALLY_SYMMETRIC: 5945 mat->structurally_symmetric = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5946 break; 5947 case MAT_SYMMETRY_ETERNAL: 5948 mat->symmetry_eternal = flg ? PETSC_TRUE : PETSC_FALSE; 5949 if (flg) mat->structural_symmetry_eternal = PETSC_TRUE; 5950 break; 5951 case MAT_STRUCTURAL_SYMMETRY_ETERNAL: 5952 mat->structural_symmetry_eternal = flg; 5953 break; 5954 case MAT_SPD_ETERNAL: 5955 mat->spd_eternal = flg; 5956 if (flg) { 5957 mat->structural_symmetry_eternal = PETSC_TRUE; 5958 mat->symmetry_eternal = PETSC_TRUE; 5959 } 5960 break; 5961 case MAT_STRUCTURE_ONLY: 5962 mat->structure_only = flg; 5963 break; 5964 case MAT_SORTED_FULL: 5965 mat->sortedfull = flg; 5966 break; 5967 default: 5968 break; 5969 } 5970 if (mat->ops->setoption) PetscCall((*mat->ops->setoption)(mat,op,flg)); 5971 PetscFunctionReturn(0); 5972 } 5973 5974 /*@ 5975 MatGetOption - Gets a parameter option that has been set for a matrix. 5976 5977 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5978 5979 Input Parameters: 5980 + mat - the matrix 5981 - option - the option, this only responds to certain options, check the code for which ones 5982 5983 Output Parameter: 5984 . flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5985 5986 Notes: 5987 Can only be called after MatSetSizes() and MatSetType() have been set. 5988 5989 Certain option values may be unknown, for those use the routines `MatIsSymmetric()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, or 5990 `MatIsSymmetricKnown()`, `MatIsHermitianKnown()`, `MatIsStructurallySymmetricKnown()` 5991 5992 Level: intermediate 5993 5994 .seealso: `MatOption`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, 5995 `MatIsSymmetricKnown()`, `MatIsHermitianKnown()`, `MatIsStructurallySymmetricKnown()` 5996 5997 @*/ 5998 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg) 5999 { 6000 PetscFunctionBegin; 6001 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6002 PetscValidType(mat,1); 6003 6004 PetscCheck(((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); 6005 PetscCheck(((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()"); 6006 6007 switch (op) { 6008 case MAT_NO_OFF_PROC_ENTRIES: 6009 *flg = mat->nooffprocentries; 6010 break; 6011 case MAT_NO_OFF_PROC_ZERO_ROWS: 6012 *flg = mat->nooffproczerorows; 6013 break; 6014 case MAT_SYMMETRIC: 6015 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Use MatIsSymmetric() or MatIsSymmetricKnown()"); 6016 break; 6017 case MAT_HERMITIAN: 6018 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Use MatIsHermitian() or MatIsHermitianKnown()"); 6019 break; 6020 case MAT_STRUCTURALLY_SYMMETRIC: 6021 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Use MatIsStructurallySymmetric() or MatIsStructurallySymmetricKnown()"); 6022 break; 6023 case MAT_SPD: 6024 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Use MatIsSPDKnown()"); 6025 break; 6026 case MAT_SYMMETRY_ETERNAL: 6027 *flg = mat->symmetry_eternal; 6028 break; 6029 case MAT_STRUCTURAL_SYMMETRY_ETERNAL: 6030 *flg = mat->symmetry_eternal; 6031 break; 6032 default: 6033 break; 6034 } 6035 PetscFunctionReturn(0); 6036 } 6037 6038 /*@ 6039 MatZeroEntries - Zeros all entries of a matrix. For sparse matrices 6040 this routine retains the old nonzero structure. 6041 6042 Logically Collective on Mat 6043 6044 Input Parameters: 6045 . mat - the matrix 6046 6047 Level: intermediate 6048 6049 Notes: 6050 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. 6051 See the Performance chapter of the users manual for information on preallocating matrices. 6052 6053 .seealso: `MatZeroRows()` 6054 @*/ 6055 PetscErrorCode MatZeroEntries(Mat mat) 6056 { 6057 PetscFunctionBegin; 6058 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6059 PetscValidType(mat,1); 6060 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6061 PetscCheck(mat->insertmode == NOT_SET_VALUES,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for matrices where you have set values but not yet assembled"); 6062 PetscCheck(mat->ops->zeroentries,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6063 MatCheckPreallocated(mat,1); 6064 6065 PetscCall(PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0)); 6066 PetscCall((*mat->ops->zeroentries)(mat)); 6067 PetscCall(PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0)); 6068 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6069 PetscFunctionReturn(0); 6070 } 6071 6072 /*@ 6073 MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal) 6074 of a set of rows and columns of a matrix. 6075 6076 Collective on Mat 6077 6078 Input Parameters: 6079 + mat - the matrix 6080 . numRows - the number of rows to remove 6081 . rows - the global row indices 6082 . diag - value put in the diagonal of the eliminated rows 6083 . x - optional vector of solutions for zeroed rows (other entries in vector are not used), these must be set before this call 6084 - b - optional vector of right hand side, that will be adjusted by provided solution 6085 6086 Notes: 6087 This routine, along with `MatZeroRows()`, is typically used to eliminate known Dirichlet boundary conditions from a linear system. 6088 6089 For each zeroed row, the value of the corresponding b is set to diag times the value of the corresponding x. 6090 The other entries of b will be adjusted by the known values of x times the corresponding matrix entries in the columns that are being eliminated 6091 6092 If the resulting linear system is to be solved with KSP then one can (but does not have to) call `KSPSetInitialGuessNonzero()` to allow the 6093 Krylov method to take advantage of the known solution on the zeroed rows. 6094 6095 For the parallel case, all processes that share the matrix (i.e., 6096 those in the communicator used for matrix creation) MUST call this 6097 routine, regardless of whether any rows being zeroed are owned by 6098 them. 6099 6100 Unlike `MatZeroRows()` this does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 6101 6102 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6103 list only rows local to itself). 6104 6105 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 6106 6107 Level: intermediate 6108 6109 .seealso: `MatZeroRowsIS()`, `MatZeroRows()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6110 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6111 @*/ 6112 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6113 { 6114 PetscFunctionBegin; 6115 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6116 PetscValidType(mat,1); 6117 if (numRows) PetscValidIntPointer(rows,3); 6118 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6119 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6120 PetscCheck(mat->ops->zerorowscolumns,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6121 MatCheckPreallocated(mat,1); 6122 6123 PetscCall((*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b)); 6124 PetscCall(MatViewFromOptions(mat,NULL,"-mat_view")); 6125 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6126 PetscFunctionReturn(0); 6127 } 6128 6129 /*@ 6130 MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal) 6131 of a set of rows and columns of a matrix. 6132 6133 Collective on Mat 6134 6135 Input Parameters: 6136 + mat - the matrix 6137 . is - the rows to zero 6138 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6139 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6140 - b - optional vector of right hand side, that will be adjusted by provided solution 6141 6142 Note: 6143 See `MatZeroRowsColumns()` for details on how this routine operates. 6144 6145 Level: intermediate 6146 6147 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6148 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRows()`, `MatZeroRowsColumnsStencil()` 6149 @*/ 6150 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6151 { 6152 PetscInt numRows; 6153 const PetscInt *rows; 6154 6155 PetscFunctionBegin; 6156 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6157 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6158 PetscValidType(mat,1); 6159 PetscValidType(is,2); 6160 PetscCall(ISGetLocalSize(is,&numRows)); 6161 PetscCall(ISGetIndices(is,&rows)); 6162 PetscCall(MatZeroRowsColumns(mat,numRows,rows,diag,x,b)); 6163 PetscCall(ISRestoreIndices(is,&rows)); 6164 PetscFunctionReturn(0); 6165 } 6166 6167 /*@ 6168 MatZeroRows - Zeros all entries (except possibly the main diagonal) 6169 of a set of rows of a matrix. 6170 6171 Collective on Mat 6172 6173 Input Parameters: 6174 + mat - the matrix 6175 . numRows - the number of rows to remove 6176 . rows - the global row indices 6177 . diag - value put in the diagonal of the eliminated rows 6178 . x - optional vector of solutions for zeroed rows (other entries in vector are not used), these must be set before this call 6179 - b - optional vector of right hand side, that will be adjusted by provided solution 6180 6181 Notes: 6182 This routine, along with `MatZeroRowsColumns()`, is typically used to eliminate known Dirichlet boundary conditions from a linear system. 6183 6184 For each zeroed row, the value of the corresponding b is set to diag times the value of the corresponding x. 6185 6186 If the resulting linear system is to be solved with KSP then one can (but does not have to) call `KSPSetInitialGuessNonzero()` to allow the 6187 Krylov method to take advantage of the known solution on the zeroed rows. 6188 6189 May be followed by using a `PC` of type `PCREDISTRIBUTE` to solve the reducing problem (after completely eliminating the zeroed rows and their corresponding columns) 6190 from the matrix. 6191 6192 Unlike `MatZeroRowsColumns()` for the AIJ and BAIJ matrix formats this removes the old nonzero structure, from the eliminated rows of the matrix 6193 but does not release memory. Because of this removal matrix-vector products with the adjusted matrix will be a bit faster. For the dense and block diagonal 6194 formats this does not alter the nonzero structure. 6195 6196 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6197 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6198 merely zeroed. 6199 6200 The user can set a value in the diagonal entry (or for the AIJ and 6201 row formats can optionally remove the main diagonal entry from the 6202 nonzero structure as well, by passing 0.0 as the final argument). 6203 6204 For the parallel case, all processes that share the matrix (i.e., 6205 those in the communicator used for matrix creation) MUST call this 6206 routine, regardless of whether any rows being zeroed are owned by 6207 them. 6208 6209 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6210 list only rows local to itself). 6211 6212 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6213 owns that are to be zeroed. This saves a global synchronization in the implementation. 6214 6215 Level: intermediate 6216 6217 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6218 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()`, `PCREDISTRIBUTE` 6219 @*/ 6220 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6221 { 6222 PetscFunctionBegin; 6223 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6224 PetscValidType(mat,1); 6225 if (numRows) PetscValidIntPointer(rows,3); 6226 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6227 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6228 PetscCheck(mat->ops->zerorows,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6229 MatCheckPreallocated(mat,1); 6230 6231 PetscCall((*mat->ops->zerorows)(mat,numRows,rows,diag,x,b)); 6232 PetscCall(MatViewFromOptions(mat,NULL,"-mat_view")); 6233 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6234 PetscFunctionReturn(0); 6235 } 6236 6237 /*@ 6238 MatZeroRowsIS - Zeros all entries (except possibly the main diagonal) 6239 of a set of rows of a matrix. 6240 6241 Collective on Mat 6242 6243 Input Parameters: 6244 + mat - the matrix 6245 . is - index set of rows to remove (if NULL then no row is removed) 6246 . diag - value put in all diagonals of eliminated rows 6247 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6248 - b - optional vector of right hand side, that will be adjusted by provided solution 6249 6250 Note: 6251 See `MatZeroRows()` for details on how this routine operates. 6252 6253 Level: intermediate 6254 6255 .seealso: `MatZeroRows()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6256 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6257 @*/ 6258 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6259 { 6260 PetscInt numRows = 0; 6261 const PetscInt *rows = NULL; 6262 6263 PetscFunctionBegin; 6264 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6265 PetscValidType(mat,1); 6266 if (is) { 6267 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6268 PetscCall(ISGetLocalSize(is,&numRows)); 6269 PetscCall(ISGetIndices(is,&rows)); 6270 } 6271 PetscCall(MatZeroRows(mat,numRows,rows,diag,x,b)); 6272 if (is) { 6273 PetscCall(ISRestoreIndices(is,&rows)); 6274 } 6275 PetscFunctionReturn(0); 6276 } 6277 6278 /*@ 6279 MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal) 6280 of a set of rows of a matrix. These rows must be local to the process. 6281 6282 Collective on Mat 6283 6284 Input Parameters: 6285 + mat - the matrix 6286 . numRows - the number of rows to remove 6287 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 6288 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6289 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6290 - b - optional vector of right hand side, that will be adjusted by provided solution 6291 6292 Notes: 6293 See `MatZeroRows()` for details on how this routine operates. 6294 6295 The grid coordinates are across the entire grid, not just the local portion 6296 6297 In Fortran idxm and idxn should be declared as 6298 $ MatStencil idxm(4,m) 6299 and the values inserted using 6300 $ idxm(MatStencil_i,1) = i 6301 $ idxm(MatStencil_j,1) = j 6302 $ idxm(MatStencil_k,1) = k 6303 $ idxm(MatStencil_c,1) = c 6304 etc 6305 6306 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6307 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6308 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6309 DM_BOUNDARY_PERIODIC boundary type. 6310 6311 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 6312 a single value per point) you can skip filling those indices. 6313 6314 Level: intermediate 6315 6316 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsl()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6317 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6318 @*/ 6319 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 6320 { 6321 PetscInt dim = mat->stencil.dim; 6322 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 6323 PetscInt *dims = mat->stencil.dims+1; 6324 PetscInt *starts = mat->stencil.starts; 6325 PetscInt *dxm = (PetscInt*) rows; 6326 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6327 6328 PetscFunctionBegin; 6329 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6330 PetscValidType(mat,1); 6331 if (numRows) PetscValidPointer(rows,3); 6332 6333 PetscCall(PetscMalloc1(numRows, &jdxm)); 6334 for (i = 0; i < numRows; ++i) { 6335 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6336 for (j = 0; j < 3-sdim; ++j) dxm++; 6337 /* Local index in X dir */ 6338 tmp = *dxm++ - starts[0]; 6339 /* Loop over remaining dimensions */ 6340 for (j = 0; j < dim-1; ++j) { 6341 /* If nonlocal, set index to be negative */ 6342 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6343 /* Update local index */ 6344 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6345 } 6346 /* Skip component slot if necessary */ 6347 if (mat->stencil.noc) dxm++; 6348 /* Local row number */ 6349 if (tmp >= 0) { 6350 jdxm[numNewRows++] = tmp; 6351 } 6352 } 6353 PetscCall(MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b)); 6354 PetscCall(PetscFree(jdxm)); 6355 PetscFunctionReturn(0); 6356 } 6357 6358 /*@ 6359 MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal) 6360 of a set of rows and columns of a matrix. 6361 6362 Collective on Mat 6363 6364 Input Parameters: 6365 + mat - the matrix 6366 . numRows - the number of rows/columns to remove 6367 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 6368 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6369 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6370 - b - optional vector of right hand side, that will be adjusted by provided solution 6371 6372 Notes: 6373 See `MatZeroRowsColumns()` for details on how this routine operates. 6374 6375 The grid coordinates are across the entire grid, not just the local portion 6376 6377 In Fortran idxm and idxn should be declared as 6378 $ MatStencil idxm(4,m) 6379 and the values inserted using 6380 $ idxm(MatStencil_i,1) = i 6381 $ idxm(MatStencil_j,1) = j 6382 $ idxm(MatStencil_k,1) = k 6383 $ idxm(MatStencil_c,1) = c 6384 etc 6385 6386 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6387 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6388 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6389 DM_BOUNDARY_PERIODIC boundary type. 6390 6391 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 6392 a single value per point) you can skip filling those indices. 6393 6394 Level: intermediate 6395 6396 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6397 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRows()` 6398 @*/ 6399 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 6400 { 6401 PetscInt dim = mat->stencil.dim; 6402 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 6403 PetscInt *dims = mat->stencil.dims+1; 6404 PetscInt *starts = mat->stencil.starts; 6405 PetscInt *dxm = (PetscInt*) rows; 6406 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6407 6408 PetscFunctionBegin; 6409 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6410 PetscValidType(mat,1); 6411 if (numRows) PetscValidPointer(rows,3); 6412 6413 PetscCall(PetscMalloc1(numRows, &jdxm)); 6414 for (i = 0; i < numRows; ++i) { 6415 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6416 for (j = 0; j < 3-sdim; ++j) dxm++; 6417 /* Local index in X dir */ 6418 tmp = *dxm++ - starts[0]; 6419 /* Loop over remaining dimensions */ 6420 for (j = 0; j < dim-1; ++j) { 6421 /* If nonlocal, set index to be negative */ 6422 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6423 /* Update local index */ 6424 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6425 } 6426 /* Skip component slot if necessary */ 6427 if (mat->stencil.noc) dxm++; 6428 /* Local row number */ 6429 if (tmp >= 0) { 6430 jdxm[numNewRows++] = tmp; 6431 } 6432 } 6433 PetscCall(MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b)); 6434 PetscCall(PetscFree(jdxm)); 6435 PetscFunctionReturn(0); 6436 } 6437 6438 /*@C 6439 MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal) 6440 of a set of rows of a matrix; using local numbering of rows. 6441 6442 Collective on Mat 6443 6444 Input Parameters: 6445 + mat - the matrix 6446 . numRows - the number of rows to remove 6447 . rows - the local row indices 6448 . diag - value put in all diagonals of eliminated rows 6449 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6450 - b - optional vector of right hand side, that will be adjusted by provided solution 6451 6452 Notes: 6453 Before calling `MatZeroRowsLocal()`, the user must first set the 6454 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6455 6456 See `MatZeroRows()` for details on how this routine operates. 6457 6458 Level: intermediate 6459 6460 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRows()`, `MatSetOption()`, 6461 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6462 @*/ 6463 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6464 { 6465 PetscFunctionBegin; 6466 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6467 PetscValidType(mat,1); 6468 if (numRows) PetscValidIntPointer(rows,3); 6469 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6470 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6471 MatCheckPreallocated(mat,1); 6472 6473 if (mat->ops->zerorowslocal) { 6474 PetscCall((*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b)); 6475 } else { 6476 IS is, newis; 6477 const PetscInt *newRows; 6478 6479 PetscCheck(mat->rmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6480 PetscCall(ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is)); 6481 PetscCall(ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis)); 6482 PetscCall(ISGetIndices(newis,&newRows)); 6483 PetscCall((*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b)); 6484 PetscCall(ISRestoreIndices(newis,&newRows)); 6485 PetscCall(ISDestroy(&newis)); 6486 PetscCall(ISDestroy(&is)); 6487 } 6488 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6489 PetscFunctionReturn(0); 6490 } 6491 6492 /*@ 6493 MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal) 6494 of a set of rows of a matrix; using local numbering of rows. 6495 6496 Collective on Mat 6497 6498 Input Parameters: 6499 + mat - the matrix 6500 . is - index set of rows to remove 6501 . diag - value put in all diagonals of eliminated rows 6502 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6503 - b - optional vector of right hand side, that will be adjusted by provided solution 6504 6505 Notes: 6506 Before calling `MatZeroRowsLocalIS()`, the user must first set the 6507 local-to-global mapping by calling `MatSetLocalToGlobalMapping()`. 6508 6509 See `MatZeroRows()` for details on how this routine operates. 6510 6511 Level: intermediate 6512 6513 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRows()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6514 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6515 @*/ 6516 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6517 { 6518 PetscInt numRows; 6519 const PetscInt *rows; 6520 6521 PetscFunctionBegin; 6522 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6523 PetscValidType(mat,1); 6524 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6525 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6526 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6527 MatCheckPreallocated(mat,1); 6528 6529 PetscCall(ISGetLocalSize(is,&numRows)); 6530 PetscCall(ISGetIndices(is,&rows)); 6531 PetscCall(MatZeroRowsLocal(mat,numRows,rows,diag,x,b)); 6532 PetscCall(ISRestoreIndices(is,&rows)); 6533 PetscFunctionReturn(0); 6534 } 6535 6536 /*@ 6537 MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal) 6538 of a set of rows and columns of a matrix; using local numbering of rows. 6539 6540 Collective on Mat 6541 6542 Input Parameters: 6543 + mat - the matrix 6544 . numRows - the number of rows to remove 6545 . rows - the global row indices 6546 . diag - value put in all diagonals of eliminated rows 6547 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6548 - b - optional vector of right hand side, that will be adjusted by provided solution 6549 6550 Notes: 6551 Before calling MatZeroRowsColumnsLocal(), the user must first set the 6552 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6553 6554 See `MatZeroRowsColumns()` for details on how this routine operates. 6555 6556 Level: intermediate 6557 6558 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6559 `MatZeroRows()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6560 @*/ 6561 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6562 { 6563 IS is, newis; 6564 const PetscInt *newRows; 6565 6566 PetscFunctionBegin; 6567 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6568 PetscValidType(mat,1); 6569 if (numRows) PetscValidIntPointer(rows,3); 6570 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6571 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6572 MatCheckPreallocated(mat,1); 6573 6574 PetscCheck(mat->cmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6575 PetscCall(ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is)); 6576 PetscCall(ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis)); 6577 PetscCall(ISGetIndices(newis,&newRows)); 6578 PetscCall((*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b)); 6579 PetscCall(ISRestoreIndices(newis,&newRows)); 6580 PetscCall(ISDestroy(&newis)); 6581 PetscCall(ISDestroy(&is)); 6582 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6583 PetscFunctionReturn(0); 6584 } 6585 6586 /*@ 6587 MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal) 6588 of a set of rows and columns of a matrix; using local numbering of rows. 6589 6590 Collective on Mat 6591 6592 Input Parameters: 6593 + mat - the matrix 6594 . is - index set of rows to remove 6595 . diag - value put in all diagonals of eliminated rows 6596 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6597 - b - optional vector of right hand side, that will be adjusted by provided solution 6598 6599 Notes: 6600 Before calling `MatZeroRowsColumnsLocalIS()`, the user must first set the 6601 local-to-global mapping by calling `MatSetLocalToGlobalMapping()`. 6602 6603 See `MatZeroRowsColumns()` for details on how this routine operates. 6604 6605 Level: intermediate 6606 6607 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6608 `MatZeroRowsColumnsLocal()`, `MatZeroRows()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6609 @*/ 6610 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6611 { 6612 PetscInt numRows; 6613 const PetscInt *rows; 6614 6615 PetscFunctionBegin; 6616 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6617 PetscValidType(mat,1); 6618 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6619 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6620 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6621 MatCheckPreallocated(mat,1); 6622 6623 PetscCall(ISGetLocalSize(is,&numRows)); 6624 PetscCall(ISGetIndices(is,&rows)); 6625 PetscCall(MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b)); 6626 PetscCall(ISRestoreIndices(is,&rows)); 6627 PetscFunctionReturn(0); 6628 } 6629 6630 /*@C 6631 MatGetSize - Returns the numbers of rows and columns in a matrix. 6632 6633 Not Collective 6634 6635 Input Parameter: 6636 . mat - the matrix 6637 6638 Output Parameters: 6639 + m - the number of global rows 6640 - n - the number of global columns 6641 6642 Note: both output parameters can be NULL on input. 6643 6644 Level: beginner 6645 6646 .seealso: `MatGetLocalSize()` 6647 @*/ 6648 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n) 6649 { 6650 PetscFunctionBegin; 6651 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6652 if (m) *m = mat->rmap->N; 6653 if (n) *n = mat->cmap->N; 6654 PetscFunctionReturn(0); 6655 } 6656 6657 /*@C 6658 MatGetLocalSize - For most matrix formats, excluding `MATELEMENTAL` and `MATSCALAPACK`, Returns the number of local rows and local columns 6659 of a matrix. For all matrices this is the local size of the left and right vectors as returned by MatCreateVecs(). 6660 6661 Not Collective 6662 6663 Input Parameter: 6664 . mat - the matrix 6665 6666 Output Parameters: 6667 + m - the number of local rows, use `NULL` to not obtain this value 6668 - n - the number of local columns, use `NULL` to not obtain this value 6669 6670 Level: beginner 6671 6672 .seealso: `MatGetSize()` 6673 @*/ 6674 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n) 6675 { 6676 PetscFunctionBegin; 6677 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6678 if (m) PetscValidIntPointer(m,2); 6679 if (n) PetscValidIntPointer(n,3); 6680 if (m) *m = mat->rmap->n; 6681 if (n) *n = mat->cmap->n; 6682 PetscFunctionReturn(0); 6683 } 6684 6685 /*@C 6686 MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies this matrix by that are owned by 6687 this processor. (The columns of the "diagonal block" for most sparse matrix formats). See :any:`<sec_matlayout>` for details on matrix layouts. 6688 6689 Not Collective, unless matrix has not been allocated, then collective on Mat 6690 6691 Input Parameter: 6692 . mat - the matrix 6693 6694 Output Parameters: 6695 + m - the global index of the first local column, use `NULL` to not obtain this value 6696 - n - one more than the global index of the last local column, use `NULL` to not obtain this value 6697 6698 Level: developer 6699 6700 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRanges()`, `MatGetOwnershipRangesColumn()`, `PetscLayout` 6701 6702 @*/ 6703 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n) 6704 { 6705 PetscFunctionBegin; 6706 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6707 PetscValidType(mat,1); 6708 if (m) PetscValidIntPointer(m,2); 6709 if (n) PetscValidIntPointer(n,3); 6710 MatCheckPreallocated(mat,1); 6711 if (m) *m = mat->cmap->rstart; 6712 if (n) *n = mat->cmap->rend; 6713 PetscFunctionReturn(0); 6714 } 6715 6716 /*@C 6717 MatGetOwnershipRange - For matrices that own values by row, excludes `MATELEMENTAL` and `MATSCALAPACK`, returns the range of matrix rows owned by 6718 this MPI rank. For all matrices it returns the range of matrix rows associated with rows of a vector that would contain the result of a matrix 6719 vector product with this matrix. See :any:`<sec_matlayout>` for details on matrix layouts 6720 6721 Not Collective 6722 6723 Input Parameter: 6724 . mat - the matrix 6725 6726 Output Parameters: 6727 + m - the global index of the first local row, use `NULL` to not obtain this value 6728 - n - one more than the global index of the last local row, use `NULL` to not obtain this value 6729 6730 Note: 6731 This function requires that the matrix be preallocated. If you have not preallocated, consider using 6732 `PetscSplitOwnership`(`MPI_Comm` comm, `PetscInt` *n, `PetscInt` *N) 6733 and then `MPI_Scan()` to calculate prefix sums of the local sizes. 6734 6735 Level: beginner 6736 6737 .seealso: `MatGetOwnershipRanges()`, `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRangesColumn()`, `PetscSplitOwnership()`, `PetscSplitOwnershipBlock()`, 6738 `PetscLayout` 6739 6740 @*/ 6741 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n) 6742 { 6743 PetscFunctionBegin; 6744 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6745 PetscValidType(mat,1); 6746 if (m) PetscValidIntPointer(m,2); 6747 if (n) PetscValidIntPointer(n,3); 6748 MatCheckPreallocated(mat,1); 6749 if (m) *m = mat->rmap->rstart; 6750 if (n) *n = mat->rmap->rend; 6751 PetscFunctionReturn(0); 6752 } 6753 6754 /*@C 6755 MatGetOwnershipRanges - For matrices that own values by row, excludes `MATELEMENTAL` and `MATSCALAPACK`, returns the range of matrix rows owned by 6756 each process. For all matrices it returns the ranges of matrix rows associated with rows of a vector that would contain the result of a matrix 6757 vector product with this matrix. See :any:`<sec_matlayout>` for details on matrix layouts 6758 6759 Not Collective, unless matrix has not been allocated, then collective on Mat 6760 6761 Input Parameters: 6762 . mat - the matrix 6763 6764 Output Parameters: 6765 . ranges - start of each processors portion plus one more than the total length at the end 6766 6767 Level: beginner 6768 6769 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRangesColumn()`, `PetscLayout` 6770 6771 @*/ 6772 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges) 6773 { 6774 PetscFunctionBegin; 6775 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6776 PetscValidType(mat,1); 6777 MatCheckPreallocated(mat,1); 6778 PetscCall(PetscLayoutGetRanges(mat->rmap,ranges)); 6779 PetscFunctionReturn(0); 6780 } 6781 6782 /*@C 6783 MatGetOwnershipRangesColumn - Returns the ranges of matrix columns associated with rows of a vector one multiplies this vector by that are owned by 6784 each processor. (The columns of the "diagonal blocks", for most sparse matrix formats). See :any:`<sec_matlayout>` for details on matrix layouts. 6785 6786 Not Collective, unless matrix has not been allocated, then collective on Mat 6787 6788 Input Parameters: 6789 . mat - the matrix 6790 6791 Output Parameters: 6792 . ranges - start of each processors portion plus one more then the total length at the end 6793 6794 Level: beginner 6795 6796 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRanges()` 6797 6798 @*/ 6799 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges) 6800 { 6801 PetscFunctionBegin; 6802 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6803 PetscValidType(mat,1); 6804 MatCheckPreallocated(mat,1); 6805 PetscCall(PetscLayoutGetRanges(mat->cmap,ranges)); 6806 PetscFunctionReturn(0); 6807 } 6808 6809 /*@C 6810 MatGetOwnershipIS - Get row and column ownership of a matrices' values as index sets. For most matrices, excluding `MATELEMENTAL` and `MATSCALAPACK`, this 6811 corresponds to values returned by `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`. For `MATELEMENTAL` and `MATSCALAPACK` the ownership 6812 is more complicated. See :any:`<sec_matlayout>` for details on matrix layouts. 6813 6814 Not Collective 6815 6816 Input Parameter: 6817 . A - matrix 6818 6819 Output Parameters: 6820 + rows - rows in which this process owns elements, , use `NULL` to not obtain this value 6821 - cols - columns in which this process owns elements, use `NULL` to not obtain this value 6822 6823 Level: intermediate 6824 6825 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`, `MatSetValues()`, ``MATELEMENTAL``, ``MATSCALAPACK`` 6826 @*/ 6827 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols) 6828 { 6829 PetscErrorCode (*f)(Mat,IS*,IS*); 6830 6831 PetscFunctionBegin; 6832 MatCheckPreallocated(A,1); 6833 PetscCall(PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f)); 6834 if (f) { 6835 PetscCall((*f)(A,rows,cols)); 6836 } else { /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */ 6837 if (rows) PetscCall(ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows)); 6838 if (cols) PetscCall(ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols)); 6839 } 6840 PetscFunctionReturn(0); 6841 } 6842 6843 /*@C 6844 MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix. 6845 Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric() 6846 to complete the factorization. 6847 6848 Collective on Mat 6849 6850 Input Parameters: 6851 + mat - the matrix 6852 . row - row permutation 6853 . column - column permutation 6854 - info - structure containing 6855 $ levels - number of levels of fill. 6856 $ expected fill - as ratio of original fill. 6857 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 6858 missing diagonal entries) 6859 6860 Output Parameters: 6861 . fact - new matrix that has been symbolically factored 6862 6863 Notes: 6864 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 6865 6866 Most users should employ the simplified KSP interface for linear solvers 6867 instead of working directly with matrix algebra routines such as this. 6868 See, e.g., KSPCreate(). 6869 6870 Level: developer 6871 6872 .seealso: `MatLUFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()` 6873 `MatGetOrdering()`, `MatFactorInfo` 6874 6875 Note: this uses the definition of level of fill as in Y. Saad, 2003 6876 6877 Developer Note: fortran interface is not autogenerated as the f90 6878 interface definition cannot be generated correctly [due to MatFactorInfo] 6879 6880 References: 6881 . * - Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6882 @*/ 6883 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 6884 { 6885 PetscFunctionBegin; 6886 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 6887 PetscValidType(mat,2); 6888 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,3); 6889 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,4); 6890 PetscValidPointer(info,5); 6891 PetscValidPointer(fact,1); 6892 PetscCheck(info->levels >= 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %" PetscInt_FMT,(PetscInt)info->levels); 6893 PetscCheck(info->fill >= 1.0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6894 if (!fact->ops->ilufactorsymbolic) { 6895 MatSolverType stype; 6896 PetscCall(MatFactorGetSolverType(fact,&stype)); 6897 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver type %s",((PetscObject)mat)->type_name,stype); 6898 } 6899 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6900 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6901 MatCheckPreallocated(mat,2); 6902 6903 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0)); 6904 PetscCall((fact->ops->ilufactorsymbolic)(fact,mat,row,col,info)); 6905 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0)); 6906 PetscFunctionReturn(0); 6907 } 6908 6909 /*@C 6910 MatICCFactorSymbolic - Performs symbolic incomplete 6911 Cholesky factorization for a symmetric matrix. Use 6912 MatCholeskyFactorNumeric() to complete the factorization. 6913 6914 Collective on Mat 6915 6916 Input Parameters: 6917 + mat - the matrix 6918 . perm - row and column permutation 6919 - info - structure containing 6920 $ levels - number of levels of fill. 6921 $ expected fill - as ratio of original fill. 6922 6923 Output Parameter: 6924 . fact - the factored matrix 6925 6926 Notes: 6927 Most users should employ the KSP interface for linear solvers 6928 instead of working directly with matrix algebra routines such as this. 6929 See, e.g., KSPCreate(). 6930 6931 Level: developer 6932 6933 .seealso: `MatCholeskyFactorNumeric()`, `MatCholeskyFactor()`, `MatFactorInfo` 6934 6935 Note: this uses the definition of level of fill as in Y. Saad, 2003 6936 6937 Developer Note: fortran interface is not autogenerated as the f90 6938 interface definition cannot be generated correctly [due to MatFactorInfo] 6939 6940 References: 6941 . * - Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6942 @*/ 6943 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 6944 { 6945 PetscFunctionBegin; 6946 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 6947 PetscValidType(mat,2); 6948 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,3); 6949 PetscValidPointer(info,4); 6950 PetscValidPointer(fact,1); 6951 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6952 PetscCheck(info->levels >= 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %" PetscInt_FMT,(PetscInt) info->levels); 6953 PetscCheck(info->fill >= 1.0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6954 if (!(fact)->ops->iccfactorsymbolic) { 6955 MatSolverType stype; 6956 PetscCall(MatFactorGetSolverType(fact,&stype)); 6957 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver type %s",((PetscObject)mat)->type_name,stype); 6958 } 6959 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6960 MatCheckPreallocated(mat,2); 6961 6962 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0)); 6963 PetscCall((fact->ops->iccfactorsymbolic)(fact,mat,perm,info)); 6964 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0)); 6965 PetscFunctionReturn(0); 6966 } 6967 6968 /*@C 6969 MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat 6970 points to an array of valid matrices, they may be reused to store the new 6971 submatrices. 6972 6973 Collective on Mat 6974 6975 Input Parameters: 6976 + mat - the matrix 6977 . n - the number of submatrixes to be extracted (on this processor, may be zero) 6978 . irow, icol - index sets of rows and columns to extract 6979 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6980 6981 Output Parameter: 6982 . submat - the array of submatrices 6983 6984 Notes: 6985 MatCreateSubMatrices() can extract ONLY sequential submatrices 6986 (from both sequential and parallel matrices). Use MatCreateSubMatrix() 6987 to extract a parallel submatrix. 6988 6989 Some matrix types place restrictions on the row and column 6990 indices, such as that they be sorted or that they be equal to each other. 6991 6992 The index sets may not have duplicate entries. 6993 6994 When extracting submatrices from a parallel matrix, each processor can 6995 form a different submatrix by setting the rows and columns of its 6996 individual index sets according to the local submatrix desired. 6997 6998 When finished using the submatrices, the user should destroy 6999 them with MatDestroySubMatrices(). 7000 7001 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 7002 original matrix has not changed from that last call to MatCreateSubMatrices(). 7003 7004 This routine creates the matrices in submat; you should NOT create them before 7005 calling it. It also allocates the array of matrix pointers submat. 7006 7007 For BAIJ matrices the index sets must respect the block structure, that is if they 7008 request one row/column in a block, they must request all rows/columns that are in 7009 that block. For example, if the block size is 2 you cannot request just row 0 and 7010 column 0. 7011 7012 Fortran Note: 7013 The Fortran interface is slightly different from that given below; it 7014 requires one to pass in as submat a Mat (integer) array of size at least n+1. 7015 7016 Level: advanced 7017 7018 .seealso: `MatDestroySubMatrices()`, `MatCreateSubMatrix()`, `MatGetRow()`, `MatGetDiagonal()`, `MatReuse` 7019 @*/ 7020 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 7021 { 7022 PetscInt i; 7023 PetscBool eq; 7024 7025 PetscFunctionBegin; 7026 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7027 PetscValidType(mat,1); 7028 if (n) { 7029 PetscValidPointer(irow,3); 7030 for (i=0; i<n; i++) PetscValidHeaderSpecific(irow[i],IS_CLASSID,3); 7031 PetscValidPointer(icol,4); 7032 for (i=0; i<n; i++) PetscValidHeaderSpecific(icol[i],IS_CLASSID,4); 7033 } 7034 PetscValidPointer(submat,6); 7035 if (n && scall == MAT_REUSE_MATRIX) { 7036 PetscValidPointer(*submat,6); 7037 for (i=0; i<n; i++) PetscValidHeaderSpecific((*submat)[i],MAT_CLASSID,6); 7038 } 7039 PetscCheck(mat->ops->createsubmatrices,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7040 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7041 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7042 MatCheckPreallocated(mat,1); 7043 PetscCall(PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0)); 7044 PetscCall((*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat)); 7045 PetscCall(PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0)); 7046 for (i=0; i<n; i++) { 7047 (*submat)[i]->factortype = MAT_FACTOR_NONE; /* in case in place factorization was previously done on submatrix */ 7048 PetscCall(ISEqualUnsorted(irow[i],icol[i],&eq)); 7049 if (eq) { 7050 PetscCall(MatPropagateSymmetryOptions(mat,(*submat)[i])); 7051 } 7052 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 7053 if (mat->boundtocpu && mat->bindingpropagates) { 7054 PetscCall(MatBindToCPU((*submat)[i],PETSC_TRUE)); 7055 PetscCall(MatSetBindingPropagates((*submat)[i],PETSC_TRUE)); 7056 } 7057 #endif 7058 } 7059 PetscFunctionReturn(0); 7060 } 7061 7062 /*@C 7063 MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms). 7064 7065 Collective on Mat 7066 7067 Input Parameters: 7068 + mat - the matrix 7069 . n - the number of submatrixes to be extracted 7070 . irow, icol - index sets of rows and columns to extract 7071 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 7072 7073 Output Parameter: 7074 . submat - the array of submatrices 7075 7076 Level: advanced 7077 7078 .seealso: `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRow()`, `MatGetDiagonal()`, `MatReuse` 7079 @*/ 7080 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 7081 { 7082 PetscInt i; 7083 PetscBool eq; 7084 7085 PetscFunctionBegin; 7086 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7087 PetscValidType(mat,1); 7088 if (n) { 7089 PetscValidPointer(irow,3); 7090 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 7091 PetscValidPointer(icol,4); 7092 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 7093 } 7094 PetscValidPointer(submat,6); 7095 if (n && scall == MAT_REUSE_MATRIX) { 7096 PetscValidPointer(*submat,6); 7097 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 7098 } 7099 PetscCheck(mat->ops->createsubmatricesmpi,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7100 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7101 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7102 MatCheckPreallocated(mat,1); 7103 7104 PetscCall(PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0)); 7105 PetscCall((*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat)); 7106 PetscCall(PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0)); 7107 for (i=0; i<n; i++) { 7108 PetscCall(ISEqualUnsorted(irow[i],icol[i],&eq)); 7109 if (eq) { 7110 PetscCall(MatPropagateSymmetryOptions(mat,(*submat)[i])); 7111 } 7112 } 7113 PetscFunctionReturn(0); 7114 } 7115 7116 /*@C 7117 MatDestroyMatrices - Destroys an array of matrices. 7118 7119 Collective on Mat 7120 7121 Input Parameters: 7122 + n - the number of local matrices 7123 - mat - the matrices (note that this is a pointer to the array of matrices) 7124 7125 Level: advanced 7126 7127 Notes: 7128 Frees not only the matrices, but also the array that contains the matrices 7129 In Fortran will not free the array. 7130 7131 .seealso: `MatCreateSubMatrices()` `MatDestroySubMatrices()` 7132 @*/ 7133 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[]) 7134 { 7135 PetscInt i; 7136 7137 PetscFunctionBegin; 7138 if (!*mat) PetscFunctionReturn(0); 7139 PetscCheck(n >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %" PetscInt_FMT,n); 7140 PetscValidPointer(mat,2); 7141 7142 for (i=0; i<n; i++) { 7143 PetscCall(MatDestroy(&(*mat)[i])); 7144 } 7145 7146 /* memory is allocated even if n = 0 */ 7147 PetscCall(PetscFree(*mat)); 7148 PetscFunctionReturn(0); 7149 } 7150 7151 /*@C 7152 MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices(). 7153 7154 Collective on Mat 7155 7156 Input Parameters: 7157 + n - the number of local matrices 7158 - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling 7159 sequence of MatCreateSubMatrices()) 7160 7161 Level: advanced 7162 7163 Notes: 7164 Frees not only the matrices, but also the array that contains the matrices 7165 In Fortran will not free the array. 7166 7167 .seealso: `MatCreateSubMatrices()` 7168 @*/ 7169 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[]) 7170 { 7171 Mat mat0; 7172 7173 PetscFunctionBegin; 7174 if (!*mat) PetscFunctionReturn(0); 7175 /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */ 7176 PetscCheck(n >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %" PetscInt_FMT,n); 7177 PetscValidPointer(mat,2); 7178 7179 mat0 = (*mat)[0]; 7180 if (mat0 && mat0->ops->destroysubmatrices) { 7181 PetscCall((mat0->ops->destroysubmatrices)(n,mat)); 7182 } else { 7183 PetscCall(MatDestroyMatrices(n,mat)); 7184 } 7185 PetscFunctionReturn(0); 7186 } 7187 7188 /*@C 7189 MatGetSeqNonzeroStructure - Extracts the nonzero structure from a matrix and stores it, in its entirety, on each process 7190 7191 Collective on Mat 7192 7193 Input Parameters: 7194 . mat - the matrix 7195 7196 Output Parameter: 7197 . matstruct - the sequential matrix with the nonzero structure of mat 7198 7199 Level: intermediate 7200 7201 .seealso: `MatDestroySeqNonzeroStructure()`, `MatCreateSubMatrices()`, `MatDestroyMatrices()` 7202 @*/ 7203 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct) 7204 { 7205 PetscFunctionBegin; 7206 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7207 PetscValidPointer(matstruct,2); 7208 7209 PetscValidType(mat,1); 7210 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7211 MatCheckPreallocated(mat,1); 7212 7213 PetscCheck(mat->ops->getseqnonzerostructure,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s",((PetscObject)mat)->type_name); 7214 PetscCall(PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0)); 7215 PetscCall((*mat->ops->getseqnonzerostructure)(mat,matstruct)); 7216 PetscCall(PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0)); 7217 PetscFunctionReturn(0); 7218 } 7219 7220 /*@C 7221 MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure(). 7222 7223 Collective on Mat 7224 7225 Input Parameters: 7226 . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling 7227 sequence of MatGetSequentialNonzeroStructure()) 7228 7229 Level: advanced 7230 7231 Notes: 7232 Frees not only the matrices, but also the array that contains the matrices 7233 7234 .seealso: `MatGetSeqNonzeroStructure()` 7235 @*/ 7236 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat) 7237 { 7238 PetscFunctionBegin; 7239 PetscValidPointer(mat,1); 7240 PetscCall(MatDestroy(mat)); 7241 PetscFunctionReturn(0); 7242 } 7243 7244 /*@ 7245 MatIncreaseOverlap - Given a set of submatrices indicated by index sets, 7246 replaces the index sets by larger ones that represent submatrices with 7247 additional overlap. 7248 7249 Collective on Mat 7250 7251 Input Parameters: 7252 + mat - the matrix 7253 . n - the number of index sets 7254 . is - the array of index sets (these index sets will changed during the call) 7255 - ov - the additional overlap requested 7256 7257 Options Database: 7258 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7259 7260 Level: developer 7261 7262 Developer Note: 7263 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. 7264 7265 .seealso: `MatCreateSubMatrices()` 7266 @*/ 7267 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov) 7268 { 7269 PetscInt i,bs,cbs; 7270 7271 PetscFunctionBegin; 7272 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7273 PetscValidType(mat,1); 7274 PetscValidLogicalCollectiveInt(mat,n,2); 7275 PetscCheck(n >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %" PetscInt_FMT,n); 7276 if (n) { 7277 PetscValidPointer(is,3); 7278 for (i = 0; i < n; i++) PetscValidHeaderSpecific(is[i],IS_CLASSID,3); 7279 } 7280 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7281 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7282 MatCheckPreallocated(mat,1); 7283 7284 if (!ov || !n) PetscFunctionReturn(0); 7285 PetscCheck(mat->ops->increaseoverlap,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7286 PetscCall(PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0)); 7287 PetscCall((*mat->ops->increaseoverlap)(mat,n,is,ov)); 7288 PetscCall(PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0)); 7289 PetscCall(MatGetBlockSizes(mat,&bs,&cbs)); 7290 if (bs == cbs) { 7291 for (i=0; i<n; i++) { 7292 PetscCall(ISSetBlockSize(is[i],bs)); 7293 } 7294 } 7295 PetscFunctionReturn(0); 7296 } 7297 7298 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt); 7299 7300 /*@ 7301 MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across 7302 a sub communicator, replaces the index sets by larger ones that represent submatrices with 7303 additional overlap. 7304 7305 Collective on Mat 7306 7307 Input Parameters: 7308 + mat - the matrix 7309 . n - the number of index sets 7310 . is - the array of index sets (these index sets will changed during the call) 7311 - ov - the additional overlap requested 7312 7313 Options Database: 7314 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7315 7316 Level: developer 7317 7318 .seealso: `MatCreateSubMatrices()` 7319 @*/ 7320 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov) 7321 { 7322 PetscInt i; 7323 7324 PetscFunctionBegin; 7325 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7326 PetscValidType(mat,1); 7327 PetscCheck(n >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %" PetscInt_FMT,n); 7328 if (n) { 7329 PetscValidPointer(is,3); 7330 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 7331 } 7332 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7333 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7334 MatCheckPreallocated(mat,1); 7335 if (!ov) PetscFunctionReturn(0); 7336 PetscCall(PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0)); 7337 for (i=0; i<n; i++) { 7338 PetscCall(MatIncreaseOverlapSplit_Single(mat,&is[i],ov)); 7339 } 7340 PetscCall(PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0)); 7341 PetscFunctionReturn(0); 7342 } 7343 7344 /*@ 7345 MatGetBlockSize - Returns the matrix block size. 7346 7347 Not Collective 7348 7349 Input Parameter: 7350 . mat - the matrix 7351 7352 Output Parameter: 7353 . bs - block size 7354 7355 Notes: 7356 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7357 7358 If the block size has not been set yet this routine returns 1. 7359 7360 Level: intermediate 7361 7362 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSizes()` 7363 @*/ 7364 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs) 7365 { 7366 PetscFunctionBegin; 7367 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7368 PetscValidIntPointer(bs,2); 7369 *bs = PetscAbs(mat->rmap->bs); 7370 PetscFunctionReturn(0); 7371 } 7372 7373 /*@ 7374 MatGetBlockSizes - Returns the matrix block row and column sizes. 7375 7376 Not Collective 7377 7378 Input Parameter: 7379 . mat - the matrix 7380 7381 Output Parameters: 7382 + rbs - row block size 7383 - cbs - column block size 7384 7385 Notes: 7386 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7387 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7388 7389 If a block size has not been set yet this routine returns 1. 7390 7391 Level: intermediate 7392 7393 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSize()`, `MatSetBlockSizes()` 7394 @*/ 7395 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs) 7396 { 7397 PetscFunctionBegin; 7398 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7399 if (rbs) PetscValidIntPointer(rbs,2); 7400 if (cbs) PetscValidIntPointer(cbs,3); 7401 if (rbs) *rbs = PetscAbs(mat->rmap->bs); 7402 if (cbs) *cbs = PetscAbs(mat->cmap->bs); 7403 PetscFunctionReturn(0); 7404 } 7405 7406 /*@ 7407 MatSetBlockSize - Sets the matrix block size. 7408 7409 Logically Collective on Mat 7410 7411 Input Parameters: 7412 + mat - the matrix 7413 - bs - block size 7414 7415 Notes: 7416 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7417 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7418 7419 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size 7420 is compatible with the matrix local sizes. 7421 7422 Level: intermediate 7423 7424 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`, `MatGetBlockSizes()` 7425 @*/ 7426 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs) 7427 { 7428 PetscFunctionBegin; 7429 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7430 PetscValidLogicalCollectiveInt(mat,bs,2); 7431 PetscCall(MatSetBlockSizes(mat,bs,bs)); 7432 PetscFunctionReturn(0); 7433 } 7434 7435 typedef struct { 7436 PetscInt n; 7437 IS *is; 7438 Mat *mat; 7439 PetscObjectState nonzerostate; 7440 Mat C; 7441 } EnvelopeData; 7442 7443 static PetscErrorCode EnvelopeDataDestroy(EnvelopeData *edata) 7444 { 7445 for (PetscInt i=0; i<edata->n; i++) { 7446 PetscCall(ISDestroy(&edata->is[i])); 7447 } 7448 PetscCall(PetscFree(edata->is)); 7449 PetscCall(PetscFree(edata)); 7450 return 0; 7451 } 7452 7453 /* 7454 MatComputeVariableBlockEnvelope - Given a matrix whose nonzeros are in blocks along the diagonal this computes and stores 7455 the sizes of these blocks in the matrix. An individual block may lie over several processes. 7456 7457 Collective on mat 7458 7459 Input Parameter: 7460 . mat - the matrix 7461 7462 Notes: 7463 There can be zeros within the blocks 7464 7465 The blocks can overlap between processes, including laying on more than two processes 7466 7467 */ 7468 static PetscErrorCode MatComputeVariableBlockEnvelope(Mat mat) 7469 { 7470 PetscInt n,*sizes,*starts,i = 0,env = 0, tbs = 0, lblocks = 0,rstart,II,ln = 0,cnt = 0,cstart,cend; 7471 PetscInt *diag,*odiag,sc; 7472 VecScatter scatter; 7473 PetscScalar *seqv; 7474 const PetscScalar *parv; 7475 const PetscInt *ia,*ja; 7476 PetscBool set,flag,done; 7477 Mat AA = mat,A; 7478 MPI_Comm comm; 7479 PetscMPIInt rank,size,tag; 7480 MPI_Status status; 7481 PetscContainer container; 7482 EnvelopeData *edata; 7483 Vec seq,par; 7484 IS isglobal; 7485 7486 PetscFunctionBegin; 7487 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7488 PetscCall(MatIsSymmetricKnown(mat,&set,&flag)); 7489 if (!set || !flag) { 7490 /* TOO: only needs nonzero structure of transpose */ 7491 PetscCall(MatTranspose(mat,MAT_INITIAL_MATRIX,&AA)); 7492 PetscCall(MatAXPY(AA,1.0,mat,DIFFERENT_NONZERO_PATTERN)); 7493 } 7494 PetscCall(MatAIJGetLocalMat(AA,&A)); 7495 PetscCall(MatGetRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ia,&ja,&done)); 7496 PetscCheck(done,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Unable to get IJ structure from matrix"); 7497 7498 PetscCall(MatGetLocalSize(mat,&n,NULL)); 7499 PetscCall(PetscObjectGetNewTag((PetscObject)mat,&tag)); 7500 PetscCall(PetscObjectGetComm((PetscObject)mat,&comm)); 7501 PetscCallMPI(MPI_Comm_size(comm,&size)); 7502 PetscCallMPI(MPI_Comm_rank(comm,&rank)); 7503 7504 PetscCall(PetscMalloc2(n,&sizes,n,&starts)); 7505 7506 if (rank > 0) { 7507 PetscCallMPI(MPI_Recv(&env,1,MPIU_INT,rank-1,tag,comm,&status)); 7508 PetscCallMPI(MPI_Recv(&tbs,1,MPIU_INT,rank-1,tag,comm,&status)); 7509 } 7510 PetscCall(MatGetOwnershipRange(mat,&rstart,NULL)); 7511 for (i=0; i<n; i++) { 7512 env = PetscMax(env,ja[ia[i+1]-1]); 7513 II = rstart + i; 7514 if (env == II) { 7515 starts[lblocks] = tbs; 7516 sizes[lblocks++] = 1 + II - tbs; 7517 tbs = 1 + II; 7518 } 7519 } 7520 if (rank < size-1) { 7521 PetscCallMPI(MPI_Send(&env,1,MPIU_INT,rank+1,tag,comm)); 7522 PetscCallMPI(MPI_Send(&tbs,1,MPIU_INT,rank+1,tag,comm)); 7523 } 7524 7525 PetscCall(MatRestoreRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ia,&ja,&done)); 7526 if (!set || !flag) { 7527 PetscCall(MatDestroy(&AA)); 7528 } 7529 PetscCall(MatDestroy(&A)); 7530 7531 PetscCall(PetscNew(&edata)); 7532 PetscCall(MatGetNonzeroState(mat,&edata->nonzerostate)); 7533 edata->n = lblocks; 7534 /* create IS needed for extracting blocks from the original matrix */ 7535 PetscCall(PetscMalloc1(lblocks,&edata->is)); 7536 for (PetscInt i=0; i<lblocks; i++) { 7537 PetscCall(ISCreateStride(PETSC_COMM_SELF,sizes[i],starts[i],1,&edata->is[i])); 7538 } 7539 7540 /* Create the resulting inverse matrix structure with preallocation information */ 7541 PetscCall(MatCreate(PetscObjectComm((PetscObject)mat),&edata->C)); 7542 PetscCall(MatSetSizes(edata->C,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N)); 7543 PetscCall(MatSetBlockSizesFromMats(edata->C,mat,mat)); 7544 PetscCall(MatSetType(edata->C,MATAIJ)); 7545 7546 /* Communicate the start and end of each row, from each block to the correct rank */ 7547 /* TODO: Use PetscSF instead of VecScatter */ 7548 for (PetscInt i=0; i<lblocks; i++) ln += sizes[i]; 7549 PetscCall(VecCreateSeq(PETSC_COMM_SELF,2*ln,&seq)); 7550 PetscCall(VecGetArrayWrite(seq,&seqv)); 7551 for (PetscInt i=0; i<lblocks; i++) { 7552 for (PetscInt j=0; j<sizes[i]; j++) { 7553 seqv[cnt] = starts[i]; 7554 seqv[cnt+1] = starts[i] + sizes[i]; 7555 cnt += 2; 7556 } 7557 } 7558 PetscCall(VecRestoreArrayWrite(seq,&seqv)); 7559 PetscCallMPI(MPI_Scan(&cnt,&sc,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat))); 7560 sc -= cnt; 7561 PetscCall(VecCreateMPI(PetscObjectComm((PetscObject)mat),2*mat->rmap->n,2*mat->rmap->N,&par)); 7562 PetscCall(ISCreateStride(PETSC_COMM_SELF,cnt,sc,1,&isglobal)); 7563 PetscCall(VecScatterCreate(seq, NULL ,par, isglobal,&scatter)); 7564 PetscCall(ISDestroy(&isglobal)); 7565 PetscCall(VecScatterBegin(scatter,seq,par,INSERT_VALUES,SCATTER_FORWARD)); 7566 PetscCall(VecScatterEnd(scatter,seq,par,INSERT_VALUES,SCATTER_FORWARD)); 7567 PetscCall(VecScatterDestroy(&scatter)); 7568 PetscCall(VecDestroy(&seq)); 7569 PetscCall(MatGetOwnershipRangeColumn(mat,&cstart,&cend)); 7570 PetscCall(PetscMalloc2(mat->rmap->n,&diag,mat->rmap->n,&odiag)); 7571 PetscCall(VecGetArrayRead(par,&parv)); 7572 cnt = 0; 7573 PetscCall(MatGetSize(mat,NULL,&n)); 7574 for (PetscInt i=0; i<mat->rmap->n; i++) { 7575 PetscInt start,end,d = 0,od = 0; 7576 7577 start = (PetscInt)PetscRealPart(parv[cnt]); 7578 end = (PetscInt)PetscRealPart(parv[cnt+1]); 7579 cnt += 2; 7580 7581 if (start < cstart) {od += cstart - start + n - cend; d += cend - cstart;} 7582 else if (start < cend) {od += n - cend; d += cend - start;} 7583 else od += n - start; 7584 if (end <= cstart) {od -= cstart - end + n - cend; d -= cend - cstart;} 7585 else if (end < cend) {od -= n - cend; d -= cend - end;} 7586 else od -= n - end; 7587 7588 odiag[i] = od; 7589 diag[i] = d; 7590 } 7591 PetscCall(VecRestoreArrayRead(par,&parv)); 7592 PetscCall(VecDestroy(&par)); 7593 PetscCall(MatXAIJSetPreallocation(edata->C,mat->rmap->bs,diag,odiag,NULL,NULL)); 7594 PetscCall(PetscFree2(diag,odiag)); 7595 PetscCall(PetscFree2(sizes,starts)); 7596 7597 PetscCall(PetscContainerCreate(PETSC_COMM_SELF,&container)); 7598 PetscCall(PetscContainerSetPointer(container,edata)); 7599 PetscCall(PetscContainerSetUserDestroy(container,(PetscErrorCode (*)(void*))EnvelopeDataDestroy)); 7600 PetscCall(PetscObjectCompose((PetscObject)mat,"EnvelopeData",(PetscObject)container)); 7601 PetscCall(PetscObjectDereference((PetscObject)container)); 7602 PetscFunctionReturn(0); 7603 } 7604 7605 /*@ 7606 MatInvertVariableBlockEnvelope - set matrix C to be the inverted block diagonal of matrix A 7607 7608 Collective on Mat 7609 7610 Input Parameters: 7611 . A - the matrix 7612 7613 Output Parameters: 7614 . C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set. 7615 7616 Notes: 7617 For efficiency the matrix A should have all the nonzero entries clustered in smallish blocks along the diagonal. 7618 7619 Level: advanced 7620 7621 .seealso: MatInvertBlockDiagonal(), MatComputeBlockDiagonal() 7622 @*/ 7623 PetscErrorCode MatInvertVariableBlockEnvelope(Mat A,MatReuse reuse, Mat *C) 7624 { 7625 PetscContainer container; 7626 EnvelopeData *edata; 7627 PetscObjectState nonzerostate; 7628 7629 PetscFunctionBegin; 7630 PetscCall(PetscObjectQuery((PetscObject)A,"EnvelopeData",(PetscObject*)&container)); 7631 if (!container) { 7632 PetscCall(MatComputeVariableBlockEnvelope(A)); 7633 PetscCall(PetscObjectQuery((PetscObject)A,"EnvelopeData",(PetscObject*)&container)); 7634 } 7635 PetscCall(PetscContainerGetPointer(container,(void**)&edata)); 7636 PetscCall(MatGetNonzeroState(A,&nonzerostate)); 7637 PetscCheck(nonzerostate <= edata->nonzerostate,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Cannot handle changes to matrix nonzero structure"); 7638 PetscCheck(reuse != MAT_REUSE_MATRIX || *C == edata->C,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C matrix must be the same as previously output"); 7639 7640 PetscCall(MatCreateSubMatrices(A,edata->n,edata->is,edata->is,MAT_INITIAL_MATRIX,&edata->mat)); 7641 *C = edata->C; 7642 7643 for (PetscInt i=0; i<edata->n; i++) { 7644 Mat D; 7645 PetscScalar *dvalues; 7646 7647 PetscCall(MatConvert(edata->mat[i], MATSEQDENSE,MAT_INITIAL_MATRIX,&D)); 7648 PetscCall(MatSetOption(*C,MAT_ROW_ORIENTED,PETSC_FALSE)); 7649 PetscCall(MatSeqDenseInvert(D)); 7650 PetscCall(MatDenseGetArray(D,&dvalues)); 7651 PetscCall(MatSetValuesIS(*C,edata->is[i],edata->is[i],dvalues,INSERT_VALUES)); 7652 PetscCall(MatDestroy(&D)); 7653 } 7654 PetscCall(MatDestroySubMatrices(edata->n,&edata->mat)); 7655 PetscCall(MatAssemblyBegin(*C,MAT_FINAL_ASSEMBLY)); 7656 PetscCall(MatAssemblyEnd(*C,MAT_FINAL_ASSEMBLY)); 7657 PetscFunctionReturn(0); 7658 } 7659 7660 /*@ 7661 MatSetVariableBlockSizes - Sets diagonal point-blocks of the matrix that need not be of the same size 7662 7663 Logically Collective on Mat 7664 7665 Input Parameters: 7666 + mat - the matrix 7667 . nblocks - the number of blocks on this process, each block can only exist on a single process 7668 - bsizes - the block sizes 7669 7670 Notes: 7671 Currently used by PCVPBJACOBI for AIJ matrices 7672 7673 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. 7674 7675 Level: intermediate 7676 7677 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`, `MatGetBlockSizes()`, `MatGetVariableBlockSizes()`, `MatComputeVariableBlockEnvelope()`, `PCVPBJACOBI` 7678 @*/ 7679 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes) 7680 { 7681 PetscInt i,ncnt = 0, nlocal; 7682 7683 PetscFunctionBegin; 7684 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7685 PetscCheck(nblocks >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero"); 7686 PetscCall(MatGetLocalSize(mat,&nlocal,NULL)); 7687 for (i=0; i<nblocks; i++) ncnt += bsizes[i]; 7688 PetscCheck(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); 7689 PetscCall(PetscFree(mat->bsizes)); 7690 mat->nblocks = nblocks; 7691 PetscCall(PetscMalloc1(nblocks,&mat->bsizes)); 7692 PetscCall(PetscArraycpy(mat->bsizes,bsizes,nblocks)); 7693 PetscFunctionReturn(0); 7694 } 7695 7696 /*@C 7697 MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size 7698 7699 Logically Collective on Mat 7700 7701 Input Parameter: 7702 . mat - the matrix 7703 7704 Output Parameters: 7705 + nblocks - the number of blocks on this process 7706 - bsizes - the block sizes 7707 7708 Notes: Currently not supported from Fortran 7709 7710 Level: intermediate 7711 7712 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`, `MatGetBlockSizes()`, `MatSetVariableBlockSizes()`, `MatComputeVariableBlockEnvelope()` 7713 @*/ 7714 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes) 7715 { 7716 PetscFunctionBegin; 7717 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7718 *nblocks = mat->nblocks; 7719 *bsizes = mat->bsizes; 7720 PetscFunctionReturn(0); 7721 } 7722 7723 /*@ 7724 MatSetBlockSizes - Sets the matrix block row and column sizes. 7725 7726 Logically Collective on Mat 7727 7728 Input Parameters: 7729 + mat - the matrix 7730 . rbs - row block size 7731 - cbs - column block size 7732 7733 Notes: 7734 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7735 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7736 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7737 7738 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes 7739 are compatible with the matrix local sizes. 7740 7741 The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs(). 7742 7743 Level: intermediate 7744 7745 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSize()`, `MatGetBlockSizes()` 7746 @*/ 7747 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs) 7748 { 7749 PetscFunctionBegin; 7750 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7751 PetscValidLogicalCollectiveInt(mat,rbs,2); 7752 PetscValidLogicalCollectiveInt(mat,cbs,3); 7753 if (mat->ops->setblocksizes) PetscCall((*mat->ops->setblocksizes)(mat,rbs,cbs)); 7754 if (mat->rmap->refcnt) { 7755 ISLocalToGlobalMapping l2g = NULL; 7756 PetscLayout nmap = NULL; 7757 7758 PetscCall(PetscLayoutDuplicate(mat->rmap,&nmap)); 7759 if (mat->rmap->mapping) { 7760 PetscCall(ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g)); 7761 } 7762 PetscCall(PetscLayoutDestroy(&mat->rmap)); 7763 mat->rmap = nmap; 7764 mat->rmap->mapping = l2g; 7765 } 7766 if (mat->cmap->refcnt) { 7767 ISLocalToGlobalMapping l2g = NULL; 7768 PetscLayout nmap = NULL; 7769 7770 PetscCall(PetscLayoutDuplicate(mat->cmap,&nmap)); 7771 if (mat->cmap->mapping) { 7772 PetscCall(ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g)); 7773 } 7774 PetscCall(PetscLayoutDestroy(&mat->cmap)); 7775 mat->cmap = nmap; 7776 mat->cmap->mapping = l2g; 7777 } 7778 PetscCall(PetscLayoutSetBlockSize(mat->rmap,rbs)); 7779 PetscCall(PetscLayoutSetBlockSize(mat->cmap,cbs)); 7780 PetscFunctionReturn(0); 7781 } 7782 7783 /*@ 7784 MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices 7785 7786 Logically Collective on Mat 7787 7788 Input Parameters: 7789 + mat - the matrix 7790 . fromRow - matrix from which to copy row block size 7791 - fromCol - matrix from which to copy column block size (can be same as fromRow) 7792 7793 Level: developer 7794 7795 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()` 7796 @*/ 7797 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol) 7798 { 7799 PetscFunctionBegin; 7800 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7801 PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2); 7802 PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3); 7803 if (fromRow->rmap->bs > 0) PetscCall(PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs)); 7804 if (fromCol->cmap->bs > 0) PetscCall(PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs)); 7805 PetscFunctionReturn(0); 7806 } 7807 7808 /*@ 7809 MatResidual - Default routine to calculate the residual. 7810 7811 Collective on Mat 7812 7813 Input Parameters: 7814 + mat - the matrix 7815 . b - the right-hand-side 7816 - x - the approximate solution 7817 7818 Output Parameter: 7819 . r - location to store the residual 7820 7821 Level: developer 7822 7823 .seealso: `PCMGSetResidual()` 7824 @*/ 7825 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r) 7826 { 7827 PetscFunctionBegin; 7828 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7829 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 7830 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 7831 PetscValidHeaderSpecific(r,VEC_CLASSID,4); 7832 PetscValidType(mat,1); 7833 MatCheckPreallocated(mat,1); 7834 PetscCall(PetscLogEventBegin(MAT_Residual,mat,0,0,0)); 7835 if (!mat->ops->residual) { 7836 PetscCall(MatMult(mat,x,r)); 7837 PetscCall(VecAYPX(r,-1.0,b)); 7838 } else { 7839 PetscCall((*mat->ops->residual)(mat,b,x,r)); 7840 } 7841 PetscCall(PetscLogEventEnd(MAT_Residual,mat,0,0,0)); 7842 PetscFunctionReturn(0); 7843 } 7844 7845 /*@C 7846 MatGetRowIJ - Returns the compressed row storage i and j indices for the local rows of a sparse matrix 7847 7848 Collective on Mat 7849 7850 Input Parameters: 7851 + mat - the matrix 7852 . shift - 0 or 1 indicating we want the indices starting at 0 or 1 7853 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized 7854 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7855 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7856 always used. 7857 7858 Output Parameters: 7859 + n - number of local rows in the (possibly compressed) matrix 7860 . ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix 7861 . ja - the column indices 7862 - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers 7863 are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set 7864 7865 Level: developer 7866 7867 Notes: 7868 You CANNOT change any of the ia[] or ja[] values. 7869 7870 Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values. 7871 7872 Fortran Notes: 7873 In Fortran use 7874 $ 7875 $ PetscInt ia(1), ja(1) 7876 $ PetscOffset iia, jja 7877 $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr) 7878 $ ! Access the ith and jth entries via ia(iia + i) and ja(jja + j) 7879 7880 or 7881 $ 7882 $ PetscInt, pointer :: ia(:),ja(:) 7883 $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr) 7884 $ ! Access the ith and jth entries via ia(i) and ja(j) 7885 7886 .seealso: `MatGetColumnIJ()`, `MatRestoreRowIJ()`, `MatSeqAIJGetArray()` 7887 @*/ 7888 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7889 { 7890 PetscFunctionBegin; 7891 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7892 PetscValidType(mat,1); 7893 if (n) PetscValidIntPointer(n,5); 7894 if (ia) PetscValidPointer(ia,6); 7895 if (ja) PetscValidPointer(ja,7); 7896 if (done) PetscValidBoolPointer(done,8); 7897 MatCheckPreallocated(mat,1); 7898 if (!mat->ops->getrowij && done) *done = PETSC_FALSE; 7899 else { 7900 if (done) *done = PETSC_TRUE; 7901 PetscCall(PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0)); 7902 PetscCall((*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done)); 7903 PetscCall(PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0)); 7904 } 7905 PetscFunctionReturn(0); 7906 } 7907 7908 /*@C 7909 MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices. 7910 7911 Collective on Mat 7912 7913 Input Parameters: 7914 + mat - the matrix 7915 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7916 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7917 symmetrized 7918 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7919 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7920 always used. 7921 . n - number of columns in the (possibly compressed) matrix 7922 . ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix 7923 - ja - the row indices 7924 7925 Output Parameters: 7926 . done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned 7927 7928 Level: developer 7929 7930 .seealso: `MatGetRowIJ()`, `MatRestoreColumnIJ()` 7931 @*/ 7932 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7933 { 7934 PetscFunctionBegin; 7935 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7936 PetscValidType(mat,1); 7937 PetscValidIntPointer(n,5); 7938 if (ia) PetscValidPointer(ia,6); 7939 if (ja) PetscValidPointer(ja,7); 7940 PetscValidBoolPointer(done,8); 7941 MatCheckPreallocated(mat,1); 7942 if (!mat->ops->getcolumnij) *done = PETSC_FALSE; 7943 else { 7944 *done = PETSC_TRUE; 7945 PetscCall((*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done)); 7946 } 7947 PetscFunctionReturn(0); 7948 } 7949 7950 /*@C 7951 MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with 7952 MatGetRowIJ(). 7953 7954 Collective on Mat 7955 7956 Input Parameters: 7957 + mat - the matrix 7958 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7959 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7960 symmetrized 7961 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7962 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7963 always used. 7964 . n - size of (possibly compressed) matrix 7965 . ia - the row pointers 7966 - ja - the column indices 7967 7968 Output Parameters: 7969 . done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7970 7971 Note: 7972 This routine zeros out n, ia, and ja. This is to prevent accidental 7973 us of the array after it has been restored. If you pass NULL, it will 7974 not zero the pointers. Use of ia or ja after MatRestoreRowIJ() is invalid. 7975 7976 Level: developer 7977 7978 .seealso: `MatGetRowIJ()`, `MatRestoreColumnIJ()` 7979 @*/ 7980 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7981 { 7982 PetscFunctionBegin; 7983 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7984 PetscValidType(mat,1); 7985 if (ia) PetscValidPointer(ia,6); 7986 if (ja) PetscValidPointer(ja,7); 7987 if (done) PetscValidBoolPointer(done,8); 7988 MatCheckPreallocated(mat,1); 7989 7990 if (!mat->ops->restorerowij && done) *done = PETSC_FALSE; 7991 else { 7992 if (done) *done = PETSC_TRUE; 7993 PetscCall((*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done)); 7994 if (n) *n = 0; 7995 if (ia) *ia = NULL; 7996 if (ja) *ja = NULL; 7997 } 7998 PetscFunctionReturn(0); 7999 } 8000 8001 /*@C 8002 MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with 8003 MatGetColumnIJ(). 8004 8005 Collective on Mat 8006 8007 Input Parameters: 8008 + mat - the matrix 8009 . shift - 1 or zero indicating we want the indices starting at 0 or 1 8010 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 8011 symmetrized 8012 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 8013 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 8014 always used. 8015 8016 Output Parameters: 8017 + n - size of (possibly compressed) matrix 8018 . ia - the column pointers 8019 . ja - the row indices 8020 - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 8021 8022 Level: developer 8023 8024 .seealso: `MatGetColumnIJ()`, `MatRestoreRowIJ()` 8025 @*/ 8026 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 8027 { 8028 PetscFunctionBegin; 8029 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8030 PetscValidType(mat,1); 8031 if (ia) PetscValidPointer(ia,6); 8032 if (ja) PetscValidPointer(ja,7); 8033 PetscValidBoolPointer(done,8); 8034 MatCheckPreallocated(mat,1); 8035 8036 if (!mat->ops->restorecolumnij) *done = PETSC_FALSE; 8037 else { 8038 *done = PETSC_TRUE; 8039 PetscCall((*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done)); 8040 if (n) *n = 0; 8041 if (ia) *ia = NULL; 8042 if (ja) *ja = NULL; 8043 } 8044 PetscFunctionReturn(0); 8045 } 8046 8047 /*@C 8048 MatColoringPatch -Used inside matrix coloring routines that 8049 use MatGetRowIJ() and/or MatGetColumnIJ(). 8050 8051 Collective on Mat 8052 8053 Input Parameters: 8054 + mat - the matrix 8055 . ncolors - max color value 8056 . n - number of entries in colorarray 8057 - colorarray - array indicating color for each column 8058 8059 Output Parameters: 8060 . iscoloring - coloring generated using colorarray information 8061 8062 Level: developer 8063 8064 .seealso: `MatGetRowIJ()`, `MatGetColumnIJ()` 8065 8066 @*/ 8067 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring) 8068 { 8069 PetscFunctionBegin; 8070 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8071 PetscValidType(mat,1); 8072 PetscValidIntPointer(colorarray,4); 8073 PetscValidPointer(iscoloring,5); 8074 MatCheckPreallocated(mat,1); 8075 8076 if (!mat->ops->coloringpatch) { 8077 PetscCall(ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring)); 8078 } else { 8079 PetscCall((*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring)); 8080 } 8081 PetscFunctionReturn(0); 8082 } 8083 8084 /*@ 8085 MatSetUnfactored - Resets a factored matrix to be treated as unfactored. 8086 8087 Logically Collective on Mat 8088 8089 Input Parameter: 8090 . mat - the factored matrix to be reset 8091 8092 Notes: 8093 This routine should be used only with factored matrices formed by in-place 8094 factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE 8095 format). This option can save memory, for example, when solving nonlinear 8096 systems with a matrix-free Newton-Krylov method and a matrix-based, in-place 8097 ILU(0) preconditioner. 8098 8099 Note that one can specify in-place ILU(0) factorization by calling 8100 .vb 8101 PCType(pc,PCILU); 8102 PCFactorSeUseInPlace(pc); 8103 .ve 8104 or by using the options -pc_type ilu -pc_factor_in_place 8105 8106 In-place factorization ILU(0) can also be used as a local 8107 solver for the blocks within the block Jacobi or additive Schwarz 8108 methods (runtime option: -sub_pc_factor_in_place). See Users-Manual: ch_pc 8109 for details on setting local solver options. 8110 8111 Most users should employ the simplified KSP interface for linear solvers 8112 instead of working directly with matrix algebra routines such as this. 8113 See, e.g., KSPCreate(). 8114 8115 Level: developer 8116 8117 .seealso: `PCFactorSetUseInPlace()`, `PCFactorGetUseInPlace()` 8118 8119 @*/ 8120 PetscErrorCode MatSetUnfactored(Mat mat) 8121 { 8122 PetscFunctionBegin; 8123 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8124 PetscValidType(mat,1); 8125 MatCheckPreallocated(mat,1); 8126 mat->factortype = MAT_FACTOR_NONE; 8127 if (!mat->ops->setunfactored) PetscFunctionReturn(0); 8128 PetscCall((*mat->ops->setunfactored)(mat)); 8129 PetscFunctionReturn(0); 8130 } 8131 8132 /*MC 8133 MatDenseGetArrayF90 - Accesses a matrix array from Fortran90. 8134 8135 Synopsis: 8136 MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 8137 8138 Not collective 8139 8140 Input Parameter: 8141 . x - matrix 8142 8143 Output Parameters: 8144 + xx_v - the Fortran90 pointer to the array 8145 - ierr - error code 8146 8147 Example of Usage: 8148 .vb 8149 PetscScalar, pointer xx_v(:,:) 8150 .... 8151 call MatDenseGetArrayF90(x,xx_v,ierr) 8152 a = xx_v(3) 8153 call MatDenseRestoreArrayF90(x,xx_v,ierr) 8154 .ve 8155 8156 Level: advanced 8157 8158 .seealso: `MatDenseRestoreArrayF90()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatSeqAIJGetArrayF90()` 8159 8160 M*/ 8161 8162 /*MC 8163 MatDenseRestoreArrayF90 - Restores a matrix array that has been 8164 accessed with MatDenseGetArrayF90(). 8165 8166 Synopsis: 8167 MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 8168 8169 Not collective 8170 8171 Input Parameters: 8172 + x - matrix 8173 - xx_v - the Fortran90 pointer to the array 8174 8175 Output Parameter: 8176 . ierr - error code 8177 8178 Example of Usage: 8179 .vb 8180 PetscScalar, pointer xx_v(:,:) 8181 .... 8182 call MatDenseGetArrayF90(x,xx_v,ierr) 8183 a = xx_v(3) 8184 call MatDenseRestoreArrayF90(x,xx_v,ierr) 8185 .ve 8186 8187 Level: advanced 8188 8189 .seealso: `MatDenseGetArrayF90()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatSeqAIJRestoreArrayF90()` 8190 8191 M*/ 8192 8193 /*MC 8194 MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90. 8195 8196 Synopsis: 8197 MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 8198 8199 Not collective 8200 8201 Input Parameter: 8202 . x - matrix 8203 8204 Output Parameters: 8205 + xx_v - the Fortran90 pointer to the array 8206 - ierr - error code 8207 8208 Example of Usage: 8209 .vb 8210 PetscScalar, pointer xx_v(:) 8211 .... 8212 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 8213 a = xx_v(3) 8214 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 8215 .ve 8216 8217 Level: advanced 8218 8219 .seealso: `MatSeqAIJRestoreArrayF90()`, `MatSeqAIJGetArray()`, `MatSeqAIJRestoreArray()`, `MatDenseGetArrayF90()` 8220 8221 M*/ 8222 8223 /*MC 8224 MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been 8225 accessed with MatSeqAIJGetArrayF90(). 8226 8227 Synopsis: 8228 MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 8229 8230 Not collective 8231 8232 Input Parameters: 8233 + x - matrix 8234 - xx_v - the Fortran90 pointer to the array 8235 8236 Output Parameter: 8237 . ierr - error code 8238 8239 Example of Usage: 8240 .vb 8241 PetscScalar, pointer xx_v(:) 8242 .... 8243 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 8244 a = xx_v(3) 8245 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 8246 .ve 8247 8248 Level: advanced 8249 8250 .seealso: `MatSeqAIJGetArrayF90()`, `MatSeqAIJGetArray()`, `MatSeqAIJRestoreArray()`, `MatDenseRestoreArrayF90()` 8251 8252 M*/ 8253 8254 /*@ 8255 MatCreateSubMatrix - Gets a single submatrix on the same number of processors 8256 as the original matrix. 8257 8258 Collective on Mat 8259 8260 Input Parameters: 8261 + mat - the original matrix 8262 . isrow - parallel IS containing the rows this processor should obtain 8263 . 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. 8264 - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 8265 8266 Output Parameter: 8267 . newmat - the new submatrix, of the same type as the old 8268 8269 Level: advanced 8270 8271 Notes: 8272 The submatrix will be able to be multiplied with vectors using the same layout as iscol. 8273 8274 Some matrix types place restrictions on the row and column indices, such 8275 as that they be sorted or that they be equal to each other. 8276 8277 The index sets may not have duplicate entries. 8278 8279 The first time this is called you should use a cll of MAT_INITIAL_MATRIX, 8280 the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls 8281 to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX 8282 will reuse the matrix generated the first time. You should call MatDestroy() on newmat when 8283 you are finished using it. 8284 8285 The communicator of the newly obtained matrix is ALWAYS the same as the communicator of 8286 the input matrix. 8287 8288 If iscol is NULL then all columns are obtained (not supported in Fortran). 8289 8290 Example usage: 8291 Consider the following 8x8 matrix with 34 non-zero values, that is 8292 assembled across 3 processors. Let's assume that proc0 owns 3 rows, 8293 proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown 8294 as follows: 8295 8296 .vb 8297 1 2 0 | 0 3 0 | 0 4 8298 Proc0 0 5 6 | 7 0 0 | 8 0 8299 9 0 10 | 11 0 0 | 12 0 8300 ------------------------------------- 8301 13 0 14 | 15 16 17 | 0 0 8302 Proc1 0 18 0 | 19 20 21 | 0 0 8303 0 0 0 | 22 23 0 | 24 0 8304 ------------------------------------- 8305 Proc2 25 26 27 | 0 0 28 | 29 0 8306 30 0 0 | 31 32 33 | 0 34 8307 .ve 8308 8309 Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is 8310 8311 .vb 8312 2 0 | 0 3 0 | 0 8313 Proc0 5 6 | 7 0 0 | 8 8314 ------------------------------- 8315 Proc1 18 0 | 19 20 21 | 0 8316 ------------------------------- 8317 Proc2 26 27 | 0 0 28 | 29 8318 0 0 | 31 32 33 | 0 8319 .ve 8320 8321 .seealso: `MatCreateSubMatrices()`, `MatCreateSubMatricesMPI()`, `MatCreateSubMatrixVirtual()`, `MatSubMatrixVirtualUpdate()` 8322 @*/ 8323 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat) 8324 { 8325 PetscMPIInt size; 8326 Mat *local; 8327 IS iscoltmp; 8328 PetscBool flg; 8329 8330 PetscFunctionBegin; 8331 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8332 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 8333 if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 8334 PetscValidPointer(newmat,5); 8335 if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5); 8336 PetscValidType(mat,1); 8337 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8338 PetscCheck(cll != MAT_IGNORE_MATRIX,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX"); 8339 8340 MatCheckPreallocated(mat,1); 8341 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 8342 8343 if (!iscol || isrow == iscol) { 8344 PetscBool stride; 8345 PetscMPIInt grabentirematrix = 0,grab; 8346 PetscCall(PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride)); 8347 if (stride) { 8348 PetscInt first,step,n,rstart,rend; 8349 PetscCall(ISStrideGetInfo(isrow,&first,&step)); 8350 if (step == 1) { 8351 PetscCall(MatGetOwnershipRange(mat,&rstart,&rend)); 8352 if (rstart == first) { 8353 PetscCall(ISGetLocalSize(isrow,&n)); 8354 if (n == rend-rstart) { 8355 grabentirematrix = 1; 8356 } 8357 } 8358 } 8359 } 8360 PetscCall(MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat))); 8361 if (grab) { 8362 PetscCall(PetscInfo(mat,"Getting entire matrix as submatrix\n")); 8363 if (cll == MAT_INITIAL_MATRIX) { 8364 *newmat = mat; 8365 PetscCall(PetscObjectReference((PetscObject)mat)); 8366 } 8367 PetscFunctionReturn(0); 8368 } 8369 } 8370 8371 if (!iscol) { 8372 PetscCall(ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp)); 8373 } else { 8374 iscoltmp = iscol; 8375 } 8376 8377 /* if original matrix is on just one processor then use submatrix generated */ 8378 if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) { 8379 PetscCall(MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat)); 8380 goto setproperties; 8381 } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) { 8382 PetscCall(MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local)); 8383 *newmat = *local; 8384 PetscCall(PetscFree(local)); 8385 goto setproperties; 8386 } else if (!mat->ops->createsubmatrix) { 8387 /* Create a new matrix type that implements the operation using the full matrix */ 8388 PetscCall(PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0)); 8389 switch (cll) { 8390 case MAT_INITIAL_MATRIX: 8391 PetscCall(MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat)); 8392 break; 8393 case MAT_REUSE_MATRIX: 8394 PetscCall(MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp)); 8395 break; 8396 default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX"); 8397 } 8398 PetscCall(PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0)); 8399 goto setproperties; 8400 } 8401 8402 PetscCheck(mat->ops->createsubmatrix,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8403 PetscCall(PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0)); 8404 PetscCall((*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat)); 8405 PetscCall(PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0)); 8406 8407 setproperties: 8408 PetscCall(ISEqualUnsorted(isrow,iscoltmp,&flg)); 8409 if (flg) PetscCall(MatPropagateSymmetryOptions(mat,*newmat)); 8410 if (!iscol) PetscCall(ISDestroy(&iscoltmp)); 8411 if (*newmat && cll == MAT_INITIAL_MATRIX) PetscCall(PetscObjectStateIncrease((PetscObject)*newmat)); 8412 PetscFunctionReturn(0); 8413 } 8414 8415 /*@ 8416 MatPropagateSymmetryOptions - Propagates symmetry options set on a matrix to another matrix 8417 8418 Not Collective 8419 8420 Input Parameters: 8421 + A - the matrix we wish to propagate options from 8422 - B - the matrix we wish to propagate options to 8423 8424 Level: beginner 8425 8426 Notes: 8427 Propagates the options associated to `MAT_SYMMETRY_ETERNAL`, `MAT_STRUCTURALLY_SYMMETRIC`, `MAT_HERMITIAN`, `MAT_SPD`, `MAT_SYMMETRIC`, and `MAT_STRUCTURAL_SYMMETRY_ETERNAL` 8428 8429 .seealso: `MatSetOption()`, `MatIsSymmetricKnown()`, `MatIsSPDKnown()`, `MatIsHermitianKnown()`, MatIsStructurallySymmetricKnown()` 8430 @*/ 8431 PetscErrorCode MatPropagateSymmetryOptions(Mat A, Mat B) 8432 { 8433 PetscFunctionBegin; 8434 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8435 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 8436 B->symmetry_eternal = A->symmetry_eternal; 8437 B->structural_symmetry_eternal = A->structural_symmetry_eternal; 8438 B->symmetric = A->symmetric; 8439 B->structurally_symmetric = A->structurally_symmetric; 8440 B->spd = A->spd; 8441 B->hermitian = A->hermitian; 8442 PetscFunctionReturn(0); 8443 } 8444 8445 /*@ 8446 MatStashSetInitialSize - sets the sizes of the matrix stash, that is 8447 used during the assembly process to store values that belong to 8448 other processors. 8449 8450 Not Collective 8451 8452 Input Parameters: 8453 + mat - the matrix 8454 . size - the initial size of the stash. 8455 - bsize - the initial size of the block-stash(if used). 8456 8457 Options Database Keys: 8458 + -matstash_initial_size <size> or <size0,size1,...sizep-1> 8459 - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1> 8460 8461 Level: intermediate 8462 8463 Notes: 8464 The block-stash is used for values set with MatSetValuesBlocked() while 8465 the stash is used for values set with MatSetValues() 8466 8467 Run with the option -info and look for output of the form 8468 MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs. 8469 to determine the appropriate value, MM, to use for size and 8470 MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs. 8471 to determine the value, BMM to use for bsize 8472 8473 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `Mat`, `MatStashGetInfo()` 8474 8475 @*/ 8476 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize) 8477 { 8478 PetscFunctionBegin; 8479 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8480 PetscValidType(mat,1); 8481 PetscCall(MatStashSetInitialSize_Private(&mat->stash,size)); 8482 PetscCall(MatStashSetInitialSize_Private(&mat->bstash,bsize)); 8483 PetscFunctionReturn(0); 8484 } 8485 8486 /*@ 8487 MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 8488 the matrix 8489 8490 Neighbor-wise Collective on Mat 8491 8492 Input Parameters: 8493 + mat - the matrix 8494 . x,y - the vectors 8495 - w - where the result is stored 8496 8497 Level: intermediate 8498 8499 Notes: 8500 w may be the same vector as y. 8501 8502 This allows one to use either the restriction or interpolation (its transpose) 8503 matrix to do the interpolation 8504 8505 .seealso: `MatMultAdd()`, `MatMultTransposeAdd()`, `MatRestrict()` 8506 8507 @*/ 8508 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w) 8509 { 8510 PetscInt M,N,Ny; 8511 8512 PetscFunctionBegin; 8513 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8514 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8515 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8516 PetscValidHeaderSpecific(w,VEC_CLASSID,4); 8517 PetscCall(MatGetSize(A,&M,&N)); 8518 PetscCall(VecGetSize(y,&Ny)); 8519 if (M == Ny) { 8520 PetscCall(MatMultAdd(A,x,y,w)); 8521 } else { 8522 PetscCall(MatMultTransposeAdd(A,x,y,w)); 8523 } 8524 PetscFunctionReturn(0); 8525 } 8526 8527 /*@ 8528 MatInterpolate - y = A*x or A'*x depending on the shape of 8529 the matrix 8530 8531 Neighbor-wise Collective on Mat 8532 8533 Input Parameters: 8534 + mat - the matrix 8535 - x,y - the vectors 8536 8537 Level: intermediate 8538 8539 Notes: 8540 This allows one to use either the restriction or interpolation (its transpose) 8541 matrix to do the interpolation 8542 8543 .seealso: `MatMultAdd()`, `MatMultTransposeAdd()`, `MatRestrict()` 8544 8545 @*/ 8546 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y) 8547 { 8548 PetscInt M,N,Ny; 8549 8550 PetscFunctionBegin; 8551 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8552 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8553 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8554 PetscCall(MatGetSize(A,&M,&N)); 8555 PetscCall(VecGetSize(y,&Ny)); 8556 if (M == Ny) { 8557 PetscCall(MatMult(A,x,y)); 8558 } else { 8559 PetscCall(MatMultTranspose(A,x,y)); 8560 } 8561 PetscFunctionReturn(0); 8562 } 8563 8564 /*@ 8565 MatRestrict - y = A*x or A'*x 8566 8567 Neighbor-wise Collective on Mat 8568 8569 Input Parameters: 8570 + mat - the matrix 8571 - x,y - the vectors 8572 8573 Level: intermediate 8574 8575 Notes: 8576 This allows one to use either the restriction or interpolation (its transpose) 8577 matrix to do the restriction 8578 8579 .seealso: `MatMultAdd()`, `MatMultTransposeAdd()`, `MatInterpolate()` 8580 8581 @*/ 8582 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y) 8583 { 8584 PetscInt M,N,Ny; 8585 8586 PetscFunctionBegin; 8587 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8588 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8589 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8590 PetscCall(MatGetSize(A,&M,&N)); 8591 PetscCall(VecGetSize(y,&Ny)); 8592 if (M == Ny) { 8593 PetscCall(MatMult(A,x,y)); 8594 } else { 8595 PetscCall(MatMultTranspose(A,x,y)); 8596 } 8597 PetscFunctionReturn(0); 8598 } 8599 8600 /*@ 8601 MatMatInterpolateAdd - Y = W + A*X or W + A'*X 8602 8603 Neighbor-wise Collective on Mat 8604 8605 Input Parameters: 8606 + mat - the matrix 8607 - w, x - the input dense matrices 8608 8609 Output Parameters: 8610 . y - the output dense matrix 8611 8612 Level: intermediate 8613 8614 Notes: 8615 This allows one to use either the restriction or interpolation (its transpose) 8616 matrix to do the interpolation. y matrix can be reused if already created with the proper sizes, 8617 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8618 8619 .seealso: `MatInterpolateAdd()`, `MatMatInterpolate()`, `MatMatRestrict()` 8620 8621 @*/ 8622 PetscErrorCode MatMatInterpolateAdd(Mat A,Mat x,Mat w,Mat *y) 8623 { 8624 PetscInt M,N,Mx,Nx,Mo,My = 0,Ny = 0; 8625 PetscBool trans = PETSC_TRUE; 8626 MatReuse reuse = MAT_INITIAL_MATRIX; 8627 8628 PetscFunctionBegin; 8629 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8630 PetscValidHeaderSpecific(x,MAT_CLASSID,2); 8631 PetscValidType(x,2); 8632 if (w) PetscValidHeaderSpecific(w,MAT_CLASSID,3); 8633 if (*y) PetscValidHeaderSpecific(*y,MAT_CLASSID,4); 8634 PetscCall(MatGetSize(A,&M,&N)); 8635 PetscCall(MatGetSize(x,&Mx,&Nx)); 8636 if (N == Mx) trans = PETSC_FALSE; 8637 else PetscCheck(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); 8638 Mo = trans ? N : M; 8639 if (*y) { 8640 PetscCall(MatGetSize(*y,&My,&Ny)); 8641 if (Mo == My && Nx == Ny) { reuse = MAT_REUSE_MATRIX; } 8642 else { 8643 PetscCheck(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); 8644 PetscCall(MatDestroy(y)); 8645 } 8646 } 8647 8648 if (w && *y == w) { /* this is to minimize changes in PCMG */ 8649 PetscBool flg; 8650 8651 PetscCall(PetscObjectQuery((PetscObject)*y,"__MatMatIntAdd_w",(PetscObject*)&w)); 8652 if (w) { 8653 PetscInt My,Ny,Mw,Nw; 8654 8655 PetscCall(PetscObjectTypeCompare((PetscObject)*y,((PetscObject)w)->type_name,&flg)); 8656 PetscCall(MatGetSize(*y,&My,&Ny)); 8657 PetscCall(MatGetSize(w,&Mw,&Nw)); 8658 if (!flg || My != Mw || Ny != Nw) w = NULL; 8659 } 8660 if (!w) { 8661 PetscCall(MatDuplicate(*y,MAT_COPY_VALUES,&w)); 8662 PetscCall(PetscObjectCompose((PetscObject)*y,"__MatMatIntAdd_w",(PetscObject)w)); 8663 PetscCall(PetscLogObjectParent((PetscObject)*y,(PetscObject)w)); 8664 PetscCall(PetscObjectDereference((PetscObject)w)); 8665 } else { 8666 PetscCall(MatCopy(*y,w,UNKNOWN_NONZERO_PATTERN)); 8667 } 8668 } 8669 if (!trans) { 8670 PetscCall(MatMatMult(A,x,reuse,PETSC_DEFAULT,y)); 8671 } else { 8672 PetscCall(MatTransposeMatMult(A,x,reuse,PETSC_DEFAULT,y)); 8673 } 8674 if (w) PetscCall(MatAXPY(*y,1.0,w,UNKNOWN_NONZERO_PATTERN)); 8675 PetscFunctionReturn(0); 8676 } 8677 8678 /*@ 8679 MatMatInterpolate - Y = A*X or A'*X 8680 8681 Neighbor-wise Collective on Mat 8682 8683 Input Parameters: 8684 + mat - the matrix 8685 - x - the input dense matrix 8686 8687 Output Parameters: 8688 . y - the output dense matrix 8689 8690 Level: intermediate 8691 8692 Notes: 8693 This allows one to use either the restriction or interpolation (its transpose) 8694 matrix to do the interpolation. y matrix can be reused if already created with the proper sizes, 8695 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8696 8697 .seealso: `MatInterpolate()`, `MatRestrict()`, `MatMatRestrict()` 8698 8699 @*/ 8700 PetscErrorCode MatMatInterpolate(Mat A,Mat x,Mat *y) 8701 { 8702 PetscFunctionBegin; 8703 PetscCall(MatMatInterpolateAdd(A,x,NULL,y)); 8704 PetscFunctionReturn(0); 8705 } 8706 8707 /*@ 8708 MatMatRestrict - Y = A*X or A'*X 8709 8710 Neighbor-wise Collective on Mat 8711 8712 Input Parameters: 8713 + mat - the matrix 8714 - x - the input dense matrix 8715 8716 Output Parameters: 8717 . y - the output dense matrix 8718 8719 Level: intermediate 8720 8721 Notes: 8722 This allows one to use either the restriction or interpolation (its transpose) 8723 matrix to do the restriction. y matrix can be reused if already created with the proper sizes, 8724 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8725 8726 .seealso: `MatRestrict()`, `MatInterpolate()`, `MatMatInterpolate()` 8727 @*/ 8728 PetscErrorCode MatMatRestrict(Mat A,Mat x,Mat *y) 8729 { 8730 PetscFunctionBegin; 8731 PetscCall(MatMatInterpolateAdd(A,x,NULL,y)); 8732 PetscFunctionReturn(0); 8733 } 8734 8735 /*@ 8736 MatGetNullSpace - retrieves the null space of a matrix. 8737 8738 Logically Collective on Mat 8739 8740 Input Parameters: 8741 + mat - the matrix 8742 - nullsp - the null space object 8743 8744 Level: developer 8745 8746 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatSetNullSpace()` 8747 @*/ 8748 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp) 8749 { 8750 PetscFunctionBegin; 8751 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8752 PetscValidPointer(nullsp,2); 8753 *nullsp = (mat->symmetric == PETSC_BOOL3_TRUE && !mat->nullsp) ? mat->transnullsp : mat->nullsp; 8754 PetscFunctionReturn(0); 8755 } 8756 8757 /*@ 8758 MatSetNullSpace - attaches a null space to a matrix. 8759 8760 Logically Collective on Mat 8761 8762 Input Parameters: 8763 + mat - the matrix 8764 - nullsp - the null space object 8765 8766 Level: advanced 8767 8768 Notes: 8769 This null space is used by the KSP linear solvers to solve singular systems. 8770 8771 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 8772 8773 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 8774 to zero but the linear system will still be solved in a least squares sense. 8775 8776 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8777 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). 8778 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 8779 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 8780 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). 8781 This \hat{b} can be obtained by calling MatNullSpaceRemove() with the null space of the transpose of the matrix. 8782 8783 If the matrix is known to be symmetric because it is an SBAIJ matrix or one as called MatSetOption(mat,MAT_SYMMETRIC or MAT_SYMMETRY_ETERNAL,PETSC_TRUE); this 8784 routine also automatically calls MatSetTransposeNullSpace(). 8785 8786 The user should call `MatNullSpaceDestroy()`. 8787 8788 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatGetNullSpace()`, `MatSetTransposeNullSpace()`, `MatGetTransposeNullSpace()`, `MatNullSpaceRemove()`, 8789 `KSPSetPCSide()` 8790 @*/ 8791 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp) 8792 { 8793 PetscFunctionBegin; 8794 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8795 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8796 if (nullsp) PetscCall(PetscObjectReference((PetscObject)nullsp)); 8797 PetscCall(MatNullSpaceDestroy(&mat->nullsp)); 8798 mat->nullsp = nullsp; 8799 if (mat->symmetric == PETSC_BOOL3_TRUE) { 8800 PetscCall(MatSetTransposeNullSpace(mat,nullsp)); 8801 } 8802 PetscFunctionReturn(0); 8803 } 8804 8805 /*@ 8806 MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix. 8807 8808 Logically Collective on Mat 8809 8810 Input Parameters: 8811 + mat - the matrix 8812 - nullsp - the null space object 8813 8814 Level: developer 8815 8816 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatSetTransposeNullSpace()`, `MatSetNullSpace()`, `MatGetNullSpace()` 8817 @*/ 8818 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp) 8819 { 8820 PetscFunctionBegin; 8821 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8822 PetscValidType(mat,1); 8823 PetscValidPointer(nullsp,2); 8824 *nullsp = (mat->symmetric == PETSC_BOOL3_TRUE && !mat->transnullsp) ? mat->nullsp : mat->transnullsp; 8825 PetscFunctionReturn(0); 8826 } 8827 8828 /*@ 8829 MatSetTransposeNullSpace - attaches the null space of a transpose of a matrix to the matrix 8830 8831 Logically Collective on Mat 8832 8833 Input Parameters: 8834 + mat - the matrix 8835 - nullsp - the null space object 8836 8837 Level: advanced 8838 8839 Notes: 8840 This allows solving singular linear systems defined by the transpose of the matrix using KSP solvers with left preconditioning. 8841 8842 See MatSetNullSpace() 8843 8844 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatGetNullSpace()`, `MatSetNullSpace()`, `MatGetTransposeNullSpace()`, `MatNullSpaceRemove()`, `KSPSetPCSide()` 8845 @*/ 8846 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp) 8847 { 8848 PetscFunctionBegin; 8849 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8850 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8851 if (nullsp) PetscCall(PetscObjectReference((PetscObject)nullsp)); 8852 PetscCall(MatNullSpaceDestroy(&mat->transnullsp)); 8853 mat->transnullsp = nullsp; 8854 PetscFunctionReturn(0); 8855 } 8856 8857 /*@ 8858 MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions 8859 This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix. 8860 8861 Logically Collective on Mat 8862 8863 Input Parameters: 8864 + mat - the matrix 8865 - nullsp - the null space object 8866 8867 Level: advanced 8868 8869 Notes: 8870 Overwrites any previous near null space that may have been attached 8871 8872 You can remove the null space by calling this routine with an nullsp of NULL 8873 8874 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNullSpace()`, `MatNullSpaceCreateRigidBody()`, `MatGetNearNullSpace()` 8875 @*/ 8876 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp) 8877 { 8878 PetscFunctionBegin; 8879 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8880 PetscValidType(mat,1); 8881 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8882 MatCheckPreallocated(mat,1); 8883 if (nullsp) PetscCall(PetscObjectReference((PetscObject)nullsp)); 8884 PetscCall(MatNullSpaceDestroy(&mat->nearnullsp)); 8885 mat->nearnullsp = nullsp; 8886 PetscFunctionReturn(0); 8887 } 8888 8889 /*@ 8890 MatGetNearNullSpace - Get null space attached with MatSetNearNullSpace() 8891 8892 Not Collective 8893 8894 Input Parameter: 8895 . mat - the matrix 8896 8897 Output Parameter: 8898 . nullsp - the null space object, NULL if not set 8899 8900 Level: developer 8901 8902 .seealso: `MatSetNearNullSpace()`, `MatGetNullSpace()`, `MatNullSpaceCreate()` 8903 @*/ 8904 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp) 8905 { 8906 PetscFunctionBegin; 8907 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8908 PetscValidType(mat,1); 8909 PetscValidPointer(nullsp,2); 8910 MatCheckPreallocated(mat,1); 8911 *nullsp = mat->nearnullsp; 8912 PetscFunctionReturn(0); 8913 } 8914 8915 /*@C 8916 MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix. 8917 8918 Collective on Mat 8919 8920 Input Parameters: 8921 + mat - the matrix 8922 . row - row/column permutation 8923 . fill - expected fill factor >= 1.0 8924 - level - level of fill, for ICC(k) 8925 8926 Notes: 8927 Probably really in-place only when level of fill is zero, otherwise allocates 8928 new space to store factored matrix and deletes previous memory. 8929 8930 Most users should employ the simplified KSP interface for linear solvers 8931 instead of working directly with matrix algebra routines such as this. 8932 See, e.g., KSPCreate(). 8933 8934 Level: developer 8935 8936 .seealso: `MatICCFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()` 8937 8938 Developer Note: fortran interface is not autogenerated as the f90 8939 interface definition cannot be generated correctly [due to MatFactorInfo] 8940 8941 @*/ 8942 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info) 8943 { 8944 PetscFunctionBegin; 8945 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8946 PetscValidType(mat,1); 8947 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 8948 PetscValidPointer(info,3); 8949 PetscCheck(mat->rmap->N == mat->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 8950 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8951 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8952 PetscCheck(mat->ops->iccfactor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8953 MatCheckPreallocated(mat,1); 8954 PetscCall((*mat->ops->iccfactor)(mat,row,info)); 8955 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 8956 PetscFunctionReturn(0); 8957 } 8958 8959 /*@ 8960 MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 8961 ghosted ones. 8962 8963 Not Collective 8964 8965 Input Parameters: 8966 + mat - the matrix 8967 - diag - the diagonal values, including ghost ones 8968 8969 Level: developer 8970 8971 Notes: 8972 Works only for MPIAIJ and MPIBAIJ matrices 8973 8974 .seealso: `MatDiagonalScale()` 8975 @*/ 8976 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag) 8977 { 8978 PetscMPIInt size; 8979 8980 PetscFunctionBegin; 8981 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8982 PetscValidHeaderSpecific(diag,VEC_CLASSID,2); 8983 PetscValidType(mat,1); 8984 8985 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled"); 8986 PetscCall(PetscLogEventBegin(MAT_Scale,mat,0,0,0)); 8987 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 8988 if (size == 1) { 8989 PetscInt n,m; 8990 PetscCall(VecGetSize(diag,&n)); 8991 PetscCall(MatGetSize(mat,NULL,&m)); 8992 if (m == n) { 8993 PetscCall(MatDiagonalScale(mat,NULL,diag)); 8994 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions"); 8995 } else { 8996 PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag)); 8997 } 8998 PetscCall(PetscLogEventEnd(MAT_Scale,mat,0,0,0)); 8999 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 9000 PetscFunctionReturn(0); 9001 } 9002 9003 /*@ 9004 MatGetInertia - Gets the inertia from a factored matrix 9005 9006 Collective on Mat 9007 9008 Input Parameter: 9009 . mat - the matrix 9010 9011 Output Parameters: 9012 + nneg - number of negative eigenvalues 9013 . nzero - number of zero eigenvalues 9014 - npos - number of positive eigenvalues 9015 9016 Level: advanced 9017 9018 Notes: 9019 Matrix must have been factored by MatCholeskyFactor() 9020 9021 @*/ 9022 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos) 9023 { 9024 PetscFunctionBegin; 9025 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9026 PetscValidType(mat,1); 9027 PetscCheck(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 9028 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled"); 9029 PetscCheck(mat->ops->getinertia,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 9030 PetscCall((*mat->ops->getinertia)(mat,nneg,nzero,npos)); 9031 PetscFunctionReturn(0); 9032 } 9033 9034 /* ----------------------------------------------------------------*/ 9035 /*@C 9036 MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors 9037 9038 Neighbor-wise Collective on Mats 9039 9040 Input Parameters: 9041 + mat - the factored matrix 9042 - b - the right-hand-side vectors 9043 9044 Output Parameter: 9045 . x - the result vectors 9046 9047 Notes: 9048 The vectors b and x cannot be the same. I.e., one cannot 9049 call MatSolves(A,x,x). 9050 9051 Notes: 9052 Most users should employ the simplified KSP interface for linear solvers 9053 instead of working directly with matrix algebra routines such as this. 9054 See, e.g., KSPCreate(). 9055 9056 Level: developer 9057 9058 .seealso: `MatSolveAdd()`, `MatSolveTranspose()`, `MatSolveTransposeAdd()`, `MatSolve()` 9059 @*/ 9060 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x) 9061 { 9062 PetscFunctionBegin; 9063 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9064 PetscValidType(mat,1); 9065 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 9066 PetscCheck(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 9067 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 9068 9069 PetscCheck(mat->ops->solves,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 9070 MatCheckPreallocated(mat,1); 9071 PetscCall(PetscLogEventBegin(MAT_Solves,mat,0,0,0)); 9072 PetscCall((*mat->ops->solves)(mat,b,x)); 9073 PetscCall(PetscLogEventEnd(MAT_Solves,mat,0,0,0)); 9074 PetscFunctionReturn(0); 9075 } 9076 9077 /*@ 9078 MatIsSymmetric - Test whether a matrix is symmetric 9079 9080 Collective on Mat 9081 9082 Input Parameters: 9083 + A - the matrix to test 9084 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose) 9085 9086 Output Parameters: 9087 . flg - the result 9088 9089 Notes: 9090 For real numbers MatIsSymmetric() and MatIsHermitian() return identical results 9091 9092 If the matrix does not yet know if it is symmetric or not this can be an expensive operation, also available `MatIsSymmetricKnown()` 9093 9094 Level: intermediate 9095 9096 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetricKnown()` 9097 @*/ 9098 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg) 9099 { 9100 PetscFunctionBegin; 9101 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9102 PetscValidBoolPointer(flg,3); 9103 9104 if (A->symmetric == PETSC_BOOL3_TRUE) *flg = PETSC_TRUE; 9105 else if (A->symmetric == PETSC_BOOL3_FALSE) *flg = PETSC_FALSE; 9106 else { 9107 if (!A->ops->issymmetric) { 9108 MatType mattype; 9109 PetscCall(MatGetType(A,&mattype)); 9110 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for symmetric",mattype); 9111 } 9112 PetscCall((*A->ops->issymmetric)(A,tol,flg)); 9113 if (!tol) PetscCall(MatSetOption(A,MAT_SYMMETRIC,*flg)); 9114 } 9115 PetscFunctionReturn(0); 9116 } 9117 9118 /*@ 9119 MatIsHermitian - Test whether a matrix is Hermitian 9120 9121 Collective on Mat 9122 9123 Input Parameters: 9124 + A - the matrix to test 9125 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian) 9126 9127 Output Parameters: 9128 . flg - the result 9129 9130 Level: intermediate 9131 9132 Notes: 9133 For real numbers MatIsSymmetric() and MatIsHermitian() return identical results 9134 9135 If the matrix does not yet know if it is hermitian or not this can be an expensive operation, also available `MatIsHermitianKnown()` 9136 9137 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitianKnown()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, 9138 `MatIsSymmetricKnown()`, `MatIsSymmetric()` 9139 @*/ 9140 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg) 9141 { 9142 PetscFunctionBegin; 9143 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9144 PetscValidBoolPointer(flg,3); 9145 9146 if (A->hermitian == PETSC_BOOL3_TRUE) *flg = PETSC_TRUE; 9147 else if (A->hermitian == PETSC_BOOL3_FALSE) *flg = PETSC_FALSE; 9148 else { 9149 if (!A->ops->ishermitian) { 9150 MatType mattype; 9151 PetscCall(MatGetType(A,&mattype)); 9152 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for hermitian",mattype); 9153 } 9154 PetscCall((*A->ops->ishermitian)(A,tol,flg)); 9155 if (!tol) PetscCall(MatSetOption(A,MAT_HERMITIAN,*flg)); 9156 } 9157 PetscFunctionReturn(0); 9158 } 9159 9160 /*@ 9161 MatIsSymmetricKnown - Checks if a matrix knows if it is symmetric or not and its symmetric state 9162 9163 Not Collective 9164 9165 Input Parameter: 9166 . A - the matrix to check 9167 9168 Output Parameters: 9169 + set - PETSC_TRUE if the matrix knows its symmetry state (this tells you if the next flag is valid) 9170 - flg - the result (only valid if set is PETSC_TRUE) 9171 9172 Level: advanced 9173 9174 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric() 9175 if you want it explicitly checked 9176 9177 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitianKnown()` 9178 @*/ 9179 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg) 9180 { 9181 PetscFunctionBegin; 9182 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9183 PetscValidBoolPointer(set,2); 9184 PetscValidBoolPointer(flg,3); 9185 if (A->symmetric != PETSC_BOOL3_UNKNOWN) { 9186 *set = PETSC_TRUE; 9187 *flg = PetscBool3ToBool(A->symmetric); 9188 } else { 9189 *set = PETSC_FALSE; 9190 } 9191 PetscFunctionReturn(0); 9192 } 9193 9194 /*@ 9195 MatIsSPDKnown - Checks if a matrix knows if it is symmetric positive definite or not and its symmetric positive definite state 9196 9197 Not Collective 9198 9199 Input Parameter: 9200 . A - the matrix to check 9201 9202 Output Parameters: 9203 + set - PETSC_TRUE if the matrix knows its symmetric positive definite state (this tells you if the next flag is valid) 9204 - flg - the result (only valid if set is PETSC_TRUE) 9205 9206 Level: advanced 9207 9208 Note: 9209 Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). 9210 9211 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitianKnown()` 9212 @*/ 9213 PetscErrorCode MatIsSPDKnown(Mat A,PetscBool *set,PetscBool *flg) 9214 { 9215 PetscFunctionBegin; 9216 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9217 PetscValidBoolPointer(set,2); 9218 PetscValidBoolPointer(flg,3); 9219 if (A->spd != PETSC_BOOL3_UNKNOWN) { 9220 *set = PETSC_TRUE; 9221 *flg = PetscBool3ToBool(A->spd); 9222 } else { 9223 *set = PETSC_FALSE; 9224 } 9225 PetscFunctionReturn(0); 9226 } 9227 9228 /*@ 9229 MatIsHermitianKnown - Checks if a matrix knows if it is Hermitian or not and its Hermitian state 9230 9231 Not Collective 9232 9233 Input Parameter: 9234 . A - the matrix to check 9235 9236 Output Parameters: 9237 + set - PETSC_TRUE if the matrix knows its Hermitian state (this tells you if the next flag is valid) 9238 - flg - the result (only valid if set is PETSC_TRUE) 9239 9240 Level: advanced 9241 9242 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian() 9243 if you want it explicitly checked 9244 9245 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()` 9246 @*/ 9247 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg) 9248 { 9249 PetscFunctionBegin; 9250 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9251 PetscValidBoolPointer(set,2); 9252 PetscValidBoolPointer(flg,3); 9253 if (A->hermitian != PETSC_BOOL3_UNKNOWN) { 9254 *set = PETSC_TRUE; 9255 *flg = PetscBool3ToBool(A->hermitian); 9256 } else { 9257 *set = PETSC_FALSE; 9258 } 9259 PetscFunctionReturn(0); 9260 } 9261 9262 /*@ 9263 MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric 9264 9265 Collective on Mat 9266 9267 Input Parameter: 9268 . A - the matrix to test 9269 9270 Output Parameters: 9271 . flg - the result 9272 9273 Notes: 9274 If the matrix does yet know it is structurally symmetric this can be an expensive operation, also available `MatIsStructurallySymmetricKnown()` 9275 9276 Level: intermediate 9277 9278 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsSymmetric()`, `MatSetOption()`, `MatIsStructurallySymmetricKnown()` 9279 @*/ 9280 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg) 9281 { 9282 PetscFunctionBegin; 9283 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9284 PetscValidBoolPointer(flg,2); 9285 if (A->structurally_symmetric != PETSC_BOOL3_UNKNOWN) { 9286 *flg = PetscBool3ToBool(A->structurally_symmetric); 9287 } else { 9288 PetscCheck(A->ops->isstructurallysymmetric,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix of type %s does not support checking for structural symmetry",((PetscObject)A)->type_name); 9289 PetscCall((*A->ops->isstructurallysymmetric)(A,flg)); 9290 PetscCall(MatSetOption(A,MAT_STRUCTURALLY_SYMMETRIC,*flg)); 9291 } 9292 PetscFunctionReturn(0); 9293 } 9294 9295 /*@ 9296 MatIsStructurallySymmetricKnown - Checks if a matrix knows if it is structurally symmetric or not and its structurally symmetric state 9297 9298 Not Collective 9299 9300 Input Parameter: 9301 . A - the matrix to check 9302 9303 Output Parameters: 9304 + set - PETSC_TRUE if the matrix knows its structurally symmetric state (this tells you if the next flag is valid) 9305 - flg - the result (only valid if set is PETSC_TRUE) 9306 9307 Level: advanced 9308 9309 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitianKnown()` 9310 @*/ 9311 PetscErrorCode MatIsStructurallySymmetricKnown(Mat A,PetscBool *set,PetscBool *flg) 9312 { 9313 PetscFunctionBegin; 9314 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9315 PetscValidBoolPointer(set,2); 9316 PetscValidBoolPointer(flg,3); 9317 if (A->structurally_symmetric != PETSC_BOOL3_UNKNOWN) { 9318 *set = PETSC_TRUE; 9319 *flg = PetscBool3ToBool(A->structurally_symmetric); 9320 } else { 9321 *set = PETSC_FALSE; 9322 } 9323 PetscFunctionReturn(0); 9324 } 9325 9326 /*@ 9327 MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need 9328 to be communicated to other processors during the MatAssemblyBegin/End() process 9329 9330 Not collective 9331 9332 Input Parameter: 9333 . vec - the vector 9334 9335 Output Parameters: 9336 + nstash - the size of the stash 9337 . reallocs - the number of additional mallocs incurred. 9338 . bnstash - the size of the block stash 9339 - breallocs - the number of additional mallocs incurred.in the block stash 9340 9341 Level: advanced 9342 9343 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `Mat`, `MatStashSetInitialSize()` 9344 9345 @*/ 9346 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs) 9347 { 9348 PetscFunctionBegin; 9349 PetscCall(MatStashGetInfo_Private(&mat->stash,nstash,reallocs)); 9350 PetscCall(MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs)); 9351 PetscFunctionReturn(0); 9352 } 9353 9354 /*@C 9355 MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same 9356 parallel layout 9357 9358 Collective on Mat 9359 9360 Input Parameter: 9361 . mat - the matrix 9362 9363 Output Parameters: 9364 + right - (optional) vector that the matrix can be multiplied against 9365 - left - (optional) vector that the matrix vector product can be stored in 9366 9367 Notes: 9368 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(). 9369 9370 Notes: 9371 These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed 9372 9373 Level: advanced 9374 9375 .seealso: `MatCreate()`, `VecDestroy()` 9376 @*/ 9377 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left) 9378 { 9379 PetscFunctionBegin; 9380 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9381 PetscValidType(mat,1); 9382 if (mat->ops->getvecs) { 9383 PetscCall((*mat->ops->getvecs)(mat,right,left)); 9384 } else { 9385 PetscInt rbs,cbs; 9386 PetscCall(MatGetBlockSizes(mat,&rbs,&cbs)); 9387 if (right) { 9388 PetscCheck(mat->cmap->n >= 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup"); 9389 PetscCall(VecCreate(PetscObjectComm((PetscObject)mat),right)); 9390 PetscCall(VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE)); 9391 PetscCall(VecSetBlockSize(*right,cbs)); 9392 PetscCall(VecSetType(*right,mat->defaultvectype)); 9393 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 9394 if (mat->boundtocpu && mat->bindingpropagates) { 9395 PetscCall(VecSetBindingPropagates(*right,PETSC_TRUE)); 9396 PetscCall(VecBindToCPU(*right,PETSC_TRUE)); 9397 } 9398 #endif 9399 PetscCall(PetscLayoutReference(mat->cmap,&(*right)->map)); 9400 } 9401 if (left) { 9402 PetscCheck(mat->rmap->n >= 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup"); 9403 PetscCall(VecCreate(PetscObjectComm((PetscObject)mat),left)); 9404 PetscCall(VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE)); 9405 PetscCall(VecSetBlockSize(*left,rbs)); 9406 PetscCall(VecSetType(*left,mat->defaultvectype)); 9407 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 9408 if (mat->boundtocpu && mat->bindingpropagates) { 9409 PetscCall(VecSetBindingPropagates(*left,PETSC_TRUE)); 9410 PetscCall(VecBindToCPU(*left,PETSC_TRUE)); 9411 } 9412 #endif 9413 PetscCall(PetscLayoutReference(mat->rmap,&(*left)->map)); 9414 } 9415 } 9416 PetscFunctionReturn(0); 9417 } 9418 9419 /*@C 9420 MatFactorInfoInitialize - Initializes a MatFactorInfo data structure 9421 with default values. 9422 9423 Not Collective 9424 9425 Input Parameters: 9426 . info - the MatFactorInfo data structure 9427 9428 Notes: 9429 The solvers are generally used through the KSP and PC objects, for example 9430 PCLU, PCILU, PCCHOLESKY, PCICC 9431 9432 Level: developer 9433 9434 .seealso: `MatFactorInfo` 9435 9436 Developer Note: fortran interface is not autogenerated as the f90 9437 interface definition cannot be generated correctly [due to MatFactorInfo] 9438 9439 @*/ 9440 9441 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info) 9442 { 9443 PetscFunctionBegin; 9444 PetscCall(PetscMemzero(info,sizeof(MatFactorInfo))); 9445 PetscFunctionReturn(0); 9446 } 9447 9448 /*@ 9449 MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed 9450 9451 Collective on Mat 9452 9453 Input Parameters: 9454 + mat - the factored matrix 9455 - is - the index set defining the Schur indices (0-based) 9456 9457 Notes: 9458 Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system. 9459 9460 You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call. 9461 9462 Level: developer 9463 9464 .seealso: `MatGetFactor()`, `MatFactorGetSchurComplement()`, `MatFactorRestoreSchurComplement()`, `MatFactorCreateSchurComplement()`, `MatFactorSolveSchurComplement()`, 9465 `MatFactorSolveSchurComplementTranspose()`, `MatFactorSolveSchurComplement()` 9466 9467 @*/ 9468 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is) 9469 { 9470 PetscErrorCode (*f)(Mat,IS); 9471 9472 PetscFunctionBegin; 9473 PetscValidType(mat,1); 9474 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9475 PetscValidType(is,2); 9476 PetscValidHeaderSpecific(is,IS_CLASSID,2); 9477 PetscCheckSameComm(mat,1,is,2); 9478 PetscCheck(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 9479 PetscCall(PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f)); 9480 PetscCheck(f,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"The selected MatSolverType does not support Schur complement computation. You should use MATSOLVERMUMPS or MATSOLVERMKL_PARDISO"); 9481 PetscCall(MatDestroy(&mat->schur)); 9482 PetscCall((*f)(mat,is)); 9483 PetscCheck(mat->schur,PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created"); 9484 PetscFunctionReturn(0); 9485 } 9486 9487 /*@ 9488 MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step 9489 9490 Logically Collective on Mat 9491 9492 Input Parameters: 9493 + F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface 9494 . S - location where to return the Schur complement, can be NULL 9495 - status - the status of the Schur complement matrix, can be NULL 9496 9497 Notes: 9498 You must call MatFactorSetSchurIS() before calling this routine. 9499 9500 The routine provides a copy of the Schur matrix stored within the solver data structures. 9501 The caller must destroy the object when it is no longer needed. 9502 If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse. 9503 9504 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) 9505 9506 Developer Notes: 9507 The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc 9508 matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix. 9509 9510 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 9511 9512 Level: advanced 9513 9514 References: 9515 9516 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorGetSchurComplement()`, `MatFactorSchurStatus` 9517 @*/ 9518 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 9519 { 9520 PetscFunctionBegin; 9521 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9522 if (S) PetscValidPointer(S,2); 9523 if (status) PetscValidPointer(status,3); 9524 if (S) { 9525 PetscErrorCode (*f)(Mat,Mat*); 9526 9527 PetscCall(PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f)); 9528 if (f) { 9529 PetscCall((*f)(F,S)); 9530 } else { 9531 PetscCall(MatDuplicate(F->schur,MAT_COPY_VALUES,S)); 9532 } 9533 } 9534 if (status) *status = F->schur_status; 9535 PetscFunctionReturn(0); 9536 } 9537 9538 /*@ 9539 MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix 9540 9541 Logically Collective on Mat 9542 9543 Input Parameters: 9544 + F - the factored matrix obtained by calling MatGetFactor() 9545 . *S - location where to return the Schur complement, can be NULL 9546 - status - the status of the Schur complement matrix, can be NULL 9547 9548 Notes: 9549 You must call MatFactorSetSchurIS() before calling this routine. 9550 9551 Schur complement mode is currently implemented for sequential matrices. 9552 The routine returns a the Schur Complement stored within the data strutures of the solver. 9553 If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement. 9554 The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed. 9555 9556 Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix 9557 9558 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 9559 9560 Level: advanced 9561 9562 References: 9563 9564 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorRestoreSchurComplement()`, `MatFactorCreateSchurComplement()`, `MatFactorSchurStatus` 9565 @*/ 9566 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 9567 { 9568 PetscFunctionBegin; 9569 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9570 if (S) PetscValidPointer(S,2); 9571 if (status) PetscValidPointer(status,3); 9572 if (S) *S = F->schur; 9573 if (status) *status = F->schur_status; 9574 PetscFunctionReturn(0); 9575 } 9576 9577 /*@ 9578 MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement 9579 9580 Logically Collective on Mat 9581 9582 Input Parameters: 9583 + F - the factored matrix obtained by calling MatGetFactor() 9584 . *S - location where the Schur complement is stored 9585 - status - the status of the Schur complement matrix (see MatFactorSchurStatus) 9586 9587 Notes: 9588 9589 Level: advanced 9590 9591 References: 9592 9593 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorRestoreSchurComplement()`, `MatFactorCreateSchurComplement()`, `MatFactorSchurStatus` 9594 @*/ 9595 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status) 9596 { 9597 PetscFunctionBegin; 9598 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9599 if (S) { 9600 PetscValidHeaderSpecific(*S,MAT_CLASSID,2); 9601 *S = NULL; 9602 } 9603 F->schur_status = status; 9604 PetscCall(MatFactorUpdateSchurStatus_Private(F)); 9605 PetscFunctionReturn(0); 9606 } 9607 9608 /*@ 9609 MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step 9610 9611 Logically Collective on Mat 9612 9613 Input Parameters: 9614 + F - the factored matrix obtained by calling MatGetFactor() 9615 . rhs - location where the right hand side of the Schur complement system is stored 9616 - sol - location where the solution of the Schur complement system has to be returned 9617 9618 Notes: 9619 The sizes of the vectors should match the size of the Schur complement 9620 9621 Must be called after MatFactorSetSchurIS() 9622 9623 Level: advanced 9624 9625 References: 9626 9627 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorSolveSchurComplement()` 9628 @*/ 9629 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol) 9630 { 9631 PetscFunctionBegin; 9632 PetscValidType(F,1); 9633 PetscValidType(rhs,2); 9634 PetscValidType(sol,3); 9635 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9636 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9637 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9638 PetscCheckSameComm(F,1,rhs,2); 9639 PetscCheckSameComm(F,1,sol,3); 9640 PetscCall(MatFactorFactorizeSchurComplement(F)); 9641 switch (F->schur_status) { 9642 case MAT_FACTOR_SCHUR_FACTORED: 9643 PetscCall(MatSolveTranspose(F->schur,rhs,sol)); 9644 break; 9645 case MAT_FACTOR_SCHUR_INVERTED: 9646 PetscCall(MatMultTranspose(F->schur,rhs,sol)); 9647 break; 9648 default: 9649 SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %d",F->schur_status); 9650 } 9651 PetscFunctionReturn(0); 9652 } 9653 9654 /*@ 9655 MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step 9656 9657 Logically Collective on Mat 9658 9659 Input Parameters: 9660 + F - the factored matrix obtained by calling MatGetFactor() 9661 . rhs - location where the right hand side of the Schur complement system is stored 9662 - sol - location where the solution of the Schur complement system has to be returned 9663 9664 Notes: 9665 The sizes of the vectors should match the size of the Schur complement 9666 9667 Must be called after MatFactorSetSchurIS() 9668 9669 Level: advanced 9670 9671 References: 9672 9673 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorSolveSchurComplementTranspose()` 9674 @*/ 9675 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol) 9676 { 9677 PetscFunctionBegin; 9678 PetscValidType(F,1); 9679 PetscValidType(rhs,2); 9680 PetscValidType(sol,3); 9681 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9682 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9683 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9684 PetscCheckSameComm(F,1,rhs,2); 9685 PetscCheckSameComm(F,1,sol,3); 9686 PetscCall(MatFactorFactorizeSchurComplement(F)); 9687 switch (F->schur_status) { 9688 case MAT_FACTOR_SCHUR_FACTORED: 9689 PetscCall(MatSolve(F->schur,rhs,sol)); 9690 break; 9691 case MAT_FACTOR_SCHUR_INVERTED: 9692 PetscCall(MatMult(F->schur,rhs,sol)); 9693 break; 9694 default: 9695 SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %d",F->schur_status); 9696 } 9697 PetscFunctionReturn(0); 9698 } 9699 9700 /*@ 9701 MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step 9702 9703 Logically Collective on Mat 9704 9705 Input Parameters: 9706 . F - the factored matrix obtained by calling MatGetFactor() 9707 9708 Notes: 9709 Must be called after MatFactorSetSchurIS(). 9710 9711 Call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it. 9712 9713 Level: advanced 9714 9715 References: 9716 9717 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorGetSchurComplement()`, `MatFactorCreateSchurComplement()` 9718 @*/ 9719 PetscErrorCode MatFactorInvertSchurComplement(Mat F) 9720 { 9721 PetscFunctionBegin; 9722 PetscValidType(F,1); 9723 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9724 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0); 9725 PetscCall(MatFactorFactorizeSchurComplement(F)); 9726 PetscCall(MatFactorInvertSchurComplement_Private(F)); 9727 F->schur_status = MAT_FACTOR_SCHUR_INVERTED; 9728 PetscFunctionReturn(0); 9729 } 9730 9731 /*@ 9732 MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step 9733 9734 Logically Collective on Mat 9735 9736 Input Parameters: 9737 . F - the factored matrix obtained by calling MatGetFactor() 9738 9739 Notes: 9740 Must be called after MatFactorSetSchurIS(). 9741 9742 Level: advanced 9743 9744 References: 9745 9746 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorInvertSchurComplement()` 9747 @*/ 9748 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F) 9749 { 9750 PetscFunctionBegin; 9751 PetscValidType(F,1); 9752 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9753 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0); 9754 PetscCall(MatFactorFactorizeSchurComplement_Private(F)); 9755 F->schur_status = MAT_FACTOR_SCHUR_FACTORED; 9756 PetscFunctionReturn(0); 9757 } 9758 9759 /*@ 9760 MatPtAP - Creates the matrix product C = P^T * A * P 9761 9762 Neighbor-wise Collective on Mat 9763 9764 Input Parameters: 9765 + A - the matrix 9766 . P - the projection matrix 9767 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9768 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate 9769 if the result is a dense matrix this is irrelevant 9770 9771 Output Parameters: 9772 . C - the product matrix 9773 9774 Notes: 9775 C will be created and must be destroyed by the user with MatDestroy(). 9776 9777 For matrix types without special implementation the function fallbacks to MatMatMult() followed by MatTransposeMatMult(). 9778 9779 Level: intermediate 9780 9781 .seealso: `MatMatMult()`, `MatRARt()` 9782 @*/ 9783 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 9784 { 9785 PetscFunctionBegin; 9786 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*C,5); 9787 PetscCheck(scall != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9788 9789 if (scall == MAT_INITIAL_MATRIX) { 9790 PetscCall(MatProductCreate(A,P,NULL,C)); 9791 PetscCall(MatProductSetType(*C,MATPRODUCT_PtAP)); 9792 PetscCall(MatProductSetAlgorithm(*C,"default")); 9793 PetscCall(MatProductSetFill(*C,fill)); 9794 9795 (*C)->product->api_user = PETSC_TRUE; 9796 PetscCall(MatProductSetFromOptions(*C)); 9797 PetscCheck((*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); 9798 PetscCall(MatProductSymbolic(*C)); 9799 } else { /* scall == MAT_REUSE_MATRIX */ 9800 PetscCall(MatProductReplaceMats(A,P,NULL,*C)); 9801 } 9802 9803 PetscCall(MatProductNumeric(*C)); 9804 (*C)->symmetric = A->symmetric; 9805 (*C)->spd = A->spd; 9806 PetscFunctionReturn(0); 9807 } 9808 9809 /*@ 9810 MatRARt - Creates the matrix product C = R * A * R^T 9811 9812 Neighbor-wise Collective on Mat 9813 9814 Input Parameters: 9815 + A - the matrix 9816 . R - the projection matrix 9817 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9818 - fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate 9819 if the result is a dense matrix this is irrelevant 9820 9821 Output Parameters: 9822 . C - the product matrix 9823 9824 Notes: 9825 C will be created and must be destroyed by the user with MatDestroy(). 9826 9827 This routine is currently only implemented for pairs of AIJ matrices and classes 9828 which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes, 9829 parallel MatRARt is implemented via explicit transpose of R, which could be very expensive. 9830 We recommend using MatPtAP(). 9831 9832 Level: intermediate 9833 9834 .seealso: `MatMatMult()`, `MatPtAP()` 9835 @*/ 9836 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C) 9837 { 9838 PetscFunctionBegin; 9839 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*C,5); 9840 PetscCheck(scall != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9841 9842 if (scall == MAT_INITIAL_MATRIX) { 9843 PetscCall(MatProductCreate(A,R,NULL,C)); 9844 PetscCall(MatProductSetType(*C,MATPRODUCT_RARt)); 9845 PetscCall(MatProductSetAlgorithm(*C,"default")); 9846 PetscCall(MatProductSetFill(*C,fill)); 9847 9848 (*C)->product->api_user = PETSC_TRUE; 9849 PetscCall(MatProductSetFromOptions(*C)); 9850 PetscCheck((*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); 9851 PetscCall(MatProductSymbolic(*C)); 9852 } else { /* scall == MAT_REUSE_MATRIX */ 9853 PetscCall(MatProductReplaceMats(A,R,NULL,*C)); 9854 } 9855 9856 PetscCall(MatProductNumeric(*C)); 9857 if (A->symmetric == PETSC_BOOL3_TRUE) { 9858 PetscCall(MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE)); 9859 } 9860 PetscFunctionReturn(0); 9861 } 9862 9863 static PetscErrorCode MatProduct_Private(Mat A,Mat B,MatReuse scall,PetscReal fill,MatProductType ptype, Mat *C) 9864 { 9865 PetscFunctionBegin; 9866 PetscCheck(scall != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9867 9868 if (scall == MAT_INITIAL_MATRIX) { 9869 PetscCall(PetscInfo(A,"Calling MatProduct API with MAT_INITIAL_MATRIX and product type %s\n",MatProductTypes[ptype])); 9870 PetscCall(MatProductCreate(A,B,NULL,C)); 9871 PetscCall(MatProductSetType(*C,ptype)); 9872 PetscCall(MatProductSetAlgorithm(*C,MATPRODUCTALGORITHMDEFAULT)); 9873 PetscCall(MatProductSetFill(*C,fill)); 9874 9875 (*C)->product->api_user = PETSC_TRUE; 9876 PetscCall(MatProductSetFromOptions(*C)); 9877 PetscCall(MatProductSymbolic(*C)); 9878 } else { /* scall == MAT_REUSE_MATRIX */ 9879 Mat_Product *product = (*C)->product; 9880 PetscBool isdense; 9881 9882 PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)(*C),&isdense,MATSEQDENSE,MATMPIDENSE,"")); 9883 if (isdense && product && product->type != ptype) { 9884 PetscCall(MatProductClear(*C)); 9885 product = NULL; 9886 } 9887 PetscCall(PetscInfo(A,"Calling MatProduct API with MAT_REUSE_MATRIX %s product present and product type %s\n",product ? "with" : "without",MatProductTypes[ptype])); 9888 if (!product) { /* user provide the dense matrix *C without calling MatProductCreate() or reusing it from previous calls */ 9889 if (isdense) { 9890 PetscCall(MatProductCreate_Private(A,B,NULL,*C)); 9891 product = (*C)->product; 9892 product->fill = fill; 9893 product->api_user = PETSC_TRUE; 9894 product->clear = PETSC_TRUE; 9895 9896 PetscCall(MatProductSetType(*C,ptype)); 9897 PetscCall(MatProductSetFromOptions(*C)); 9898 PetscCheck((*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); 9899 PetscCall(MatProductSymbolic(*C)); 9900 } else SETERRQ(PetscObjectComm((PetscObject)(*C)),PETSC_ERR_SUP,"Call MatProductCreate() first"); 9901 } else { /* user may change input matrices A or B when REUSE */ 9902 PetscCall(MatProductReplaceMats(A,B,NULL,*C)); 9903 } 9904 } 9905 PetscCall(MatProductNumeric(*C)); 9906 PetscFunctionReturn(0); 9907 } 9908 9909 /*@ 9910 MatMatMult - Performs Matrix-Matrix Multiplication C=A*B. 9911 9912 Neighbor-wise Collective on Mat 9913 9914 Input Parameters: 9915 + A - the left matrix 9916 . B - the right matrix 9917 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9918 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate 9919 if the result is a dense matrix this is irrelevant 9920 9921 Output Parameters: 9922 . C - the product matrix 9923 9924 Notes: 9925 Unless scall is MAT_REUSE_MATRIX C will be created. 9926 9927 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 9928 call to this function with MAT_INITIAL_MATRIX. 9929 9930 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value actually needed. 9931 9932 If you have many matrices with the same non-zero structure to multiply, you should use MatProductCreate()/MatProductSymbolic()/MatProductReplaceMats(), and call MatProductNumeric() repeatedly. 9933 9934 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. 9935 9936 Example of Usage: 9937 .vb 9938 MatProductCreate(A,B,NULL,&C); 9939 MatProductSetType(C,MATPRODUCT_AB); 9940 MatProductSymbolic(C); 9941 MatProductNumeric(C); // compute C=A * B 9942 MatProductReplaceMats(A1,B1,NULL,C); // compute C=A1 * B1 9943 MatProductNumeric(C); 9944 MatProductReplaceMats(A2,NULL,NULL,C); // compute C=A2 * B1 9945 MatProductNumeric(C); 9946 .ve 9947 9948 Level: intermediate 9949 9950 .seealso: `MatTransposeMatMult()`, `MatMatTransposeMult()`, `MatPtAP()`, `MatProductCreate()`, `MatProductSymbolic()`, `MatProductReplaceMats()`, `MatProductNumeric()` 9951 @*/ 9952 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9953 { 9954 PetscFunctionBegin; 9955 PetscCall(MatProduct_Private(A,B,scall,fill,MATPRODUCT_AB,C)); 9956 PetscFunctionReturn(0); 9957 } 9958 9959 /*@ 9960 MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T. 9961 9962 Neighbor-wise Collective on Mat 9963 9964 Input Parameters: 9965 + A - the left matrix 9966 . B - the right matrix 9967 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9968 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9969 9970 Output Parameters: 9971 . C - the product matrix 9972 9973 Notes: 9974 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9975 9976 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9977 9978 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9979 actually needed. 9980 9981 This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class, 9982 and for pairs of MPIDense matrices. 9983 9984 Options Database Keys: 9985 . -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorithms for MPIDense matrices: the 9986 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity; 9987 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity. 9988 9989 Level: intermediate 9990 9991 .seealso: `MatMatMult()`, `MatTransposeMatMult()` `MatPtAP()` 9992 @*/ 9993 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9994 { 9995 PetscFunctionBegin; 9996 PetscCall(MatProduct_Private(A,B,scall,fill,MATPRODUCT_ABt,C)); 9997 if (A == B) { 9998 PetscCall(MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE)); 9999 } 10000 PetscFunctionReturn(0); 10001 } 10002 10003 /*@ 10004 MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B. 10005 10006 Neighbor-wise Collective on Mat 10007 10008 Input Parameters: 10009 + A - the left matrix 10010 . B - the right matrix 10011 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10012 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 10013 10014 Output Parameters: 10015 . C - the product matrix 10016 10017 Notes: 10018 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 10019 10020 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call. 10021 10022 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 10023 actually needed. 10024 10025 This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes 10026 which inherit from SeqAIJ. C will be of the same type as the input matrices. 10027 10028 Level: intermediate 10029 10030 .seealso: `MatMatMult()`, `MatMatTransposeMult()`, `MatPtAP()` 10031 @*/ 10032 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 10033 { 10034 PetscFunctionBegin; 10035 PetscCall(MatProduct_Private(A,B,scall,fill,MATPRODUCT_AtB,C)); 10036 PetscFunctionReturn(0); 10037 } 10038 10039 /*@ 10040 MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C. 10041 10042 Neighbor-wise Collective on Mat 10043 10044 Input Parameters: 10045 + A - the left matrix 10046 . B - the middle matrix 10047 . C - the right matrix 10048 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10049 - 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 10050 if the result is a dense matrix this is irrelevant 10051 10052 Output Parameters: 10053 . D - the product matrix 10054 10055 Notes: 10056 Unless scall is MAT_REUSE_MATRIX D will be created. 10057 10058 MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call 10059 10060 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 10061 actually needed. 10062 10063 If you have many matrices with the same non-zero structure to multiply, you 10064 should use MAT_REUSE_MATRIX in all calls but the first 10065 10066 Level: intermediate 10067 10068 .seealso: `MatMatMult`, `MatPtAP()`, `MatMatTransposeMult()`, `MatTransposeMatMult()` 10069 @*/ 10070 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D) 10071 { 10072 PetscFunctionBegin; 10073 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*D,6); 10074 PetscCheck(scall != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 10075 10076 if (scall == MAT_INITIAL_MATRIX) { 10077 PetscCall(MatProductCreate(A,B,C,D)); 10078 PetscCall(MatProductSetType(*D,MATPRODUCT_ABC)); 10079 PetscCall(MatProductSetAlgorithm(*D,"default")); 10080 PetscCall(MatProductSetFill(*D,fill)); 10081 10082 (*D)->product->api_user = PETSC_TRUE; 10083 PetscCall(MatProductSetFromOptions(*D)); 10084 PetscCheck((*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); 10085 PetscCall(MatProductSymbolic(*D)); 10086 } else { /* user may change input matrices when REUSE */ 10087 PetscCall(MatProductReplaceMats(A,B,C,*D)); 10088 } 10089 PetscCall(MatProductNumeric(*D)); 10090 PetscFunctionReturn(0); 10091 } 10092 10093 /*@ 10094 MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators. 10095 10096 Collective on Mat 10097 10098 Input Parameters: 10099 + mat - the matrix 10100 . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices) 10101 . subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used) 10102 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10103 10104 Output Parameter: 10105 . matredundant - redundant matrix 10106 10107 Notes: 10108 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 10109 original matrix has not changed from that last call to MatCreateRedundantMatrix(). 10110 10111 This routine creates the duplicated matrices in the subcommunicators; you should NOT create them before 10112 calling it. 10113 10114 Level: advanced 10115 10116 .seealso: `MatDestroy()` 10117 @*/ 10118 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant) 10119 { 10120 MPI_Comm comm; 10121 PetscMPIInt size; 10122 PetscInt mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs; 10123 Mat_Redundant *redund=NULL; 10124 PetscSubcomm psubcomm=NULL; 10125 MPI_Comm subcomm_in=subcomm; 10126 Mat *matseq; 10127 IS isrow,iscol; 10128 PetscBool newsubcomm=PETSC_FALSE; 10129 10130 PetscFunctionBegin; 10131 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10132 if (nsubcomm && reuse == MAT_REUSE_MATRIX) { 10133 PetscValidPointer(*matredundant,5); 10134 PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5); 10135 } 10136 10137 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 10138 if (size == 1 || nsubcomm == 1) { 10139 if (reuse == MAT_INITIAL_MATRIX) { 10140 PetscCall(MatDuplicate(mat,MAT_COPY_VALUES,matredundant)); 10141 } else { 10142 PetscCheck(*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"); 10143 PetscCall(MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN)); 10144 } 10145 PetscFunctionReturn(0); 10146 } 10147 10148 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10149 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10150 MatCheckPreallocated(mat,1); 10151 10152 PetscCall(PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0)); 10153 if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */ 10154 /* create psubcomm, then get subcomm */ 10155 PetscCall(PetscObjectGetComm((PetscObject)mat,&comm)); 10156 PetscCallMPI(MPI_Comm_size(comm,&size)); 10157 PetscCheck(nsubcomm >= 1 && nsubcomm <= size,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %d",size); 10158 10159 PetscCall(PetscSubcommCreate(comm,&psubcomm)); 10160 PetscCall(PetscSubcommSetNumber(psubcomm,nsubcomm)); 10161 PetscCall(PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS)); 10162 PetscCall(PetscSubcommSetFromOptions(psubcomm)); 10163 PetscCall(PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL)); 10164 newsubcomm = PETSC_TRUE; 10165 PetscCall(PetscSubcommDestroy(&psubcomm)); 10166 } 10167 10168 /* get isrow, iscol and a local sequential matrix matseq[0] */ 10169 if (reuse == MAT_INITIAL_MATRIX) { 10170 mloc_sub = PETSC_DECIDE; 10171 nloc_sub = PETSC_DECIDE; 10172 if (bs < 1) { 10173 PetscCall(PetscSplitOwnership(subcomm,&mloc_sub,&M)); 10174 PetscCall(PetscSplitOwnership(subcomm,&nloc_sub,&N)); 10175 } else { 10176 PetscCall(PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M)); 10177 PetscCall(PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N)); 10178 } 10179 PetscCallMPI(MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm)); 10180 rstart = rend - mloc_sub; 10181 PetscCall(ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow)); 10182 PetscCall(ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol)); 10183 } else { /* reuse == MAT_REUSE_MATRIX */ 10184 PetscCheck(*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"); 10185 /* retrieve subcomm */ 10186 PetscCall(PetscObjectGetComm((PetscObject)(*matredundant),&subcomm)); 10187 redund = (*matredundant)->redundant; 10188 isrow = redund->isrow; 10189 iscol = redund->iscol; 10190 matseq = redund->matseq; 10191 } 10192 PetscCall(MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq)); 10193 10194 /* get matredundant over subcomm */ 10195 if (reuse == MAT_INITIAL_MATRIX) { 10196 PetscCall(MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant)); 10197 10198 /* create a supporting struct and attach it to C for reuse */ 10199 PetscCall(PetscNewLog(*matredundant,&redund)); 10200 (*matredundant)->redundant = redund; 10201 redund->isrow = isrow; 10202 redund->iscol = iscol; 10203 redund->matseq = matseq; 10204 if (newsubcomm) { 10205 redund->subcomm = subcomm; 10206 } else { 10207 redund->subcomm = MPI_COMM_NULL; 10208 } 10209 } else { 10210 PetscCall(MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant)); 10211 } 10212 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 10213 if (matseq[0]->boundtocpu && matseq[0]->bindingpropagates) { 10214 PetscCall(MatBindToCPU(*matredundant,PETSC_TRUE)); 10215 PetscCall(MatSetBindingPropagates(*matredundant,PETSC_TRUE)); 10216 } 10217 #endif 10218 PetscCall(PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0)); 10219 PetscFunctionReturn(0); 10220 } 10221 10222 /*@C 10223 MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from 10224 a given 'mat' object. Each submatrix can span multiple procs. 10225 10226 Collective on Mat 10227 10228 Input Parameters: 10229 + mat - the matrix 10230 . subcomm - the subcommunicator obtained by com_split(comm) 10231 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10232 10233 Output Parameter: 10234 . subMat - 'parallel submatrices each spans a given subcomm 10235 10236 Notes: 10237 The submatrix partition across processors is dictated by 'subComm' a 10238 communicator obtained by MPI_comm_split(). The subComm 10239 is not restriced to be grouped with consecutive original ranks. 10240 10241 Due the MPI_Comm_split() usage, the parallel layout of the submatrices 10242 map directly to the layout of the original matrix [wrt the local 10243 row,col partitioning]. So the original 'DiagonalMat' naturally maps 10244 into the 'DiagonalMat' of the subMat, hence it is used directly from 10245 the subMat. However the offDiagMat looses some columns - and this is 10246 reconstructed with MatSetValues() 10247 10248 Level: advanced 10249 10250 .seealso: `MatCreateSubMatrices()` 10251 @*/ 10252 PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat) 10253 { 10254 PetscMPIInt commsize,subCommSize; 10255 10256 PetscFunctionBegin; 10257 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize)); 10258 PetscCallMPI(MPI_Comm_size(subComm,&subCommSize)); 10259 PetscCheck(subCommSize <= commsize,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %d < SubCommZize %d",commsize,subCommSize); 10260 10261 PetscCheck(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"); 10262 PetscCall(PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0)); 10263 PetscCall((*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat)); 10264 PetscCall(PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0)); 10265 PetscFunctionReturn(0); 10266 } 10267 10268 /*@ 10269 MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering 10270 10271 Not Collective 10272 10273 Input Parameters: 10274 + mat - matrix to extract local submatrix from 10275 . isrow - local row indices for submatrix 10276 - iscol - local column indices for submatrix 10277 10278 Output Parameter: 10279 . submat - the submatrix 10280 10281 Level: intermediate 10282 10283 Notes: 10284 The submat should be returned with MatRestoreLocalSubMatrix(). 10285 10286 Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be 10287 the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's. 10288 10289 The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then 10290 MatSetValuesBlockedLocal() will also be implemented. 10291 10292 The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that 10293 matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided. 10294 10295 .seealso: `MatRestoreLocalSubMatrix()`, `MatCreateLocalRef()`, `MatSetLocalToGlobalMapping()` 10296 @*/ 10297 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10298 { 10299 PetscFunctionBegin; 10300 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10301 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10302 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10303 PetscCheckSameComm(isrow,2,iscol,3); 10304 PetscValidPointer(submat,4); 10305 PetscCheck(mat->rmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call"); 10306 10307 if (mat->ops->getlocalsubmatrix) { 10308 PetscCall((*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat)); 10309 } else { 10310 PetscCall(MatCreateLocalRef(mat,isrow,iscol,submat)); 10311 } 10312 PetscFunctionReturn(0); 10313 } 10314 10315 /*@ 10316 MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering 10317 10318 Not Collective 10319 10320 Input Parameters: 10321 + mat - matrix to extract local submatrix from 10322 . isrow - local row indices for submatrix 10323 . iscol - local column indices for submatrix 10324 - submat - the submatrix 10325 10326 Level: intermediate 10327 10328 .seealso: `MatGetLocalSubMatrix()` 10329 @*/ 10330 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10331 { 10332 PetscFunctionBegin; 10333 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10334 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10335 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10336 PetscCheckSameComm(isrow,2,iscol,3); 10337 PetscValidPointer(submat,4); 10338 if (*submat) { 10339 PetscValidHeaderSpecific(*submat,MAT_CLASSID,4); 10340 } 10341 10342 if (mat->ops->restorelocalsubmatrix) { 10343 PetscCall((*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat)); 10344 } else { 10345 PetscCall(MatDestroy(submat)); 10346 } 10347 *submat = NULL; 10348 PetscFunctionReturn(0); 10349 } 10350 10351 /* --------------------------------------------------------*/ 10352 /*@ 10353 MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix 10354 10355 Collective on Mat 10356 10357 Input Parameter: 10358 . mat - the matrix 10359 10360 Output Parameter: 10361 . is - if any rows have zero diagonals this contains the list of them 10362 10363 Level: developer 10364 10365 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 10366 @*/ 10367 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is) 10368 { 10369 PetscFunctionBegin; 10370 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10371 PetscValidType(mat,1); 10372 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10373 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10374 10375 if (!mat->ops->findzerodiagonals) { 10376 Vec diag; 10377 const PetscScalar *a; 10378 PetscInt *rows; 10379 PetscInt rStart, rEnd, r, nrow = 0; 10380 10381 PetscCall(MatCreateVecs(mat, &diag, NULL)); 10382 PetscCall(MatGetDiagonal(mat, diag)); 10383 PetscCall(MatGetOwnershipRange(mat, &rStart, &rEnd)); 10384 PetscCall(VecGetArrayRead(diag, &a)); 10385 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow; 10386 PetscCall(PetscMalloc1(nrow, &rows)); 10387 nrow = 0; 10388 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart; 10389 PetscCall(VecRestoreArrayRead(diag, &a)); 10390 PetscCall(VecDestroy(&diag)); 10391 PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is)); 10392 } else { 10393 PetscCall((*mat->ops->findzerodiagonals)(mat, is)); 10394 } 10395 PetscFunctionReturn(0); 10396 } 10397 10398 /*@ 10399 MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size) 10400 10401 Collective on Mat 10402 10403 Input Parameter: 10404 . mat - the matrix 10405 10406 Output Parameter: 10407 . is - contains the list of rows with off block diagonal entries 10408 10409 Level: developer 10410 10411 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 10412 @*/ 10413 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is) 10414 { 10415 PetscFunctionBegin; 10416 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10417 PetscValidType(mat,1); 10418 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10419 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10420 10421 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); 10422 PetscCall((*mat->ops->findoffblockdiagonalentries)(mat,is)); 10423 PetscFunctionReturn(0); 10424 } 10425 10426 /*@C 10427 MatInvertBlockDiagonal - Inverts the block diagonal entries. 10428 10429 Collective on Mat 10430 10431 Input Parameters: 10432 . mat - the matrix 10433 10434 Output Parameters: 10435 . values - the block inverses in column major order (FORTRAN-like) 10436 10437 Note: 10438 The size of the blocks is determined by the block size of the matrix. 10439 10440 Fortran Note: 10441 This routine is not available from Fortran. 10442 10443 Level: advanced 10444 10445 .seealso: `MatInvertVariableBlockEnvelope()`, `MatInvertBlockDiagonalMat()` 10446 @*/ 10447 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values) 10448 { 10449 PetscFunctionBegin; 10450 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10451 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10452 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10453 PetscCheck(mat->ops->invertblockdiagonal,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for type %s",((PetscObject)mat)->type_name); 10454 PetscCall((*mat->ops->invertblockdiagonal)(mat,values)); 10455 PetscFunctionReturn(0); 10456 } 10457 10458 /*@C 10459 MatInvertVariableBlockDiagonal - Inverts the point block diagonal entries. 10460 10461 Collective on Mat 10462 10463 Input Parameters: 10464 + mat - the matrix 10465 . nblocks - the number of blocks on the process, set with MatSetVariableBlockSizes() 10466 - bsizes - the size of each block on the process, set with MatSetVariableBlockSizes() 10467 10468 Output Parameters: 10469 . values - the block inverses in column major order (FORTRAN-like) 10470 10471 Note: 10472 This routine is not available from Fortran. 10473 10474 Level: advanced 10475 10476 .seealso: `MatInvertBlockDiagonal()`, `MatSetVariableBlockSizes()`, `MatInvertVariableBlockEnvelope()` 10477 @*/ 10478 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values) 10479 { 10480 PetscFunctionBegin; 10481 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10482 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10483 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10484 PetscCheck(mat->ops->invertvariableblockdiagonal,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for type %s",((PetscObject)mat)->type_name); 10485 PetscCall((*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values)); 10486 PetscFunctionReturn(0); 10487 } 10488 10489 /*@ 10490 MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A 10491 10492 Collective on Mat 10493 10494 Input Parameters: 10495 . A - the matrix 10496 10497 Output Parameters: 10498 . C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set. 10499 10500 Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C 10501 10502 Level: advanced 10503 10504 .seealso: `MatInvertBlockDiagonal()` 10505 @*/ 10506 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C) 10507 { 10508 const PetscScalar *vals; 10509 PetscInt *dnnz; 10510 PetscInt m,rstart,rend,bs,i,j; 10511 10512 PetscFunctionBegin; 10513 PetscCall(MatInvertBlockDiagonal(A,&vals)); 10514 PetscCall(MatGetBlockSize(A,&bs)); 10515 PetscCall(MatGetLocalSize(A,&m,NULL)); 10516 PetscCall(MatSetLayouts(C,A->rmap,A->cmap)); 10517 PetscCall(PetscMalloc1(m/bs,&dnnz)); 10518 for (j = 0; j < m/bs; j++) dnnz[j] = 1; 10519 PetscCall(MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL)); 10520 PetscCall(PetscFree(dnnz)); 10521 PetscCall(MatGetOwnershipRange(C,&rstart,&rend)); 10522 PetscCall(MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE)); 10523 for (i = rstart/bs; i < rend/bs; i++) { 10524 PetscCall(MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES)); 10525 } 10526 PetscCall(MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY)); 10527 PetscCall(MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY)); 10528 PetscCall(MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE)); 10529 PetscFunctionReturn(0); 10530 } 10531 10532 /*@C 10533 MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created 10534 via MatTransposeColoringCreate(). 10535 10536 Collective on MatTransposeColoring 10537 10538 Input Parameter: 10539 . c - coloring context 10540 10541 Level: intermediate 10542 10543 .seealso: `MatTransposeColoringCreate()` 10544 @*/ 10545 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c) 10546 { 10547 MatTransposeColoring matcolor=*c; 10548 10549 PetscFunctionBegin; 10550 if (!matcolor) PetscFunctionReturn(0); 10551 if (--((PetscObject)matcolor)->refct > 0) {matcolor = NULL; PetscFunctionReturn(0);} 10552 10553 PetscCall(PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow)); 10554 PetscCall(PetscFree(matcolor->rows)); 10555 PetscCall(PetscFree(matcolor->den2sp)); 10556 PetscCall(PetscFree(matcolor->colorforcol)); 10557 PetscCall(PetscFree(matcolor->columns)); 10558 if (matcolor->brows>0) PetscCall(PetscFree(matcolor->lstart)); 10559 PetscCall(PetscHeaderDestroy(c)); 10560 PetscFunctionReturn(0); 10561 } 10562 10563 /*@C 10564 MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which 10565 a MatTransposeColoring context has been created, computes a dense B^T by Apply 10566 MatTransposeColoring to sparse B. 10567 10568 Collective on MatTransposeColoring 10569 10570 Input Parameters: 10571 + B - sparse matrix B 10572 . Btdense - symbolic dense matrix B^T 10573 - coloring - coloring context created with MatTransposeColoringCreate() 10574 10575 Output Parameter: 10576 . Btdense - dense matrix B^T 10577 10578 Level: advanced 10579 10580 Notes: 10581 These are used internally for some implementations of MatRARt() 10582 10583 .seealso: `MatTransposeColoringCreate()`, `MatTransposeColoringDestroy()`, `MatTransColoringApplyDenToSp()` 10584 10585 @*/ 10586 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense) 10587 { 10588 PetscFunctionBegin; 10589 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 10590 PetscValidHeaderSpecific(Btdense,MAT_CLASSID,3); 10591 PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,1); 10592 10593 PetscCheck(B->ops->transcoloringapplysptoden,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name); 10594 PetscCall((B->ops->transcoloringapplysptoden)(coloring,B,Btdense)); 10595 PetscFunctionReturn(0); 10596 } 10597 10598 /*@C 10599 MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which 10600 a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense 10601 in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix 10602 Csp from Cden. 10603 10604 Collective on MatTransposeColoring 10605 10606 Input Parameters: 10607 + coloring - coloring context created with MatTransposeColoringCreate() 10608 - Cden - matrix product of a sparse matrix and a dense matrix Btdense 10609 10610 Output Parameter: 10611 . Csp - sparse matrix 10612 10613 Level: advanced 10614 10615 Notes: 10616 These are used internally for some implementations of MatRARt() 10617 10618 .seealso: `MatTransposeColoringCreate()`, `MatTransposeColoringDestroy()`, `MatTransColoringApplySpToDen()` 10619 10620 @*/ 10621 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp) 10622 { 10623 PetscFunctionBegin; 10624 PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1); 10625 PetscValidHeaderSpecific(Cden,MAT_CLASSID,2); 10626 PetscValidHeaderSpecific(Csp,MAT_CLASSID,3); 10627 10628 PetscCheck(Csp->ops->transcoloringapplydentosp,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name); 10629 PetscCall((Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp)); 10630 PetscCall(MatAssemblyBegin(Csp,MAT_FINAL_ASSEMBLY)); 10631 PetscCall(MatAssemblyEnd(Csp,MAT_FINAL_ASSEMBLY)); 10632 PetscFunctionReturn(0); 10633 } 10634 10635 /*@C 10636 MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T. 10637 10638 Collective on Mat 10639 10640 Input Parameters: 10641 + mat - the matrix product C 10642 - iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring() 10643 10644 Output Parameter: 10645 . color - the new coloring context 10646 10647 Level: intermediate 10648 10649 .seealso: `MatTransposeColoringDestroy()`, `MatTransColoringApplySpToDen()`, 10650 `MatTransColoringApplyDenToSp()` 10651 @*/ 10652 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color) 10653 { 10654 MatTransposeColoring c; 10655 MPI_Comm comm; 10656 10657 PetscFunctionBegin; 10658 PetscCall(PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0)); 10659 PetscCall(PetscObjectGetComm((PetscObject)mat,&comm)); 10660 PetscCall(PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL)); 10661 10662 c->ctype = iscoloring->ctype; 10663 if (mat->ops->transposecoloringcreate) { 10664 PetscCall((*mat->ops->transposecoloringcreate)(mat,iscoloring,c)); 10665 } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for matrix type %s",((PetscObject)mat)->type_name); 10666 10667 *color = c; 10668 PetscCall(PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0)); 10669 PetscFunctionReturn(0); 10670 } 10671 10672 /*@ 10673 MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the 10674 matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the 10675 same, otherwise it will be larger 10676 10677 Not Collective 10678 10679 Input Parameter: 10680 . A - the matrix 10681 10682 Output Parameter: 10683 . state - the current state 10684 10685 Notes: 10686 You can only compare states from two different calls to the SAME matrix, you cannot compare calls between 10687 different matrices 10688 10689 Level: intermediate 10690 10691 .seealso: `PetscObjectStateGet()` 10692 @*/ 10693 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state) 10694 { 10695 PetscFunctionBegin; 10696 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10697 *state = mat->nonzerostate; 10698 PetscFunctionReturn(0); 10699 } 10700 10701 /*@ 10702 MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential 10703 matrices from each processor 10704 10705 Collective 10706 10707 Input Parameters: 10708 + comm - the communicators the parallel matrix will live on 10709 . seqmat - the input sequential matrices 10710 . n - number of local columns (or PETSC_DECIDE) 10711 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10712 10713 Output Parameter: 10714 . mpimat - the parallel matrix generated 10715 10716 Level: advanced 10717 10718 Notes: 10719 The number of columns of the matrix in EACH processor MUST be the same. 10720 10721 @*/ 10722 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat) 10723 { 10724 PetscMPIInt size; 10725 10726 PetscFunctionBegin; 10727 PetscCallMPI(MPI_Comm_size(comm,&size)); 10728 if (size == 1) { 10729 if (reuse == MAT_INITIAL_MATRIX) { 10730 PetscCall(MatDuplicate(seqmat,MAT_COPY_VALUES,mpimat)); 10731 } else { 10732 PetscCall(MatCopy(seqmat,*mpimat,SAME_NONZERO_PATTERN)); 10733 } 10734 PetscFunctionReturn(0); 10735 } 10736 10737 PetscCheck(seqmat->ops->creatempimatconcatenateseqmat,PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name); 10738 PetscCheck(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"); 10739 10740 PetscCall(PetscLogEventBegin(MAT_Merge,seqmat,0,0,0)); 10741 PetscCall((*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat)); 10742 PetscCall(PetscLogEventEnd(MAT_Merge,seqmat,0,0,0)); 10743 PetscFunctionReturn(0); 10744 } 10745 10746 /*@ 10747 MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent 10748 ranks' ownership ranges. 10749 10750 Collective on A 10751 10752 Input Parameters: 10753 + A - the matrix to create subdomains from 10754 - N - requested number of subdomains 10755 10756 Output Parameters: 10757 + n - number of subdomains resulting on this rank 10758 - iss - IS list with indices of subdomains on this rank 10759 10760 Level: advanced 10761 10762 Notes: 10763 number of subdomains must be smaller than the communicator size 10764 @*/ 10765 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[]) 10766 { 10767 MPI_Comm comm,subcomm; 10768 PetscMPIInt size,rank,color; 10769 PetscInt rstart,rend,k; 10770 10771 PetscFunctionBegin; 10772 PetscCall(PetscObjectGetComm((PetscObject)A,&comm)); 10773 PetscCallMPI(MPI_Comm_size(comm,&size)); 10774 PetscCallMPI(MPI_Comm_rank(comm,&rank)); 10775 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); 10776 *n = 1; 10777 k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */ 10778 color = rank/k; 10779 PetscCallMPI(MPI_Comm_split(comm,color,rank,&subcomm)); 10780 PetscCall(PetscMalloc1(1,iss)); 10781 PetscCall(MatGetOwnershipRange(A,&rstart,&rend)); 10782 PetscCall(ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0])); 10783 PetscCallMPI(MPI_Comm_free(&subcomm)); 10784 PetscFunctionReturn(0); 10785 } 10786 10787 /*@ 10788 MatGalerkin - Constructs the coarse grid problem via Galerkin projection. 10789 10790 If the interpolation and restriction operators are the same, uses MatPtAP. 10791 If they are not the same, use MatMatMatMult. 10792 10793 Once the coarse grid problem is constructed, correct for interpolation operators 10794 that are not of full rank, which can legitimately happen in the case of non-nested 10795 geometric multigrid. 10796 10797 Input Parameters: 10798 + restrct - restriction operator 10799 . dA - fine grid matrix 10800 . interpolate - interpolation operator 10801 . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10802 - fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate 10803 10804 Output Parameters: 10805 . A - the Galerkin coarse matrix 10806 10807 Options Database Key: 10808 . -pc_mg_galerkin <both,pmat,mat,none> - for what matrices the Galerkin process should be used 10809 10810 Level: developer 10811 10812 .seealso: `MatPtAP()`, `MatMatMatMult()` 10813 @*/ 10814 PetscErrorCode MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A) 10815 { 10816 IS zerorows; 10817 Vec diag; 10818 10819 PetscFunctionBegin; 10820 PetscCheck(reuse != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 10821 /* Construct the coarse grid matrix */ 10822 if (interpolate == restrct) { 10823 PetscCall(MatPtAP(dA,interpolate,reuse,fill,A)); 10824 } else { 10825 PetscCall(MatMatMatMult(restrct,dA,interpolate,reuse,fill,A)); 10826 } 10827 10828 /* If the interpolation matrix is not of full rank, A will have zero rows. 10829 This can legitimately happen in the case of non-nested geometric multigrid. 10830 In that event, we set the rows of the matrix to the rows of the identity, 10831 ignoring the equations (as the RHS will also be zero). */ 10832 10833 PetscCall(MatFindZeroRows(*A, &zerorows)); 10834 10835 if (zerorows != NULL) { /* if there are any zero rows */ 10836 PetscCall(MatCreateVecs(*A, &diag, NULL)); 10837 PetscCall(MatGetDiagonal(*A, diag)); 10838 PetscCall(VecISSet(diag, zerorows, 1.0)); 10839 PetscCall(MatDiagonalSet(*A, diag, INSERT_VALUES)); 10840 PetscCall(VecDestroy(&diag)); 10841 PetscCall(ISDestroy(&zerorows)); 10842 } 10843 PetscFunctionReturn(0); 10844 } 10845 10846 /*@C 10847 MatSetOperation - Allows user to set a matrix operation for any matrix type 10848 10849 Logically Collective on Mat 10850 10851 Input Parameters: 10852 + mat - the matrix 10853 . op - the name of the operation 10854 - f - the function that provides the operation 10855 10856 Level: developer 10857 10858 Usage: 10859 $ extern PetscErrorCode usermult(Mat,Vec,Vec); 10860 $ PetscCall(MatCreateXXX(comm,...&A); 10861 $ PetscCall(MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult); 10862 10863 Notes: 10864 See the file include/petscmat.h for a complete list of matrix 10865 operations, which all have the form MATOP_<OPERATION>, where 10866 <OPERATION> is the name (in all capital letters) of the 10867 user interface routine (e.g., MatMult() -> MATOP_MULT). 10868 10869 All user-provided functions (except for MATOP_DESTROY) should have the same calling 10870 sequence as the usual matrix interface routines, since they 10871 are intended to be accessed via the usual matrix interface 10872 routines, e.g., 10873 $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 10874 10875 In particular each function MUST return an error code of 0 on success and 10876 nonzero on failure. 10877 10878 This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type. 10879 10880 .seealso: `MatGetOperation()`, `MatCreateShell()`, `MatShellSetContext()`, `MatShellSetOperation()` 10881 @*/ 10882 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void)) 10883 { 10884 PetscFunctionBegin; 10885 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10886 if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) { 10887 mat->ops->viewnative = mat->ops->view; 10888 } 10889 (((void(**)(void))mat->ops)[op]) = f; 10890 PetscFunctionReturn(0); 10891 } 10892 10893 /*@C 10894 MatGetOperation - Gets a matrix operation for any matrix type. 10895 10896 Not Collective 10897 10898 Input Parameters: 10899 + mat - the matrix 10900 - op - the name of the operation 10901 10902 Output Parameter: 10903 . f - the function that provides the operation 10904 10905 Level: developer 10906 10907 Usage: 10908 $ PetscErrorCode (*usermult)(Mat,Vec,Vec); 10909 $ MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult); 10910 10911 Notes: 10912 See the file include/petscmat.h for a complete list of matrix 10913 operations, which all have the form MATOP_<OPERATION>, where 10914 <OPERATION> is the name (in all capital letters) of the 10915 user interface routine (e.g., MatMult() -> MATOP_MULT). 10916 10917 This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type. 10918 10919 .seealso: `MatSetOperation()`, `MatCreateShell()`, `MatShellGetContext()`, `MatShellGetOperation()` 10920 @*/ 10921 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void)) 10922 { 10923 PetscFunctionBegin; 10924 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10925 *f = (((void (**)(void))mat->ops)[op]); 10926 PetscFunctionReturn(0); 10927 } 10928 10929 /*@ 10930 MatHasOperation - Determines whether the given matrix supports the particular 10931 operation. 10932 10933 Not Collective 10934 10935 Input Parameters: 10936 + mat - the matrix 10937 - op - the operation, for example, MATOP_GET_DIAGONAL 10938 10939 Output Parameter: 10940 . has - either PETSC_TRUE or PETSC_FALSE 10941 10942 Level: advanced 10943 10944 Notes: 10945 See the file include/petscmat.h for a complete list of matrix 10946 operations, which all have the form MATOP_<OPERATION>, where 10947 <OPERATION> is the name (in all capital letters) of the 10948 user-level routine. E.g., MatNorm() -> MATOP_NORM. 10949 10950 .seealso: `MatCreateShell()` 10951 @*/ 10952 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has) 10953 { 10954 PetscFunctionBegin; 10955 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10956 PetscValidBoolPointer(has,3); 10957 if (mat->ops->hasoperation) { 10958 PetscCall((*mat->ops->hasoperation)(mat,op,has)); 10959 } else { 10960 if (((void**)mat->ops)[op]) *has = PETSC_TRUE; 10961 else { 10962 *has = PETSC_FALSE; 10963 if (op == MATOP_CREATE_SUBMATRIX) { 10964 PetscMPIInt size; 10965 10966 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 10967 if (size == 1) { 10968 PetscCall(MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has)); 10969 } 10970 } 10971 } 10972 } 10973 PetscFunctionReturn(0); 10974 } 10975 10976 /*@ 10977 MatHasCongruentLayouts - Determines whether the rows and columns layouts 10978 of the matrix are congruent 10979 10980 Collective on mat 10981 10982 Input Parameters: 10983 . mat - the matrix 10984 10985 Output Parameter: 10986 . cong - either PETSC_TRUE or PETSC_FALSE 10987 10988 Level: beginner 10989 10990 Notes: 10991 10992 .seealso: `MatCreate()`, `MatSetSizes()` 10993 @*/ 10994 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong) 10995 { 10996 PetscFunctionBegin; 10997 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10998 PetscValidType(mat,1); 10999 PetscValidBoolPointer(cong,2); 11000 if (!mat->rmap || !mat->cmap) { 11001 *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE; 11002 PetscFunctionReturn(0); 11003 } 11004 if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */ 11005 PetscCall(PetscLayoutSetUp(mat->rmap)); 11006 PetscCall(PetscLayoutSetUp(mat->cmap)); 11007 PetscCall(PetscLayoutCompare(mat->rmap,mat->cmap,cong)); 11008 if (*cong) mat->congruentlayouts = 1; 11009 else mat->congruentlayouts = 0; 11010 } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE; 11011 PetscFunctionReturn(0); 11012 } 11013 11014 PetscErrorCode MatSetInf(Mat A) 11015 { 11016 PetscFunctionBegin; 11017 PetscCheck(A->ops->setinf,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"No support for this operation for this matrix type"); 11018 PetscCall((*A->ops->setinf)(A)); 11019 PetscFunctionReturn(0); 11020 } 11021 11022 /*C 11023 MatCreateGraph - create a scalar matrix, for use in graph algorithms 11024 11025 Collective on mat 11026 11027 Input Parameters: 11028 + A - the matrix 11029 - sym - PETSC_TRUE indicates that the graph will be symmetrized 11030 . scale - PETSC_TRUE indicates that the graph will be scaled with the diagonal 11031 11032 Output Parameter: 11033 . graph - the resulting graph 11034 11035 Level: advanced 11036 11037 Notes: 11038 11039 .seealso: `MatCreate()`, `MatFilter()` 11040 */ 11041 PETSC_EXTERN PetscErrorCode MatCreateGraph(Mat A, PetscBool sym, PetscBool scale, Mat *graph) 11042 { 11043 PetscFunctionBegin; 11044 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 11045 PetscValidType(A,1); 11046 PetscValidPointer(graph,3); 11047 PetscCheck(A->ops->creategraph,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"No support for this operation for this matrix type"); 11048 PetscCall((*A->ops->creategraph)(A,sym,scale,graph)); 11049 PetscFunctionReturn(0); 11050 } 11051 11052 /*C 11053 MatFilter - filters a Mat values with an absolut value equal to or below a give threshold 11054 11055 Collective on mat 11056 11057 Input Parameter: 11058 . value - filter value - < 0: does nothing; == 0: removes only 0.0 entries; otherwise: removes entries <= value 11059 11060 Input/Output Parameter: 11061 . A - the Mat to filter in place 11062 11063 Level: advanced 11064 11065 Notes: 11066 11067 .seealso: `MatCreate()`, `MatCreateGraph()` 11068 */ 11069 PETSC_EXTERN PetscErrorCode MatFilter(Mat G,PetscReal value,Mat *F) 11070 { 11071 PetscFunctionBegin; 11072 PetscValidHeaderSpecific(G,MAT_CLASSID,1); 11073 PetscValidType(G,1); 11074 PetscValidPointer(F,3); 11075 if (value >= 0.0) { 11076 PetscCheck(G->ops->filter,PetscObjectComm((PetscObject)G),PETSC_ERR_SUP,"No support for this operation for this matrix type"); 11077 PetscCall((G->ops->filter)(G,value,F)); 11078 } 11079 PetscFunctionReturn(0); 11080 } 11081