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 `PetscRandom` object, 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: `PetscRandom`, `PetscRandomCreate()`, `MatZeroEntries()`, `MatSetValues()`, `PetscRandomCreate()`, `PetscRandomDestroy()` 71 @*/ 72 PetscErrorCode MatSetRandom(Mat x, PetscRandom rctx) { 73 PetscRandom randObj = NULL; 74 75 PetscFunctionBegin; 76 PetscValidHeaderSpecific(x, MAT_CLASSID, 1); 77 if (rctx) PetscValidHeaderSpecific(rctx, PETSC_RANDOM_CLASSID, 2); 78 PetscValidType(x, 1); 79 MatCheckPreallocated(x, 1); 80 81 if (!rctx) { 82 MPI_Comm comm; 83 PetscCall(PetscObjectGetComm((PetscObject)x, &comm)); 84 PetscCall(PetscRandomCreate(comm, &randObj)); 85 PetscCall(PetscRandomSetType(randObj, x->defaultrandtype)); 86 PetscCall(PetscRandomSetFromOptions(randObj)); 87 rctx = randObj; 88 } 89 PetscCall(PetscLogEventBegin(MAT_SetRandom, x, rctx, 0, 0)); 90 PetscUseTypeMethod(x, setrandom, rctx); 91 PetscCall(PetscLogEventEnd(MAT_SetRandom, x, rctx, 0, 0)); 92 93 PetscCall(MatAssemblyBegin(x, MAT_FINAL_ASSEMBLY)); 94 PetscCall(MatAssemblyEnd(x, MAT_FINAL_ASSEMBLY)); 95 PetscCall(PetscRandomDestroy(&randObj)); 96 PetscFunctionReturn(0); 97 } 98 99 /*@ 100 MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in 101 102 Logically Collective on mat 103 104 Input Parameter: 105 . mat - the factored matrix 106 107 Output Parameters: 108 + pivot - the pivot value computed 109 - row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes 110 the share the matrix 111 112 Level: advanced 113 114 Notes: 115 This routine does not work for factorizations done with external packages. 116 117 This routine should only be called if `MatGetFactorError()` returns a value of `MAT_FACTOR_NUMERIC_ZEROPIVOT` 118 119 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 120 121 .seealso: `MatZeroEntries()`, `MatFactor()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()`, `MatFactorClearError()`, `MatFactorGetErrorZeroPivot()`, 122 `MAT_FACTOR_NUMERIC_ZEROPIVOT` 123 @*/ 124 PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat, PetscReal *pivot, PetscInt *row) { 125 PetscFunctionBegin; 126 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 127 PetscValidRealPointer(pivot, 2); 128 PetscValidIntPointer(row, 3); 129 *pivot = mat->factorerror_zeropivot_value; 130 *row = mat->factorerror_zeropivot_row; 131 PetscFunctionReturn(0); 132 } 133 134 /*@ 135 MatFactorGetError - gets the error code from a factorization 136 137 Logically Collective on mat 138 139 Input Parameters: 140 . mat - the factored matrix 141 142 Output Parameter: 143 . err - the error code 144 145 Level: advanced 146 147 Note: 148 This can also be called on non-factored matrices that come from, for example, matrices used in SOR. 149 150 .seealso: `MatZeroEntries()`, `MatFactor()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()`, `MatFactorClearError()`, `MatFactorGetErrorZeroPivot()`, 151 `MatFactorError` 152 @*/ 153 PetscErrorCode MatFactorGetError(Mat mat, MatFactorError *err) { 154 PetscFunctionBegin; 155 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 156 PetscValidPointer(err, 2); 157 *err = mat->factorerrortype; 158 PetscFunctionReturn(0); 159 } 160 161 /*@ 162 MatFactorClearError - clears the error code in a factorization 163 164 Logically Collective on mat 165 166 Input Parameter: 167 . mat - the factored matrix 168 169 Level: developer 170 171 Note: 172 This can also be called on non-factored matrices that come from, for example, matrices used in SOR. 173 174 .seealso: `MatZeroEntries()`, `MatFactor()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()`, `MatFactorGetError()`, `MatFactorGetErrorZeroPivot()`, 175 `MatGetErrorCode()`, `MatFactorError` 176 @*/ 177 PetscErrorCode MatFactorClearError(Mat mat) { 178 PetscFunctionBegin; 179 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 180 mat->factorerrortype = MAT_FACTOR_NOERROR; 181 mat->factorerror_zeropivot_value = 0.0; 182 mat->factorerror_zeropivot_row = 0; 183 PetscFunctionReturn(0); 184 } 185 186 PETSC_INTERN PetscErrorCode MatFindNonzeroRowsOrCols_Basic(Mat mat, PetscBool cols, PetscReal tol, IS *nonzero) { 187 Vec r, l; 188 const PetscScalar *al; 189 PetscInt i, nz, gnz, N, n; 190 191 PetscFunctionBegin; 192 PetscCall(MatCreateVecs(mat, &r, &l)); 193 if (!cols) { /* nonzero rows */ 194 PetscCall(MatGetSize(mat, &N, NULL)); 195 PetscCall(MatGetLocalSize(mat, &n, NULL)); 196 PetscCall(VecSet(l, 0.0)); 197 PetscCall(VecSetRandom(r, NULL)); 198 PetscCall(MatMult(mat, r, l)); 199 PetscCall(VecGetArrayRead(l, &al)); 200 } else { /* nonzero columns */ 201 PetscCall(MatGetSize(mat, NULL, &N)); 202 PetscCall(MatGetLocalSize(mat, NULL, &n)); 203 PetscCall(VecSet(r, 0.0)); 204 PetscCall(VecSetRandom(l, NULL)); 205 PetscCall(MatMultTranspose(mat, l, r)); 206 PetscCall(VecGetArrayRead(r, &al)); 207 } 208 if (tol <= 0.0) { 209 for (i = 0, nz = 0; i < n; i++) 210 if (al[i] != 0.0) nz++; 211 } else { 212 for (i = 0, nz = 0; i < n; i++) 213 if (PetscAbsScalar(al[i]) > tol) nz++; 214 } 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) { 221 for (i = 0, nz = 0; i < n; i++) 222 if (al[i] != 0.0) nzr[nz++] = i; 223 } else { 224 for (i = 0, nz = 0; i < n; i++) 225 if (PetscAbsScalar(al[i]) > tol) nzr[nz++] = i; 226 } 227 } 228 PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)mat), nz, nzr, PETSC_OWN_POINTER, nonzero)); 229 } else *nonzero = NULL; 230 if (!cols) { /* nonzero rows */ 231 PetscCall(VecRestoreArrayRead(l, &al)); 232 } else { 233 PetscCall(VecRestoreArrayRead(r, &al)); 234 } 235 PetscCall(VecDestroy(&l)); 236 PetscCall(VecDestroy(&r)); 237 PetscFunctionReturn(0); 238 } 239 240 /*@ 241 MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix 242 243 Input Parameter: 244 . A - the matrix 245 246 Output Parameter: 247 . keptrows - the rows that are not completely zero 248 249 Note: 250 keptrows is set to NULL if all rows are nonzero. 251 252 Level: intermediate 253 254 .seealso: `Mat`, `MatFindZeroRows()` 255 @*/ 256 PetscErrorCode MatFindNonzeroRows(Mat mat, IS *keptrows) { 257 PetscFunctionBegin; 258 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 259 PetscValidType(mat, 1); 260 PetscValidPointer(keptrows, 2); 261 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 262 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 263 if (mat->ops->findnonzerorows) PetscUseTypeMethod(mat, findnonzerorows, keptrows); 264 else PetscCall(MatFindNonzeroRowsOrCols_Basic(mat, PETSC_FALSE, 0.0, keptrows)); 265 PetscFunctionReturn(0); 266 } 267 268 /*@ 269 MatFindZeroRows - Locate all rows that are completely zero in the matrix 270 271 Input Parameter: 272 . A - the matrix 273 274 Output Parameter: 275 . zerorows - the rows that are completely zero 276 277 Note: 278 zerorows is set to NULL if no rows are zero. 279 280 Level: intermediate 281 282 .seealso: `Mat`, `MatFindNonzeroRows()` 283 @*/ 284 PetscErrorCode MatFindZeroRows(Mat mat, IS *zerorows) { 285 IS keptrows; 286 PetscInt m, n; 287 288 PetscFunctionBegin; 289 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 290 PetscValidType(mat, 1); 291 PetscValidPointer(zerorows, 2); 292 PetscCall(MatFindNonzeroRows(mat, &keptrows)); 293 /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows. 294 In keeping with this convention, we set zerorows to NULL if there are no zero 295 rows. */ 296 if (keptrows == NULL) { 297 *zerorows = NULL; 298 } else { 299 PetscCall(MatGetOwnershipRange(mat, &m, &n)); 300 PetscCall(ISComplement(keptrows, m, n, zerorows)); 301 PetscCall(ISDestroy(&keptrows)); 302 } 303 PetscFunctionReturn(0); 304 } 305 306 /*@ 307 MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling 308 309 Not Collective 310 311 Input Parameters: 312 . A - the matrix 313 314 Output Parameters: 315 . a - the diagonal part (which is a SEQUENTIAL matrix) 316 317 Notes: 318 See the manual page for `MatCreateAIJ()` for more information on the "diagonal part" of the matrix. 319 320 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. 321 322 Level: advanced 323 324 .seelaso: `MatCreateAIJ()`, `MATAIJ`, `MATBAIJ`, `MATSBAIJ` 325 @*/ 326 PetscErrorCode MatGetDiagonalBlock(Mat A, Mat *a) { 327 PetscFunctionBegin; 328 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 329 PetscValidType(A, 1); 330 PetscValidPointer(a, 2); 331 PetscCheck(!A->factortype, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 332 if (A->ops->getdiagonalblock) PetscUseTypeMethod(A, getdiagonalblock, 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 .seealso: `Mat` 357 @*/ 358 PetscErrorCode MatGetTrace(Mat mat, PetscScalar *trace) { 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 PetscFunctionBegin; 385 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 386 PetscValidType(mat, 1); 387 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 388 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 389 MatCheckPreallocated(mat, 1); 390 PetscUseTypeMethod(mat, realpart); 391 PetscFunctionReturn(0); 392 } 393 394 /*@C 395 MatGetGhosts - Get the global indices of all ghost nodes defined by the sparse matrix 396 397 Collective on mat 398 399 Input Parameter: 400 . mat - the matrix 401 402 Output Parameters: 403 + nghosts - number of ghosts (note for `MATBAIJ` and `MATSBAIJ` matrices there is one ghost for each block) 404 - ghosts - the global indices of the ghost points 405 406 Note: 407 the nghosts and ghosts are suitable to pass into `VecCreateGhost()` 408 409 Level: advanced 410 411 .seealso: `Mat`, `VecCreateGhost()` 412 @*/ 413 PetscErrorCode MatGetGhosts(Mat mat, PetscInt *nghosts, const PetscInt *ghosts[]) { 414 PetscFunctionBegin; 415 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 416 PetscValidType(mat, 1); 417 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 418 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 419 if (mat->ops->getghosts) PetscUseTypeMethod(mat, getghosts, nghosts, ghosts); 420 else { 421 if (nghosts) *nghosts = 0; 422 if (ghosts) *ghosts = NULL; 423 } 424 PetscFunctionReturn(0); 425 } 426 427 /*@ 428 MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part 429 430 Logically Collective on mat 431 432 Input Parameters: 433 . mat - the matrix 434 435 Level: advanced 436 437 .seealso: `MatRealPart()` 438 @*/ 439 PetscErrorCode MatImaginaryPart(Mat mat) { 440 PetscFunctionBegin; 441 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 442 PetscValidType(mat, 1); 443 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 444 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 445 MatCheckPreallocated(mat, 1); 446 PetscUseTypeMethod(mat, imaginarypart); 447 PetscFunctionReturn(0); 448 } 449 450 /*@ 451 MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for `MATBAIJ` and `MATSBAIJ` matrices) 452 453 Not Collective 454 455 Input Parameter: 456 . mat - the matrix 457 458 Output Parameters: 459 + missing - is any diagonal missing 460 - dd - first diagonal entry that is missing (optional) on this process 461 462 Level: advanced 463 464 .seealso: `Mat` 465 @*/ 466 PetscErrorCode MatMissingDiagonal(Mat mat, PetscBool *missing, PetscInt *dd) { 467 PetscFunctionBegin; 468 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 469 PetscValidType(mat, 1); 470 PetscValidBoolPointer(missing, 2); 471 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix %s", ((PetscObject)mat)->type_name); 472 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 473 PetscUseTypeMethod(mat, missingdiagonal, missing, dd); 474 PetscFunctionReturn(0); 475 } 476 477 /*@C 478 MatGetRow - Gets a row of a matrix. You MUST call `MatRestoreRow()` 479 for each row that you get to ensure that your application does 480 not bleed memory. 481 482 Not Collective 483 484 Input Parameters: 485 + mat - the matrix 486 - row - the row to get 487 488 Output Parameters: 489 + ncols - if not NULL, the number of nonzeros in the row 490 . cols - if not NULL, the column numbers 491 - vals - if not NULL, the values 492 493 Notes: 494 This routine is provided for people who need to have direct access 495 to the structure of a matrix. We hope that we provide enough 496 high-level matrix routines that few users will need it. 497 498 `MatGetRow()` always returns 0-based column indices, regardless of 499 whether the internal representation is 0-based (default) or 1-based. 500 501 For better efficiency, set cols and/or vals to NULL if you do 502 not wish to extract these quantities. 503 504 The user can only examine the values extracted with `MatGetRow()`; 505 the values cannot be altered. To change the matrix entries, one 506 must use `MatSetValues()`. 507 508 You can only have one call to `MatGetRow()` outstanding for a particular 509 matrix at a time, per processor. `MatGetRow()` can only obtain rows 510 associated with the given processor, it cannot get rows from the 511 other processors; for that we suggest using `MatCreateSubMatrices()`, then 512 MatGetRow() on the submatrix. The row index passed to `MatGetRow()` 513 is in the global number of rows. 514 515 Use `MatGetRowIJ()` and `MatRestoreRowIJ()` to access all the local indices of the sparse matrix. 516 517 Use `MatSeqAIJGetArray()` and similar functions to access the numerical values for certain matrix types directly. 518 519 Fortran Note: 520 The calling sequence from Fortran is 521 .vb 522 MatGetRow(matrix,row,ncols,cols,values,ierr) 523 Mat matrix (input) 524 integer row (input) 525 integer ncols (output) 526 integer cols(maxcols) (output) 527 double precision (or double complex) values(maxcols) output 528 .ve 529 where maxcols >= maximum nonzeros in any row of the matrix. 530 531 Caution: 532 Do not try to change the contents of the output arrays (cols and vals). 533 In some cases, this may corrupt the matrix. 534 535 Level: advanced 536 537 .seealso: `MatRestoreRow()`, `MatSetValues()`, `MatGetValues()`, `MatCreateSubMatrices()`, `MatGetDiagonal()`, `MatGetRowIJ()`, `MatRestoreRowIJ()` 538 @*/ 539 PetscErrorCode MatGetRow(Mat mat, PetscInt row, PetscInt *ncols, const PetscInt *cols[], const PetscScalar *vals[]) { 540 PetscInt incols; 541 542 PetscFunctionBegin; 543 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 544 PetscValidType(mat, 1); 545 PetscCheck(mat->assembled, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 546 PetscCheck(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 547 MatCheckPreallocated(mat, 1); 548 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); 549 PetscCall(PetscLogEventBegin(MAT_GetRow, mat, 0, 0, 0)); 550 PetscCall((*mat->ops->getrow)(mat, row, &incols, (PetscInt **)cols, (PetscScalar **)vals)); 551 if (ncols) *ncols = incols; 552 PetscCall(PetscLogEventEnd(MAT_GetRow, mat, 0, 0, 0)); 553 PetscFunctionReturn(0); 554 } 555 556 /*@ 557 MatConjugate - replaces the matrix values with their complex conjugates 558 559 Logically Collective on mat 560 561 Input Parameters: 562 . mat - the matrix 563 564 Level: advanced 565 566 .seealso: `MatRealPart()`, `MatImaginaryPart()`, `VecConjugate()`, `MatTranspose()` 567 @*/ 568 PetscErrorCode MatConjugate(Mat mat) { 569 PetscFunctionBegin; 570 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 571 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 572 if (PetscDefined(USE_COMPLEX) && mat->hermitian != PETSC_BOOL3_TRUE) { 573 PetscUseTypeMethod(mat, conjugate); 574 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 575 } 576 PetscFunctionReturn(0); 577 } 578 579 /*@C 580 MatRestoreRow - Frees any temporary space allocated by `MatGetRow()`. 581 582 Not Collective 583 584 Input Parameters: 585 + mat - the matrix 586 . row - the row to get 587 . ncols, cols - the number of nonzeros and their columns 588 - vals - if nonzero the column values 589 590 Notes: 591 This routine should be called after you have finished examining the entries. 592 593 This routine zeros out ncols, cols, and vals. This is to prevent accidental 594 us of the array after it has been restored. If you pass NULL, it will 595 not zero the pointers. Use of cols or vals after `MatRestoreRow()` is invalid. 596 597 Fortran Notes: 598 The calling sequence from Fortran is 599 .vb 600 MatRestoreRow(matrix,row,ncols,cols,values,ierr) 601 Mat matrix (input) 602 integer row (input) 603 integer ncols (output) 604 integer cols(maxcols) (output) 605 double precision (or double complex) values(maxcols) output 606 .ve 607 Where maxcols >= maximum nonzeros in any row of the matrix. 608 609 In Fortran `MatRestoreRow()` MUST be called after `MatGetRow()` 610 before another call to `MatGetRow()` can be made. 611 612 Level: advanced 613 614 .seealso: `MatGetRow()` 615 @*/ 616 PetscErrorCode MatRestoreRow(Mat mat, PetscInt row, PetscInt *ncols, const PetscInt *cols[], const PetscScalar *vals[]) { 617 PetscFunctionBegin; 618 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 619 if (ncols) PetscValidIntPointer(ncols, 3); 620 PetscCheck(mat->assembled, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 621 if (!mat->ops->restorerow) PetscFunctionReturn(0); 622 PetscCall((*mat->ops->restorerow)(mat, row, ncols, (PetscInt **)cols, (PetscScalar **)vals)); 623 if (ncols) *ncols = 0; 624 if (cols) *cols = NULL; 625 if (vals) *vals = NULL; 626 PetscFunctionReturn(0); 627 } 628 629 /*@ 630 MatGetRowUpperTriangular - Sets a flag to enable calls to `MatGetRow()` for matrix in `MATSBAIJ` format. 631 You should call `MatRestoreRowUpperTriangular()` after calling` MatGetRow()` and `MatRestoreRow()` to disable the flag. 632 633 Not Collective 634 635 Input Parameters: 636 . mat - the matrix 637 638 Note: 639 The flag is to ensure that users are aware that `MatGetRow()` only provides the upper triangular part of the row for the matrices in `MATSBAIJ` format. 640 641 Level: advanced 642 643 .seealso: `MATSBAIJ`, `MatRestoreRowUpperTriangular()` 644 @*/ 645 PetscErrorCode MatGetRowUpperTriangular(Mat mat) { 646 PetscFunctionBegin; 647 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 648 PetscValidType(mat, 1); 649 PetscCheck(mat->assembled, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 650 PetscCheck(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 651 MatCheckPreallocated(mat, 1); 652 if (!mat->ops->getrowuppertriangular) PetscFunctionReturn(0); 653 PetscUseTypeMethod(mat, getrowuppertriangular); 654 PetscFunctionReturn(0); 655 } 656 657 /*@ 658 MatRestoreRowUpperTriangular - Disable calls to `MatGetRow()` for matrix in `MATSBAIJ` format. 659 660 Not Collective 661 662 Input Parameters: 663 . mat - the matrix 664 665 Note: 666 This routine should be called after you have finished calls to `MatGetRow()` and `MatRestoreRow()`. 667 668 Level: advanced 669 670 .seealso: `MATSBAIJ`, `MatGetRowUpperTriangular()` 671 @*/ 672 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat) { 673 PetscFunctionBegin; 674 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 675 PetscValidType(mat, 1); 676 PetscCheck(mat->assembled, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 677 PetscCheck(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 678 MatCheckPreallocated(mat, 1); 679 if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0); 680 PetscUseTypeMethod(mat, restorerowuppertriangular); 681 PetscFunctionReturn(0); 682 } 683 684 /*@C 685 MatSetOptionsPrefix - Sets the prefix used for searching for all 686 `Mat` options in the database. 687 688 Logically Collective on A 689 690 Input Parameters: 691 + A - the matrix 692 - prefix - the prefix to prepend to all option names 693 694 Notes: 695 A hyphen (-) must NOT be given at the beginning of the prefix name. 696 The first character of all runtime options is AUTOMATICALLY the hyphen. 697 698 This is NOT used for options for the factorization of the matrix. Normally the 699 prefix is automatically passed in from the PC calling the factorization. To set 700 it directly use `MatSetOptionsPrefixFactor()` 701 702 Level: advanced 703 704 .seealso: `MatSetFromOptions()`, `MatSetOptionsPrefixFactor()` 705 @*/ 706 PetscErrorCode MatSetOptionsPrefix(Mat A, const char prefix[]) { 707 PetscFunctionBegin; 708 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 709 PetscCall(PetscObjectSetOptionsPrefix((PetscObject)A, prefix)); 710 PetscFunctionReturn(0); 711 } 712 713 /*@C 714 MatSetOptionsPrefixFactor - Sets the prefix used for searching for all matrix factor options in the database for 715 for matrices created with `MatGetFactor()` 716 717 Logically Collective on A 718 719 Input Parameters: 720 + A - the matrix 721 - prefix - the prefix to prepend to all option names for the factored matrix 722 723 Notes: 724 A hyphen (-) must NOT be given at the beginning of the prefix name. 725 The first character of all runtime options is AUTOMATICALLY the hyphen. 726 727 Normally the prefix is automatically passed in from the `PC` calling the factorization. To set 728 it directly when not using `KSP`/`PC` use `MatSetOptionsPrefixFactor()` 729 730 Level: developer 731 732 .seealso: [Matrix Factorization](sec_matfactor), `MatGetFactor()`, `MatSetFromOptions()`, `MatSetOptionsPrefix()`, `MatAppendOptionsPrefixFactor()` 733 @*/ 734 PetscErrorCode MatSetOptionsPrefixFactor(Mat A, const char prefix[]) { 735 PetscFunctionBegin; 736 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 737 if (prefix) { 738 PetscValidCharPointer(prefix, 2); 739 PetscCheck(prefix[0] != '-', PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Options prefix should not begin with a hyphen"); 740 if (prefix != A->factorprefix) { 741 PetscCall(PetscFree(A->factorprefix)); 742 PetscCall(PetscStrallocpy(prefix, &A->factorprefix)); 743 } 744 } else PetscCall(PetscFree(A->factorprefix)); 745 PetscFunctionReturn(0); 746 } 747 748 /*@C 749 MatAppendOptionsPrefixFactor - Appends to the prefix used for searching for all matrix factor options in the database for 750 for matrices created with `MatGetFactor()` 751 752 Logically Collective on A 753 754 Input Parameters: 755 + A - the matrix 756 - prefix - the prefix to prepend to all option names for the factored matrix 757 758 Notes: 759 A hyphen (-) must NOT be given at the beginning of the prefix name. 760 The first character of all runtime options is AUTOMATICALLY the hyphen. 761 762 Normally the prefix is automatically passed in from the `PC` calling the factorization. To set 763 it directly when not using `KSP`/`PC` use `MatAppendOptionsPrefixFactor()` 764 765 Level: developer 766 767 .seealso: [Matrix Factorization](sec_matfactor), `MatGetFactor()`, PetscOptionsCreate()`, `PetscOptionsDestroy()`, `PetscObjectSetOptionsPrefix()`, `PetscObjectPrependOptionsPrefix()`, 768 `PetscObjectGetOptionsPrefix()`, `TSAppendOptionsPrefix()`, `SNESAppendOptionsPrefix()`, `KSPAppendOptionsPrefix()`, `MatSetOptionsPrefixFactor()`, 769 `MatSetOptionsPrefix()` 770 @*/ 771 PetscErrorCode MatAppendOptionsPrefixFactor(Mat A, const char prefix[]) { 772 char *buf = A->factorprefix; 773 size_t len1, len2; 774 775 PetscFunctionBegin; 776 PetscValidHeader(A, 1); 777 if (!prefix) PetscFunctionReturn(0); 778 if (!buf) { 779 PetscCall(MatSetOptionsPrefixFactor(A, prefix)); 780 PetscFunctionReturn(0); 781 } 782 PetscCheck(prefix[0] != '-', PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Options prefix should not begin with a hyphen"); 783 784 PetscCall(PetscStrlen(prefix, &len1)); 785 PetscCall(PetscStrlen(buf, &len2)); 786 PetscCall(PetscMalloc1(1 + len1 + len2, &A->factorprefix)); 787 PetscCall(PetscStrcpy(A->factorprefix, buf)); 788 PetscCall(PetscStrcat(A->factorprefix, prefix)); 789 PetscCall(PetscFree(buf)); 790 PetscFunctionReturn(0); 791 } 792 793 /*@C 794 MatAppendOptionsPrefix - Appends to the prefix used for searching for all 795 matrix options in the database. 796 797 Logically Collective on A 798 799 Input Parameters: 800 + A - the matrix 801 - prefix - the prefix to prepend to all option names 802 803 Note: 804 A hyphen (-) must NOT be given at the beginning of the prefix name. 805 The first character of all runtime options is AUTOMATICALLY the hyphen. 806 807 Level: advanced 808 809 .seealso: `Mat`, `MatGetOptionsPrefix()`, `MatAppendOptionsPrefixFactor()`, `MatSetOptionsPrefix()` 810 @*/ 811 PetscErrorCode MatAppendOptionsPrefix(Mat A, const char prefix[]) { 812 PetscFunctionBegin; 813 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 814 PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)A, prefix)); 815 PetscFunctionReturn(0); 816 } 817 818 /*@C 819 MatGetOptionsPrefix - Gets the prefix used for searching for all 820 matrix options in the database. 821 822 Not Collective 823 824 Input Parameter: 825 . A - the matrix 826 827 Output Parameter: 828 . prefix - pointer to the prefix string used 829 830 Fortran Note: 831 On the fortran side, the user should pass in a string 'prefix' of 832 sufficient length to hold the prefix. 833 834 Level: advanced 835 836 .seealso: `MatAppendOptionsPrefix()`, `MatSetOptionsPrefix()`, `MatAppendOptionsPrefixFactor()`, `MatSetOptionsPrefixFactor()` 837 @*/ 838 PetscErrorCode MatGetOptionsPrefix(Mat A, const char *prefix[]) { 839 PetscFunctionBegin; 840 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 841 PetscValidPointer(prefix, 2); 842 PetscCall(PetscObjectGetOptionsPrefix((PetscObject)A, prefix)); 843 PetscFunctionReturn(0); 844 } 845 846 /*@ 847 MatResetPreallocation - Reset matrix to use the original nonzero pattern provided by users. 848 849 Collective on A 850 851 Input Parameters: 852 . A - the matrix 853 854 Notes: 855 The allocated memory will be shrunk after calling `MatAssemblyBegin()` and `MatAssemblyEnd()` with `MAT_FINAL_ASSEMBLY`. 856 857 Users can reset the preallocation to access the original memory. 858 859 Currently only supported for `MATMPIAIJ` and `MATSEQAIJ` matrices. 860 861 Level: beginner 862 863 .seealso: `MatSeqAIJSetPreallocation()`, `MatMPIAIJSetPreallocation()`, `MatXAIJSetPreallocation()` 864 @*/ 865 PetscErrorCode MatResetPreallocation(Mat A) { 866 PetscFunctionBegin; 867 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 868 PetscValidType(A, 1); 869 PetscUseMethod(A, "MatResetPreallocation_C", (Mat), (A)); 870 PetscFunctionReturn(0); 871 } 872 873 /*@ 874 MatSetUp - Sets up the internal matrix data structures for later use. 875 876 Collective on A 877 878 Input Parameters: 879 . A - the matrix 880 881 Notes: 882 If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used. 883 884 If a suitable preallocation routine is used, this function does not need to be called. 885 886 See the Performance chapter of the PETSc users manual for how to preallocate matrices 887 888 This routine is called internally by other matrix functions when needed so rarely needs to be called by users 889 890 Level: intermediate 891 892 .seealso: `Mat`, `MatMult()`, `MatCreate()`, `MatDestroy()` 893 @*/ 894 PetscErrorCode MatSetUp(Mat A) { 895 PetscFunctionBegin; 896 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 897 if (!((PetscObject)A)->type_name) { 898 PetscMPIInt size; 899 900 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)A), &size)); 901 PetscCall(MatSetType(A, size == 1 ? MATSEQAIJ : MATMPIAIJ)); 902 } 903 if (!A->preallocated && A->ops->setup) { 904 PetscCall(PetscInfo(A, "Warning not preallocating matrix storage\n")); 905 PetscUseTypeMethod(A, setup); 906 } 907 PetscCall(PetscLayoutSetUp(A->rmap)); 908 PetscCall(PetscLayoutSetUp(A->cmap)); 909 A->preallocated = PETSC_TRUE; 910 PetscFunctionReturn(0); 911 } 912 913 #if defined(PETSC_HAVE_SAWS) 914 #include <petscviewersaws.h> 915 #endif 916 917 /*@C 918 MatViewFromOptions - View properties of the matrix from the options database 919 920 Collective on A 921 922 Input Parameters: 923 + A - the matrix 924 . obj - optional additional object that provides the options prefix to use 925 - name - command line option 926 927 Options Database: 928 . -mat_view [viewertype]:... - the viewer and its options 929 930 Notes: 931 .vb 932 If no value is provided ascii:stdout is used 933 ascii[:[filename][:[format][:append]]] defaults to stdout - format can be one of ascii_info, ascii_info_detail, or ascii_matlab, 934 for example ascii::ascii_info prints just the information about the object not all details 935 unless :append is given filename opens in write mode, overwriting what was already there 936 binary[:[filename][:[format][:append]]] defaults to the file binaryoutput 937 draw[:drawtype[:filename]] for example, draw:tikz, draw:tikz:figure.tex or draw:x 938 socket[:port] defaults to the standard output port 939 saws[:communicatorname] publishes object to the Scientific Application Webserver (SAWs) 940 .ve 941 942 Level: intermediate 943 944 .seealso: `Mat`, `MatView()`, `PetscObjectViewFromOptions()`, `MatCreate()` 945 @*/ 946 PetscErrorCode MatViewFromOptions(Mat A, PetscObject obj, const char name[]) { 947 PetscFunctionBegin; 948 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 949 PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name)); 950 PetscFunctionReturn(0); 951 } 952 953 /*@C 954 MatView - display information about a matrix in a variety ways 955 956 Collective on mat 957 958 Input Parameters: 959 + mat - the matrix 960 - viewer - visualization context 961 962 Notes: 963 The available visualization contexts include 964 + `PETSC_VIEWER_STDOUT_SELF` - for sequential matrices 965 . `PETSC_VIEWER_STDOUT_WORLD` - for parallel matrices created on `PETSC_COMM_WORLD` 966 . `PETSC_VIEWER_STDOUT_`(comm) - for matrices created on MPI communicator comm 967 - `PETSC_VIEWER_DRAW_WORLD` - graphical display of nonzero structure 968 969 The user can open alternative visualization contexts with 970 + `PetscViewerASCIIOpen()` - Outputs matrix to a specified file 971 . `PetscViewerBinaryOpen()` - Outputs matrix in binary to a 972 specified file; corresponding input uses MatLoad() 973 . `PetscViewerDrawOpen()` - Outputs nonzero matrix structure to 974 an X window display 975 - `PetscViewerSocketOpen()` - Outputs matrix to Socket viewer. 976 Currently only the sequential dense and AIJ 977 matrix types support the Socket viewer. 978 979 The user can call `PetscViewerPushFormat()` to specify the output 980 format of ASCII printed objects (when using `PETSC_VIEWER_STDOUT_SELF`, 981 `PETSC_VIEWER_STDOUT_WORLD` and `PetscViewerASCIIOpen()`). Available formats include 982 + `PETSC_VIEWER_DEFAULT` - default, prints matrix contents 983 . `PETSC_VIEWER_ASCII_MATLAB` - prints matrix contents in Matlab format 984 . `PETSC_VIEWER_ASCII_DENSE` - prints entire matrix including zeros 985 . `PETSC_VIEWER_ASCII_COMMON` - prints matrix contents, using a sparse 986 format common among all matrix types 987 . `PETSC_VIEWER_ASCII_IMPL` - prints matrix contents, using an implementation-specific 988 format (which is in many cases the same as the default) 989 . `PETSC_VIEWER_ASCII_INFO` - prints basic information about the matrix 990 size and structure (not the matrix entries) 991 - `PETSC_VIEWER_ASCII_INFO_DETAIL` - prints more detailed information about 992 the matrix structure 993 994 Options Database Keys: 995 + -mat_view ::ascii_info - Prints info on matrix at conclusion of `MatAssemblyEnd()` 996 . -mat_view ::ascii_info_detail - Prints more detailed info 997 . -mat_view - Prints matrix in ASCII format 998 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 999 . -mat_view draw - PetscDraws nonzero structure of matrix, using `MatView()` and `PetscDrawOpenX()`. 1000 . -display <name> - Sets display name (default is host) 1001 . -draw_pause <sec> - Sets number of seconds to pause after display 1002 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details) 1003 . -viewer_socket_machine <machine> - 1004 . -viewer_socket_port <port> - 1005 . -mat_view binary - save matrix to file in binary format 1006 - -viewer_binary_filename <name> - 1007 1008 Level: beginner 1009 1010 Notes: 1011 The ASCII viewers are only recommended for small matrices on at most a moderate number of processes, 1012 the program will seemingly hang and take hours for larger matrices, for larger matrices one should use the binary format. 1013 1014 In the debugger you can do "call MatView(mat,0)" to display the matrix. (The same holds for any PETSc object viewer). 1015 1016 See the manual page for `MatLoad()` for the exact format of the binary file when the binary 1017 viewer is used. 1018 1019 See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary 1020 viewer is used and lib/petsc/bin/PetscBinaryIO.py for loading them into Python. 1021 1022 One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure, 1023 and then use the following mouse functions. 1024 .vb 1025 left mouse: zoom in 1026 middle mouse: zoom out 1027 right mouse: continue with the simulation 1028 .ve 1029 1030 .seealso: `PetscViewerPushFormat()`, `PetscViewerASCIIOpen()`, `PetscViewerDrawOpen()`, `PetscViewer`, `Mat`, 1031 `PetscViewerSocketOpen()`, `PetscViewerBinaryOpen()`, `MatLoad()`, `MatViewFromOptions()` 1032 @*/ 1033 PetscErrorCode MatView(Mat mat, PetscViewer viewer) { 1034 PetscInt rows, cols, rbs, cbs; 1035 PetscBool isascii, isstring, issaws; 1036 PetscViewerFormat format; 1037 PetscMPIInt size; 1038 1039 PetscFunctionBegin; 1040 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 1041 PetscValidType(mat, 1); 1042 if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat), &viewer)); 1043 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1044 PetscCheckSameComm(mat, 1, viewer, 2); 1045 MatCheckPreallocated(mat, 1); 1046 1047 PetscCall(PetscViewerGetFormat(viewer, &format)); 1048 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size)); 1049 if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0); 1050 1051 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring)); 1052 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii)); 1053 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSAWS, &issaws)); 1054 PetscCheck((isascii && (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) || !mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "No viewers for factored matrix except ASCII, info, or info_detail"); 1055 1056 PetscCall(PetscLogEventBegin(MAT_View, mat, viewer, 0, 0)); 1057 if (isascii) { 1058 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ORDER, "Must call MatAssemblyBegin/End() before viewing matrix"); 1059 PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)mat, viewer)); 1060 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1061 MatNullSpace nullsp, transnullsp; 1062 1063 PetscCall(PetscViewerASCIIPushTab(viewer)); 1064 PetscCall(MatGetSize(mat, &rows, &cols)); 1065 PetscCall(MatGetBlockSizes(mat, &rbs, &cbs)); 1066 if (rbs != 1 || cbs != 1) { 1067 if (rbs != cbs) PetscCall(PetscViewerASCIIPrintf(viewer, "rows=%" PetscInt_FMT ", cols=%" PetscInt_FMT ", rbs=%" PetscInt_FMT ", cbs=%" PetscInt_FMT "\n", rows, cols, rbs, cbs)); 1068 else PetscCall(PetscViewerASCIIPrintf(viewer, "rows=%" PetscInt_FMT ", cols=%" PetscInt_FMT ", bs=%" PetscInt_FMT "\n", rows, cols, rbs)); 1069 } else PetscCall(PetscViewerASCIIPrintf(viewer, "rows=%" PetscInt_FMT ", cols=%" PetscInt_FMT "\n", rows, cols)); 1070 if (mat->factortype) { 1071 MatSolverType solver; 1072 PetscCall(MatFactorGetSolverType(mat, &solver)); 1073 PetscCall(PetscViewerASCIIPrintf(viewer, "package used to perform factorization: %s\n", solver)); 1074 } 1075 if (mat->ops->getinfo) { 1076 MatInfo info; 1077 PetscCall(MatGetInfo(mat, MAT_GLOBAL_SUM, &info)); 1078 PetscCall(PetscViewerASCIIPrintf(viewer, "total: nonzeros=%.f, allocated nonzeros=%.f\n", info.nz_used, info.nz_allocated)); 1079 if (!mat->factortype) PetscCall(PetscViewerASCIIPrintf(viewer, "total number of mallocs used during MatSetValues calls=%" PetscInt_FMT "\n", (PetscInt)info.mallocs)); 1080 } 1081 PetscCall(MatGetNullSpace(mat, &nullsp)); 1082 PetscCall(MatGetTransposeNullSpace(mat, &transnullsp)); 1083 if (nullsp) PetscCall(PetscViewerASCIIPrintf(viewer, " has attached null space\n")); 1084 if (transnullsp && transnullsp != nullsp) PetscCall(PetscViewerASCIIPrintf(viewer, " has attached transposed null space\n")); 1085 PetscCall(MatGetNearNullSpace(mat, &nullsp)); 1086 if (nullsp) PetscCall(PetscViewerASCIIPrintf(viewer, " has attached near null space\n")); 1087 PetscCall(PetscViewerASCIIPushTab(viewer)); 1088 PetscCall(MatProductView(mat, viewer)); 1089 PetscCall(PetscViewerASCIIPopTab(viewer)); 1090 } 1091 } else if (issaws) { 1092 #if defined(PETSC_HAVE_SAWS) 1093 PetscMPIInt rank; 1094 1095 PetscCall(PetscObjectName((PetscObject)mat)); 1096 PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank)); 1097 if (!((PetscObject)mat)->amsmem && rank == 0) PetscCall(PetscObjectViewSAWs((PetscObject)mat, viewer)); 1098 #endif 1099 } else if (isstring) { 1100 const char *type; 1101 PetscCall(MatGetType(mat, &type)); 1102 PetscCall(PetscViewerStringSPrintf(viewer, " MatType: %-7.7s", type)); 1103 PetscTryTypeMethod(mat, view, viewer); 1104 } 1105 if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) { 1106 PetscCall(PetscViewerASCIIPushTab(viewer)); 1107 PetscUseTypeMethod(mat, viewnative, viewer); 1108 PetscCall(PetscViewerASCIIPopTab(viewer)); 1109 } else if (mat->ops->view) { 1110 PetscCall(PetscViewerASCIIPushTab(viewer)); 1111 PetscUseTypeMethod(mat, view, viewer); 1112 PetscCall(PetscViewerASCIIPopTab(viewer)); 1113 } 1114 if (isascii) { 1115 PetscCall(PetscViewerGetFormat(viewer, &format)); 1116 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) PetscCall(PetscViewerASCIIPopTab(viewer)); 1117 } 1118 PetscCall(PetscLogEventEnd(MAT_View, mat, viewer, 0, 0)); 1119 PetscFunctionReturn(0); 1120 } 1121 1122 #if defined(PETSC_USE_DEBUG) 1123 #include <../src/sys/totalview/tv_data_display.h> 1124 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat) { 1125 TV_add_row("Local rows", "int", &mat->rmap->n); 1126 TV_add_row("Local columns", "int", &mat->cmap->n); 1127 TV_add_row("Global rows", "int", &mat->rmap->N); 1128 TV_add_row("Global columns", "int", &mat->cmap->N); 1129 TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name); 1130 return TV_format_OK; 1131 } 1132 #endif 1133 1134 /*@C 1135 MatLoad - Loads a matrix that has been stored in binary/HDF5 format 1136 with `MatView()`. The matrix format is determined from the options database. 1137 Generates a parallel MPI matrix if the communicator has more than one 1138 processor. The default matrix type is `MATAIJ`. 1139 1140 Collective on mat 1141 1142 Input Parameters: 1143 + mat - the newly loaded matrix, this needs to have been created with `MatCreate()` 1144 or some related function before a call to `MatLoad()` 1145 - viewer - binary/HDF5 file viewer 1146 1147 Options Database Keys: 1148 Used with block matrix formats (`MATSEQBAIJ`, ...) to specify 1149 block size 1150 . -matload_block_size <bs> - set block size 1151 1152 Level: beginner 1153 1154 Notes: 1155 If the `Mat` type has not yet been given then `MATAIJ` is used, call `MatSetFromOptions()` on the 1156 `Mat` before calling this routine if you wish to set it from the options database. 1157 1158 `MatLoad()` automatically loads into the options database any options 1159 given in the file filename.info where filename is the name of the file 1160 that was passed to the `PetscViewerBinaryOpen()`. The options in the info 1161 file will be ignored if you use the -viewer_binary_skip_info option. 1162 1163 If the type or size of mat is not set before a call to `MatLoad()`, PETSc 1164 sets the default matrix type AIJ and sets the local and global sizes. 1165 If type and/or size is already set, then the same are used. 1166 1167 In parallel, each processor can load a subset of rows (or the 1168 entire matrix). This routine is especially useful when a large 1169 matrix is stored on disk and only part of it is desired on each 1170 processor. For example, a parallel solver may access only some of 1171 the rows from each processor. The algorithm used here reads 1172 relatively small blocks of data rather than reading the entire 1173 matrix and then subsetting it. 1174 1175 Viewer's `PetscViewerType` must be either `PETSCVIEWERBINARY` or `PETSCVIEWERHDF5`. 1176 Such viewer can be created using `PetscViewerBinaryOpen()` or `PetscViewerHDF5Open()`, 1177 or the sequence like 1178 .vb 1179 `PetscViewer` v; 1180 `PetscViewerCreate`(`PETSC_COMM_WORLD`,&v); 1181 `PetscViewerSetType`(v,`PETSCVIEWERBINARY`); 1182 `PetscViewerSetFromOptions`(v); 1183 `PetscViewerFileSetMode`(v,`FILE_MODE_READ`); 1184 `PetscViewerFileSetName`(v,"datafile"); 1185 .ve 1186 The optional `PetscViewerSetFromOptions()` call allows overriding `PetscViewerSetType()` using the option 1187 $ -viewer_type {binary,hdf5} 1188 1189 See the example src/ksp/ksp/tutorials/ex27.c with the first approach, 1190 and src/mat/tutorials/ex10.c with the second approach. 1191 1192 Notes about the PETSc binary format: 1193 In case of `PETSCVIEWERBINARY`, a native PETSc binary format is used. Each of the blocks 1194 is read onto rank 0 and then shipped to its destination rank, one after another. 1195 Multiple objects, both matrices and vectors, can be stored within the same file. 1196 Their PetscObject name is ignored; they are loaded in the order of their storage. 1197 1198 Most users should not need to know the details of the binary storage 1199 format, since `MatLoad()` and `MatView()` completely hide these details. 1200 But for anyone who's interested, the standard binary matrix storage 1201 format is 1202 1203 $ PetscInt MAT_FILE_CLASSID 1204 $ PetscInt number of rows 1205 $ PetscInt number of columns 1206 $ PetscInt total number of nonzeros 1207 $ PetscInt *number nonzeros in each row 1208 $ PetscInt *column indices of all nonzeros (starting index is zero) 1209 $ PetscScalar *values of all nonzeros 1210 1211 PETSc automatically does the byte swapping for 1212 machines that store the bytes reversed, e.g. DEC alpha, freebsd, 1213 Linux, Microsoft Windows and the Intel Paragon; thus if you write your own binary 1214 read/write routines you have to swap the bytes; see `PetscBinaryRead()` 1215 and `PetscBinaryWrite()` to see how this may be done. 1216 1217 Notes about the HDF5 (MATLAB MAT-File Version 7.3) format: 1218 In case of `PETSCVIEWERHDF5`, a parallel HDF5 reader is used. 1219 Each processor's chunk is loaded independently by its owning rank. 1220 Multiple objects, both matrices and vectors, can be stored within the same file. 1221 They are looked up by their PetscObject name. 1222 1223 As the MATLAB MAT-File Version 7.3 format is also a HDF5 flavor, we decided to use 1224 by default the same structure and naming of the AIJ arrays and column count 1225 within the HDF5 file. This means that a MAT file saved with -v7.3 flag, e.g. 1226 $ save example.mat A b -v7.3 1227 can be directly read by this routine (see Reference 1 for details). 1228 Note that depending on your MATLAB version, this format might be a default, 1229 otherwise you can set it as default in Preferences. 1230 1231 Unless -nocompression flag is used to save the file in MATLAB, 1232 PETSc must be configured with ZLIB package. 1233 1234 See also examples src/mat/tutorials/ex10.c and src/ksp/ksp/tutorials/ex27.c 1235 1236 Current HDF5 (MAT-File) limitations: 1237 This reader currently supports only real `MATSEQAIJ`, `MATMPIAIJ`, `MATSEQDENSE` and `MATMPIDENSE` matrices. 1238 1239 Corresponding `MatView()` is not yet implemented. 1240 1241 The loaded matrix is actually a transpose of the original one in MATLAB, 1242 unless you push `PETSC_VIEWER_HDF5_MAT` format (see examples above). 1243 With this format, matrix is automatically transposed by PETSc, 1244 unless the matrix is marked as SPD or symmetric 1245 (see `MatSetOption()`, `MAT_SPD`, `MAT_SYMMETRIC`). 1246 1247 References: 1248 . * - MATLAB(R) Documentation, manual page of save(), https://www.mathworks.com/help/matlab/ref/save.html#btox10b-1-version 1249 1250 .seealso: `PetscViewerBinaryOpen()`, `PetscViewerSetType()`, `MatView()`, `VecLoad()` 1251 @*/ 1252 PetscErrorCode MatLoad(Mat mat, PetscViewer viewer) { 1253 PetscBool flg; 1254 1255 PetscFunctionBegin; 1256 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 1257 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1258 1259 if (!((PetscObject)mat)->type_name) PetscCall(MatSetType(mat, MATAIJ)); 1260 1261 flg = PETSC_FALSE; 1262 PetscCall(PetscOptionsGetBool(((PetscObject)mat)->options, ((PetscObject)mat)->prefix, "-matload_symmetric", &flg, NULL)); 1263 if (flg) { 1264 PetscCall(MatSetOption(mat, MAT_SYMMETRIC, PETSC_TRUE)); 1265 PetscCall(MatSetOption(mat, MAT_SYMMETRY_ETERNAL, PETSC_TRUE)); 1266 } 1267 flg = PETSC_FALSE; 1268 PetscCall(PetscOptionsGetBool(((PetscObject)mat)->options, ((PetscObject)mat)->prefix, "-matload_spd", &flg, NULL)); 1269 if (flg) PetscCall(MatSetOption(mat, MAT_SPD, PETSC_TRUE)); 1270 1271 PetscCall(PetscLogEventBegin(MAT_Load, mat, viewer, 0, 0)); 1272 PetscUseTypeMethod(mat, load, viewer); 1273 PetscCall(PetscLogEventEnd(MAT_Load, mat, viewer, 0, 0)); 1274 PetscFunctionReturn(0); 1275 } 1276 1277 static PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant) { 1278 Mat_Redundant *redund = *redundant; 1279 1280 PetscFunctionBegin; 1281 if (redund) { 1282 if (redund->matseq) { /* via MatCreateSubMatrices() */ 1283 PetscCall(ISDestroy(&redund->isrow)); 1284 PetscCall(ISDestroy(&redund->iscol)); 1285 PetscCall(MatDestroySubMatrices(1, &redund->matseq)); 1286 } else { 1287 PetscCall(PetscFree2(redund->send_rank, redund->recv_rank)); 1288 PetscCall(PetscFree(redund->sbuf_j)); 1289 PetscCall(PetscFree(redund->sbuf_a)); 1290 for (PetscInt i = 0; i < redund->nrecvs; i++) { 1291 PetscCall(PetscFree(redund->rbuf_j[i])); 1292 PetscCall(PetscFree(redund->rbuf_a[i])); 1293 } 1294 PetscCall(PetscFree4(redund->sbuf_nz, redund->rbuf_nz, redund->rbuf_j, redund->rbuf_a)); 1295 } 1296 1297 if (redund->subcomm) PetscCall(PetscCommDestroy(&redund->subcomm)); 1298 PetscCall(PetscFree(redund)); 1299 } 1300 PetscFunctionReturn(0); 1301 } 1302 1303 /*@C 1304 MatDestroy - Frees space taken by a matrix. 1305 1306 Collective on A 1307 1308 Input Parameter: 1309 . A - the matrix 1310 1311 Level: beginner 1312 1313 Developer Note: 1314 Some special arrays of matrices are not destroyed in this routine but instead by the routines called by 1315 `MatDestroySubMatrices()`. Thus one must be sure that any changes here must also be made in those routines. 1316 `MatHeaderMerge()` and `MatHeaderReplace()` also manipulate the data in the `Mat` object and likely need changes 1317 if changes are needed here. 1318 1319 .seealso: `Mat`, `MatCreate()` 1320 @*/ 1321 PetscErrorCode MatDestroy(Mat *A) { 1322 PetscFunctionBegin; 1323 if (!*A) PetscFunctionReturn(0); 1324 PetscValidHeaderSpecific(*A, MAT_CLASSID, 1); 1325 if (--((PetscObject)(*A))->refct > 0) { 1326 *A = NULL; 1327 PetscFunctionReturn(0); 1328 } 1329 1330 /* if memory was published with SAWs then destroy it */ 1331 PetscCall(PetscObjectSAWsViewOff((PetscObject)*A)); 1332 PetscTryTypeMethod((*A), destroy); 1333 1334 PetscCall(PetscFree((*A)->factorprefix)); 1335 PetscCall(PetscFree((*A)->defaultvectype)); 1336 PetscCall(PetscFree((*A)->defaultrandtype)); 1337 PetscCall(PetscFree((*A)->bsizes)); 1338 PetscCall(PetscFree((*A)->solvertype)); 1339 for (PetscInt i = 0; i < MAT_FACTOR_NUM_TYPES; i++) PetscCall(PetscFree((*A)->preferredordering[i])); 1340 if ((*A)->redundant && (*A)->redundant->matseq[0] == *A) (*A)->redundant->matseq[0] = NULL; 1341 PetscCall(MatDestroy_Redundant(&(*A)->redundant)); 1342 PetscCall(MatProductClear(*A)); 1343 PetscCall(MatNullSpaceDestroy(&(*A)->nullsp)); 1344 PetscCall(MatNullSpaceDestroy(&(*A)->transnullsp)); 1345 PetscCall(MatNullSpaceDestroy(&(*A)->nearnullsp)); 1346 PetscCall(MatDestroy(&(*A)->schur)); 1347 PetscCall(PetscLayoutDestroy(&(*A)->rmap)); 1348 PetscCall(PetscLayoutDestroy(&(*A)->cmap)); 1349 PetscCall(PetscHeaderDestroy(A)); 1350 PetscFunctionReturn(0); 1351 } 1352 1353 /*@C 1354 MatSetValues - Inserts or adds a block of values into a matrix. 1355 These values may be cached, so `MatAssemblyBegin()` and `MatAssemblyEnd()` 1356 MUST be called after all calls to `MatSetValues()` have been completed. 1357 1358 Not Collective 1359 1360 Input Parameters: 1361 + mat - the matrix 1362 . v - a logically two-dimensional array of values 1363 . m, idxm - the number of rows and their global indices 1364 . n, idxn - the number of columns and their global indices 1365 - addv - either `ADD_VALUES` to add values to any existing entries, or `INSERT_VALUES` to replace existing entries with new values 1366 1367 Notes: 1368 If you create the matrix yourself (that is not with a call to `DMCreateMatrix()`) then you MUST call MatXXXXSetPreallocation() or 1369 `MatSetUp()` before using this routine 1370 1371 By default the values, v, are row-oriented. See `MatSetOption()` for other options. 1372 1373 Calls to `MatSetValues()` with the `INSERT_VALUES` and `ADD_VALUES` 1374 options cannot be mixed without intervening calls to the assembly 1375 routines. 1376 1377 `MatSetValues()` uses 0-based row and column numbers in Fortran 1378 as well as in C. 1379 1380 Negative indices may be passed in idxm and idxn, these rows and columns are 1381 simply ignored. This allows easily inserting element stiffness matrices 1382 with homogeneous Dirchlet boundary conditions that you don't want represented 1383 in the matrix. 1384 1385 Efficiency Alert: 1386 The routine `MatSetValuesBlocked()` may offer much better efficiency 1387 for users of block sparse formats (`MATSEQBAIJ` and `MATMPIBAIJ`). 1388 1389 Level: beginner 1390 1391 Developer Note: 1392 This is labeled with C so does not automatically generate Fortran stubs and interfaces 1393 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 1394 1395 .seealso: `Mat`, `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 1396 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES` 1397 @*/ 1398 PetscErrorCode MatSetValues(Mat mat, PetscInt m, const PetscInt idxm[], PetscInt n, const PetscInt idxn[], const PetscScalar v[], InsertMode addv) { 1399 PetscFunctionBeginHot; 1400 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 1401 PetscValidType(mat, 1); 1402 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1403 PetscValidIntPointer(idxm, 3); 1404 PetscValidIntPointer(idxn, 5); 1405 MatCheckPreallocated(mat, 1); 1406 1407 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 1408 else PetscCheck(mat->insertmode == addv, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cannot mix add values and insert values"); 1409 1410 if (PetscDefined(USE_DEBUG)) { 1411 PetscInt i, j; 1412 1413 PetscCheck(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 1414 for (i = 0; i < m; i++) { 1415 for (j = 0; j < n; j++) { 1416 if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i * n + j])) 1417 #if defined(PETSC_USE_COMPLEX) 1418 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]); 1419 #else 1420 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]); 1421 #endif 1422 } 1423 } 1424 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); 1425 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); 1426 } 1427 1428 if (mat->assembled) { 1429 mat->was_assembled = PETSC_TRUE; 1430 mat->assembled = PETSC_FALSE; 1431 } 1432 PetscCall(PetscLogEventBegin(MAT_SetValues, mat, 0, 0, 0)); 1433 PetscUseTypeMethod(mat, setvalues, m, idxm, n, idxn, v, addv); 1434 PetscCall(PetscLogEventEnd(MAT_SetValues, mat, 0, 0, 0)); 1435 PetscFunctionReturn(0); 1436 } 1437 1438 /*@C 1439 MatSetValuesIS - Inserts or adds a block of values into a matrix using an `IS` to indicate the rows and columns 1440 These values may be cached, so `MatAssemblyBegin()` and `MatAssemblyEnd()` 1441 MUST be called after all calls to `MatSetValues()` have been completed. 1442 1443 Not Collective 1444 1445 Input Parameters: 1446 + mat - the matrix 1447 . v - a logically two-dimensional array of values 1448 . ism - the rows to provide 1449 . isn - the columns to provide 1450 - addv - either `ADD_VALUES` to add values to any existing entries, or `INSERT_VALUES` to replace existing entries with new values 1451 1452 Notes: 1453 If you create the matrix yourself (that is not with a call to `DMCreateMatrix()`) then you MUST call MatXXXXSetPreallocation() or 1454 `MatSetUp()` before using this routine 1455 1456 By default the values, v, are row-oriented. See `MatSetOption()` for other options. 1457 1458 Calls to `MatSetValues()` with the `INSERT_VALUES` and `ADD_VALUES` 1459 options cannot be mixed without intervening calls to the assembly 1460 routines. 1461 1462 MatSetValues() uses 0-based row and column numbers in Fortran 1463 as well as in C. 1464 1465 Negative indices may be passed in ism and isn, these rows and columns are 1466 simply ignored. This allows easily inserting element stiffness matrices 1467 with homogeneous Dirchlet boundary conditions that you don't want represented 1468 in the matrix. 1469 1470 Efficiency Alert: 1471 The routine `MatSetValuesBlocked()` may offer much better efficiency 1472 for users of block sparse formats (`MATSEQBAIJ` and `MATMPIBAIJ`). 1473 1474 Level: beginner 1475 1476 Developer Notes: 1477 This is labeled with C so does not automatically generate Fortran stubs and interfaces 1478 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 1479 1480 This is currently not optimized for any particular `ISType` 1481 1482 .seealso: `MatSetOption()`, `MatSetValues()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 1483 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()` 1484 @*/ 1485 PetscErrorCode MatSetValuesIS(Mat mat, IS ism, IS isn, const PetscScalar v[], InsertMode addv) { 1486 PetscInt m, n; 1487 const PetscInt *rows, *cols; 1488 1489 PetscFunctionBeginHot; 1490 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 1491 PetscCall(ISGetIndices(ism, &rows)); 1492 PetscCall(ISGetIndices(isn, &cols)); 1493 PetscCall(ISGetLocalSize(ism, &m)); 1494 PetscCall(ISGetLocalSize(isn, &n)); 1495 PetscCall(MatSetValues(mat, m, rows, n, cols, v, addv)); 1496 PetscCall(ISRestoreIndices(ism, &rows)); 1497 PetscCall(ISRestoreIndices(isn, &cols)); 1498 PetscFunctionReturn(0); 1499 } 1500 1501 /*@ 1502 MatSetValuesRowLocal - Inserts a row (block row for `MATBAIJ` matrices) of nonzero 1503 values into a matrix 1504 1505 Not Collective 1506 1507 Input Parameters: 1508 + mat - the matrix 1509 . row - the (block) row to set 1510 - v - a logically two-dimensional array of values 1511 1512 Notes: 1513 By the values, v, are column-oriented (for the block version) and sorted 1514 1515 All the nonzeros in the row must be provided 1516 1517 The matrix must have previously had its column indices set 1518 1519 The row must belong to this process 1520 1521 Level: intermediate 1522 1523 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 1524 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()`, `MatSetValuesRow()`, `MatSetLocalToGlobalMapping()` 1525 @*/ 1526 PetscErrorCode MatSetValuesRowLocal(Mat mat, PetscInt row, const PetscScalar v[]) { 1527 PetscInt globalrow; 1528 1529 PetscFunctionBegin; 1530 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 1531 PetscValidType(mat, 1); 1532 PetscValidScalarPointer(v, 3); 1533 PetscCall(ISLocalToGlobalMappingApply(mat->rmap->mapping, 1, &row, &globalrow)); 1534 PetscCall(MatSetValuesRow(mat, globalrow, v)); 1535 PetscFunctionReturn(0); 1536 } 1537 1538 /*@ 1539 MatSetValuesRow - Inserts a row (block row for `MATBAIJ` matrices) of nonzero 1540 values into a matrix 1541 1542 Not Collective 1543 1544 Input Parameters: 1545 + mat - the matrix 1546 . row - the (block) row to set 1547 - 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 1548 1549 Notes: 1550 The values, v, are column-oriented for the block version. 1551 1552 All the nonzeros in the row must be provided 1553 1554 THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually `MatSetValues()` is used. 1555 1556 The row must belong to this process 1557 1558 Level: advanced 1559 1560 .seealso: `MatSetValues()`, `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 1561 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()` 1562 @*/ 1563 PetscErrorCode MatSetValuesRow(Mat mat, PetscInt row, const PetscScalar v[]) { 1564 PetscFunctionBeginHot; 1565 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 1566 PetscValidType(mat, 1); 1567 MatCheckPreallocated(mat, 1); 1568 PetscValidScalarPointer(v, 3); 1569 PetscCheck(mat->insertmode != ADD_VALUES, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cannot mix add and insert values"); 1570 PetscCheck(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 1571 mat->insertmode = INSERT_VALUES; 1572 1573 if (mat->assembled) { 1574 mat->was_assembled = PETSC_TRUE; 1575 mat->assembled = PETSC_FALSE; 1576 } 1577 PetscCall(PetscLogEventBegin(MAT_SetValues, mat, 0, 0, 0)); 1578 PetscUseTypeMethod(mat, setvaluesrow, row, v); 1579 PetscCall(PetscLogEventEnd(MAT_SetValues, mat, 0, 0, 0)); 1580 PetscFunctionReturn(0); 1581 } 1582 1583 /*@ 1584 MatSetValuesStencil - Inserts or adds a block of values into a matrix. 1585 Using structured grid indexing 1586 1587 Not Collective 1588 1589 Input Parameters: 1590 + mat - the matrix 1591 . m - number of rows being entered 1592 . idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered 1593 . n - number of columns being entered 1594 . idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered 1595 . v - a logically two-dimensional array of values 1596 - addv - either `ADD_VALUES` to add to existing entries at that location or `INSERT_VALUES` to replace existing entries with new values 1597 1598 Notes: 1599 By default the values, v, are row-oriented. See `MatSetOption()` for other options. 1600 1601 Calls to `MatSetValuesStencil()` with the `INSERT_VALUES` and `ADD_VALUES` 1602 options cannot be mixed without intervening calls to the assembly 1603 routines. 1604 1605 The grid coordinates are across the entire grid, not just the local portion 1606 1607 `MatSetValuesStencil()` uses 0-based row and column numbers in Fortran 1608 as well as in C. 1609 1610 For setting/accessing vector values via array coordinates you can use the `DMDAVecGetArray()` routine 1611 1612 In order to use this routine you must either obtain the matrix with `DMCreateMatrix()` 1613 or call `MatSetLocalToGlobalMapping()` and `MatSetStencil()` first. 1614 1615 The columns and rows in the stencil passed in MUST be contained within the 1616 ghost region of the given process as set with DMDACreateXXX() or `MatSetStencil()`. For example, 1617 if you create a `DMDA` with an overlap of one grid level and on a particular process its first 1618 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1619 first i index you can use in your column and row indices in `MatSetStencil()` is 5. 1620 1621 In Fortran idxm and idxn should be declared as 1622 $ MatStencil idxm(4,m),idxn(4,n) 1623 and the values inserted using 1624 $ idxm(MatStencil_i,1) = i 1625 $ idxm(MatStencil_j,1) = j 1626 $ idxm(MatStencil_k,1) = k 1627 $ idxm(MatStencil_c,1) = c 1628 etc 1629 1630 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 1631 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 1632 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 1633 `DM_BOUNDARY_PERIODIC` boundary type. 1634 1635 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 1636 a single value per point) you can skip filling those indices. 1637 1638 Inspired by the structured grid interface to the HYPRE package 1639 (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods) 1640 1641 Efficiency Alert: 1642 The routine `MatSetValuesBlockedStencil()` may offer much better efficiency 1643 for users of block sparse formats (`MATSEQBAIJ` and `MATMPIBAIJ`). 1644 1645 Level: beginner 1646 1647 .seealso: `Mat`, `DMDA`, `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()` 1648 `MatSetValues()`, `MatSetValuesBlockedStencil()`, `MatSetStencil()`, `DMCreateMatrix()`, `DMDAVecGetArray()`, `MatStencil` 1649 @*/ 1650 PetscErrorCode MatSetValuesStencil(Mat mat, PetscInt m, const MatStencil idxm[], PetscInt n, const MatStencil idxn[], const PetscScalar v[], InsertMode addv) { 1651 PetscInt buf[8192], *bufm = NULL, *bufn = NULL, *jdxm, *jdxn; 1652 PetscInt j, i, dim = mat->stencil.dim, *dims = mat->stencil.dims + 1, tmp; 1653 PetscInt *starts = mat->stencil.starts, *dxm = (PetscInt *)idxm, *dxn = (PetscInt *)idxn, sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1654 1655 PetscFunctionBegin; 1656 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1657 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 1658 PetscValidType(mat, 1); 1659 PetscValidPointer(idxm, 3); 1660 PetscValidPointer(idxn, 5); 1661 1662 if ((m + n) <= (PetscInt)(sizeof(buf) / sizeof(PetscInt))) { 1663 jdxm = buf; 1664 jdxn = buf + m; 1665 } else { 1666 PetscCall(PetscMalloc2(m, &bufm, n, &bufn)); 1667 jdxm = bufm; 1668 jdxn = bufn; 1669 } 1670 for (i = 0; i < m; i++) { 1671 for (j = 0; j < 3 - sdim; j++) dxm++; 1672 tmp = *dxm++ - starts[0]; 1673 for (j = 0; j < dim - 1; j++) { 1674 if ((*dxm++ - starts[j + 1]) < 0 || tmp < 0) tmp = -1; 1675 else tmp = tmp * dims[j] + *(dxm - 1) - starts[j + 1]; 1676 } 1677 if (mat->stencil.noc) dxm++; 1678 jdxm[i] = tmp; 1679 } 1680 for (i = 0; i < n; i++) { 1681 for (j = 0; j < 3 - sdim; j++) dxn++; 1682 tmp = *dxn++ - starts[0]; 1683 for (j = 0; j < dim - 1; j++) { 1684 if ((*dxn++ - starts[j + 1]) < 0 || tmp < 0) tmp = -1; 1685 else tmp = tmp * dims[j] + *(dxn - 1) - starts[j + 1]; 1686 } 1687 if (mat->stencil.noc) dxn++; 1688 jdxn[i] = tmp; 1689 } 1690 PetscCall(MatSetValuesLocal(mat, m, jdxm, n, jdxn, v, addv)); 1691 PetscCall(PetscFree2(bufm, bufn)); 1692 PetscFunctionReturn(0); 1693 } 1694 1695 /*@ 1696 MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix. 1697 Using structured grid indexing 1698 1699 Not Collective 1700 1701 Input Parameters: 1702 + mat - the matrix 1703 . m - number of rows being entered 1704 . idxm - grid coordinates for matrix rows being entered 1705 . n - number of columns being entered 1706 . idxn - grid coordinates for matrix columns being entered 1707 . v - a logically two-dimensional array of values 1708 - addv - either `ADD_VALUES` to add to existing entries or `INSERT_VALUES` to replace existing entries with new values 1709 1710 Notes: 1711 By default the values, v, are row-oriented and unsorted. 1712 See `MatSetOption()` for other options. 1713 1714 Calls to `MatSetValuesBlockedStencil()` with the `INSERT_VALUES` and `ADD_VALUES` 1715 options cannot be mixed without intervening calls to the assembly 1716 routines. 1717 1718 The grid coordinates are across the entire grid, not just the local portion 1719 1720 `MatSetValuesBlockedStencil()` uses 0-based row and column numbers in Fortran 1721 as well as in C. 1722 1723 For setting/accessing vector values via array coordinates you can use the `DMDAVecGetArray()` routine 1724 1725 In order to use this routine you must either obtain the matrix with `DMCreateMatrix()` 1726 or call `MatSetBlockSize()`, `MatSetLocalToGlobalMapping()` and `MatSetStencil()` first. 1727 1728 The columns and rows in the stencil passed in MUST be contained within the 1729 ghost region of the given process as set with DMDACreateXXX() or `MatSetStencil()`. For example, 1730 if you create a `DMDA` with an overlap of one grid level and on a particular process its first 1731 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1732 first i index you can use in your column and row indices in `MatSetStencil()` is 5. 1733 1734 In Fortran idxm and idxn should be declared as 1735 $ MatStencil idxm(4,m),idxn(4,n) 1736 and the values inserted using 1737 $ idxm(MatStencil_i,1) = i 1738 $ idxm(MatStencil_j,1) = j 1739 $ idxm(MatStencil_k,1) = k 1740 etc 1741 1742 Negative indices may be passed in idxm and idxn, these rows and columns are 1743 simply ignored. This allows easily inserting element stiffness matrices 1744 with homogeneous Dirchlet boundary conditions that you don't want represented 1745 in the matrix. 1746 1747 Inspired by the structured grid interface to the HYPRE package 1748 (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods) 1749 1750 Level: beginner 1751 1752 .seealso: `Mat`, `DMDA`, `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()` 1753 `MatSetValues()`, `MatSetValuesStencil()`, `MatSetStencil()`, `DMCreateMatrix()`, `DMDAVecGetArray()`, `MatStencil`, 1754 `MatSetBlockSize()`, `MatSetLocalToGlobalMapping()` 1755 @*/ 1756 PetscErrorCode MatSetValuesBlockedStencil(Mat mat, PetscInt m, const MatStencil idxm[], PetscInt n, const MatStencil idxn[], const PetscScalar v[], InsertMode addv) { 1757 PetscInt buf[8192], *bufm = NULL, *bufn = NULL, *jdxm, *jdxn; 1758 PetscInt j, i, dim = mat->stencil.dim, *dims = mat->stencil.dims + 1, tmp; 1759 PetscInt *starts = mat->stencil.starts, *dxm = (PetscInt *)idxm, *dxn = (PetscInt *)idxn, sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1760 1761 PetscFunctionBegin; 1762 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1763 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 1764 PetscValidType(mat, 1); 1765 PetscValidPointer(idxm, 3); 1766 PetscValidPointer(idxn, 5); 1767 PetscValidScalarPointer(v, 6); 1768 1769 if ((m + n) <= (PetscInt)(sizeof(buf) / sizeof(PetscInt))) { 1770 jdxm = buf; 1771 jdxn = buf + m; 1772 } else { 1773 PetscCall(PetscMalloc2(m, &bufm, n, &bufn)); 1774 jdxm = bufm; 1775 jdxn = bufn; 1776 } 1777 for (i = 0; i < m; i++) { 1778 for (j = 0; j < 3 - sdim; j++) dxm++; 1779 tmp = *dxm++ - starts[0]; 1780 for (j = 0; j < sdim - 1; j++) { 1781 if ((*dxm++ - starts[j + 1]) < 0 || tmp < 0) tmp = -1; 1782 else tmp = tmp * dims[j] + *(dxm - 1) - starts[j + 1]; 1783 } 1784 dxm++; 1785 jdxm[i] = tmp; 1786 } 1787 for (i = 0; i < n; i++) { 1788 for (j = 0; j < 3 - sdim; j++) dxn++; 1789 tmp = *dxn++ - starts[0]; 1790 for (j = 0; j < sdim - 1; j++) { 1791 if ((*dxn++ - starts[j + 1]) < 0 || tmp < 0) tmp = -1; 1792 else tmp = tmp * dims[j] + *(dxn - 1) - starts[j + 1]; 1793 } 1794 dxn++; 1795 jdxn[i] = tmp; 1796 } 1797 PetscCall(MatSetValuesBlockedLocal(mat, m, jdxm, n, jdxn, v, addv)); 1798 PetscCall(PetscFree2(bufm, bufn)); 1799 PetscFunctionReturn(0); 1800 } 1801 1802 /*@ 1803 MatSetStencil - Sets the grid information for setting values into a matrix via 1804 `MatSetValuesStencil()` 1805 1806 Not Collective 1807 1808 Input Parameters: 1809 + mat - the matrix 1810 . dim - dimension of the grid 1, 2, or 3 1811 . dims - number of grid points in x, y, and z direction, including ghost points on your processor 1812 . starts - starting point of ghost nodes on your processor in x, y, and z direction 1813 - dof - number of degrees of freedom per node 1814 1815 Notes: 1816 Inspired by the structured grid interface to the HYPRE package 1817 (www.llnl.gov/CASC/hyper) 1818 1819 For matrices generated with `DMCreateMatrix()` this routine is automatically called and so not needed by the 1820 user. 1821 1822 Level: beginner 1823 1824 .seealso: `Mat`, `MatStencil`, `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()` 1825 `MatSetValues()`, `MatSetValuesBlockedStencil()`, `MatSetValuesStencil()` 1826 @*/ 1827 PetscErrorCode MatSetStencil(Mat mat, PetscInt dim, const PetscInt dims[], const PetscInt starts[], PetscInt dof) { 1828 PetscFunctionBegin; 1829 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 1830 PetscValidIntPointer(dims, 3); 1831 PetscValidIntPointer(starts, 4); 1832 1833 mat->stencil.dim = dim + (dof > 1); 1834 for (PetscInt i = 0; i < dim; i++) { 1835 mat->stencil.dims[i] = dims[dim - i - 1]; /* copy the values in backwards */ 1836 mat->stencil.starts[i] = starts[dim - i - 1]; 1837 } 1838 mat->stencil.dims[dim] = dof; 1839 mat->stencil.starts[dim] = 0; 1840 mat->stencil.noc = (PetscBool)(dof == 1); 1841 PetscFunctionReturn(0); 1842 } 1843 1844 /*@C 1845 MatSetValuesBlocked - Inserts or adds a block of values into a matrix. 1846 1847 Not Collective 1848 1849 Input Parameters: 1850 + mat - the matrix 1851 . v - a logically two-dimensional array of values 1852 . m, idxm - the number of block rows and their global block indices 1853 . n, idxn - the number of block columns and their global block indices 1854 - addv - either `ADD_VALUES` to add values to any existing entries, or `INSERT_VALUES` replaces existing entries with new values 1855 1856 Notes: 1857 If you create the matrix yourself (that is not with a call to `DMCreateMatrix()`) then you MUST call 1858 MatXXXXSetPreallocation() or `MatSetUp()` before using this routine. 1859 1860 The m and n count the NUMBER of blocks in the row direction and column direction, 1861 NOT the total number of rows/columns; for example, if the block size is 2 and 1862 you are passing in values for rows 2,3,4,5 then m would be 2 (not 4). 1863 The values in idxm would be 1 2; that is the first index for each block divided by 1864 the block size. 1865 1866 Note that you must call `MatSetBlockSize()` when constructing this matrix (before 1867 preallocating it). 1868 1869 By default the values, v, are row-oriented, so the layout of 1870 v is the same as for `MatSetValues()`. See `MatSetOption()` for other options. 1871 1872 Calls to `MatSetValuesBlocked()` with the `INSERT_VALUES` and `ADD_VALUES` 1873 options cannot be mixed without intervening calls to the assembly 1874 routines. 1875 1876 `MatSetValuesBlocked()` uses 0-based row and column numbers in Fortran 1877 as well as in C. 1878 1879 Negative indices may be passed in idxm and idxn, these rows and columns are 1880 simply ignored. This allows easily inserting element stiffness matrices 1881 with homogeneous Dirchlet boundary conditions that you don't want represented 1882 in the matrix. 1883 1884 Each time an entry is set within a sparse matrix via `MatSetValues()`, 1885 internal searching must be done to determine where to place the 1886 data in the matrix storage space. By instead inserting blocks of 1887 entries via `MatSetValuesBlocked()`, the overhead of matrix assembly is 1888 reduced. 1889 1890 Example: 1891 $ Suppose m=n=2 and block size(bs) = 2 The array is 1892 $ 1893 $ 1 2 | 3 4 1894 $ 5 6 | 7 8 1895 $ - - - | - - - 1896 $ 9 10 | 11 12 1897 $ 13 14 | 15 16 1898 $ 1899 $ v[] should be passed in like 1900 $ v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] 1901 $ 1902 $ If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then 1903 $ v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16] 1904 1905 Level: intermediate 1906 1907 .seealso: `Mat`, `MatSetBlockSize()`, `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetValuesBlockedLocal()` 1908 @*/ 1909 PetscErrorCode MatSetValuesBlocked(Mat mat, PetscInt m, const PetscInt idxm[], PetscInt n, const PetscInt idxn[], const PetscScalar v[], InsertMode addv) { 1910 PetscFunctionBeginHot; 1911 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 1912 PetscValidType(mat, 1); 1913 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1914 PetscValidIntPointer(idxm, 3); 1915 PetscValidIntPointer(idxn, 5); 1916 MatCheckPreallocated(mat, 1); 1917 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 1918 else PetscCheck(mat->insertmode == addv, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cannot mix add values and insert values"); 1919 if (PetscDefined(USE_DEBUG)) { 1920 PetscCheck(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 1921 PetscCheck(mat->ops->setvaluesblocked || mat->ops->setvalues, PETSC_COMM_SELF, PETSC_ERR_SUP, "Mat type %s", ((PetscObject)mat)->type_name); 1922 } 1923 if (PetscDefined(USE_DEBUG)) { 1924 PetscInt rbs, cbs, M, N, i; 1925 PetscCall(MatGetBlockSizes(mat, &rbs, &cbs)); 1926 PetscCall(MatGetSize(mat, &M, &N)); 1927 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); 1928 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); 1929 } 1930 if (mat->assembled) { 1931 mat->was_assembled = PETSC_TRUE; 1932 mat->assembled = PETSC_FALSE; 1933 } 1934 PetscCall(PetscLogEventBegin(MAT_SetValues, mat, 0, 0, 0)); 1935 if (mat->ops->setvaluesblocked) { 1936 PetscUseTypeMethod(mat, setvaluesblocked, m, idxm, n, idxn, v, addv); 1937 } else { 1938 PetscInt buf[8192], *bufr = NULL, *bufc = NULL, *iidxm, *iidxn; 1939 PetscInt i, j, bs, cbs; 1940 1941 PetscCall(MatGetBlockSizes(mat, &bs, &cbs)); 1942 if (m * bs + n * cbs <= (PetscInt)(sizeof(buf) / sizeof(PetscInt))) { 1943 iidxm = buf; 1944 iidxn = buf + m * bs; 1945 } else { 1946 PetscCall(PetscMalloc2(m * bs, &bufr, n * cbs, &bufc)); 1947 iidxm = bufr; 1948 iidxn = bufc; 1949 } 1950 for (i = 0; i < m; i++) { 1951 for (j = 0; j < bs; j++) iidxm[i * bs + j] = bs * idxm[i] + j; 1952 } 1953 if (m != n || bs != cbs || idxm != idxn) { 1954 for (i = 0; i < n; i++) { 1955 for (j = 0; j < cbs; j++) iidxn[i * cbs + j] = cbs * idxn[i] + j; 1956 } 1957 } else iidxn = iidxm; 1958 PetscCall(MatSetValues(mat, m * bs, iidxm, n * cbs, iidxn, v, addv)); 1959 PetscCall(PetscFree2(bufr, bufc)); 1960 } 1961 PetscCall(PetscLogEventEnd(MAT_SetValues, mat, 0, 0, 0)); 1962 PetscFunctionReturn(0); 1963 } 1964 1965 /*@C 1966 MatGetValues - Gets a block of local values from a matrix. 1967 1968 Not Collective; can only return values that are owned by the give process 1969 1970 Input Parameters: 1971 + mat - the matrix 1972 . v - a logically two-dimensional array for storing the values 1973 . m, idxm - the number of rows and their global indices 1974 - n, idxn - the number of columns and their global indices 1975 1976 Notes: 1977 The user must allocate space (m*n `PetscScalar`s) for the values, v. 1978 The values, v, are then returned in a row-oriented format, 1979 analogous to that used by default in `MatSetValues()`. 1980 1981 `MatGetValues()` uses 0-based row and column numbers in 1982 Fortran as well as in C. 1983 1984 `MatGetValues()` requires that the matrix has been assembled 1985 with `MatAssemblyBegin()`/`MatAssemblyEnd()`. Thus, calls to 1986 `MatSetValues()` and `MatGetValues()` CANNOT be made in succession 1987 without intermediate matrix assembly. 1988 1989 Negative row or column indices will be ignored and those locations in v[] will be 1990 left unchanged. 1991 1992 For the standard row-based matrix formats, idxm[] can only contain rows owned by the requesting MPI rank. 1993 That is, rows with global index greater than or equal to rstart and less than rend where rstart and rend are obtainable 1994 from `MatGetOwnershipRange`(mat,&rstart,&rend). 1995 1996 Level: advanced 1997 1998 .seealso: `Mat`, `MatGetRow()`, `MatCreateSubMatrices()`, `MatSetValues()`, `MatGetOwnershipRange()`, `MatGetValuesLocal()`, `MatGetValue()` 1999 @*/ 2000 PetscErrorCode MatGetValues(Mat mat, PetscInt m, const PetscInt idxm[], PetscInt n, const PetscInt idxn[], PetscScalar v[]) { 2001 PetscFunctionBegin; 2002 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2003 PetscValidType(mat, 1); 2004 if (!m || !n) PetscFunctionReturn(0); 2005 PetscValidIntPointer(idxm, 3); 2006 PetscValidIntPointer(idxn, 5); 2007 PetscValidScalarPointer(v, 6); 2008 PetscCheck(mat->assembled, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 2009 PetscCheck(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 2010 MatCheckPreallocated(mat, 1); 2011 2012 PetscCall(PetscLogEventBegin(MAT_GetValues, mat, 0, 0, 0)); 2013 PetscUseTypeMethod(mat, getvalues, m, idxm, n, idxn, v); 2014 PetscCall(PetscLogEventEnd(MAT_GetValues, mat, 0, 0, 0)); 2015 PetscFunctionReturn(0); 2016 } 2017 2018 /*@C 2019 MatGetValuesLocal - retrieves values from certain locations in a matrix using the local numbering of the indices 2020 defined previously by `MatSetLocalToGlobalMapping()` 2021 2022 Not Collective 2023 2024 Input Parameters: 2025 + mat - the matrix 2026 . nrow, irow - number of rows and their local indices 2027 - ncol, icol - number of columns and their local indices 2028 2029 Output Parameter: 2030 . y - a logically two-dimensional array of values 2031 2032 Notes: 2033 If you create the matrix yourself (that is not with a call to `DMCreateMatrix()`) then you MUST call `MatSetLocalToGlobalMapping()` before using this routine. 2034 2035 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, 2036 are greater than or equal to rstart and less than rend where rstart and rend are obtainable from `MatGetOwnershipRange`(mat,&rstart,&rend). One can 2037 determine if the resulting global row associated with the local row r is owned by the requesting MPI rank by applying the `ISLocalToGlobalMapping` set 2038 with `MatSetLocalToGlobalMapping()`. 2039 2040 Developer Note: 2041 This is labelled with C so does not automatically generate Fortran stubs and interfaces 2042 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2043 2044 Level: advanced 2045 2046 .seealso: `Mat`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetLocalToGlobalMapping()`, 2047 `MatSetValuesLocal()`, `MatGetValues()` 2048 @*/ 2049 PetscErrorCode MatGetValuesLocal(Mat mat, PetscInt nrow, const PetscInt irow[], PetscInt ncol, const PetscInt icol[], PetscScalar y[]) { 2050 PetscFunctionBeginHot; 2051 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2052 PetscValidType(mat, 1); 2053 MatCheckPreallocated(mat, 1); 2054 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to retrieve */ 2055 PetscValidIntPointer(irow, 3); 2056 PetscValidIntPointer(icol, 5); 2057 if (PetscDefined(USE_DEBUG)) { 2058 PetscCheck(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 2059 PetscCheck(mat->ops->getvalueslocal || mat->ops->getvalues, PETSC_COMM_SELF, PETSC_ERR_SUP, "Mat type %s", ((PetscObject)mat)->type_name); 2060 } 2061 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 2062 PetscCall(PetscLogEventBegin(MAT_GetValues, mat, 0, 0, 0)); 2063 if (mat->ops->getvalueslocal) PetscUseTypeMethod(mat, getvalueslocal, nrow, irow, ncol, icol, y); 2064 else { 2065 PetscInt buf[8192], *bufr = NULL, *bufc = NULL, *irowm, *icolm; 2066 if ((nrow + ncol) <= (PetscInt)(sizeof(buf) / sizeof(PetscInt))) { 2067 irowm = buf; 2068 icolm = buf + nrow; 2069 } else { 2070 PetscCall(PetscMalloc2(nrow, &bufr, ncol, &bufc)); 2071 irowm = bufr; 2072 icolm = bufc; 2073 } 2074 PetscCheck(mat->rmap->mapping, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "MatGetValuesLocal() cannot proceed without local-to-global row mapping (See MatSetLocalToGlobalMapping())."); 2075 PetscCheck(mat->cmap->mapping, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "MatGetValuesLocal() cannot proceed without local-to-global column mapping (See MatSetLocalToGlobalMapping())."); 2076 PetscCall(ISLocalToGlobalMappingApply(mat->rmap->mapping, nrow, irow, irowm)); 2077 PetscCall(ISLocalToGlobalMappingApply(mat->cmap->mapping, ncol, icol, icolm)); 2078 PetscCall(MatGetValues(mat, nrow, irowm, ncol, icolm, y)); 2079 PetscCall(PetscFree2(bufr, bufc)); 2080 } 2081 PetscCall(PetscLogEventEnd(MAT_GetValues, mat, 0, 0, 0)); 2082 PetscFunctionReturn(0); 2083 } 2084 2085 /*@ 2086 MatSetValuesBatch - Adds (`ADD_VALUES`) many blocks of values into a matrix at once. The blocks must all be square and 2087 the same size. Currently, this can only be called once and creates the given matrix. 2088 2089 Not Collective 2090 2091 Input Parameters: 2092 + mat - the matrix 2093 . nb - the number of blocks 2094 . bs - the number of rows (and columns) in each block 2095 . rows - a concatenation of the rows for each block 2096 - v - a concatenation of logically two-dimensional arrays of values 2097 2098 Note: 2099 `MatSetPreallocationCOO()` and `MatSetValuesCOO()` may be a better way to provide the values 2100 2101 In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix. 2102 2103 Level: advanced 2104 2105 .seealso: `Mat`, `Mat`MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 2106 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()`, `MatSetPreallocationCOO()`, `MatSetValuesCOO()` 2107 @*/ 2108 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[]) { 2109 PetscFunctionBegin; 2110 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2111 PetscValidType(mat, 1); 2112 PetscValidIntPointer(rows, 4); 2113 PetscValidScalarPointer(v, 5); 2114 PetscAssert(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 2115 2116 PetscCall(PetscLogEventBegin(MAT_SetValuesBatch, mat, 0, 0, 0)); 2117 if (mat->ops->setvaluesbatch) PetscUseTypeMethod(mat, setvaluesbatch, nb, bs, rows, v); 2118 else { 2119 for (PetscInt b = 0; b < nb; ++b) PetscCall(MatSetValues(mat, bs, &rows[b * bs], bs, &rows[b * bs], &v[b * bs * bs], ADD_VALUES)); 2120 } 2121 PetscCall(PetscLogEventEnd(MAT_SetValuesBatch, mat, 0, 0, 0)); 2122 PetscFunctionReturn(0); 2123 } 2124 2125 /*@ 2126 MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by 2127 the routine `MatSetValuesLocal()` to allow users to insert matrix entries 2128 using a local (per-processor) numbering. 2129 2130 Not Collective 2131 2132 Input Parameters: 2133 + x - the matrix 2134 . rmapping - row mapping created with `ISLocalToGlobalMappingCreate()` or `ISLocalToGlobalMappingCreateIS()` 2135 - cmapping - column mapping 2136 2137 Level: intermediate 2138 2139 Note: 2140 If the matrix is obtained with `DMCreateMatrix()` then this may already have been called on the matrix 2141 2142 .seealso: `Mat`, `DM`, `DMCreateMatrix()`, `MatGetLocalToGlobalMapping()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetValuesLocal()`, `MatGetValuesLocal()` 2143 @*/ 2144 PetscErrorCode MatSetLocalToGlobalMapping(Mat x, ISLocalToGlobalMapping rmapping, ISLocalToGlobalMapping cmapping) { 2145 PetscFunctionBegin; 2146 PetscValidHeaderSpecific(x, MAT_CLASSID, 1); 2147 PetscValidType(x, 1); 2148 if (rmapping) PetscValidHeaderSpecific(rmapping, IS_LTOGM_CLASSID, 2); 2149 if (cmapping) PetscValidHeaderSpecific(cmapping, IS_LTOGM_CLASSID, 3); 2150 if (x->ops->setlocaltoglobalmapping) PetscUseTypeMethod(x, setlocaltoglobalmapping, rmapping, cmapping); 2151 else { 2152 PetscCall(PetscLayoutSetISLocalToGlobalMapping(x->rmap, rmapping)); 2153 PetscCall(PetscLayoutSetISLocalToGlobalMapping(x->cmap, cmapping)); 2154 } 2155 PetscFunctionReturn(0); 2156 } 2157 2158 /*@ 2159 MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by `MatSetLocalToGlobalMapping()` 2160 2161 Not Collective 2162 2163 Input Parameter: 2164 . A - the matrix 2165 2166 Output Parameters: 2167 + rmapping - row mapping 2168 - cmapping - column mapping 2169 2170 Level: advanced 2171 2172 .seealso: `Mat`, `MatSetLocalToGlobalMapping()`, `MatSetValuesLocal()` 2173 @*/ 2174 PetscErrorCode MatGetLocalToGlobalMapping(Mat A, ISLocalToGlobalMapping *rmapping, ISLocalToGlobalMapping *cmapping) { 2175 PetscFunctionBegin; 2176 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2177 PetscValidType(A, 1); 2178 if (rmapping) { 2179 PetscValidPointer(rmapping, 2); 2180 *rmapping = A->rmap->mapping; 2181 } 2182 if (cmapping) { 2183 PetscValidPointer(cmapping, 3); 2184 *cmapping = A->cmap->mapping; 2185 } 2186 PetscFunctionReturn(0); 2187 } 2188 2189 /*@ 2190 MatSetLayouts - Sets the `PetscLayout` objects for rows and columns of a matrix 2191 2192 Logically Collective on A 2193 2194 Input Parameters: 2195 + A - the matrix 2196 . rmap - row layout 2197 - cmap - column layout 2198 2199 Level: advanced 2200 2201 Note: 2202 The `PetscLayout` objects are usually created automatically for the matrix so this routine rarely needs to be called. 2203 2204 .seealso: `PetscLayout`, `MatCreateVecs()`, `MatGetLocalToGlobalMapping()`, `MatGetLayouts()` 2205 @*/ 2206 PetscErrorCode MatSetLayouts(Mat A, PetscLayout rmap, PetscLayout cmap) { 2207 PetscFunctionBegin; 2208 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2209 PetscCall(PetscLayoutReference(rmap, &A->rmap)); 2210 PetscCall(PetscLayoutReference(cmap, &A->cmap)); 2211 PetscFunctionReturn(0); 2212 } 2213 2214 /*@ 2215 MatGetLayouts - Gets the `PetscLayout` objects for rows and columns 2216 2217 Not Collective 2218 2219 Input Parameter: 2220 . A - the matrix 2221 2222 Output Parameters: 2223 + rmap - row layout 2224 - cmap - column layout 2225 2226 Level: advanced 2227 2228 .seealso: [Matrix Layouts](sec_matlayout), `PetscLayout`, `MatCreateVecs()`, `MatGetLocalToGlobalMapping()`, `MatSetLayouts()` 2229 @*/ 2230 PetscErrorCode MatGetLayouts(Mat A, PetscLayout *rmap, PetscLayout *cmap) { 2231 PetscFunctionBegin; 2232 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2233 PetscValidType(A, 1); 2234 if (rmap) { 2235 PetscValidPointer(rmap, 2); 2236 *rmap = A->rmap; 2237 } 2238 if (cmap) { 2239 PetscValidPointer(cmap, 3); 2240 *cmap = A->cmap; 2241 } 2242 PetscFunctionReturn(0); 2243 } 2244 2245 /*@C 2246 MatSetValuesLocal - Inserts or adds values into certain locations of a matrix, 2247 using a local numbering of the nodes. 2248 2249 Not Collective 2250 2251 Input Parameters: 2252 + mat - the matrix 2253 . nrow, irow - number of rows and their local indices 2254 . ncol, icol - number of columns and their local indices 2255 . y - a logically two-dimensional array of values 2256 - addv - either `INSERT_VALUES` to add values to any existing entries, or `INSERT_VALUES` to replace existing entries with new values 2257 2258 Notes: 2259 If you create the matrix yourself (that is not with a call to `DMCreateMatrix()`) then you MUST call MatXXXXSetPreallocation() or 2260 `MatSetUp()` before using this routine 2261 2262 If you create the matrix yourself (that is not with a call to `DMCreateMatrix()`) then you MUST call `MatSetLocalToGlobalMapping()` before using this routine 2263 2264 Calls to `MatSetValuesLocal()` with the `INSERT_VALUES` and `ADD_VALUES` 2265 options cannot be mixed without intervening calls to the assembly 2266 routines. 2267 2268 These values may be cached, so `MatAssemblyBegin()` and `MatAssemblyEnd()` 2269 MUST be called after all calls to `MatSetValuesLocal()` have been completed. 2270 2271 Level: intermediate 2272 2273 Developer Note: 2274 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2275 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2276 2277 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetLocalToGlobalMapping()`, 2278 `MatGetValuesLocal()` 2279 @*/ 2280 PetscErrorCode MatSetValuesLocal(Mat mat, PetscInt nrow, const PetscInt irow[], PetscInt ncol, const PetscInt icol[], const PetscScalar y[], InsertMode addv) { 2281 PetscFunctionBeginHot; 2282 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2283 PetscValidType(mat, 1); 2284 MatCheckPreallocated(mat, 1); 2285 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2286 PetscValidIntPointer(irow, 3); 2287 PetscValidIntPointer(icol, 5); 2288 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 2289 else PetscCheck(mat->insertmode == addv, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cannot mix add values and insert values"); 2290 if (PetscDefined(USE_DEBUG)) { 2291 PetscCheck(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 2292 PetscCheck(mat->ops->setvalueslocal || mat->ops->setvalues, PETSC_COMM_SELF, PETSC_ERR_SUP, "Mat type %s", ((PetscObject)mat)->type_name); 2293 } 2294 2295 if (mat->assembled) { 2296 mat->was_assembled = PETSC_TRUE; 2297 mat->assembled = PETSC_FALSE; 2298 } 2299 PetscCall(PetscLogEventBegin(MAT_SetValues, mat, 0, 0, 0)); 2300 if (mat->ops->setvalueslocal) PetscUseTypeMethod(mat, setvalueslocal, nrow, irow, ncol, icol, y, addv); 2301 else { 2302 PetscInt buf[8192], *bufr = NULL, *bufc = NULL; 2303 const PetscInt *irowm, *icolm; 2304 2305 if ((!mat->rmap->mapping && !mat->cmap->mapping) || (nrow + ncol) <= (PetscInt)(sizeof(buf) / sizeof(PetscInt))) { 2306 bufr = buf; 2307 bufc = buf + nrow; 2308 irowm = bufr; 2309 icolm = bufc; 2310 } else { 2311 PetscCall(PetscMalloc2(nrow, &bufr, ncol, &bufc)); 2312 irowm = bufr; 2313 icolm = bufc; 2314 } 2315 if (mat->rmap->mapping) PetscCall(ISLocalToGlobalMappingApply(mat->rmap->mapping, nrow, irow, bufr)); 2316 else irowm = irow; 2317 if (mat->cmap->mapping) { 2318 if (mat->cmap->mapping != mat->rmap->mapping || ncol != nrow || icol != irow) { 2319 PetscCall(ISLocalToGlobalMappingApply(mat->cmap->mapping, ncol, icol, bufc)); 2320 } else icolm = irowm; 2321 } else icolm = icol; 2322 PetscCall(MatSetValues(mat, nrow, irowm, ncol, icolm, y, addv)); 2323 if (bufr != buf) PetscCall(PetscFree2(bufr, bufc)); 2324 } 2325 PetscCall(PetscLogEventEnd(MAT_SetValues, mat, 0, 0, 0)); 2326 PetscFunctionReturn(0); 2327 } 2328 2329 /*@C 2330 MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix, 2331 using a local ordering of the nodes a block at a time. 2332 2333 Not Collective 2334 2335 Input Parameters: 2336 + x - the matrix 2337 . nrow, irow - number of rows and their local indices 2338 . ncol, icol - number of columns and their local indices 2339 . y - a logically two-dimensional array of values 2340 - addv - either `ADD_VALUES` to add values to any existing entries, or `INSERT_VALUES` to replace existing entries with new values 2341 2342 Notes: 2343 If you create the matrix yourself (that is not with a call to `DMCreateMatrix()`) then you MUST call MatXXXXSetPreallocation() or 2344 `MatSetUp()` before using this routine 2345 2346 If you create the matrix yourself (that is not with a call to `DMCreateMatrix()`) then you MUST call `MatSetBlockSize()` and `MatSetLocalToGlobalMapping()` 2347 before using this routineBefore calling `MatSetValuesLocal()`, the user must first set the 2348 2349 Calls to `MatSetValuesBlockedLocal()` with the `INSERT_VALUES` and `ADD_VALUES` 2350 options cannot be mixed without intervening calls to the assembly 2351 routines. 2352 2353 These values may be cached, so `MatAssemblyBegin()` and `MatAssemblyEnd()` 2354 MUST be called after all calls to `MatSetValuesBlockedLocal()` have been completed. 2355 2356 Level: intermediate 2357 2358 Developer Note: 2359 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2360 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2361 2362 .seealso: `Mat`, `MatSetBlockSize()`, `MatSetLocalToGlobalMapping()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, 2363 `MatSetValuesLocal()`, `MatSetValuesBlocked()` 2364 @*/ 2365 PetscErrorCode MatSetValuesBlockedLocal(Mat mat, PetscInt nrow, const PetscInt irow[], PetscInt ncol, const PetscInt icol[], const PetscScalar y[], InsertMode addv) { 2366 PetscFunctionBeginHot; 2367 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2368 PetscValidType(mat, 1); 2369 MatCheckPreallocated(mat, 1); 2370 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2371 PetscValidIntPointer(irow, 3); 2372 PetscValidIntPointer(icol, 5); 2373 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 2374 else PetscCheck(mat->insertmode == addv, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cannot mix add values and insert values"); 2375 if (PetscDefined(USE_DEBUG)) { 2376 PetscCheck(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 2377 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); 2378 } 2379 2380 if (mat->assembled) { 2381 mat->was_assembled = PETSC_TRUE; 2382 mat->assembled = PETSC_FALSE; 2383 } 2384 if (PetscUnlikelyDebug(mat->rmap->mapping)) { /* Condition on the mapping existing, because MatSetValuesBlockedLocal_IS does not require it to be set. */ 2385 PetscInt irbs, rbs; 2386 PetscCall(MatGetBlockSizes(mat, &rbs, NULL)); 2387 PetscCall(ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping, &irbs)); 2388 PetscCheck(rbs == irbs, PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Different row block sizes! mat %" PetscInt_FMT ", row l2g map %" PetscInt_FMT, rbs, irbs); 2389 } 2390 if (PetscUnlikelyDebug(mat->cmap->mapping)) { 2391 PetscInt icbs, cbs; 2392 PetscCall(MatGetBlockSizes(mat, NULL, &cbs)); 2393 PetscCall(ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping, &icbs)); 2394 PetscCheck(cbs == icbs, PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Different col block sizes! mat %" PetscInt_FMT ", col l2g map %" PetscInt_FMT, cbs, icbs); 2395 } 2396 PetscCall(PetscLogEventBegin(MAT_SetValues, mat, 0, 0, 0)); 2397 if (mat->ops->setvaluesblockedlocal) PetscUseTypeMethod(mat, setvaluesblockedlocal, nrow, irow, ncol, icol, y, addv); 2398 else { 2399 PetscInt buf[8192], *bufr = NULL, *bufc = NULL; 2400 const PetscInt *irowm, *icolm; 2401 2402 if ((!mat->rmap->mapping && !mat->cmap->mapping) || (nrow + ncol) <= (PetscInt)(sizeof(buf) / sizeof(PetscInt))) { 2403 bufr = buf; 2404 bufc = buf + nrow; 2405 irowm = bufr; 2406 icolm = bufc; 2407 } else { 2408 PetscCall(PetscMalloc2(nrow, &bufr, ncol, &bufc)); 2409 irowm = bufr; 2410 icolm = bufc; 2411 } 2412 if (mat->rmap->mapping) PetscCall(ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping, nrow, irow, bufr)); 2413 else irowm = irow; 2414 if (mat->cmap->mapping) { 2415 if (mat->cmap->mapping != mat->rmap->mapping || ncol != nrow || icol != irow) { 2416 PetscCall(ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping, ncol, icol, bufc)); 2417 } else icolm = irowm; 2418 } else icolm = icol; 2419 PetscCall(MatSetValuesBlocked(mat, nrow, irowm, ncol, icolm, y, addv)); 2420 if (bufr != buf) PetscCall(PetscFree2(bufr, bufc)); 2421 } 2422 PetscCall(PetscLogEventEnd(MAT_SetValues, mat, 0, 0, 0)); 2423 PetscFunctionReturn(0); 2424 } 2425 2426 /*@ 2427 MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal 2428 2429 Collective on mat 2430 2431 Input Parameters: 2432 + mat - the matrix 2433 - x - the vector to be multiplied 2434 2435 Output Parameters: 2436 . y - the result 2437 2438 Note: 2439 The vectors x and y cannot be the same. I.e., one cannot 2440 call `MatMultDiagonalBlock`(A,y,y). 2441 2442 Level: developer 2443 2444 .seealso: `Mat`, `MatMult()`, `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 2445 @*/ 2446 PetscErrorCode MatMultDiagonalBlock(Mat mat, Vec x, Vec y) { 2447 PetscFunctionBegin; 2448 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2449 PetscValidType(mat, 1); 2450 PetscValidHeaderSpecific(x, VEC_CLASSID, 2); 2451 PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 2452 2453 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 2454 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 2455 PetscCheck(x != y, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "x and y must be different vectors"); 2456 MatCheckPreallocated(mat, 1); 2457 2458 PetscUseTypeMethod(mat, multdiagonalblock, x, y); 2459 PetscCall(PetscObjectStateIncrease((PetscObject)y)); 2460 PetscFunctionReturn(0); 2461 } 2462 2463 /* --------------------------------------------------------*/ 2464 /*@ 2465 MatMult - Computes the matrix-vector product, y = Ax. 2466 2467 Neighbor-wise 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 Note: 2477 The vectors x and y cannot be the same. I.e., one cannot 2478 call `MatMult`(A,y,y). 2479 2480 Level: beginner 2481 2482 .seealso: `Mat`, `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 2483 @*/ 2484 PetscErrorCode MatMult(Mat mat, Vec x, Vec y) { 2485 PetscFunctionBegin; 2486 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2487 PetscValidType(mat, 1); 2488 PetscValidHeaderSpecific(x, VEC_CLASSID, 2); 2489 PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 2490 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 2491 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 2492 PetscCheck(x != y, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "x and y must be different vectors"); 2493 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); 2494 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); 2495 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); 2496 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); 2497 PetscCall(VecSetErrorIfLocked(y, 3)); 2498 if (mat->erroriffailure) PetscCall(VecValidValues_Internal(x, 2, PETSC_TRUE)); 2499 MatCheckPreallocated(mat, 1); 2500 2501 PetscCall(VecLockReadPush(x)); 2502 PetscCall(PetscLogEventBegin(MAT_Mult, mat, x, y, 0)); 2503 PetscUseTypeMethod(mat, mult, x, y); 2504 PetscCall(PetscLogEventEnd(MAT_Mult, mat, x, y, 0)); 2505 if (mat->erroriffailure) PetscCall(VecValidValues_Internal(y, 3, PETSC_FALSE)); 2506 PetscCall(VecLockReadPop(x)); 2507 PetscFunctionReturn(0); 2508 } 2509 2510 /*@ 2511 MatMultTranspose - Computes matrix transpose times a vector y = A^T * x. 2512 2513 Neighbor-wise Collective on mat 2514 2515 Input Parameters: 2516 + mat - the matrix 2517 - x - the vector to be multiplied 2518 2519 Output Parameters: 2520 . y - the result 2521 2522 Notes: 2523 The vectors x and y cannot be the same. I.e., one cannot 2524 call `MatMultTranspose`(A,y,y). 2525 2526 For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple, 2527 use `MatMultHermitianTranspose()` 2528 2529 Level: beginner 2530 2531 .seealso: `Mat`, `MatMult()`, `MatMultAdd()`, `MatMultTransposeAdd()`, `MatMultHermitianTranspose()`, `MatTranspose()` 2532 @*/ 2533 PetscErrorCode MatMultTranspose(Mat mat, Vec x, Vec y) { 2534 PetscErrorCode (*op)(Mat, Vec, Vec) = NULL; 2535 2536 PetscFunctionBegin; 2537 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2538 PetscValidType(mat, 1); 2539 PetscValidHeaderSpecific(x, VEC_CLASSID, 2); 2540 PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 2541 2542 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 2543 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 2544 PetscCheck(x != y, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "x and y must be different vectors"); 2545 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); 2546 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); 2547 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); 2548 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); 2549 if (mat->erroriffailure) PetscCall(VecValidValues_Internal(x, 2, PETSC_TRUE)); 2550 MatCheckPreallocated(mat, 1); 2551 2552 if (!mat->ops->multtranspose) { 2553 if (mat->symmetric == PETSC_BOOL3_TRUE && mat->ops->mult) op = mat->ops->mult; 2554 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); 2555 } else op = mat->ops->multtranspose; 2556 PetscCall(PetscLogEventBegin(MAT_MultTranspose, mat, x, y, 0)); 2557 PetscCall(VecLockReadPush(x)); 2558 PetscCall((*op)(mat, x, y)); 2559 PetscCall(VecLockReadPop(x)); 2560 PetscCall(PetscLogEventEnd(MAT_MultTranspose, mat, x, y, 0)); 2561 PetscCall(PetscObjectStateIncrease((PetscObject)y)); 2562 if (mat->erroriffailure) PetscCall(VecValidValues_Internal(y, 3, PETSC_FALSE)); 2563 PetscFunctionReturn(0); 2564 } 2565 2566 /*@ 2567 MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector. 2568 2569 Neighbor-wise Collective on mat 2570 2571 Input Parameters: 2572 + mat - the matrix 2573 - x - the vector to be multilplied 2574 2575 Output Parameters: 2576 . y - the result 2577 2578 Notes: 2579 The vectors x and y cannot be the same. I.e., one cannot 2580 call `MatMultHermitianTranspose`(A,y,y). 2581 2582 Also called the conjugate transpose, complex conjugate transpose, or adjoint. 2583 2584 For real numbers `MatMultTranspose()` and `MatMultHermitianTranspose()` are identical. 2585 2586 Level: beginner 2587 2588 .seealso: `Mat`, `MatMult()`, `MatMultAdd()`, `MatMultHermitianTransposeAdd()`, `MatMultTranspose()` 2589 @*/ 2590 PetscErrorCode MatMultHermitianTranspose(Mat mat, Vec x, Vec y) { 2591 PetscFunctionBegin; 2592 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2593 PetscValidType(mat, 1); 2594 PetscValidHeaderSpecific(x, VEC_CLASSID, 2); 2595 PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 2596 2597 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 2598 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 2599 PetscCheck(x != y, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "x and y must be different vectors"); 2600 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); 2601 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); 2602 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); 2603 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); 2604 MatCheckPreallocated(mat, 1); 2605 2606 PetscCall(PetscLogEventBegin(MAT_MultHermitianTranspose, mat, x, y, 0)); 2607 #if defined(PETSC_USE_COMPLEX) 2608 if (mat->ops->multhermitiantranspose || (mat->hermitian == PETSC_BOOL3_TRUE && mat->ops->mult)) { 2609 PetscCall(VecLockReadPush(x)); 2610 if (mat->ops->multhermitiantranspose) PetscUseTypeMethod(mat, multhermitiantranspose, x, y); 2611 else PetscUseTypeMethod(mat, mult, x, y); 2612 PetscCall(VecLockReadPop(x)); 2613 } else { 2614 Vec w; 2615 PetscCall(VecDuplicate(x, &w)); 2616 PetscCall(VecCopy(x, w)); 2617 PetscCall(VecConjugate(w)); 2618 PetscCall(MatMultTranspose(mat, w, y)); 2619 PetscCall(VecDestroy(&w)); 2620 PetscCall(VecConjugate(y)); 2621 } 2622 PetscCall(PetscObjectStateIncrease((PetscObject)y)); 2623 #else 2624 PetscCall(MatMultTranspose(mat, x, y)); 2625 #endif 2626 PetscCall(PetscLogEventEnd(MAT_MultHermitianTranspose, mat, x, y, 0)); 2627 PetscFunctionReturn(0); 2628 } 2629 2630 /*@ 2631 MatMultAdd - Computes v3 = v2 + A * v1. 2632 2633 Neighbor-wise Collective on mat 2634 2635 Input Parameters: 2636 + mat - the matrix 2637 - v1, v2 - the vectors 2638 2639 Output Parameters: 2640 . v3 - the result 2641 2642 Note: 2643 The vectors v1 and v3 cannot be the same. I.e., one cannot 2644 call `MatMultAdd`(A,v1,v2,v1). 2645 2646 Level: beginner 2647 2648 .seealso: `Mat`, `MatMultTranspose()`, `MatMult()`, `MatMultTransposeAdd()` 2649 @*/ 2650 PetscErrorCode MatMultAdd(Mat mat, Vec v1, Vec v2, Vec v3) { 2651 PetscFunctionBegin; 2652 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2653 PetscValidType(mat, 1); 2654 PetscValidHeaderSpecific(v1, VEC_CLASSID, 2); 2655 PetscValidHeaderSpecific(v2, VEC_CLASSID, 3); 2656 PetscValidHeaderSpecific(v3, VEC_CLASSID, 4); 2657 2658 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 2659 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 2660 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); 2661 /* 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); 2662 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); */ 2663 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); 2664 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); 2665 PetscCheck(v1 != v3, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_IDN, "v1 and v3 must be different vectors"); 2666 MatCheckPreallocated(mat, 1); 2667 2668 PetscCall(PetscLogEventBegin(MAT_MultAdd, mat, v1, v2, v3)); 2669 PetscCall(VecLockReadPush(v1)); 2670 PetscUseTypeMethod(mat, multadd, v1, v2, v3); 2671 PetscCall(VecLockReadPop(v1)); 2672 PetscCall(PetscLogEventEnd(MAT_MultAdd, mat, v1, v2, v3)); 2673 PetscCall(PetscObjectStateIncrease((PetscObject)v3)); 2674 PetscFunctionReturn(0); 2675 } 2676 2677 /*@ 2678 MatMultTransposeAdd - 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 Note: 2690 The vectors v1 and v3 cannot be the same. I.e., one cannot 2691 call `MatMultTransposeAdd`(A,v1,v2,v1). 2692 2693 Level: beginner 2694 2695 .seealso: `Mat`, `MatMultTranspose()`, `MatMultAdd()`, `MatMult()` 2696 @*/ 2697 PetscErrorCode MatMultTransposeAdd(Mat mat, Vec v1, Vec v2, Vec v3) { 2698 PetscErrorCode (*op)(Mat, Vec, Vec, Vec) = (!mat->ops->multtransposeadd && mat->symmetric) ? mat->ops->multadd : mat->ops->multtransposeadd; 2699 2700 PetscFunctionBegin; 2701 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2702 PetscValidType(mat, 1); 2703 PetscValidHeaderSpecific(v1, VEC_CLASSID, 2); 2704 PetscValidHeaderSpecific(v2, VEC_CLASSID, 3); 2705 PetscValidHeaderSpecific(v3, VEC_CLASSID, 4); 2706 2707 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 2708 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 2709 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); 2710 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); 2711 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); 2712 PetscCheck(v1 != v3, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_IDN, "v1 and v3 must be different vectors"); 2713 PetscCheck(op, PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Mat type %s", ((PetscObject)mat)->type_name); 2714 MatCheckPreallocated(mat, 1); 2715 2716 PetscCall(PetscLogEventBegin(MAT_MultTransposeAdd, mat, v1, v2, v3)); 2717 PetscCall(VecLockReadPush(v1)); 2718 PetscCall((*op)(mat, v1, v2, v3)); 2719 PetscCall(VecLockReadPop(v1)); 2720 PetscCall(PetscLogEventEnd(MAT_MultTransposeAdd, mat, v1, v2, v3)); 2721 PetscCall(PetscObjectStateIncrease((PetscObject)v3)); 2722 PetscFunctionReturn(0); 2723 } 2724 2725 /*@ 2726 MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1. 2727 2728 Neighbor-wise Collective on mat 2729 2730 Input Parameters: 2731 + mat - the matrix 2732 - v1, v2 - the vectors 2733 2734 Output Parameters: 2735 . v3 - the result 2736 2737 Note: 2738 The vectors v1 and v3 cannot be the same. I.e., one cannot 2739 call `MatMultHermitianTransposeAdd`(A,v1,v2,v1). 2740 2741 Level: beginner 2742 2743 .seealso: `Mat`, `MatMultHermitianTranspose()`, `MatMultTranspose()`, `MatMultAdd()`, `MatMult()` 2744 @*/ 2745 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat, Vec v1, Vec v2, Vec v3) { 2746 PetscFunctionBegin; 2747 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2748 PetscValidType(mat, 1); 2749 PetscValidHeaderSpecific(v1, VEC_CLASSID, 2); 2750 PetscValidHeaderSpecific(v2, VEC_CLASSID, 3); 2751 PetscValidHeaderSpecific(v3, VEC_CLASSID, 4); 2752 2753 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 2754 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 2755 PetscCheck(v1 != v3, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_IDN, "v1 and v3 must be different vectors"); 2756 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); 2757 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); 2758 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); 2759 MatCheckPreallocated(mat, 1); 2760 2761 PetscCall(PetscLogEventBegin(MAT_MultHermitianTransposeAdd, mat, v1, v2, v3)); 2762 PetscCall(VecLockReadPush(v1)); 2763 if (mat->ops->multhermitiantransposeadd) PetscUseTypeMethod(mat, multhermitiantransposeadd, v1, v2, v3); 2764 else { 2765 Vec w, z; 2766 PetscCall(VecDuplicate(v1, &w)); 2767 PetscCall(VecCopy(v1, w)); 2768 PetscCall(VecConjugate(w)); 2769 PetscCall(VecDuplicate(v3, &z)); 2770 PetscCall(MatMultTranspose(mat, w, z)); 2771 PetscCall(VecDestroy(&w)); 2772 PetscCall(VecConjugate(z)); 2773 if (v2 != v3) { 2774 PetscCall(VecWAXPY(v3, 1.0, v2, z)); 2775 } else { 2776 PetscCall(VecAXPY(v3, 1.0, z)); 2777 } 2778 PetscCall(VecDestroy(&z)); 2779 } 2780 PetscCall(VecLockReadPop(v1)); 2781 PetscCall(PetscLogEventEnd(MAT_MultHermitianTransposeAdd, mat, v1, v2, v3)); 2782 PetscCall(PetscObjectStateIncrease((PetscObject)v3)); 2783 PetscFunctionReturn(0); 2784 } 2785 2786 /*@C 2787 MatGetFactorType - gets the type of factorization it is 2788 2789 Not Collective 2790 2791 Input Parameters: 2792 . mat - the matrix 2793 2794 Output Parameters: 2795 . t - the type, one of `MAT_FACTOR_NONE`, `MAT_FACTOR_LU`, `MAT_FACTOR_CHOLESKY`, `MAT_FACTOR_ILU`, `MAT_FACTOR_ICC,MAT_FACTOR_ILUDT`, `MAT_FACTOR_QR` 2796 2797 Level: intermediate 2798 2799 .seealso: [Matrix Factorization](sec_matfactor), `MatFactorType`, `MatGetFactor()`, `MatSetFactorType()`, `MAT_FACTOR_NONE`, `MAT_FACTOR_LU`, `MAT_FACTOR_CHOLESKY`, `MAT_FACTOR_ILU`, 2800 `MAT_FACTOR_ICC,MAT_FACTOR_ILUDT`, `MAT_FACTOR_QR` 2801 @*/ 2802 PetscErrorCode MatGetFactorType(Mat mat, MatFactorType *t) { 2803 PetscFunctionBegin; 2804 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2805 PetscValidType(mat, 1); 2806 PetscValidPointer(t, 2); 2807 *t = mat->factortype; 2808 PetscFunctionReturn(0); 2809 } 2810 2811 /*@C 2812 MatSetFactorType - sets the type of factorization it is 2813 2814 Logically Collective on mat 2815 2816 Input Parameters: 2817 + mat - the matrix 2818 - t - the type, one of `MAT_FACTOR_NONE`, `MAT_FACTOR_LU`, `MAT_FACTOR_CHOLESKY`, `MAT_FACTOR_ILU`, `MAT_FACTOR_ICC,MAT_FACTOR_ILUDT`, `MAT_FACTOR_QR` 2819 2820 Level: intermediate 2821 2822 .seealso: [Matrix Factorization](sec_matfactor), `MatFactorType`, `MatGetFactor()`, `MatGetFactorType()`, `MAT_FACTOR_NONE`, `MAT_FACTOR_LU`, `MAT_FACTOR_CHOLESKY`, `MAT_FACTOR_ILU`, 2823 `MAT_FACTOR_ICC,MAT_FACTOR_ILUDT`, `MAT_FACTOR_QR` 2824 @*/ 2825 PetscErrorCode MatSetFactorType(Mat mat, MatFactorType t) { 2826 PetscFunctionBegin; 2827 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2828 PetscValidType(mat, 1); 2829 mat->factortype = t; 2830 PetscFunctionReturn(0); 2831 } 2832 2833 /* ------------------------------------------------------------*/ 2834 /*@C 2835 MatGetInfo - Returns information about matrix storage (number of 2836 nonzeros, memory, etc.). 2837 2838 Collective on mat if `MAT_GLOBAL_MAX` or `MAT_GLOBAL_SUM` is used as the flag 2839 2840 Input Parameter: 2841 . mat - the matrix 2842 2843 Output Parameters: 2844 + flag - flag indicating the type of parameters to be returned 2845 (`MAT_LOCAL` - local matrix, `MAT_GLOBAL_MAX` - maximum over all processors, 2846 MAT_GLOBAL_SUM - sum over all processors) 2847 - info - matrix information context 2848 2849 Notes: 2850 The `MatInfo` context contains a variety of matrix data, including 2851 number of nonzeros allocated and used, number of mallocs during 2852 matrix assembly, etc. Additional information for factored matrices 2853 is provided (such as the fill ratio, number of mallocs during 2854 factorization, etc.). Much of this info is printed to `PETSC_STDOUT` 2855 when using the runtime options 2856 $ -info -mat_view ::ascii_info 2857 2858 Example for C/C++ Users: 2859 See the file ${PETSC_DIR}/include/petscmat.h for a complete list of 2860 data within the MatInfo context. For example, 2861 .vb 2862 MatInfo info; 2863 Mat A; 2864 double mal, nz_a, nz_u; 2865 2866 MatGetInfo(A,MAT_LOCAL,&info); 2867 mal = info.mallocs; 2868 nz_a = info.nz_allocated; 2869 .ve 2870 2871 Example for Fortran Users: 2872 Fortran users should declare info as a double precision 2873 array of dimension `MAT_INFO_SIZE`, and then extract the parameters 2874 of interest. See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h 2875 a complete list of parameter names. 2876 .vb 2877 double precision info(MAT_INFO_SIZE) 2878 double precision mal, nz_a 2879 Mat A 2880 integer ierr 2881 2882 call MatGetInfo(A,MAT_LOCAL,info,ierr) 2883 mal = info(MAT_INFO_MALLOCS) 2884 nz_a = info(MAT_INFO_NZ_ALLOCATED) 2885 .ve 2886 2887 Level: intermediate 2888 2889 Developer Note: fortran interface is not autogenerated as the f90 2890 interface definition cannot be generated correctly [due to MatInfo] 2891 2892 .seealso: `MatInfo`, `MatStashGetInfo()` 2893 @*/ 2894 PetscErrorCode MatGetInfo(Mat mat, MatInfoType flag, MatInfo *info) { 2895 PetscFunctionBegin; 2896 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2897 PetscValidType(mat, 1); 2898 PetscValidPointer(info, 3); 2899 MatCheckPreallocated(mat, 1); 2900 PetscUseTypeMethod(mat, getinfo, flag, info); 2901 PetscFunctionReturn(0); 2902 } 2903 2904 /* 2905 This is used by external packages where it is not easy to get the info from the actual 2906 matrix factorization. 2907 */ 2908 PetscErrorCode MatGetInfo_External(Mat A, MatInfoType flag, MatInfo *info) { 2909 PetscFunctionBegin; 2910 PetscCall(PetscMemzero(info, sizeof(MatInfo))); 2911 PetscFunctionReturn(0); 2912 } 2913 2914 /* ----------------------------------------------------------*/ 2915 2916 /*@C 2917 MatLUFactor - Performs in-place LU factorization of matrix. 2918 2919 Collective on mat 2920 2921 Input Parameters: 2922 + mat - the matrix 2923 . row - row permutation 2924 . col - column permutation 2925 - info - options for factorization, includes 2926 $ fill - expected fill as ratio of original fill. 2927 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 2928 $ Run with the option -info to determine an optimal value to use 2929 2930 Notes: 2931 Most users should employ the `KSP` interface for linear solvers 2932 instead of working directly with matrix algebra routines such as this. 2933 See, e.g., `KSPCreate()`. 2934 2935 This changes the state of the matrix to a factored matrix; it cannot be used 2936 for example with `MatSetValues()` unless one first calls `MatSetUnfactored()`. 2937 2938 This is really in-place only for dense matrices, the prefered approach is to use `MatGetFactor()`, `MatLUFactorSymbolic()`, and `MatLUFactorNumeric()` 2939 when not using `KSP`. 2940 2941 Level: developer 2942 2943 Developer Note: 2944 The Fortran interface is not autogenerated as the f90 2945 interface definition cannot be generated correctly [due to `MatFactorInfo`] 2946 2947 .seealso: [Matrix Factorization](sec_matfactor), `Mat`, `MatFactorType`, `MatLUFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()`, 2948 `MatGetOrdering()`, `MatSetUnfactored()`, `MatFactorInfo`, `MatGetFactor()` 2949 @*/ 2950 PetscErrorCode MatLUFactor(Mat mat, IS row, IS col, const MatFactorInfo *info) { 2951 MatFactorInfo tinfo; 2952 2953 PetscFunctionBegin; 2954 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2955 if (row) PetscValidHeaderSpecific(row, IS_CLASSID, 2); 2956 if (col) PetscValidHeaderSpecific(col, IS_CLASSID, 3); 2957 if (info) PetscValidPointer(info, 4); 2958 PetscValidType(mat, 1); 2959 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 2960 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 2961 MatCheckPreallocated(mat, 1); 2962 if (!info) { 2963 PetscCall(MatFactorInfoInitialize(&tinfo)); 2964 info = &tinfo; 2965 } 2966 2967 PetscCall(PetscLogEventBegin(MAT_LUFactor, mat, row, col, 0)); 2968 PetscUseTypeMethod(mat, lufactor, row, col, info); 2969 PetscCall(PetscLogEventEnd(MAT_LUFactor, mat, row, col, 0)); 2970 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 2971 PetscFunctionReturn(0); 2972 } 2973 2974 /*@C 2975 MatILUFactor - Performs in-place ILU factorization of matrix. 2976 2977 Collective on mat 2978 2979 Input Parameters: 2980 + mat - the matrix 2981 . row - row permutation 2982 . col - column permutation 2983 - info - structure containing 2984 $ levels - number of levels of fill. 2985 $ expected fill - as ratio of original fill. 2986 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 2987 missing diagonal entries) 2988 2989 Notes: 2990 Most users should employ the `KSP` interface for linear solvers 2991 instead of working directly with matrix algebra routines such as this. 2992 See, e.g., `KSPCreate()`. 2993 2994 Probably really in-place only when level of fill is zero, otherwise allocates 2995 new space to store factored matrix and deletes previous memory. The prefered approach is to use `MatGetFactor()`, `MatILUFactorSymbolic()`, and `MatILUFactorNumeric()` 2996 when not using `KSP`. 2997 2998 Level: developer 2999 3000 Developer Note: 3001 The Fortran interface is not autogenerated as the f90 3002 interface definition cannot be generated correctly [due to MatFactorInfo] 3003 3004 .seealso: [Matrix Factorization](sec_matfactor), `MatILUFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()`, `MatFactorInfo` 3005 @*/ 3006 PetscErrorCode MatILUFactor(Mat mat, IS row, IS col, const MatFactorInfo *info) { 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 PetscValidPointer(info, 4); 3012 PetscValidType(mat, 1); 3013 PetscCheck(mat->rmap->N == mat->cmap->N, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONG, "matrix must be square"); 3014 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 3015 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 3016 MatCheckPreallocated(mat, 1); 3017 3018 PetscCall(PetscLogEventBegin(MAT_ILUFactor, mat, row, col, 0)); 3019 PetscUseTypeMethod(mat, ilufactor, row, col, info); 3020 PetscCall(PetscLogEventEnd(MAT_ILUFactor, mat, row, col, 0)); 3021 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 3022 PetscFunctionReturn(0); 3023 } 3024 3025 /*@C 3026 MatLUFactorSymbolic - Performs symbolic LU factorization of matrix. 3027 Call this routine before calling `MatLUFactorNumeric()` and after `MatGetFactor()`. 3028 3029 Collective on fact 3030 3031 Input Parameters: 3032 + fact - the factor matrix obtained with `MatGetFactor()` 3033 . mat - the matrix 3034 . row, col - row and column permutations 3035 - info - options for factorization, includes 3036 .vb 3037 fill - expected fill as ratio of original fill. Run with the option -info to determine an optimal value to use 3038 dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3039 .ve 3040 3041 Notes: 3042 See [Matrix Factorization](sec_matfactor) for additional information about factorizations 3043 3044 Most users should employ the simplified `KSP` interface for linear solvers 3045 instead of working directly with matrix algebra routines such as this. 3046 See, e.g., `KSPCreate()`. 3047 3048 Level: developer 3049 3050 Developer Note: 3051 The Fortran interface is not autogenerated as the f90 3052 interface definition cannot be generated correctly [due to `MatFactorInfo`] 3053 3054 .seealso: [Matrix Factorization](sec_matfactor), `MatGetFactor()`, `MatLUFactor()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()`, `MatFactorInfo`, `MatFactorInfoInitialize()` 3055 @*/ 3056 PetscErrorCode MatLUFactorSymbolic(Mat fact, Mat mat, IS row, IS col, const MatFactorInfo *info) { 3057 MatFactorInfo tinfo; 3058 3059 PetscFunctionBegin; 3060 PetscValidHeaderSpecific(mat, MAT_CLASSID, 2); 3061 if (row) PetscValidHeaderSpecific(row, IS_CLASSID, 3); 3062 if (col) PetscValidHeaderSpecific(col, IS_CLASSID, 4); 3063 if (info) PetscValidPointer(info, 5); 3064 PetscValidType(mat, 2); 3065 PetscValidPointer(fact, 1); 3066 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 3067 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 3068 if (!(fact)->ops->lufactorsymbolic) { 3069 MatSolverType stype; 3070 PetscCall(MatFactorGetSolverType(fact, &stype)); 3071 SETERRQ(PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Matrix type %s symbolic LU using solver package %s", ((PetscObject)mat)->type_name, stype); 3072 } 3073 MatCheckPreallocated(mat, 2); 3074 if (!info) { 3075 PetscCall(MatFactorInfoInitialize(&tinfo)); 3076 info = &tinfo; 3077 } 3078 3079 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_LUFactorSymbolic, mat, row, col, 0)); 3080 PetscCall((fact->ops->lufactorsymbolic)(fact, mat, row, col, info)); 3081 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_LUFactorSymbolic, mat, row, col, 0)); 3082 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3083 PetscFunctionReturn(0); 3084 } 3085 3086 /*@C 3087 MatLUFactorNumeric - Performs numeric LU factorization of a matrix. 3088 Call this routine after first calling `MatLUFactorSymbolic()` and `MatGetFactor()`. 3089 3090 Collective on fact 3091 3092 Input Parameters: 3093 + fact - the factor matrix obtained with `MatGetFactor()` 3094 . mat - the matrix 3095 - info - options for factorization 3096 3097 Notes: 3098 See `MatLUFactor()` for in-place factorization. See 3099 `MatCholeskyFactorNumeric()` for the symmetric, positive definite case. 3100 3101 Most users should employ the `KSP` interface for linear solvers 3102 instead of working directly with matrix algebra routines such as this. 3103 See, e.g., `KSPCreate()`. 3104 3105 Level: developer 3106 3107 Developer Note: 3108 The Fortran interface is not autogenerated as the f90 3109 interface definition cannot be generated correctly [due to `MatFactorInfo`] 3110 3111 .seealso: [Matrix Factorization](sec_matfactor), `MatGetFactor()`, `MatFactorInfo`, `MatLUFactorSymbolic()`, `MatLUFactor()`, `MatCholeskyFactor()` 3112 @*/ 3113 PetscErrorCode MatLUFactorNumeric(Mat fact, Mat mat, const MatFactorInfo *info) { 3114 MatFactorInfo tinfo; 3115 3116 PetscFunctionBegin; 3117 PetscValidHeaderSpecific(mat, MAT_CLASSID, 2); 3118 PetscValidType(mat, 2); 3119 PetscValidPointer(fact, 1); 3120 PetscValidHeaderSpecific(fact, MAT_CLASSID, 1); 3121 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 3122 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, 3123 mat->rmap->N, (fact)->rmap->N, mat->cmap->N, (fact)->cmap->N); 3124 3125 PetscCheck((fact)->ops->lufactornumeric, PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Mat type %s numeric LU", ((PetscObject)mat)->type_name); 3126 MatCheckPreallocated(mat, 2); 3127 if (!info) { 3128 PetscCall(MatFactorInfoInitialize(&tinfo)); 3129 info = &tinfo; 3130 } 3131 3132 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_LUFactorNumeric, mat, fact, 0, 0)); 3133 else PetscCall(PetscLogEventBegin(MAT_LUFactor, mat, fact, 0, 0)); 3134 PetscCall((fact->ops->lufactornumeric)(fact, mat, info)); 3135 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_LUFactorNumeric, mat, fact, 0, 0)); 3136 else PetscCall(PetscLogEventEnd(MAT_LUFactor, mat, fact, 0, 0)); 3137 PetscCall(MatViewFromOptions(fact, NULL, "-mat_factor_view")); 3138 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3139 PetscFunctionReturn(0); 3140 } 3141 3142 /*@C 3143 MatCholeskyFactor - Performs in-place Cholesky factorization of a 3144 symmetric matrix. 3145 3146 Collective on mat 3147 3148 Input Parameters: 3149 + mat - the matrix 3150 . perm - row and column permutations 3151 - f - expected fill as ratio of original fill 3152 3153 Notes: 3154 See `MatLUFactor()` for the nonsymmetric case. See also `MatGetFactor()`, 3155 `MatCholeskyFactorSymbolic()`, and `MatCholeskyFactorNumeric()`. 3156 3157 Most users should employ the `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 Developer Note: 3164 The Fortran interface is not autogenerated as the f90 3165 interface definition cannot be generated correctly [due to `MatFactorInfo`] 3166 3167 .seealso: [Matrix Factorization](sec_matfactor), `MatGetFactor()`, `MatFactorInfo`, `MatLUFactor()`, `MatCholeskyFactorSymbolic()`, `MatCholeskyFactorNumeric()` 3168 `MatGetOrdering()` 3169 @*/ 3170 PetscErrorCode MatCholeskyFactor(Mat mat, IS perm, const MatFactorInfo *info) { 3171 MatFactorInfo tinfo; 3172 3173 PetscFunctionBegin; 3174 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 3175 PetscValidType(mat, 1); 3176 if (perm) PetscValidHeaderSpecific(perm, IS_CLASSID, 2); 3177 if (info) PetscValidPointer(info, 3); 3178 PetscCheck(mat->rmap->N == mat->cmap->N, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONG, "Matrix must be square"); 3179 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 3180 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 3181 MatCheckPreallocated(mat, 1); 3182 if (!info) { 3183 PetscCall(MatFactorInfoInitialize(&tinfo)); 3184 info = &tinfo; 3185 } 3186 3187 PetscCall(PetscLogEventBegin(MAT_CholeskyFactor, mat, perm, 0, 0)); 3188 PetscUseTypeMethod(mat, choleskyfactor, perm, info); 3189 PetscCall(PetscLogEventEnd(MAT_CholeskyFactor, mat, perm, 0, 0)); 3190 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 3191 PetscFunctionReturn(0); 3192 } 3193 3194 /*@C 3195 MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization 3196 of a symmetric matrix. 3197 3198 Collective on fact 3199 3200 Input Parameters: 3201 + fact - the factor matrix obtained with `MatGetFactor()` 3202 . mat - the matrix 3203 . perm - row and column permutations 3204 - info - options for factorization, includes 3205 $ fill - expected fill as ratio of original fill. 3206 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3207 $ Run with the option -info to determine an optimal value to use 3208 3209 Notes: 3210 See `MatLUFactorSymbolic()` for the nonsymmetric case. See also 3211 `MatCholeskyFactor()` and `MatCholeskyFactorNumeric()`. 3212 3213 Most users should employ the `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 Developer Note: 3220 The Fortran interface is not autogenerated as the f90 3221 interface definition cannot be generated correctly [due to `MatFactorInfo`] 3222 3223 .seealso: [Matrix Factorization](sec_matfactor), `MatFactorInfo`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactor()`, `MatCholeskyFactorNumeric()` 3224 `MatGetOrdering()` 3225 @*/ 3226 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact, Mat mat, IS perm, const MatFactorInfo *info) { 3227 MatFactorInfo tinfo; 3228 3229 PetscFunctionBegin; 3230 PetscValidHeaderSpecific(mat, MAT_CLASSID, 2); 3231 PetscValidType(mat, 2); 3232 if (perm) PetscValidHeaderSpecific(perm, IS_CLASSID, 3); 3233 if (info) PetscValidPointer(info, 4); 3234 PetscValidPointer(fact, 1); 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 if (!(fact)->ops->choleskyfactorsymbolic) { 3239 MatSolverType stype; 3240 PetscCall(MatFactorGetSolverType(fact, &stype)); 3241 SETERRQ(PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Mat type %s symbolic factor Cholesky using solver package %s", ((PetscObject)mat)->type_name, stype); 3242 } 3243 MatCheckPreallocated(mat, 2); 3244 if (!info) { 3245 PetscCall(MatFactorInfoInitialize(&tinfo)); 3246 info = &tinfo; 3247 } 3248 3249 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_CholeskyFactorSymbolic, mat, perm, 0, 0)); 3250 PetscCall((fact->ops->choleskyfactorsymbolic)(fact, mat, perm, info)); 3251 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_CholeskyFactorSymbolic, mat, perm, 0, 0)); 3252 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3253 PetscFunctionReturn(0); 3254 } 3255 3256 /*@C 3257 MatCholeskyFactorNumeric - Performs numeric Cholesky factorization 3258 of a symmetric matrix. Call this routine after first calling `MatGetFactor()` and 3259 `MatCholeskyFactorSymbolic()`. 3260 3261 Collective on fact 3262 3263 Input Parameters: 3264 + fact - the factor matrix obtained with `MatGetFactor()` 3265 . mat - the initial matrix 3266 . info - options for factorization 3267 - fact - the symbolic factor of mat 3268 3269 Note: 3270 Most users should employ the `KSP` interface for linear solvers 3271 instead of working directly with matrix algebra routines such as this. 3272 See, e.g., `KSPCreate()`. 3273 3274 Level: developer 3275 3276 Developer Note: 3277 The Fortran interface is not autogenerated as the f90 3278 interface definition cannot be generated correctly [due to `MatFactorInfo`] 3279 3280 .seealso: [Matrix Factorization](sec_matfactor), `MatFactorInfo`, `MatGetFactor()`, `MatCholeskyFactorSymbolic()`, `MatCholeskyFactor()`, `MatLUFactorNumeric()` 3281 @*/ 3282 PetscErrorCode MatCholeskyFactorNumeric(Mat fact, Mat mat, const MatFactorInfo *info) { 3283 MatFactorInfo tinfo; 3284 3285 PetscFunctionBegin; 3286 PetscValidHeaderSpecific(mat, MAT_CLASSID, 2); 3287 PetscValidType(mat, 2); 3288 PetscValidPointer(fact, 1); 3289 PetscValidHeaderSpecific(fact, MAT_CLASSID, 1); 3290 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 3291 PetscCheck((fact)->ops->choleskyfactornumeric, PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Mat type %s numeric factor Cholesky", ((PetscObject)mat)->type_name); 3292 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, 3293 mat->rmap->N, (fact)->rmap->N, mat->cmap->N, (fact)->cmap->N); 3294 MatCheckPreallocated(mat, 2); 3295 if (!info) { 3296 PetscCall(MatFactorInfoInitialize(&tinfo)); 3297 info = &tinfo; 3298 } 3299 3300 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_CholeskyFactorNumeric, mat, fact, 0, 0)); 3301 else PetscCall(PetscLogEventBegin(MAT_CholeskyFactor, mat, fact, 0, 0)); 3302 PetscCall((fact->ops->choleskyfactornumeric)(fact, mat, info)); 3303 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_CholeskyFactorNumeric, mat, fact, 0, 0)); 3304 else PetscCall(PetscLogEventEnd(MAT_CholeskyFactor, mat, fact, 0, 0)); 3305 PetscCall(MatViewFromOptions(fact, NULL, "-mat_factor_view")); 3306 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3307 PetscFunctionReturn(0); 3308 } 3309 3310 /*@ 3311 MatQRFactor - Performs in-place QR factorization of matrix. 3312 3313 Collective on mat 3314 3315 Input Parameters: 3316 + mat - the matrix 3317 . col - column permutation 3318 - info - options for factorization, includes 3319 $ fill - expected fill as ratio of original fill. 3320 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3321 $ Run with the option -info to determine an optimal value to use 3322 3323 Notes: 3324 Most users should employ the `KSP` interface for linear solvers 3325 instead of working directly with matrix algebra routines such as this. 3326 See, e.g., `KSPCreate()`. 3327 3328 This changes the state of the matrix to a factored matrix; it cannot be used 3329 for example with `MatSetValues()` unless one first calls `MatSetUnfactored()`. 3330 3331 Level: developer 3332 3333 Developer Note: 3334 The Fortran interface is not autogenerated as the f90 3335 interface definition cannot be generated correctly [due to MatFactorInfo] 3336 3337 .seealso: [Matrix Factorization](sec_matfactor), `MatFactorInfo`, `MatGetFactor()`, `MatQRFactorSymbolic()`, `MatQRFactorNumeric()`, `MatLUFactor()`, 3338 `MatSetUnfactored()`, `MatFactorInfo`, `MatGetFactor()` 3339 @*/ 3340 PetscErrorCode MatQRFactor(Mat mat, IS col, const MatFactorInfo *info) { 3341 PetscFunctionBegin; 3342 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 3343 if (col) PetscValidHeaderSpecific(col, IS_CLASSID, 2); 3344 if (info) PetscValidPointer(info, 3); 3345 PetscValidType(mat, 1); 3346 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 3347 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 3348 MatCheckPreallocated(mat, 1); 3349 PetscCall(PetscLogEventBegin(MAT_QRFactor, mat, col, 0, 0)); 3350 PetscUseMethod(mat, "MatQRFactor_C", (Mat, IS, const MatFactorInfo *), (mat, col, info)); 3351 PetscCall(PetscLogEventEnd(MAT_QRFactor, mat, col, 0, 0)); 3352 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 3353 PetscFunctionReturn(0); 3354 } 3355 3356 /*@ 3357 MatQRFactorSymbolic - Performs symbolic QR factorization of matrix. 3358 Call this routine after `MatGetFactor()` but before calling `MatQRFactorNumeric()`. 3359 3360 Collective on fact 3361 3362 Input Parameters: 3363 + fact - the factor matrix obtained with `MatGetFactor()` 3364 . mat - the matrix 3365 . col - column permutation 3366 - info - options for factorization, includes 3367 $ fill - expected fill as ratio of original fill. 3368 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3369 $ Run with the option -info to determine an optimal value to use 3370 3371 Most users should employ the `KSP` interface for linear solvers 3372 instead of working directly with matrix algebra routines such as this. 3373 See, e.g., `KSPCreate()`. 3374 3375 Level: developer 3376 3377 Developer Note: 3378 The Fortran interface is not autogenerated as the f90 3379 interface definition cannot be generated correctly [due to `MatFactorInfo`] 3380 3381 .seealso: [Matrix Factorization](sec_matfactor), `MatGetFactor()`, `MatFactorInfo`, `MatQRFactor()`, `MatQRFactorNumeric()`, `MatLUFactor()`, `MatFactorInfo`, `MatFactorInfoInitialize()` 3382 @*/ 3383 PetscErrorCode MatQRFactorSymbolic(Mat fact, Mat mat, IS col, const MatFactorInfo *info) { 3384 MatFactorInfo tinfo; 3385 3386 PetscFunctionBegin; 3387 PetscValidHeaderSpecific(mat, MAT_CLASSID, 2); 3388 if (col) PetscValidHeaderSpecific(col, IS_CLASSID, 3); 3389 if (info) PetscValidPointer(info, 4); 3390 PetscValidType(mat, 2); 3391 PetscValidPointer(fact, 1); 3392 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 3393 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 3394 MatCheckPreallocated(mat, 2); 3395 if (!info) { 3396 PetscCall(MatFactorInfoInitialize(&tinfo)); 3397 info = &tinfo; 3398 } 3399 3400 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_QRFactorSymbolic, fact, mat, col, 0)); 3401 PetscUseMethod(fact, "MatQRFactorSymbolic_C", (Mat, Mat, IS, const MatFactorInfo *), (fact, mat, col, info)); 3402 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_QRFactorSymbolic, fact, mat, col, 0)); 3403 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3404 PetscFunctionReturn(0); 3405 } 3406 3407 /*@ 3408 MatQRFactorNumeric - Performs numeric QR factorization of a matrix. 3409 Call this routine after first calling `MatGetFactor()`, and `MatQRFactorSymbolic()`. 3410 3411 Collective on fact 3412 3413 Input Parameters: 3414 + fact - the factor matrix obtained with `MatGetFactor()` 3415 . mat - the matrix 3416 - info - options for factorization 3417 3418 Notes: 3419 See `MatQRFactor()` for in-place factorization. 3420 3421 Most users should employ the `KSP` interface for linear solvers 3422 instead of working directly with matrix algebra routines such as this. 3423 See, e.g., `KSPCreate()`. 3424 3425 Level: developer 3426 3427 Developer Note: 3428 The Fortran interface is not autogenerated as the f90 3429 interface definition cannot be generated correctly [due to `MatFactorInfo`] 3430 3431 .seealso: [Matrix Factorization](sec_matfactor), `MatFactorInfo`, `MatGetFactor()`, `MatQRFactor()`, `MatQRFactorSymbolic()`, `MatLUFactor()` 3432 @*/ 3433 PetscErrorCode MatQRFactorNumeric(Mat fact, Mat mat, const MatFactorInfo *info) { 3434 MatFactorInfo tinfo; 3435 3436 PetscFunctionBegin; 3437 PetscValidHeaderSpecific(mat, MAT_CLASSID, 2); 3438 PetscValidType(mat, 2); 3439 PetscValidPointer(fact, 1); 3440 PetscValidHeaderSpecific(fact, MAT_CLASSID, 1); 3441 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 3442 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, 3443 mat->rmap->N, (fact)->rmap->N, mat->cmap->N, (fact)->cmap->N); 3444 3445 MatCheckPreallocated(mat, 2); 3446 if (!info) { 3447 PetscCall(MatFactorInfoInitialize(&tinfo)); 3448 info = &tinfo; 3449 } 3450 3451 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_QRFactorNumeric, mat, fact, 0, 0)); 3452 else PetscCall(PetscLogEventBegin(MAT_QRFactor, mat, fact, 0, 0)); 3453 PetscUseMethod(fact, "MatQRFactorNumeric_C", (Mat, Mat, const MatFactorInfo *), (fact, mat, info)); 3454 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_QRFactorNumeric, mat, fact, 0, 0)); 3455 else PetscCall(PetscLogEventEnd(MAT_QRFactor, mat, fact, 0, 0)); 3456 PetscCall(MatViewFromOptions(fact, NULL, "-mat_factor_view")); 3457 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3458 PetscFunctionReturn(0); 3459 } 3460 3461 /* ----------------------------------------------------------------*/ 3462 /*@ 3463 MatSolve - Solves A x = b, given a factored matrix. 3464 3465 Neighbor-wise Collective on mat 3466 3467 Input Parameters: 3468 + mat - the factored matrix 3469 - b - the right-hand-side vector 3470 3471 Output Parameter: 3472 . x - the result vector 3473 3474 Notes: 3475 The vectors b and x cannot be the same. I.e., one cannot 3476 call `MatSolve`(A,x,x). 3477 3478 Most users should employ the `KSP` interface for linear solvers 3479 instead of working directly with matrix algebra routines such as this. 3480 See, e.g., `KSPCreate()`. 3481 3482 Level: developer 3483 3484 .seealso: [Matrix Factorization](sec_matfactor), `MatGetFactor()`, `MatLUFactor()`, `MatSolveAdd()`, `MatSolveTranspose()`, `MatSolveTransposeAdd()` 3485 @*/ 3486 PetscErrorCode MatSolve(Mat mat, Vec b, Vec x) { 3487 PetscFunctionBegin; 3488 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 3489 PetscValidType(mat, 1); 3490 PetscValidHeaderSpecific(b, VEC_CLASSID, 2); 3491 PetscValidHeaderSpecific(x, VEC_CLASSID, 3); 3492 PetscCheckSameComm(mat, 1, b, 2); 3493 PetscCheckSameComm(mat, 1, x, 3); 3494 PetscCheck(x != b, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_IDN, "x and b must be different vectors"); 3495 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); 3496 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); 3497 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); 3498 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3499 MatCheckPreallocated(mat, 1); 3500 3501 PetscCall(PetscLogEventBegin(MAT_Solve, mat, b, x, 0)); 3502 if (mat->factorerrortype) { 3503 PetscCall(PetscInfo(mat, "MatFactorError %d\n", mat->factorerrortype)); 3504 PetscCall(VecSetInf(x)); 3505 } else PetscUseTypeMethod(mat, solve, b, x); 3506 PetscCall(PetscLogEventEnd(MAT_Solve, mat, b, x, 0)); 3507 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3508 PetscFunctionReturn(0); 3509 } 3510 3511 static PetscErrorCode MatMatSolve_Basic(Mat A, Mat B, Mat X, PetscBool trans) { 3512 Vec b, x; 3513 PetscInt N, i; 3514 PetscErrorCode (*f)(Mat, Vec, Vec); 3515 PetscBool Abound, Bneedconv = PETSC_FALSE, Xneedconv = PETSC_FALSE; 3516 3517 PetscFunctionBegin; 3518 if (A->factorerrortype) { 3519 PetscCall(PetscInfo(A, "MatFactorError %d\n", A->factorerrortype)); 3520 PetscCall(MatSetInf(X)); 3521 PetscFunctionReturn(0); 3522 } 3523 f = (!trans || (!A->ops->solvetranspose && A->symmetric)) ? A->ops->solve : A->ops->solvetranspose; 3524 PetscCheck(f, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Mat type %s", ((PetscObject)A)->type_name); 3525 PetscCall(MatBoundToCPU(A, &Abound)); 3526 if (!Abound) { 3527 PetscCall(PetscObjectTypeCompareAny((PetscObject)B, &Bneedconv, MATSEQDENSE, MATMPIDENSE, "")); 3528 PetscCall(PetscObjectTypeCompareAny((PetscObject)X, &Xneedconv, MATSEQDENSE, MATMPIDENSE, "")); 3529 } 3530 if (Bneedconv) PetscCall(MatConvert(B, MATDENSECUDA, MAT_INPLACE_MATRIX, &B)); 3531 if (Xneedconv) PetscCall(MatConvert(X, MATDENSECUDA, MAT_INPLACE_MATRIX, &X)); 3532 PetscCall(MatGetSize(B, NULL, &N)); 3533 for (i = 0; i < N; i++) { 3534 PetscCall(MatDenseGetColumnVecRead(B, i, &b)); 3535 PetscCall(MatDenseGetColumnVecWrite(X, i, &x)); 3536 PetscCall((*f)(A, b, x)); 3537 PetscCall(MatDenseRestoreColumnVecWrite(X, i, &x)); 3538 PetscCall(MatDenseRestoreColumnVecRead(B, i, &b)); 3539 } 3540 if (Bneedconv) PetscCall(MatConvert(B, MATDENSE, MAT_INPLACE_MATRIX, &B)); 3541 if (Xneedconv) PetscCall(MatConvert(X, MATDENSE, MAT_INPLACE_MATRIX, &X)); 3542 PetscFunctionReturn(0); 3543 } 3544 3545 /*@ 3546 MatMatSolve - Solves A X = B, given a factored matrix. 3547 3548 Neighbor-wise Collective on A 3549 3550 Input Parameters: 3551 + A - the factored matrix 3552 - B - the right-hand-side matrix `MATDENSE` (or sparse `MATAIJ`-- when using MUMPS) 3553 3554 Output Parameter: 3555 . X - the result matrix (dense matrix) 3556 3557 Note: 3558 If B is a `MATDENSE` matrix then one can call `MatMatSolve`(A,B,B) except with MKL_CPARDISO; 3559 otherwise, B and X cannot be the same. 3560 3561 Level: developer 3562 3563 .seealso: [Matrix Factorization](sec_matfactor), `MatGetFactor()`, `MatSolve()`, `MatMatSolveTranspose()`, `MatLUFactor()`, `MatCholeskyFactor()` 3564 @*/ 3565 PetscErrorCode MatMatSolve(Mat A, Mat B, Mat X) { 3566 PetscFunctionBegin; 3567 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 3568 PetscValidType(A, 1); 3569 PetscValidHeaderSpecific(B, MAT_CLASSID, 2); 3570 PetscValidHeaderSpecific(X, MAT_CLASSID, 3); 3571 PetscCheckSameComm(A, 1, B, 2); 3572 PetscCheckSameComm(A, 1, X, 3); 3573 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); 3574 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); 3575 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"); 3576 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3577 PetscCheck(A->factortype, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Unfactored matrix"); 3578 MatCheckPreallocated(A, 1); 3579 3580 PetscCall(PetscLogEventBegin(MAT_MatSolve, A, B, X, 0)); 3581 if (!A->ops->matsolve) { 3582 PetscCall(PetscInfo(A, "Mat type %s using basic MatMatSolve\n", ((PetscObject)A)->type_name)); 3583 PetscCall(MatMatSolve_Basic(A, B, X, PETSC_FALSE)); 3584 } else PetscUseTypeMethod(A, matsolve, B, X); 3585 PetscCall(PetscLogEventEnd(MAT_MatSolve, A, B, X, 0)); 3586 PetscCall(PetscObjectStateIncrease((PetscObject)X)); 3587 PetscFunctionReturn(0); 3588 } 3589 3590 /*@ 3591 MatMatSolveTranspose - Solves A^T X = B, given a factored matrix. 3592 3593 Neighbor-wise Collective on A 3594 3595 Input Parameters: 3596 + A - the factored matrix 3597 - B - the right-hand-side matrix (`MATDENSE` matrix) 3598 3599 Output Parameter: 3600 . X - the result matrix (dense matrix) 3601 3602 Note: 3603 The matrices B and X cannot be the same. I.e., one cannot 3604 call `MatMatSolveTranspose`(A,X,X). 3605 3606 Level: developer 3607 3608 .seealso: [Matrix Factorization](sec_matfactor), `MatGetFactor()`, `MatSolveTranspose()`, `MatMatSolve()`, `MatLUFactor()`, `MatCholeskyFactor()` 3609 @*/ 3610 PetscErrorCode MatMatSolveTranspose(Mat A, Mat B, Mat X) { 3611 PetscFunctionBegin; 3612 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 3613 PetscValidType(A, 1); 3614 PetscValidHeaderSpecific(B, MAT_CLASSID, 2); 3615 PetscValidHeaderSpecific(X, MAT_CLASSID, 3); 3616 PetscCheckSameComm(A, 1, B, 2); 3617 PetscCheckSameComm(A, 1, X, 3); 3618 PetscCheck(X != B, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_IDN, "X and B must be different matrices"); 3619 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); 3620 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); 3621 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); 3622 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"); 3623 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3624 PetscCheck(A->factortype, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Unfactored matrix"); 3625 MatCheckPreallocated(A, 1); 3626 3627 PetscCall(PetscLogEventBegin(MAT_MatSolve, A, B, X, 0)); 3628 if (!A->ops->matsolvetranspose) { 3629 PetscCall(PetscInfo(A, "Mat type %s using basic MatMatSolveTranspose\n", ((PetscObject)A)->type_name)); 3630 PetscCall(MatMatSolve_Basic(A, B, X, PETSC_TRUE)); 3631 } else PetscUseTypeMethod(A, matsolvetranspose, B, X); 3632 PetscCall(PetscLogEventEnd(MAT_MatSolve, A, B, X, 0)); 3633 PetscCall(PetscObjectStateIncrease((PetscObject)X)); 3634 PetscFunctionReturn(0); 3635 } 3636 3637 /*@ 3638 MatMatTransposeSolve - Solves A X = B^T, given a factored matrix. 3639 3640 Neighbor-wise Collective on A 3641 3642 Input Parameters: 3643 + A - the factored matrix 3644 - Bt - the transpose of right-hand-side matrix as a `MATDENSE` 3645 3646 Output Parameter: 3647 . X - the result matrix (dense matrix) 3648 3649 Note: 3650 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 3651 format on the host processor and call `MatMatTransposeSolve()` to implement MUMPS' `MatMatSolve()`. 3652 3653 Level: developer 3654 3655 .seealso: [Matrix Factorization](sec_matfactor), `MatMatSolve()`, `MatMatSolveTranspose()`, `MatLUFactor()`, `MatCholeskyFactor()` 3656 @*/ 3657 PetscErrorCode MatMatTransposeSolve(Mat A, Mat Bt, Mat X) { 3658 PetscFunctionBegin; 3659 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 3660 PetscValidType(A, 1); 3661 PetscValidHeaderSpecific(Bt, MAT_CLASSID, 2); 3662 PetscValidHeaderSpecific(X, MAT_CLASSID, 3); 3663 PetscCheckSameComm(A, 1, Bt, 2); 3664 PetscCheckSameComm(A, 1, X, 3); 3665 3666 PetscCheck(X != Bt, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_IDN, "X and B must be different matrices"); 3667 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); 3668 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); 3669 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"); 3670 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3671 PetscCheck(A->factortype, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Unfactored matrix"); 3672 MatCheckPreallocated(A, 1); 3673 3674 PetscCall(PetscLogEventBegin(MAT_MatTrSolve, A, Bt, X, 0)); 3675 PetscUseTypeMethod(A, mattransposesolve, Bt, X); 3676 PetscCall(PetscLogEventEnd(MAT_MatTrSolve, A, Bt, X, 0)); 3677 PetscCall(PetscObjectStateIncrease((PetscObject)X)); 3678 PetscFunctionReturn(0); 3679 } 3680 3681 /*@ 3682 MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or 3683 U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U, 3684 3685 Neighbor-wise Collective on mat 3686 3687 Input Parameters: 3688 + mat - the factored matrix 3689 - b - the right-hand-side vector 3690 3691 Output Parameter: 3692 . x - the result vector 3693 3694 Notes: 3695 `MatSolve()` should be used for most applications, as it performs 3696 a forward solve followed by a backward solve. 3697 3698 The vectors b and x cannot be the same, i.e., one cannot 3699 call `MatForwardSolve`(A,x,x). 3700 3701 For matrix in `MATSEQBAIJ` format with block size larger than 1, 3702 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3703 `MatForwardSolve()` solves U^T*D y = b, and 3704 `MatBackwardSolve()` solves U x = y. 3705 Thus they do not provide a symmetric preconditioner. 3706 3707 Level: developer 3708 3709 .seealso: `MatBackwardSolve()`, `MatGetFactor()`, `MatSolve()`, `MatBackwardSolve()` 3710 @*/ 3711 PetscErrorCode MatForwardSolve(Mat mat, Vec b, Vec x) { 3712 PetscFunctionBegin; 3713 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 3714 PetscValidType(mat, 1); 3715 PetscValidHeaderSpecific(b, VEC_CLASSID, 2); 3716 PetscValidHeaderSpecific(x, VEC_CLASSID, 3); 3717 PetscCheckSameComm(mat, 1, b, 2); 3718 PetscCheckSameComm(mat, 1, x, 3); 3719 PetscCheck(x != b, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_IDN, "x and b must be different vectors"); 3720 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); 3721 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); 3722 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); 3723 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3724 MatCheckPreallocated(mat, 1); 3725 3726 PetscCall(PetscLogEventBegin(MAT_ForwardSolve, mat, b, x, 0)); 3727 PetscUseTypeMethod(mat, forwardsolve, b, x); 3728 PetscCall(PetscLogEventEnd(MAT_ForwardSolve, mat, b, x, 0)); 3729 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3730 PetscFunctionReturn(0); 3731 } 3732 3733 /*@ 3734 MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU. 3735 D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U, 3736 3737 Neighbor-wise Collective on mat 3738 3739 Input Parameters: 3740 + mat - the factored matrix 3741 - b - the right-hand-side vector 3742 3743 Output Parameter: 3744 . x - the result vector 3745 3746 Notes: 3747 `MatSolve()` should be used for most applications, as it performs 3748 a forward solve followed by a backward solve. 3749 3750 The vectors b and x cannot be the same. I.e., one cannot 3751 call `MatBackwardSolve`(A,x,x). 3752 3753 For matrix in `MATSEQBAIJ` format with block size larger than 1, 3754 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3755 `MatForwardSolve()` solves U^T*D y = b, and 3756 `MatBackwardSolve()` solves U x = y. 3757 Thus they do not provide a symmetric preconditioner. 3758 3759 Level: developer 3760 3761 .seealso: `MatForwardSolve()`, `MatGetFactor()`, `MatSolve()`, `MatForwardSolve()` 3762 @*/ 3763 PetscErrorCode MatBackwardSolve(Mat mat, Vec b, Vec x) { 3764 PetscFunctionBegin; 3765 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 3766 PetscValidType(mat, 1); 3767 PetscValidHeaderSpecific(b, VEC_CLASSID, 2); 3768 PetscValidHeaderSpecific(x, VEC_CLASSID, 3); 3769 PetscCheckSameComm(mat, 1, b, 2); 3770 PetscCheckSameComm(mat, 1, x, 3); 3771 PetscCheck(x != b, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_IDN, "x and b must be different vectors"); 3772 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); 3773 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); 3774 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); 3775 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3776 MatCheckPreallocated(mat, 1); 3777 3778 PetscCall(PetscLogEventBegin(MAT_BackwardSolve, mat, b, x, 0)); 3779 PetscUseTypeMethod(mat, backwardsolve, b, x); 3780 PetscCall(PetscLogEventEnd(MAT_BackwardSolve, mat, b, x, 0)); 3781 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3782 PetscFunctionReturn(0); 3783 } 3784 3785 /*@ 3786 MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix. 3787 3788 Neighbor-wise Collective on mat 3789 3790 Input Parameters: 3791 + mat - the factored matrix 3792 . b - the right-hand-side vector 3793 - y - the vector to be added to 3794 3795 Output Parameter: 3796 . x - the result vector 3797 3798 Note: 3799 The vectors b and x cannot be the same. I.e., one cannot 3800 call `MatSolveAdd`(A,x,y,x). 3801 3802 Level: developer 3803 3804 .seealso: [Matrix Factorization](sec_matfactor), `MatSolve()`, `MatGetFactor()`, `MatSolveTranspose()`, `MatSolveTransposeAdd()` 3805 @*/ 3806 PetscErrorCode MatSolveAdd(Mat mat, Vec b, Vec y, Vec x) { 3807 PetscScalar one = 1.0; 3808 Vec tmp; 3809 3810 PetscFunctionBegin; 3811 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 3812 PetscValidType(mat, 1); 3813 PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 3814 PetscValidHeaderSpecific(b, VEC_CLASSID, 2); 3815 PetscValidHeaderSpecific(x, VEC_CLASSID, 4); 3816 PetscCheckSameComm(mat, 1, b, 2); 3817 PetscCheckSameComm(mat, 1, y, 3); 3818 PetscCheckSameComm(mat, 1, x, 4); 3819 PetscCheck(x != b, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_IDN, "x and b must be different vectors"); 3820 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); 3821 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); 3822 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); 3823 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); 3824 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); 3825 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3826 MatCheckPreallocated(mat, 1); 3827 3828 PetscCall(PetscLogEventBegin(MAT_SolveAdd, mat, b, x, y)); 3829 if (mat->factorerrortype) { 3830 PetscCall(PetscInfo(mat, "MatFactorError %d\n", mat->factorerrortype)); 3831 PetscCall(VecSetInf(x)); 3832 } else if (mat->ops->solveadd) { 3833 PetscUseTypeMethod(mat, solveadd, b, y, x); 3834 } else { 3835 /* do the solve then the add manually */ 3836 if (x != y) { 3837 PetscCall(MatSolve(mat, b, x)); 3838 PetscCall(VecAXPY(x, one, y)); 3839 } else { 3840 PetscCall(VecDuplicate(x, &tmp)); 3841 PetscCall(VecCopy(x, tmp)); 3842 PetscCall(MatSolve(mat, b, x)); 3843 PetscCall(VecAXPY(x, one, tmp)); 3844 PetscCall(VecDestroy(&tmp)); 3845 } 3846 } 3847 PetscCall(PetscLogEventEnd(MAT_SolveAdd, mat, b, x, y)); 3848 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3849 PetscFunctionReturn(0); 3850 } 3851 3852 /*@ 3853 MatSolveTranspose - Solves A' x = b, given a factored matrix. 3854 3855 Neighbor-wise Collective on mat 3856 3857 Input Parameters: 3858 + mat - the factored matrix 3859 - b - the right-hand-side vector 3860 3861 Output Parameter: 3862 . x - the result vector 3863 3864 Notes: 3865 The vectors b and x cannot be the same. I.e., one cannot 3866 call `MatSolveTranspose`(A,x,x). 3867 3868 Most users should employ the `KSP` interface for linear solvers 3869 instead of working directly with matrix algebra routines such as this. 3870 See, e.g., `KSPCreate()`. 3871 3872 Level: developer 3873 3874 .seealso: `MatGetFactor()`, `KSP`, `MatSolve()`, `MatSolveAdd()`, `MatSolveTransposeAdd()` 3875 @*/ 3876 PetscErrorCode MatSolveTranspose(Mat mat, Vec b, Vec x) { 3877 PetscErrorCode (*f)(Mat, Vec, Vec) = (!mat->ops->solvetranspose && mat->symmetric) ? mat->ops->solve : mat->ops->solvetranspose; 3878 3879 PetscFunctionBegin; 3880 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 3881 PetscValidType(mat, 1); 3882 PetscValidHeaderSpecific(b, VEC_CLASSID, 2); 3883 PetscValidHeaderSpecific(x, VEC_CLASSID, 3); 3884 PetscCheckSameComm(mat, 1, b, 2); 3885 PetscCheckSameComm(mat, 1, x, 3); 3886 PetscCheck(x != b, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_IDN, "x and b must be different vectors"); 3887 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); 3888 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); 3889 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3890 MatCheckPreallocated(mat, 1); 3891 PetscCall(PetscLogEventBegin(MAT_SolveTranspose, mat, b, x, 0)); 3892 if (mat->factorerrortype) { 3893 PetscCall(PetscInfo(mat, "MatFactorError %d\n", mat->factorerrortype)); 3894 PetscCall(VecSetInf(x)); 3895 } else { 3896 PetscCheck(f, PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Matrix type %s", ((PetscObject)mat)->type_name); 3897 PetscCall((*f)(mat, b, x)); 3898 } 3899 PetscCall(PetscLogEventEnd(MAT_SolveTranspose, mat, b, x, 0)); 3900 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3901 PetscFunctionReturn(0); 3902 } 3903 3904 /*@ 3905 MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a 3906 factored matrix. 3907 3908 Neighbor-wise Collective on mat 3909 3910 Input Parameters: 3911 + mat - the factored matrix 3912 . b - the right-hand-side vector 3913 - y - the vector to be added to 3914 3915 Output Parameter: 3916 . x - the result vector 3917 3918 Note: 3919 The vectors b and x cannot be the same. I.e., one cannot 3920 call `MatSolveTransposeAdd`(A,x,y,x). 3921 3922 Level: developer 3923 3924 .seealso: `MatGetFactor()`, `MatSolve()`, `MatSolveAdd()`, `MatSolveTranspose()` 3925 @*/ 3926 PetscErrorCode MatSolveTransposeAdd(Mat mat, Vec b, Vec y, Vec x) { 3927 PetscScalar one = 1.0; 3928 Vec tmp; 3929 PetscErrorCode (*f)(Mat, Vec, Vec, Vec) = (!mat->ops->solvetransposeadd && mat->symmetric) ? mat->ops->solveadd : mat->ops->solvetransposeadd; 3930 3931 PetscFunctionBegin; 3932 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 3933 PetscValidType(mat, 1); 3934 PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 3935 PetscValidHeaderSpecific(b, VEC_CLASSID, 2); 3936 PetscValidHeaderSpecific(x, VEC_CLASSID, 4); 3937 PetscCheckSameComm(mat, 1, b, 2); 3938 PetscCheckSameComm(mat, 1, y, 3); 3939 PetscCheckSameComm(mat, 1, x, 4); 3940 PetscCheck(x != b, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_IDN, "x and b must be different vectors"); 3941 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); 3942 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); 3943 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); 3944 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); 3945 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3946 MatCheckPreallocated(mat, 1); 3947 3948 PetscCall(PetscLogEventBegin(MAT_SolveTransposeAdd, mat, b, x, y)); 3949 if (mat->factorerrortype) { 3950 PetscCall(PetscInfo(mat, "MatFactorError %d\n", mat->factorerrortype)); 3951 PetscCall(VecSetInf(x)); 3952 } else if (f) { 3953 PetscCall((*f)(mat, b, y, x)); 3954 } else { 3955 /* do the solve then the add manually */ 3956 if (x != y) { 3957 PetscCall(MatSolveTranspose(mat, b, x)); 3958 PetscCall(VecAXPY(x, one, y)); 3959 } else { 3960 PetscCall(VecDuplicate(x, &tmp)); 3961 PetscCall(VecCopy(x, tmp)); 3962 PetscCall(MatSolveTranspose(mat, b, x)); 3963 PetscCall(VecAXPY(x, one, tmp)); 3964 PetscCall(VecDestroy(&tmp)); 3965 } 3966 } 3967 PetscCall(PetscLogEventEnd(MAT_SolveTransposeAdd, mat, b, x, y)); 3968 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3969 PetscFunctionReturn(0); 3970 } 3971 /* ----------------------------------------------------------------*/ 3972 3973 /*@ 3974 MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps. 3975 3976 Neighbor-wise Collective on mat 3977 3978 Input Parameters: 3979 + mat - the matrix 3980 . b - the right hand side 3981 . omega - the relaxation factor 3982 . flag - flag indicating the type of SOR (see below) 3983 . shift - diagonal shift 3984 . its - the number of iterations 3985 - lits - the number of local iterations 3986 3987 Output Parameter: 3988 . x - the solution (can contain an initial guess, use option `SOR_ZERO_INITIAL_GUESS` to indicate no guess) 3989 3990 SOR Flags: 3991 + `SOR_FORWARD_SWEEP` - forward SOR 3992 . `SOR_BACKWARD_SWEEP` - backward SOR 3993 . `SOR_SYMMETRIC_SWEEP` - SSOR (symmetric SOR) 3994 . `SOR_LOCAL_FORWARD_SWEEP` - local forward SOR 3995 . `SOR_LOCAL_BACKWARD_SWEEP` - local forward SOR 3996 . `SOR_LOCAL_SYMMETRIC_SWEEP` - local SSOR 3997 . `SOR_EISENSTAT` - SOR with Eisenstat trick 3998 . `SOR_APPLY_UPPER`, `SOR_APPLY_LOWER` - applies 3999 upper/lower triangular part of matrix to 4000 vector (with omega) 4001 - `SOR_ZERO_INITIAL_GUESS` - zero initial guess 4002 4003 Notes: 4004 `SOR_LOCAL_FORWARD_SWEEP`, `SOR_LOCAL_BACKWARD_SWEEP`, and 4005 `SOR_LOCAL_SYMMETRIC_SWEEP` perform separate independent smoothings 4006 on each processor. 4007 4008 Application programmers will not generally use `MatSOR()` directly, 4009 but instead will employ the `KSP`/`PC` interface. 4010 4011 For `MATBAIJ`, `MATSBAIJ`, and `MATAIJ` matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing 4012 4013 Most users should employ the `KSP` interface for linear solvers 4014 instead of working directly with matrix algebra routines such as this. 4015 See, e.g., `KSPCreate()`. 4016 4017 Vectors x and b CANNOT be the same 4018 4019 Notes for Advanced Users: 4020 The flags are implemented as bitwise inclusive or operations. 4021 For example, use (`SOR_ZERO_INITIAL_GUESS` | `SOR_SYMMETRIC_SWEEP`) 4022 to specify a zero initial guess for SSOR. 4023 4024 Developer Note: 4025 We should add block SOR support for `MATAIJ` matrices with block size set to great than one and no inodes 4026 4027 Level: developer 4028 4029 .seealso: `Mat`, `MatMult()`, `KSP`, `PC`, `MatGetFactor()` 4030 @*/ 4031 PetscErrorCode MatSOR(Mat mat, Vec b, PetscReal omega, MatSORType flag, PetscReal shift, PetscInt its, PetscInt lits, Vec x) { 4032 PetscFunctionBegin; 4033 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4034 PetscValidType(mat, 1); 4035 PetscValidHeaderSpecific(b, VEC_CLASSID, 2); 4036 PetscValidHeaderSpecific(x, VEC_CLASSID, 8); 4037 PetscCheckSameComm(mat, 1, b, 2); 4038 PetscCheckSameComm(mat, 1, x, 8); 4039 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 4040 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 4041 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); 4042 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); 4043 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); 4044 PetscCheck(its > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Relaxation requires global its %" PetscInt_FMT " positive", its); 4045 PetscCheck(lits > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Relaxation requires local its %" PetscInt_FMT " positive", lits); 4046 PetscCheck(b != x, PETSC_COMM_SELF, PETSC_ERR_ARG_IDN, "b and x vector cannot be the same"); 4047 4048 MatCheckPreallocated(mat, 1); 4049 PetscCall(PetscLogEventBegin(MAT_SOR, mat, b, x, 0)); 4050 PetscUseTypeMethod(mat, sor, b, omega, flag, shift, its, lits, x); 4051 PetscCall(PetscLogEventEnd(MAT_SOR, mat, b, x, 0)); 4052 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 4053 PetscFunctionReturn(0); 4054 } 4055 4056 /* 4057 Default matrix copy routine. 4058 */ 4059 PetscErrorCode MatCopy_Basic(Mat A, Mat B, MatStructure str) { 4060 PetscInt i, rstart = 0, rend = 0, nz; 4061 const PetscInt *cwork; 4062 const PetscScalar *vwork; 4063 4064 PetscFunctionBegin; 4065 if (B->assembled) PetscCall(MatZeroEntries(B)); 4066 if (str == SAME_NONZERO_PATTERN) { 4067 PetscCall(MatGetOwnershipRange(A, &rstart, &rend)); 4068 for (i = rstart; i < rend; i++) { 4069 PetscCall(MatGetRow(A, i, &nz, &cwork, &vwork)); 4070 PetscCall(MatSetValues(B, 1, &i, nz, cwork, vwork, INSERT_VALUES)); 4071 PetscCall(MatRestoreRow(A, i, &nz, &cwork, &vwork)); 4072 } 4073 } else { 4074 PetscCall(MatAYPX(B, 0.0, A, str)); 4075 } 4076 PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 4077 PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 4078 PetscFunctionReturn(0); 4079 } 4080 4081 /*@ 4082 MatCopy - Copies a matrix to another matrix. 4083 4084 Collective on A 4085 4086 Input Parameters: 4087 + A - the matrix 4088 - str - `SAME_NONZERO_PATTERN` or `DIFFERENT_NONZERO_PATTERN` 4089 4090 Output Parameter: 4091 . B - where the copy is put 4092 4093 Notes: 4094 If you use `SAME_NONZERO_PATTERN `then the two matrices must have the same nonzero pattern or the routine will crash. 4095 4096 `MatCopy()` copies the matrix entries of a matrix to another existing 4097 matrix (after first zeroing the second matrix). A related routine is 4098 `MatConvert()`, which first creates a new matrix and then copies the data. 4099 4100 Level: intermediate 4101 4102 .seealso: `Mat`, `MatConvert()`, `MatDuplicate()` 4103 @*/ 4104 PetscErrorCode MatCopy(Mat A, Mat B, MatStructure str) { 4105 PetscInt i; 4106 4107 PetscFunctionBegin; 4108 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 4109 PetscValidHeaderSpecific(B, MAT_CLASSID, 2); 4110 PetscValidType(A, 1); 4111 PetscValidType(B, 2); 4112 PetscCheckSameComm(A, 1, B, 2); 4113 MatCheckPreallocated(B, 2); 4114 PetscCheck(A->assembled, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 4115 PetscCheck(!A->factortype, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 4116 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, 4117 A->cmap->N, B->cmap->N); 4118 MatCheckPreallocated(A, 1); 4119 if (A == B) PetscFunctionReturn(0); 4120 4121 PetscCall(PetscLogEventBegin(MAT_Copy, A, B, 0, 0)); 4122 if (A->ops->copy) PetscUseTypeMethod(A, copy, B, str); 4123 else PetscCall(MatCopy_Basic(A, B, str)); 4124 4125 B->stencil.dim = A->stencil.dim; 4126 B->stencil.noc = A->stencil.noc; 4127 for (i = 0; i <= A->stencil.dim; i++) { 4128 B->stencil.dims[i] = A->stencil.dims[i]; 4129 B->stencil.starts[i] = A->stencil.starts[i]; 4130 } 4131 4132 PetscCall(PetscLogEventEnd(MAT_Copy, A, B, 0, 0)); 4133 PetscCall(PetscObjectStateIncrease((PetscObject)B)); 4134 PetscFunctionReturn(0); 4135 } 4136 4137 /*@C 4138 MatConvert - Converts a matrix to another matrix, either of the same 4139 or different type. 4140 4141 Collective on mat 4142 4143 Input Parameters: 4144 + mat - the matrix 4145 . newtype - new matrix type. Use `MATSAME` to create a new matrix of the 4146 same type as the original matrix. 4147 - reuse - denotes if the destination matrix is to be created or reused. 4148 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 4149 `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). 4150 4151 Output Parameter: 4152 . M - pointer to place new matrix 4153 4154 Notes: 4155 `MatConvert()` first creates a new matrix and then copies the data from 4156 the first matrix. A related routine is `MatCopy()`, which copies the matrix 4157 entries of one matrix to another already existing matrix context. 4158 4159 Cannot be used to convert a sequential matrix to parallel or parallel to sequential, 4160 the MPI communicator of the generated matrix is always the same as the communicator 4161 of the input matrix. 4162 4163 Level: intermediate 4164 4165 .seealso: `Mat`, `MatCopy()`, `MatDuplicate()`, `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, `MAT_INPLACE_MATRIX` 4166 @*/ 4167 PetscErrorCode MatConvert(Mat mat, MatType newtype, MatReuse reuse, Mat *M) { 4168 PetscBool sametype, issame, flg; 4169 PetscBool3 issymmetric, ishermitian; 4170 char convname[256], mtype[256]; 4171 Mat B; 4172 4173 PetscFunctionBegin; 4174 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4175 PetscValidType(mat, 1); 4176 PetscValidPointer(M, 4); 4177 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 4178 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 4179 MatCheckPreallocated(mat, 1); 4180 4181 PetscCall(PetscOptionsGetString(((PetscObject)mat)->options, ((PetscObject)mat)->prefix, "-matconvert_type", mtype, sizeof(mtype), &flg)); 4182 if (flg) newtype = mtype; 4183 4184 PetscCall(PetscObjectTypeCompare((PetscObject)mat, newtype, &sametype)); 4185 PetscCall(PetscStrcmp(newtype, "same", &issame)); 4186 PetscCheck(!(reuse == MAT_INPLACE_MATRIX) || !(mat != *M), PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "MAT_INPLACE_MATRIX requires same input and output matrix"); 4187 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"); 4188 4189 if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) { 4190 PetscCall(PetscInfo(mat, "Early return for inplace %s %d %d\n", ((PetscObject)mat)->type_name, sametype, issame)); 4191 PetscFunctionReturn(0); 4192 } 4193 4194 /* Cache Mat options because some converters use MatHeaderReplace */ 4195 issymmetric = mat->symmetric; 4196 ishermitian = mat->hermitian; 4197 4198 if ((sametype || issame) && (reuse == MAT_INITIAL_MATRIX) && mat->ops->duplicate) { 4199 PetscCall(PetscInfo(mat, "Calling duplicate for initial matrix %s %d %d\n", ((PetscObject)mat)->type_name, sametype, issame)); 4200 PetscUseTypeMethod(mat, duplicate, MAT_COPY_VALUES, M); 4201 } else { 4202 PetscErrorCode (*conv)(Mat, MatType, MatReuse, Mat *) = NULL; 4203 const char *prefix[3] = {"seq", "mpi", ""}; 4204 PetscInt i; 4205 /* 4206 Order of precedence: 4207 0) See if newtype is a superclass of the current matrix. 4208 1) See if a specialized converter is known to the current matrix. 4209 2) See if a specialized converter is known to the desired matrix class. 4210 3) See if a good general converter is registered for the desired class 4211 (as of 6/27/03 only MATMPIADJ falls into this category). 4212 4) See if a good general converter is known for the current matrix. 4213 5) Use a really basic converter. 4214 */ 4215 4216 /* 0) See if newtype is a superclass of the current matrix. 4217 i.e mat is mpiaij and newtype is aij */ 4218 for (i = 0; i < 2; i++) { 4219 PetscCall(PetscStrncpy(convname, prefix[i], sizeof(convname))); 4220 PetscCall(PetscStrlcat(convname, newtype, sizeof(convname))); 4221 PetscCall(PetscStrcmp(convname, ((PetscObject)mat)->type_name, &flg)); 4222 PetscCall(PetscInfo(mat, "Check superclass %s %s -> %d\n", convname, ((PetscObject)mat)->type_name, flg)); 4223 if (flg) { 4224 if (reuse == MAT_INPLACE_MATRIX) { 4225 PetscCall(PetscInfo(mat, "Early return\n")); 4226 PetscFunctionReturn(0); 4227 } else if (reuse == MAT_INITIAL_MATRIX && mat->ops->duplicate) { 4228 PetscCall(PetscInfo(mat, "Calling MatDuplicate\n")); 4229 PetscUseTypeMethod(mat, duplicate, MAT_COPY_VALUES, M); 4230 PetscFunctionReturn(0); 4231 } else if (reuse == MAT_REUSE_MATRIX && mat->ops->copy) { 4232 PetscCall(PetscInfo(mat, "Calling MatCopy\n")); 4233 PetscCall(MatCopy(mat, *M, SAME_NONZERO_PATTERN)); 4234 PetscFunctionReturn(0); 4235 } 4236 } 4237 } 4238 /* 1) See if a specialized converter is known to the current matrix and the desired class */ 4239 for (i = 0; i < 3; i++) { 4240 PetscCall(PetscStrncpy(convname, "MatConvert_", sizeof(convname))); 4241 PetscCall(PetscStrlcat(convname, ((PetscObject)mat)->type_name, sizeof(convname))); 4242 PetscCall(PetscStrlcat(convname, "_", sizeof(convname))); 4243 PetscCall(PetscStrlcat(convname, prefix[i], sizeof(convname))); 4244 PetscCall(PetscStrlcat(convname, issame ? ((PetscObject)mat)->type_name : newtype, sizeof(convname))); 4245 PetscCall(PetscStrlcat(convname, "_C", sizeof(convname))); 4246 PetscCall(PetscObjectQueryFunction((PetscObject)mat, convname, &conv)); 4247 PetscCall(PetscInfo(mat, "Check specialized (1) %s (%s) -> %d\n", convname, ((PetscObject)mat)->type_name, !!conv)); 4248 if (conv) goto foundconv; 4249 } 4250 4251 /* 2) See if a specialized converter is known to the desired matrix class. */ 4252 PetscCall(MatCreate(PetscObjectComm((PetscObject)mat), &B)); 4253 PetscCall(MatSetSizes(B, mat->rmap->n, mat->cmap->n, mat->rmap->N, mat->cmap->N)); 4254 PetscCall(MatSetType(B, newtype)); 4255 for (i = 0; i < 3; i++) { 4256 PetscCall(PetscStrncpy(convname, "MatConvert_", sizeof(convname))); 4257 PetscCall(PetscStrlcat(convname, ((PetscObject)mat)->type_name, sizeof(convname))); 4258 PetscCall(PetscStrlcat(convname, "_", sizeof(convname))); 4259 PetscCall(PetscStrlcat(convname, prefix[i], sizeof(convname))); 4260 PetscCall(PetscStrlcat(convname, newtype, sizeof(convname))); 4261 PetscCall(PetscStrlcat(convname, "_C", sizeof(convname))); 4262 PetscCall(PetscObjectQueryFunction((PetscObject)B, convname, &conv)); 4263 PetscCall(PetscInfo(mat, "Check specialized (2) %s (%s) -> %d\n", convname, ((PetscObject)B)->type_name, !!conv)); 4264 if (conv) { 4265 PetscCall(MatDestroy(&B)); 4266 goto foundconv; 4267 } 4268 } 4269 4270 /* 3) See if a good general converter is registered for the desired class */ 4271 conv = B->ops->convertfrom; 4272 PetscCall(PetscInfo(mat, "Check convertfrom (%s) -> %d\n", ((PetscObject)B)->type_name, !!conv)); 4273 PetscCall(MatDestroy(&B)); 4274 if (conv) goto foundconv; 4275 4276 /* 4) See if a good general converter is known for the current matrix */ 4277 if (mat->ops->convert) conv = mat->ops->convert; 4278 PetscCall(PetscInfo(mat, "Check general convert (%s) -> %d\n", ((PetscObject)mat)->type_name, !!conv)); 4279 if (conv) goto foundconv; 4280 4281 /* 5) Use a really basic converter. */ 4282 PetscCall(PetscInfo(mat, "Using MatConvert_Basic\n")); 4283 conv = MatConvert_Basic; 4284 4285 foundconv: 4286 PetscCall(PetscLogEventBegin(MAT_Convert, mat, 0, 0, 0)); 4287 PetscCall((*conv)(mat, newtype, reuse, M)); 4288 if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) { 4289 /* the block sizes must be same if the mappings are copied over */ 4290 (*M)->rmap->bs = mat->rmap->bs; 4291 (*M)->cmap->bs = mat->cmap->bs; 4292 PetscCall(PetscObjectReference((PetscObject)mat->rmap->mapping)); 4293 PetscCall(PetscObjectReference((PetscObject)mat->cmap->mapping)); 4294 (*M)->rmap->mapping = mat->rmap->mapping; 4295 (*M)->cmap->mapping = mat->cmap->mapping; 4296 } 4297 (*M)->stencil.dim = mat->stencil.dim; 4298 (*M)->stencil.noc = mat->stencil.noc; 4299 for (i = 0; i <= mat->stencil.dim; i++) { 4300 (*M)->stencil.dims[i] = mat->stencil.dims[i]; 4301 (*M)->stencil.starts[i] = mat->stencil.starts[i]; 4302 } 4303 PetscCall(PetscLogEventEnd(MAT_Convert, mat, 0, 0, 0)); 4304 } 4305 PetscCall(PetscObjectStateIncrease((PetscObject)*M)); 4306 4307 /* Copy Mat options */ 4308 if (issymmetric == PETSC_BOOL3_TRUE) PetscCall(MatSetOption(*M, MAT_SYMMETRIC, PETSC_TRUE)); 4309 else if (issymmetric == PETSC_BOOL3_FALSE) PetscCall(MatSetOption(*M, MAT_SYMMETRIC, PETSC_FALSE)); 4310 if (ishermitian == PETSC_BOOL3_TRUE) PetscCall(MatSetOption(*M, MAT_HERMITIAN, PETSC_TRUE)); 4311 else if (ishermitian == PETSC_BOOL3_FALSE) PetscCall(MatSetOption(*M, MAT_HERMITIAN, PETSC_FALSE)); 4312 PetscFunctionReturn(0); 4313 } 4314 4315 /*@C 4316 MatFactorGetSolverType - Returns name of the package providing the factorization routines 4317 4318 Not Collective 4319 4320 Input Parameter: 4321 . mat - the matrix, must be a factored matrix 4322 4323 Output Parameter: 4324 . type - the string name of the package (do not free this string) 4325 4326 Note: 4327 In Fortran you pass in a empty string and the package name will be copied into it. 4328 (Make sure the string is long enough) 4329 4330 Level: intermediate 4331 4332 .seealso: [Matrix Factorization](sec_matfactor), `MatGetFactor()`, `MatSolverType`, `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()` 4333 @*/ 4334 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type) { 4335 PetscErrorCode (*conv)(Mat, MatSolverType *); 4336 4337 PetscFunctionBegin; 4338 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4339 PetscValidType(mat, 1); 4340 PetscValidPointer(type, 2); 4341 PetscCheck(mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Only for factored matrix"); 4342 PetscCall(PetscObjectQueryFunction((PetscObject)mat, "MatFactorGetSolverType_C", &conv)); 4343 if (conv) PetscCall((*conv)(mat, type)); 4344 else *type = MATSOLVERPETSC; 4345 PetscFunctionReturn(0); 4346 } 4347 4348 typedef struct _MatSolverTypeForSpecifcType *MatSolverTypeForSpecifcType; 4349 struct _MatSolverTypeForSpecifcType { 4350 MatType mtype; 4351 /* no entry for MAT_FACTOR_NONE */ 4352 PetscErrorCode (*createfactor[MAT_FACTOR_NUM_TYPES - 1])(Mat, MatFactorType, Mat *); 4353 MatSolverTypeForSpecifcType next; 4354 }; 4355 4356 typedef struct _MatSolverTypeHolder *MatSolverTypeHolder; 4357 struct _MatSolverTypeHolder { 4358 char *name; 4359 MatSolverTypeForSpecifcType handlers; 4360 MatSolverTypeHolder next; 4361 }; 4362 4363 static MatSolverTypeHolder MatSolverTypeHolders = NULL; 4364 4365 /*@C 4366 MatSolverTypeRegister - Registers a `MatSolverType` that works for a particular matrix type 4367 4368 Input Parameters: 4369 + package - name of the package, for example petsc or superlu 4370 . mtype - the matrix type that works with this package 4371 . ftype - the type of factorization supported by the package 4372 - createfactor - routine that will create the factored matrix ready to be used 4373 4374 Level: developer 4375 4376 .seealso: [Matrix Factorization](sec_matfactor), `MatFactorGetSolverType()`, `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()` 4377 @*/ 4378 PetscErrorCode MatSolverTypeRegister(MatSolverType package, MatType mtype, MatFactorType ftype, PetscErrorCode (*createfactor)(Mat, MatFactorType, Mat *)) { 4379 MatSolverTypeHolder next = MatSolverTypeHolders, prev = NULL; 4380 PetscBool flg; 4381 MatSolverTypeForSpecifcType inext, iprev = NULL; 4382 4383 PetscFunctionBegin; 4384 PetscCall(MatInitializePackage()); 4385 if (!next) { 4386 PetscCall(PetscNew(&MatSolverTypeHolders)); 4387 PetscCall(PetscStrallocpy(package, &MatSolverTypeHolders->name)); 4388 PetscCall(PetscNew(&MatSolverTypeHolders->handlers)); 4389 PetscCall(PetscStrallocpy(mtype, (char **)&MatSolverTypeHolders->handlers->mtype)); 4390 MatSolverTypeHolders->handlers->createfactor[(int)ftype - 1] = createfactor; 4391 PetscFunctionReturn(0); 4392 } 4393 while (next) { 4394 PetscCall(PetscStrcasecmp(package, next->name, &flg)); 4395 if (flg) { 4396 PetscCheck(next->handlers, PETSC_COMM_SELF, PETSC_ERR_PLIB, "MatSolverTypeHolder is missing handlers"); 4397 inext = next->handlers; 4398 while (inext) { 4399 PetscCall(PetscStrcasecmp(mtype, inext->mtype, &flg)); 4400 if (flg) { 4401 inext->createfactor[(int)ftype - 1] = createfactor; 4402 PetscFunctionReturn(0); 4403 } 4404 iprev = inext; 4405 inext = inext->next; 4406 } 4407 PetscCall(PetscNew(&iprev->next)); 4408 PetscCall(PetscStrallocpy(mtype, (char **)&iprev->next->mtype)); 4409 iprev->next->createfactor[(int)ftype - 1] = createfactor; 4410 PetscFunctionReturn(0); 4411 } 4412 prev = next; 4413 next = next->next; 4414 } 4415 PetscCall(PetscNew(&prev->next)); 4416 PetscCall(PetscStrallocpy(package, &prev->next->name)); 4417 PetscCall(PetscNew(&prev->next->handlers)); 4418 PetscCall(PetscStrallocpy(mtype, (char **)&prev->next->handlers->mtype)); 4419 prev->next->handlers->createfactor[(int)ftype - 1] = createfactor; 4420 PetscFunctionReturn(0); 4421 } 4422 4423 /*@C 4424 MatSolverTypeGet - Gets the function that creates the factor matrix if it exist 4425 4426 Input Parameters: 4427 + type - name of the package, for example petsc or superlu 4428 . ftype - the type of factorization supported by the type 4429 - mtype - the matrix type that works with this type 4430 4431 Output Parameters: 4432 + foundtype - `PETSC_TRUE` if the type was registered 4433 . foundmtype - `PETSC_TRUE` if the type supports the requested mtype 4434 - createfactor - routine that will create the factored matrix ready to be used or NULL if not found 4435 4436 Level: developer 4437 4438 .seealso: `MatFactorType`, `MatType`, `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatSolverTypeRegister()`, `MatGetFactor()` 4439 @*/ 4440 PetscErrorCode MatSolverTypeGet(MatSolverType type, MatType mtype, MatFactorType ftype, PetscBool *foundtype, PetscBool *foundmtype, PetscErrorCode (**createfactor)(Mat, MatFactorType, Mat *)) { 4441 MatSolverTypeHolder next = MatSolverTypeHolders; 4442 PetscBool flg; 4443 MatSolverTypeForSpecifcType inext; 4444 4445 PetscFunctionBegin; 4446 if (foundtype) *foundtype = PETSC_FALSE; 4447 if (foundmtype) *foundmtype = PETSC_FALSE; 4448 if (createfactor) *createfactor = NULL; 4449 4450 if (type) { 4451 while (next) { 4452 PetscCall(PetscStrcasecmp(type, next->name, &flg)); 4453 if (flg) { 4454 if (foundtype) *foundtype = PETSC_TRUE; 4455 inext = next->handlers; 4456 while (inext) { 4457 PetscCall(PetscStrbeginswith(mtype, inext->mtype, &flg)); 4458 if (flg) { 4459 if (foundmtype) *foundmtype = PETSC_TRUE; 4460 if (createfactor) *createfactor = inext->createfactor[(int)ftype - 1]; 4461 PetscFunctionReturn(0); 4462 } 4463 inext = inext->next; 4464 } 4465 } 4466 next = next->next; 4467 } 4468 } else { 4469 while (next) { 4470 inext = next->handlers; 4471 while (inext) { 4472 PetscCall(PetscStrcmp(mtype, inext->mtype, &flg)); 4473 if (flg && inext->createfactor[(int)ftype - 1]) { 4474 if (foundtype) *foundtype = PETSC_TRUE; 4475 if (foundmtype) *foundmtype = PETSC_TRUE; 4476 if (createfactor) *createfactor = inext->createfactor[(int)ftype - 1]; 4477 PetscFunctionReturn(0); 4478 } 4479 inext = inext->next; 4480 } 4481 next = next->next; 4482 } 4483 /* try with base classes inext->mtype */ 4484 next = MatSolverTypeHolders; 4485 while (next) { 4486 inext = next->handlers; 4487 while (inext) { 4488 PetscCall(PetscStrbeginswith(mtype, inext->mtype, &flg)); 4489 if (flg && inext->createfactor[(int)ftype - 1]) { 4490 if (foundtype) *foundtype = PETSC_TRUE; 4491 if (foundmtype) *foundmtype = PETSC_TRUE; 4492 if (createfactor) *createfactor = inext->createfactor[(int)ftype - 1]; 4493 PetscFunctionReturn(0); 4494 } 4495 inext = inext->next; 4496 } 4497 next = next->next; 4498 } 4499 } 4500 PetscFunctionReturn(0); 4501 } 4502 4503 PetscErrorCode MatSolverTypeDestroy(void) { 4504 MatSolverTypeHolder next = MatSolverTypeHolders, prev; 4505 MatSolverTypeForSpecifcType inext, iprev; 4506 4507 PetscFunctionBegin; 4508 while (next) { 4509 PetscCall(PetscFree(next->name)); 4510 inext = next->handlers; 4511 while (inext) { 4512 PetscCall(PetscFree(inext->mtype)); 4513 iprev = inext; 4514 inext = inext->next; 4515 PetscCall(PetscFree(iprev)); 4516 } 4517 prev = next; 4518 next = next->next; 4519 PetscCall(PetscFree(prev)); 4520 } 4521 MatSolverTypeHolders = NULL; 4522 PetscFunctionReturn(0); 4523 } 4524 4525 /*@C 4526 MatFactorGetCanUseOrdering - Indicates if the factorization can use the ordering provided in `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()` 4527 4528 Logically Collective on mat 4529 4530 Input Parameters: 4531 . mat - the matrix 4532 4533 Output Parameters: 4534 . flg - `PETSC_TRUE` if uses the ordering 4535 4536 Note: 4537 Most internal PETSc factorizations use the ordering passed to the factorization routine but external 4538 packages do not, thus we want to skip generating the ordering when it is not needed or used. 4539 4540 Level: developer 4541 4542 .seealso: [Matrix Factorization](sec_matfactor), `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()` 4543 @*/ 4544 PetscErrorCode MatFactorGetCanUseOrdering(Mat mat, PetscBool *flg) { 4545 PetscFunctionBegin; 4546 *flg = mat->canuseordering; 4547 PetscFunctionReturn(0); 4548 } 4549 4550 /*@C 4551 MatFactorGetPreferredOrdering - The preferred ordering for a particular matrix factor object 4552 4553 Logically Collective on mat 4554 4555 Input Parameters: 4556 . mat - the matrix obtained with `MatGetFactor()` 4557 4558 Output Parameters: 4559 . otype - the preferred type 4560 4561 Level: developer 4562 4563 .seealso: [Matrix Factorization](sec_matfactor), `MatFactorType`, `MatOrderingType`, `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()` 4564 @*/ 4565 PetscErrorCode MatFactorGetPreferredOrdering(Mat mat, MatFactorType ftype, MatOrderingType *otype) { 4566 PetscFunctionBegin; 4567 *otype = mat->preferredordering[ftype]; 4568 PetscCheck(*otype, PETSC_COMM_SELF, PETSC_ERR_PLIB, "MatFactor did not have a preferred ordering"); 4569 PetscFunctionReturn(0); 4570 } 4571 4572 /*@C 4573 MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic() 4574 4575 Collective on mat 4576 4577 Input Parameters: 4578 + mat - the matrix 4579 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4580 - ftype - factor type, `MAT_FACTOR_LU`, `MAT_FACTOR_CHOLESKY`, `MAT_FACTOR_ICC`, `MAT_FACTOR_ILU`, `MAT_FACTOR_QR` 4581 4582 Output Parameters: 4583 . f - the factor matrix used with MatXXFactorSymbolic() calls 4584 4585 Options Database Key: 4586 . -mat_factor_bind_factorization <host, device> - Where to do matrix factorization? Default is device (might consume more device memory. 4587 One can choose host to save device memory). Currently only supported with `MATSEQAIJCUSPARSE` matrices. 4588 4589 Notes: 4590 Users usually access the factorization solvers via `KSP` 4591 4592 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4593 such as pastix, superlu, mumps etc. 4594 4595 PETSc must have been ./configure to use the external solver, using the option --download-package 4596 4597 Some of the packages have options for controlling the factorization, these are in the form -prefix_mat_packagename_packageoption 4598 where prefix is normally obtained from the calling `KSP`/`PC`. If `MatGetFactor()` is called directly one can set 4599 call `MatSetOptionsPrefixFactor()` on the originating matrix or `MatSetOptionsPrefix()` on the resulting factor matrix. 4600 4601 Developer Note: 4602 This should actually be called `MatCreateFactor()` since it creates a new factor object 4603 4604 Level: intermediate 4605 4606 .seealso: [Matrix Factorization](sec_matfactor), `KSP`, `MatSolverType`, `MatFactorType`, `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatFactorGetCanUseOrdering()`, `MatSolverTypeRegister()`, 4607 `MAT_FACTOR_LU`, `MAT_FACTOR_CHOLESKY`, `MAT_FACTOR_ICC`, `MAT_FACTOR_ILU`, `MAT_FACTOR_QR` 4608 @*/ 4609 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type, MatFactorType ftype, Mat *f) { 4610 PetscBool foundtype, foundmtype; 4611 PetscErrorCode (*conv)(Mat, MatFactorType, Mat *); 4612 4613 PetscFunctionBegin; 4614 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4615 PetscValidType(mat, 1); 4616 4617 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 4618 MatCheckPreallocated(mat, 1); 4619 4620 PetscCall(MatSolverTypeGet(type, ((PetscObject)mat)->type_name, ftype, &foundtype, &foundmtype, &conv)); 4621 if (!foundtype) { 4622 if (type) { 4623 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], 4624 ((PetscObject)mat)->type_name, type); 4625 } else { 4626 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); 4627 } 4628 } 4629 PetscCheck(foundmtype, PetscObjectComm((PetscObject)mat), PETSC_ERR_MISSING_FACTOR, "MatSolverType %s does not support matrix type %s", type, ((PetscObject)mat)->type_name); 4630 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); 4631 4632 PetscCall((*conv)(mat, ftype, f)); 4633 if (mat->factorprefix) PetscCall(MatSetOptionsPrefix(*f, mat->factorprefix)); 4634 PetscFunctionReturn(0); 4635 } 4636 4637 /*@C 4638 MatGetFactorAvailable - Returns a a flag if matrix supports particular type and factor type 4639 4640 Not Collective 4641 4642 Input Parameters: 4643 + mat - the matrix 4644 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4645 - ftype - factor type, `MAT_FACTOR_LU`, `MAT_FACTOR_CHOLESKY`, `MAT_FACTOR_ICC`, `MAT_FACTOR_ILU`, `MAT_FACTOR_QR` 4646 4647 Output Parameter: 4648 . flg - PETSC_TRUE if the factorization is available 4649 4650 Notes: 4651 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4652 such as pastix, superlu, mumps etc. 4653 4654 PETSc must have been ./configure to use the external solver, using the option --download-package 4655 4656 Developer Note: 4657 This should actually be called MatCreateFactorAvailable() since MatGetFactor() creates a new factor object 4658 4659 Level: intermediate 4660 4661 .seealso: [Matrix Factorization](sec_matfactor), `MatSolverType`, `MatFactorType`, `MatGetFactor()`, `MatCopy()`, `MatDuplicate()`, `MatGetFactor()`, `MatSolverTypeRegister()`, 4662 `MAT_FACTOR_LU`, `MAT_FACTOR_CHOLESKY`, `MAT_FACTOR_ICC`, `MAT_FACTOR_ILU`, `MAT_FACTOR_QR` 4663 @*/ 4664 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type, MatFactorType ftype, PetscBool *flg) { 4665 PetscErrorCode (*gconv)(Mat, MatFactorType, Mat *); 4666 4667 PetscFunctionBegin; 4668 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4669 PetscValidType(mat, 1); 4670 PetscValidBoolPointer(flg, 4); 4671 4672 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 4673 MatCheckPreallocated(mat, 1); 4674 4675 PetscCall(MatSolverTypeGet(type, ((PetscObject)mat)->type_name, ftype, NULL, NULL, &gconv)); 4676 *flg = gconv ? PETSC_TRUE : PETSC_FALSE; 4677 PetscFunctionReturn(0); 4678 } 4679 4680 /*@ 4681 MatDuplicate - Duplicates a matrix including the non-zero structure. 4682 4683 Collective on mat 4684 4685 Input Parameters: 4686 + mat - the matrix 4687 - op - One of `MAT_DO_NOT_COPY_VALUES`, `MAT_COPY_VALUES`, or `MAT_SHARE_NONZERO_PATTERN`. 4688 See the manual page for `MatDuplicateOption()` for an explanation of these options. 4689 4690 Output Parameter: 4691 . M - pointer to place new matrix 4692 4693 Level: intermediate 4694 4695 Notes: 4696 You cannot change the nonzero pattern for the parent or child matrix if you use `MAT_SHARE_NONZERO_PATTERN`. 4697 4698 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. 4699 4700 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 4701 is duplicated and the internal data structures created for the reuse of previous matrix operations are not duplicated. 4702 User should not use `MatDuplicate()` to create new matrix M if M is intended to be reused as the product of matrix operation. 4703 4704 .seealso: `MatCopy()`, `MatConvert()`, `MatDuplicateOption` 4705 @*/ 4706 PetscErrorCode MatDuplicate(Mat mat, MatDuplicateOption op, Mat *M) { 4707 Mat B; 4708 VecType vtype; 4709 PetscInt i; 4710 PetscObject dm; 4711 void (*viewf)(void); 4712 4713 PetscFunctionBegin; 4714 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4715 PetscValidType(mat, 1); 4716 PetscValidPointer(M, 3); 4717 PetscCheck(op != MAT_COPY_VALUES || mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "MAT_COPY_VALUES not allowed for unassembled matrix"); 4718 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 4719 MatCheckPreallocated(mat, 1); 4720 4721 *M = NULL; 4722 PetscCall(PetscLogEventBegin(MAT_Convert, mat, 0, 0, 0)); 4723 PetscUseTypeMethod(mat, duplicate, op, M); 4724 PetscCall(PetscLogEventEnd(MAT_Convert, mat, 0, 0, 0)); 4725 B = *M; 4726 4727 PetscCall(MatGetOperation(mat, MATOP_VIEW, &viewf)); 4728 if (viewf) PetscCall(MatSetOperation(B, MATOP_VIEW, viewf)); 4729 PetscCall(MatGetVecType(mat, &vtype)); 4730 PetscCall(MatSetVecType(B, vtype)); 4731 4732 B->stencil.dim = mat->stencil.dim; 4733 B->stencil.noc = mat->stencil.noc; 4734 for (i = 0; i <= mat->stencil.dim; i++) { 4735 B->stencil.dims[i] = mat->stencil.dims[i]; 4736 B->stencil.starts[i] = mat->stencil.starts[i]; 4737 } 4738 4739 B->nooffproczerorows = mat->nooffproczerorows; 4740 B->nooffprocentries = mat->nooffprocentries; 4741 4742 PetscCall(PetscObjectQuery((PetscObject)mat, "__PETSc_dm", &dm)); 4743 if (dm) PetscCall(PetscObjectCompose((PetscObject)B, "__PETSc_dm", dm)); 4744 PetscCall(PetscObjectStateIncrease((PetscObject)B)); 4745 PetscFunctionReturn(0); 4746 } 4747 4748 /*@ 4749 MatGetDiagonal - Gets the diagonal of a matrix as a `Vec` 4750 4751 Logically Collective on mat 4752 4753 Input Parameters: 4754 + mat - the matrix 4755 - v - the vector for storing the diagonal 4756 4757 Output Parameter: 4758 . v - the diagonal of the matrix 4759 4760 Level: intermediate 4761 4762 Note: 4763 Currently only correct in parallel for square matrices. 4764 4765 .seealso: `Mat`, `Vec`, `MatGetRow()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMaxAbs()` 4766 @*/ 4767 PetscErrorCode MatGetDiagonal(Mat mat, Vec v) { 4768 PetscFunctionBegin; 4769 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4770 PetscValidType(mat, 1); 4771 PetscValidHeaderSpecific(v, VEC_CLASSID, 2); 4772 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 4773 MatCheckPreallocated(mat, 1); 4774 4775 PetscUseTypeMethod(mat, getdiagonal, v); 4776 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 4777 PetscFunctionReturn(0); 4778 } 4779 4780 /*@C 4781 MatGetRowMin - Gets the minimum value (of the real part) of each 4782 row of the matrix 4783 4784 Logically Collective on mat 4785 4786 Input Parameter: 4787 . mat - the matrix 4788 4789 Output Parameters: 4790 + v - the vector for storing the maximums 4791 - idx - the indices of the column found for each row (optional) 4792 4793 Level: intermediate 4794 4795 Note: 4796 The result of this call are the same as if one converted the matrix to dense format 4797 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4798 4799 This code is only implemented for a couple of matrix formats. 4800 4801 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMaxAbs()`, `MatGetRowMinAbs()`, 4802 `MatGetRowMax()` 4803 @*/ 4804 PetscErrorCode MatGetRowMin(Mat mat, Vec v, PetscInt idx[]) { 4805 PetscFunctionBegin; 4806 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4807 PetscValidType(mat, 1); 4808 PetscValidHeaderSpecific(v, VEC_CLASSID, 2); 4809 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 4810 4811 if (!mat->cmap->N) { 4812 PetscCall(VecSet(v, PETSC_MAX_REAL)); 4813 if (idx) { 4814 PetscInt i, m = mat->rmap->n; 4815 for (i = 0; i < m; i++) idx[i] = -1; 4816 } 4817 } else { 4818 MatCheckPreallocated(mat, 1); 4819 } 4820 PetscUseTypeMethod(mat, getrowmin, v, idx); 4821 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 4822 PetscFunctionReturn(0); 4823 } 4824 4825 /*@C 4826 MatGetRowMinAbs - Gets the minimum value (in absolute value) of each 4827 row of the matrix 4828 4829 Logically Collective on mat 4830 4831 Input Parameter: 4832 . mat - the matrix 4833 4834 Output Parameters: 4835 + v - the vector for storing the minimums 4836 - idx - the indices of the column found for each row (or NULL if not needed) 4837 4838 Level: intermediate 4839 4840 Notes: 4841 if a row is completely empty or has only 0.0 values then the idx[] value for that 4842 row is 0 (the first column). 4843 4844 This code is only implemented for a couple of matrix formats. 4845 4846 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMax()`, `MatGetRowMaxAbs()`, `MatGetRowMin()` 4847 @*/ 4848 PetscErrorCode MatGetRowMinAbs(Mat mat, Vec v, PetscInt idx[]) { 4849 PetscFunctionBegin; 4850 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4851 PetscValidType(mat, 1); 4852 PetscValidHeaderSpecific(v, VEC_CLASSID, 2); 4853 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 4854 PetscCheck(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 4855 4856 if (!mat->cmap->N) { 4857 PetscCall(VecSet(v, 0.0)); 4858 if (idx) { 4859 PetscInt i, m = mat->rmap->n; 4860 for (i = 0; i < m; i++) idx[i] = -1; 4861 } 4862 } else { 4863 MatCheckPreallocated(mat, 1); 4864 if (idx) PetscCall(PetscArrayzero(idx, mat->rmap->n)); 4865 PetscUseTypeMethod(mat, getrowminabs, v, idx); 4866 } 4867 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 4868 PetscFunctionReturn(0); 4869 } 4870 4871 /*@C 4872 MatGetRowMax - Gets the maximum value (of the real part) of each 4873 row of the matrix 4874 4875 Logically Collective on mat 4876 4877 Input Parameter: 4878 . mat - the matrix 4879 4880 Output Parameters: 4881 + v - the vector for storing the maximums 4882 - idx - the indices of the column found for each row (optional) 4883 4884 Level: intermediate 4885 4886 Notes: 4887 The result of this call are the same as if one converted the matrix to dense format 4888 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4889 4890 This code is only implemented for a couple of matrix formats. 4891 4892 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMaxAbs()`, `MatGetRowMin()`, `MatGetRowMinAbs()` 4893 @*/ 4894 PetscErrorCode MatGetRowMax(Mat mat, Vec v, PetscInt idx[]) { 4895 PetscFunctionBegin; 4896 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4897 PetscValidType(mat, 1); 4898 PetscValidHeaderSpecific(v, VEC_CLASSID, 2); 4899 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 4900 4901 if (!mat->cmap->N) { 4902 PetscCall(VecSet(v, PETSC_MIN_REAL)); 4903 if (idx) { 4904 PetscInt i, m = mat->rmap->n; 4905 for (i = 0; i < m; i++) idx[i] = -1; 4906 } 4907 } else { 4908 MatCheckPreallocated(mat, 1); 4909 PetscUseTypeMethod(mat, getrowmax, v, idx); 4910 } 4911 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 4912 PetscFunctionReturn(0); 4913 } 4914 4915 /*@C 4916 MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each 4917 row of the matrix 4918 4919 Logically Collective on mat 4920 4921 Input Parameter: 4922 . mat - the matrix 4923 4924 Output Parameters: 4925 + v - the vector for storing the maximums 4926 - idx - the indices of the column found for each row (or NULL if not needed) 4927 4928 Level: intermediate 4929 4930 Notes: 4931 if a row is completely empty or has only 0.0 values then the idx[] value for that 4932 row is 0 (the first column). 4933 4934 This code is only implemented for a couple of matrix formats. 4935 4936 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMax()`, `MatGetRowMin()`, `MatGetRowMinAbs()` 4937 @*/ 4938 PetscErrorCode MatGetRowMaxAbs(Mat mat, Vec v, PetscInt idx[]) { 4939 PetscFunctionBegin; 4940 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4941 PetscValidType(mat, 1); 4942 PetscValidHeaderSpecific(v, VEC_CLASSID, 2); 4943 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 4944 4945 if (!mat->cmap->N) { 4946 PetscCall(VecSet(v, 0.0)); 4947 if (idx) { 4948 PetscInt i, m = mat->rmap->n; 4949 for (i = 0; i < m; i++) idx[i] = -1; 4950 } 4951 } else { 4952 MatCheckPreallocated(mat, 1); 4953 if (idx) PetscCall(PetscArrayzero(idx, mat->rmap->n)); 4954 PetscUseTypeMethod(mat, getrowmaxabs, v, idx); 4955 } 4956 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 4957 PetscFunctionReturn(0); 4958 } 4959 4960 /*@ 4961 MatGetRowSum - Gets the sum of each row of the matrix 4962 4963 Logically or Neighborhood Collective on mat 4964 4965 Input Parameters: 4966 . mat - the matrix 4967 4968 Output Parameter: 4969 . v - the vector for storing the sum of rows 4970 4971 Level: intermediate 4972 4973 Notes: 4974 This code is slow since it is not currently specialized for different formats 4975 4976 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMax()`, `MatGetRowMin()`, `MatGetRowMaxAbs()`, `MatGetRowMinAbs()` 4977 @*/ 4978 PetscErrorCode MatGetRowSum(Mat mat, Vec v) { 4979 Vec ones; 4980 4981 PetscFunctionBegin; 4982 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4983 PetscValidType(mat, 1); 4984 PetscValidHeaderSpecific(v, VEC_CLASSID, 2); 4985 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 4986 MatCheckPreallocated(mat, 1); 4987 PetscCall(MatCreateVecs(mat, &ones, NULL)); 4988 PetscCall(VecSet(ones, 1.)); 4989 PetscCall(MatMult(mat, ones, v)); 4990 PetscCall(VecDestroy(&ones)); 4991 PetscFunctionReturn(0); 4992 } 4993 4994 /*@ 4995 MatTransposeSetPrecursor - Set the matrix from which the second matrix will receive numerical transpose data with a call to `MatTranspose`(A,`MAT_REUSE_MATRIX`,&B) 4996 when B was not obtained with `MatTranspose`(A,`MAT_INITIAL_MATRIX`,&B) 4997 4998 Collective on mat 4999 5000 Input Parameter: 5001 . mat - the matrix to provide the transpose 5002 5003 Output Parameter: 5004 . 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 5005 5006 Level: advanced 5007 5008 Note: 5009 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 5010 routine allows bypassing that call. 5011 5012 .seealso: `MatTransposeSymbolic()`, `MatTranspose()`, `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse`, `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, `MAT_INPLACE_MATRIX` 5013 @*/ 5014 PetscErrorCode MatTransposeSetPrecursor(Mat mat, Mat B) { 5015 PetscContainer rB = NULL; 5016 MatParentState *rb = NULL; 5017 5018 PetscFunctionBegin; 5019 PetscCall(PetscNew(&rb)); 5020 rb->id = ((PetscObject)mat)->id; 5021 rb->state = 0; 5022 PetscCall(MatGetNonzeroState(mat, &rb->nonzerostate)); 5023 PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)B), &rB)); 5024 PetscCall(PetscContainerSetPointer(rB, rb)); 5025 PetscCall(PetscContainerSetUserDestroy(rB, PetscContainerUserDestroyDefault)); 5026 PetscCall(PetscObjectCompose((PetscObject)B, "MatTransposeParent", (PetscObject)rB)); 5027 PetscCall(PetscObjectDereference((PetscObject)rB)); 5028 PetscFunctionReturn(0); 5029 } 5030 5031 /*@ 5032 MatTranspose - Computes an in-place or out-of-place transpose of a matrix. 5033 5034 Collective on mat 5035 5036 Input Parameters: 5037 + mat - the matrix to transpose 5038 - reuse - either `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, or `MAT_INPLACE_MATRIX` 5039 5040 Output Parameter: 5041 . B - the transpose 5042 5043 Notes: 5044 If you use `MAT_INPLACE_MATRIX` then you must pass in &mat for B 5045 5046 `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 5047 transpose, call `MatTransposeSetPrecursor`(mat,B) before calling this routine. 5048 5049 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. 5050 5051 Consider using `MatCreateTranspose()` instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed. 5052 5053 If mat is unchanged from the last call this function returns immediately without recomputing the result 5054 5055 If you only need the symbolic transpose, and not the numerical values, use `MatTransposeSymbolic()` 5056 5057 Level: intermediate 5058 5059 .seealso: `MatTransposeSetPrecursor()`, `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse`, `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, `MAT_INPLACE_MATRIX`, 5060 `MatTransposeSymbolic()` 5061 @*/ 5062 PetscErrorCode MatTranspose(Mat mat, MatReuse reuse, Mat *B) { 5063 PetscContainer rB = NULL; 5064 MatParentState *rb = NULL; 5065 5066 PetscFunctionBegin; 5067 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5068 PetscValidType(mat, 1); 5069 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 5070 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 5071 PetscCheck(reuse != MAT_INPLACE_MATRIX || mat == *B, PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "MAT_INPLACE_MATRIX requires last matrix to match first"); 5072 PetscCheck(reuse != MAT_REUSE_MATRIX || mat != *B, PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Perhaps you mean MAT_INPLACE_MATRIX"); 5073 MatCheckPreallocated(mat, 1); 5074 if (reuse == MAT_REUSE_MATRIX) { 5075 PetscCall(PetscObjectQuery((PetscObject)*B, "MatTransposeParent", (PetscObject *)&rB)); 5076 PetscCheck(rB, PetscObjectComm((PetscObject)*B), PETSC_ERR_ARG_WRONG, "Reuse matrix used was not generated from call to MatTranspose(). Suggest MatTransposeSetPrecursor()."); 5077 PetscCall(PetscContainerGetPointer(rB, (void **)&rb)); 5078 PetscCheck(rb->id == ((PetscObject)mat)->id, PetscObjectComm((PetscObject)*B), PETSC_ERR_ARG_WRONG, "Reuse matrix used was not generated from input matrix"); 5079 if (rb->state == ((PetscObject)mat)->state) PetscFunctionReturn(0); 5080 } 5081 5082 PetscCall(PetscLogEventBegin(MAT_Transpose, mat, 0, 0, 0)); 5083 if (reuse != MAT_INPLACE_MATRIX || mat->symmetric != PETSC_BOOL3_TRUE) { 5084 PetscUseTypeMethod(mat, transpose, reuse, B); 5085 PetscCall(PetscObjectStateIncrease((PetscObject)*B)); 5086 } 5087 PetscCall(PetscLogEventEnd(MAT_Transpose, mat, 0, 0, 0)); 5088 5089 if (reuse == MAT_INITIAL_MATRIX) PetscCall(MatTransposeSetPrecursor(mat, *B)); 5090 if (reuse != MAT_INPLACE_MATRIX) { 5091 PetscCall(PetscObjectQuery((PetscObject)*B, "MatTransposeParent", (PetscObject *)&rB)); 5092 PetscCall(PetscContainerGetPointer(rB, (void **)&rb)); 5093 rb->state = ((PetscObject)mat)->state; 5094 rb->nonzerostate = mat->nonzerostate; 5095 } 5096 PetscFunctionReturn(0); 5097 } 5098 5099 /*@ 5100 MatTransposeSymbolic - Computes the symbolic part of the transpose of a matrix. 5101 5102 Collective on A 5103 5104 Input Parameters: 5105 . A - the matrix to transpose 5106 5107 Output Parameter: 5108 . 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 5109 numerical portion. 5110 5111 Level: intermediate 5112 5113 Note: 5114 This is not supported for many matrix types, use `MatTranspose()` in those cases 5115 5116 .seealso: `MatTransposeSetPrecursor()`, `MatTranspose()`, `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse`, `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, `MAT_INPLACE_MATRIX` 5117 @*/ 5118 PetscErrorCode MatTransposeSymbolic(Mat A, Mat *B) { 5119 PetscFunctionBegin; 5120 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 5121 PetscValidType(A, 1); 5122 PetscCheck(A->assembled, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 5123 PetscCheck(!A->factortype, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 5124 PetscCheck(A->ops->transposesymbolic, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Mat type %s", ((PetscObject)A)->type_name); 5125 PetscCall(PetscLogEventBegin(MAT_Transpose, A, 0, 0, 0)); 5126 PetscCall((*A->ops->transposesymbolic)(A, B)); 5127 PetscCall(PetscLogEventEnd(MAT_Transpose, A, 0, 0, 0)); 5128 5129 PetscCall(MatTransposeSetPrecursor(A, *B)); 5130 PetscFunctionReturn(0); 5131 } 5132 5133 PetscErrorCode MatTransposeCheckNonzeroState_Private(Mat A, Mat B) { 5134 PetscContainer rB; 5135 MatParentState *rb; 5136 5137 PetscFunctionBegin; 5138 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 5139 PetscValidType(A, 1); 5140 PetscCheck(A->assembled, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 5141 PetscCheck(!A->factortype, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 5142 PetscCall(PetscObjectQuery((PetscObject)B, "MatTransposeParent", (PetscObject *)&rB)); 5143 PetscCheck(rB, PetscObjectComm((PetscObject)B), PETSC_ERR_ARG_WRONG, "Reuse matrix used was not generated from call to MatTranspose()"); 5144 PetscCall(PetscContainerGetPointer(rB, (void **)&rb)); 5145 PetscCheck(rb->id == ((PetscObject)A)->id, PetscObjectComm((PetscObject)B), PETSC_ERR_ARG_WRONG, "Reuse matrix used was not generated from input matrix"); 5146 PetscCheck(rb->nonzerostate == A->nonzerostate, PetscObjectComm((PetscObject)B), PETSC_ERR_ARG_WRONGSTATE, "Reuse matrix has changed nonzero structure"); 5147 PetscFunctionReturn(0); 5148 } 5149 5150 /*@ 5151 MatIsTranspose - Test whether a matrix is another one's transpose, 5152 or its own, in which case it tests symmetry. 5153 5154 Collective on A 5155 5156 Input Parameters: 5157 + A - the matrix to test 5158 - B - the matrix to test against, this can equal the first parameter 5159 5160 Output Parameters: 5161 . flg - the result 5162 5163 Notes: 5164 Only available for `MATAIJ` matrices. 5165 5166 The sequential algorithm has a running time of the order of the number of nonzeros; the parallel 5167 test involves parallel copies of the block-offdiagonal parts of the matrix. 5168 5169 Level: intermediate 5170 5171 .seealso: `MatTranspose()`, `MatIsSymmetric()`, `MatIsHermitian()` 5172 @*/ 5173 PetscErrorCode MatIsTranspose(Mat A, Mat B, PetscReal tol, PetscBool *flg) { 5174 PetscErrorCode (*f)(Mat, Mat, PetscReal, PetscBool *), (*g)(Mat, Mat, PetscReal, PetscBool *); 5175 5176 PetscFunctionBegin; 5177 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 5178 PetscValidHeaderSpecific(B, MAT_CLASSID, 2); 5179 PetscValidBoolPointer(flg, 4); 5180 PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatIsTranspose_C", &f)); 5181 PetscCall(PetscObjectQueryFunction((PetscObject)B, "MatIsTranspose_C", &g)); 5182 *flg = PETSC_FALSE; 5183 if (f && g) { 5184 PetscCheck(f == g, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_NOTSAMETYPE, "Matrices do not have the same comparator for symmetry test"); 5185 PetscCall((*f)(A, B, tol, flg)); 5186 } else { 5187 MatType mattype; 5188 5189 PetscCall(MatGetType(f ? B : A, &mattype)); 5190 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Matrix of type %s does not support checking for transpose", mattype); 5191 } 5192 PetscFunctionReturn(0); 5193 } 5194 5195 /*@ 5196 MatHermitianTranspose - Computes an in-place or out-of-place Hermitian transpose of a matrix in complex conjugate. 5197 5198 Collective on mat 5199 5200 Input Parameters: 5201 + mat - the matrix to transpose and complex conjugate 5202 - reuse - either `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, or `MAT_INPLACE_MATRIX` 5203 5204 Output Parameter: 5205 . B - the Hermitian transpose 5206 5207 Level: intermediate 5208 5209 .seealso: `MatTranspose()`, `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse` 5210 @*/ 5211 PetscErrorCode MatHermitianTranspose(Mat mat, MatReuse reuse, Mat *B) { 5212 PetscFunctionBegin; 5213 PetscCall(MatTranspose(mat, reuse, B)); 5214 #if defined(PETSC_USE_COMPLEX) 5215 PetscCall(MatConjugate(*B)); 5216 #endif 5217 PetscFunctionReturn(0); 5218 } 5219 5220 /*@ 5221 MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose, 5222 5223 Collective on A 5224 5225 Input Parameters: 5226 + A - the matrix to test 5227 - B - the matrix to test against, this can equal the first parameter 5228 5229 Output Parameters: 5230 . flg - the result 5231 5232 Notes: 5233 Only available for `MATAIJ` matrices. 5234 5235 The sequential algorithm 5236 has a running time of the order of the number of nonzeros; the parallel 5237 test involves parallel copies of the block-offdiagonal parts of the matrix. 5238 5239 Level: intermediate 5240 5241 .seealso: `MatTranspose()`, `MatIsSymmetric()`, `MatIsHermitian()`, `MatIsTranspose()` 5242 @*/ 5243 PetscErrorCode MatIsHermitianTranspose(Mat A, Mat B, PetscReal tol, PetscBool *flg) { 5244 PetscErrorCode (*f)(Mat, Mat, PetscReal, PetscBool *), (*g)(Mat, Mat, PetscReal, PetscBool *); 5245 5246 PetscFunctionBegin; 5247 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 5248 PetscValidHeaderSpecific(B, MAT_CLASSID, 2); 5249 PetscValidBoolPointer(flg, 4); 5250 PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatIsHermitianTranspose_C", &f)); 5251 PetscCall(PetscObjectQueryFunction((PetscObject)B, "MatIsHermitianTranspose_C", &g)); 5252 if (f && g) { 5253 PetscCheck(f != g, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_NOTSAMETYPE, "Matrices do not have the same comparator for Hermitian test"); 5254 PetscCall((*f)(A, B, tol, flg)); 5255 } 5256 PetscFunctionReturn(0); 5257 } 5258 5259 /*@ 5260 MatPermute - Creates a new matrix with rows and columns permuted from the 5261 original. 5262 5263 Collective on mat 5264 5265 Input Parameters: 5266 + mat - the matrix to permute 5267 . row - row permutation, each processor supplies only the permutation for its rows 5268 - col - column permutation, each processor supplies only the permutation for its columns 5269 5270 Output Parameters: 5271 . B - the permuted matrix 5272 5273 Level: advanced 5274 5275 Note: 5276 The index sets map from row/col of permuted matrix to row/col of original matrix. 5277 The index sets should be on the same communicator as mat and have the same local sizes. 5278 5279 Developer Note: 5280 If you want to implement `MatPermute()` for a matrix type, and your approach doesn't 5281 exploit the fact that row and col are permutations, consider implementing the 5282 more general `MatCreateSubMatrix()` instead. 5283 5284 .seealso: `MatGetOrdering()`, `ISAllGather()`, `MatCreateSubMatrix()` 5285 @*/ 5286 PetscErrorCode MatPermute(Mat mat, IS row, IS col, Mat *B) { 5287 PetscFunctionBegin; 5288 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5289 PetscValidType(mat, 1); 5290 PetscValidHeaderSpecific(row, IS_CLASSID, 2); 5291 PetscValidHeaderSpecific(col, IS_CLASSID, 3); 5292 PetscValidPointer(B, 4); 5293 PetscCheckSameComm(mat, 1, row, 2); 5294 if (row != col) PetscCheckSameComm(row, 2, col, 3); 5295 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 5296 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 5297 PetscCheck(mat->ops->permute || mat->ops->createsubmatrix, PETSC_COMM_SELF, PETSC_ERR_SUP, "MatPermute not available for Mat type %s", ((PetscObject)mat)->type_name); 5298 MatCheckPreallocated(mat, 1); 5299 5300 if (mat->ops->permute) { 5301 PetscUseTypeMethod(mat, permute, row, col, B); 5302 PetscCall(PetscObjectStateIncrease((PetscObject)*B)); 5303 } else { 5304 PetscCall(MatCreateSubMatrix(mat, row, col, MAT_INITIAL_MATRIX, B)); 5305 } 5306 PetscFunctionReturn(0); 5307 } 5308 5309 /*@ 5310 MatEqual - Compares two matrices. 5311 5312 Collective on A 5313 5314 Input Parameters: 5315 + A - the first matrix 5316 - B - the second matrix 5317 5318 Output Parameter: 5319 . flg - `PETSC_TRUE` if the matrices are equal; `PETSC_FALSE` otherwise. 5320 5321 Level: intermediate 5322 5323 .seealso: `Mat` 5324 @*/ 5325 PetscErrorCode MatEqual(Mat A, Mat B, PetscBool *flg) { 5326 PetscFunctionBegin; 5327 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 5328 PetscValidHeaderSpecific(B, MAT_CLASSID, 2); 5329 PetscValidType(A, 1); 5330 PetscValidType(B, 2); 5331 PetscValidBoolPointer(flg, 3); 5332 PetscCheckSameComm(A, 1, B, 2); 5333 MatCheckPreallocated(A, 1); 5334 MatCheckPreallocated(B, 2); 5335 PetscCheck(A->assembled, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 5336 PetscCheck(B->assembled, PetscObjectComm((PetscObject)B), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 5337 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, 5338 B->cmap->N); 5339 if (A->ops->equal && A->ops->equal == B->ops->equal) { 5340 PetscUseTypeMethod(A, equal, B, flg); 5341 } else { 5342 PetscCall(MatMultEqual(A, B, 10, flg)); 5343 } 5344 PetscFunctionReturn(0); 5345 } 5346 5347 /*@ 5348 MatDiagonalScale - Scales a matrix on the left and right by diagonal 5349 matrices that are stored as vectors. Either of the two scaling 5350 matrices can be NULL. 5351 5352 Collective on mat 5353 5354 Input Parameters: 5355 + mat - the matrix to be scaled 5356 . l - the left scaling vector (or NULL) 5357 - r - the right scaling vector (or NULL) 5358 5359 Note: 5360 `MatDiagonalScale()` computes A = LAR, where 5361 L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector) 5362 The L scales the rows of the matrix, the R scales the columns of the matrix. 5363 5364 Level: intermediate 5365 5366 .seealso: `Mat`, `MatScale()`, `MatShift()`, `MatDiagonalSet()` 5367 @*/ 5368 PetscErrorCode MatDiagonalScale(Mat mat, Vec l, Vec r) { 5369 PetscFunctionBegin; 5370 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5371 PetscValidType(mat, 1); 5372 if (l) { 5373 PetscValidHeaderSpecific(l, VEC_CLASSID, 2); 5374 PetscCheckSameComm(mat, 1, l, 2); 5375 } 5376 if (r) { 5377 PetscValidHeaderSpecific(r, VEC_CLASSID, 3); 5378 PetscCheckSameComm(mat, 1, r, 3); 5379 } 5380 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 5381 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 5382 MatCheckPreallocated(mat, 1); 5383 if (!l && !r) PetscFunctionReturn(0); 5384 5385 PetscCall(PetscLogEventBegin(MAT_Scale, mat, 0, 0, 0)); 5386 PetscUseTypeMethod(mat, diagonalscale, l, r); 5387 PetscCall(PetscLogEventEnd(MAT_Scale, mat, 0, 0, 0)); 5388 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5389 if (l != r) mat->symmetric = PETSC_BOOL3_FALSE; 5390 PetscFunctionReturn(0); 5391 } 5392 5393 /*@ 5394 MatScale - Scales all elements of a matrix by a given number. 5395 5396 Logically Collective on mat 5397 5398 Input Parameters: 5399 + mat - the matrix to be scaled 5400 - a - the scaling value 5401 5402 Output Parameter: 5403 . mat - the scaled matrix 5404 5405 Level: intermediate 5406 5407 .seealso: `Mat`, `MatDiagonalScale()` 5408 @*/ 5409 PetscErrorCode MatScale(Mat mat, PetscScalar a) { 5410 PetscFunctionBegin; 5411 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5412 PetscValidType(mat, 1); 5413 PetscCheck(a == (PetscScalar)1.0 || mat->ops->scale, PETSC_COMM_SELF, PETSC_ERR_SUP, "Mat type %s", ((PetscObject)mat)->type_name); 5414 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 5415 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 5416 PetscValidLogicalCollectiveScalar(mat, a, 2); 5417 MatCheckPreallocated(mat, 1); 5418 5419 PetscCall(PetscLogEventBegin(MAT_Scale, mat, 0, 0, 0)); 5420 if (a != (PetscScalar)1.0) { 5421 PetscUseTypeMethod(mat, scale, a); 5422 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5423 } 5424 PetscCall(PetscLogEventEnd(MAT_Scale, mat, 0, 0, 0)); 5425 PetscFunctionReturn(0); 5426 } 5427 5428 /*@ 5429 MatNorm - Calculates various norms of a matrix. 5430 5431 Collective on mat 5432 5433 Input Parameters: 5434 + mat - the matrix 5435 - type - the type of norm, `NORM_1`, `NORM_FROBENIUS`, `NORM_INFINITY` 5436 5437 Output Parameter: 5438 . nrm - the resulting norm 5439 5440 Level: intermediate 5441 5442 .seealso: `Mat` 5443 @*/ 5444 PetscErrorCode MatNorm(Mat mat, NormType type, PetscReal *nrm) { 5445 PetscFunctionBegin; 5446 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5447 PetscValidType(mat, 1); 5448 PetscValidRealPointer(nrm, 3); 5449 5450 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 5451 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 5452 MatCheckPreallocated(mat, 1); 5453 5454 PetscUseTypeMethod(mat, norm, type, nrm); 5455 PetscFunctionReturn(0); 5456 } 5457 5458 /* 5459 This variable is used to prevent counting of MatAssemblyBegin() that 5460 are called from within a MatAssemblyEnd(). 5461 */ 5462 static PetscInt MatAssemblyEnd_InUse = 0; 5463 /*@ 5464 MatAssemblyBegin - Begins assembling the matrix. This routine should 5465 be called after completing all calls to `MatSetValues()`. 5466 5467 Collective on mat 5468 5469 Input Parameters: 5470 + mat - the matrix 5471 - type - type of assembly, either `MAT_FLUSH_ASSEMBLY` or `MAT_FINAL_ASSEMBLY` 5472 5473 Notes: 5474 `MatSetValues()` generally caches the values that belong to other MPI ranks. The matrix is ready to 5475 use only after `MatAssemblyBegin()` and `MatAssemblyEnd()` have been called. 5476 5477 Use `MAT_FLUSH_ASSEMBLY` when switching between `ADD_VALUES` and `INSERT_VALUES` 5478 in `MatSetValues()`; use `MAT_FINAL_ASSEMBLY` for the final assembly before 5479 using the matrix. 5480 5481 ALL processes that share a matrix MUST call `MatAssemblyBegin()` and `MatAssemblyEnd()` the SAME NUMBER of times, and each time with the 5482 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 5483 a global collective operation requring all processes that share the matrix. 5484 5485 Space for preallocated nonzeros that is not filled by a call to `MatSetValues()` or a related routine are compressed 5486 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5487 before `MAT_FINAL_ASSEMBLY` so the space is not compressed out. 5488 5489 Level: beginner 5490 5491 .seealso: `Mat`, `MatAssemblyEnd()`, `MatSetValues()`, `MatAssembled()` 5492 @*/ 5493 PetscErrorCode MatAssemblyBegin(Mat mat, MatAssemblyType type) { 5494 PetscFunctionBegin; 5495 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5496 PetscValidType(mat, 1); 5497 MatCheckPreallocated(mat, 1); 5498 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix.\nDid you forget to call MatSetUnfactored()?"); 5499 if (mat->assembled) { 5500 mat->was_assembled = PETSC_TRUE; 5501 mat->assembled = PETSC_FALSE; 5502 } 5503 5504 if (!MatAssemblyEnd_InUse) { 5505 PetscCall(PetscLogEventBegin(MAT_AssemblyBegin, mat, 0, 0, 0)); 5506 PetscTryTypeMethod(mat, assemblybegin, type); 5507 PetscCall(PetscLogEventEnd(MAT_AssemblyBegin, mat, 0, 0, 0)); 5508 } else PetscTryTypeMethod(mat, assemblybegin, type); 5509 PetscFunctionReturn(0); 5510 } 5511 5512 /*@ 5513 MatAssembled - Indicates if a matrix has been assembled and is ready for 5514 use; for example, in matrix-vector product. 5515 5516 Not Collective 5517 5518 Input Parameter: 5519 . mat - the matrix 5520 5521 Output Parameter: 5522 . assembled - `PETSC_TRUE` or `PETSC_FALSE` 5523 5524 Level: advanced 5525 5526 .seealso: `Mat`, `MatAssemblyEnd()`, `MatSetValues()`, `MatAssemblyBegin()` 5527 @*/ 5528 PetscErrorCode MatAssembled(Mat mat, PetscBool *assembled) { 5529 PetscFunctionBegin; 5530 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5531 PetscValidBoolPointer(assembled, 2); 5532 *assembled = mat->assembled; 5533 PetscFunctionReturn(0); 5534 } 5535 5536 /*@ 5537 MatAssemblyEnd - Completes assembling the matrix. This routine should 5538 be called after `MatAssemblyBegin()`. 5539 5540 Collective on Mat 5541 5542 Input Parameters: 5543 + mat - the matrix 5544 - type - type of assembly, either `MAT_FLUSH_ASSEMBLY` or `MAT_FINAL_ASSEMBLY` 5545 5546 Options Database Keys: 5547 + -mat_view ::ascii_info - Prints info on matrix at conclusion of `MatEndAssembly()` 5548 . -mat_view ::ascii_info_detail - Prints more detailed info 5549 . -mat_view - Prints matrix in ASCII format 5550 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 5551 . -mat_view draw - draws nonzero structure of matrix, using `MatView()` and `PetscDrawOpenX()`. 5552 . -display <name> - Sets display name (default is host) 5553 . -draw_pause <sec> - Sets number of seconds to pause after display 5554 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See [Using MATLAB with PETSc](ch_matlab)) 5555 . -viewer_socket_machine <machine> - Machine to use for socket 5556 . -viewer_socket_port <port> - Port number to use for socket 5557 - -mat_view binary:filename[:append] - Save matrix to file in binary format 5558 5559 Level: beginner 5560 5561 .seealso: `Mat`, `MatAssemblyBegin()`, `MatSetValues()`, `PetscDrawOpenX()`, `PetscDrawCreate()`, `MatView()`, `MatAssembled()`, `PetscViewerSocketOpen()` 5562 @*/ 5563 PetscErrorCode MatAssemblyEnd(Mat mat, MatAssemblyType type) { 5564 static PetscInt inassm = 0; 5565 PetscBool flg = PETSC_FALSE; 5566 5567 PetscFunctionBegin; 5568 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5569 PetscValidType(mat, 1); 5570 5571 inassm++; 5572 MatAssemblyEnd_InUse++; 5573 if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */ 5574 PetscCall(PetscLogEventBegin(MAT_AssemblyEnd, mat, 0, 0, 0)); 5575 PetscTryTypeMethod(mat, assemblyend, type); 5576 PetscCall(PetscLogEventEnd(MAT_AssemblyEnd, mat, 0, 0, 0)); 5577 } else PetscTryTypeMethod(mat, assemblyend, type); 5578 5579 /* Flush assembly is not a true assembly */ 5580 if (type != MAT_FLUSH_ASSEMBLY) { 5581 if (mat->num_ass) { 5582 if (!mat->symmetry_eternal) { 5583 mat->symmetric = PETSC_BOOL3_UNKNOWN; 5584 mat->hermitian = PETSC_BOOL3_UNKNOWN; 5585 } 5586 if (!mat->structural_symmetry_eternal && mat->ass_nonzerostate != mat->nonzerostate) mat->structurally_symmetric = PETSC_BOOL3_UNKNOWN; 5587 if (!mat->spd_eternal) mat->spd = PETSC_BOOL3_UNKNOWN; 5588 } 5589 mat->num_ass++; 5590 mat->assembled = PETSC_TRUE; 5591 mat->ass_nonzerostate = mat->nonzerostate; 5592 } 5593 5594 mat->insertmode = NOT_SET_VALUES; 5595 MatAssemblyEnd_InUse--; 5596 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5597 if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) { 5598 PetscCall(MatViewFromOptions(mat, NULL, "-mat_view")); 5599 5600 if (mat->checksymmetryonassembly) { 5601 PetscCall(MatIsSymmetric(mat, mat->checksymmetrytol, &flg)); 5602 if (flg) { 5603 PetscCall(PetscPrintf(PetscObjectComm((PetscObject)mat), "Matrix is symmetric (tolerance %g)\n", (double)mat->checksymmetrytol)); 5604 } else { 5605 PetscCall(PetscPrintf(PetscObjectComm((PetscObject)mat), "Matrix is not symmetric (tolerance %g)\n", (double)mat->checksymmetrytol)); 5606 } 5607 } 5608 if (mat->nullsp && mat->checknullspaceonassembly) PetscCall(MatNullSpaceTest(mat->nullsp, mat, NULL)); 5609 } 5610 inassm--; 5611 PetscFunctionReturn(0); 5612 } 5613 5614 /*@ 5615 MatSetOption - Sets a parameter option for a matrix. Some options 5616 may be specific to certain storage formats. Some options 5617 determine how values will be inserted (or added). Sorted, 5618 row-oriented input will generally assemble the fastest. The default 5619 is row-oriented. 5620 5621 Logically Collective on mat for certain operations, such as `MAT_SPD`, not collective for `MAT_ROW_ORIENTED`, see `MatOption` 5622 5623 Input Parameters: 5624 + mat - the matrix 5625 . option - the option, one of those listed below (and possibly others), 5626 - flg - turn the option on (`PETSC_TRUE`) or off (`PETSC_FALSE`) 5627 5628 Options Describing Matrix Structure: 5629 + `MAT_SPD` - symmetric positive definite 5630 . `MAT_SYMMETRIC` - symmetric in terms of both structure and value 5631 . `MAT_HERMITIAN` - transpose is the complex conjugation 5632 . `MAT_STRUCTURALLY_SYMMETRIC` - symmetric nonzero structure 5633 . `MAT_SYMMETRY_ETERNAL` - indicates the symmetry (or Hermitian structure) or its absence will persist through any changes to the matrix 5634 . `MAT_STRUCTURAL_SYMMETRY_ETERNAL` - indicates the structural symmetry or its absence will persist through any changes to the matrix 5635 - `MAT_SPD_ETERNAL` - indicates the value of `MAT_SPD` (true or false) will persist through any changes to the matrix 5636 5637 These are not really options of the matrix, they are knowledge about the structure of the matrix that users may provide so that they 5638 do not need to be computed (usually at a high cost) 5639 5640 Options For Use with `MatSetValues()`: 5641 Insert a logically dense subblock, which can be 5642 . `MAT_ROW_ORIENTED` - row-oriented (default) 5643 5644 Note these options reflect the data you pass in with `MatSetValues()`; it has 5645 nothing to do with how the data is stored internally in the matrix 5646 data structure. 5647 5648 When (re)assembling a matrix, we can restrict the input for 5649 efficiency/debugging purposes. These options include 5650 + `MAT_NEW_NONZERO_LOCATIONS` - additional insertions will be allowed if they generate a new nonzero (slow) 5651 . `MAT_FORCE_DIAGONAL_ENTRIES` - forces diagonal entries to be allocated 5652 . `MAT_IGNORE_OFF_PROC_ENTRIES` - drops off-processor entries 5653 . `MAT_NEW_NONZERO_LOCATION_ERR` - generates an error for new matrix entry 5654 . `MAT_USE_HASH_TABLE` - uses a hash table to speed up matrix assembly 5655 . `MAT_NO_OFF_PROC_ENTRIES` - you know each process will only set values for its own rows, will generate an error if 5656 any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves 5657 performance for very large process counts. 5658 - `MAT_SUBSET_OFF_PROC_ENTRIES` - you know that the first assembly after setting this flag will set a superset 5659 of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly 5660 functions, instead sending only neighbor messages. 5661 5662 Notes: 5663 Except for `MAT_UNUSED_NONZERO_LOCATION_ERR` and `MAT_ROW_ORIENTED` all processes that share the matrix must pass the same value in flg! 5664 5665 Some options are relevant only for particular matrix types and 5666 are thus ignored by others. Other options are not supported by 5667 certain matrix types and will generate an error message if set. 5668 5669 If using a Fortran 77 module to compute a matrix, one may need to 5670 use the column-oriented option (or convert to the row-oriented 5671 format). 5672 5673 `MAT_NEW_NONZERO_LOCATIONS` set to `PETSC_FALSE` indicates that any add or insertion 5674 that would generate a new entry in the nonzero structure is instead 5675 ignored. Thus, if memory has not alredy been allocated for this particular 5676 data, then the insertion is ignored. For dense matrices, in which 5677 the entire array is allocated, no entries are ever ignored. 5678 Set after the first `MatAssemblyEnd()`. If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5679 5680 `MAT_NEW_NONZERO_LOCATION_ERR` set to PETSC_TRUE indicates that any add or insertion 5681 that would generate a new entry in the nonzero structure instead produces 5682 an error. (Currently supported for `MATAIJ` and `MATBAIJ` formats only.) If this option is set then the `MatAssemblyBegin()`/`MatAssemblyEnd()` processes has one less global reduction 5683 5684 `MAT_NEW_NONZERO_ALLOCATION_ERR` set to `PETSC_TRUE` indicates that any add or insertion 5685 that would generate a new entry that has not been preallocated will 5686 instead produce an error. (Currently supported for `MATAIJ` and `MATBAIJ` formats 5687 only.) This is a useful flag when debugging matrix memory preallocation. 5688 If this option is set then the `MatAssemblyBegin()`/`MatAssemblyEnd()` processes has one less global reduction 5689 5690 `MAT_IGNORE_OFF_PROC_ENTRIES` set to `PETSC_TRUE` indicates entries destined for 5691 other processors should be dropped, rather than stashed. 5692 This is useful if you know that the "owning" processor is also 5693 always generating the correct matrix entries, so that PETSc need 5694 not transfer duplicate entries generated on another processor. 5695 5696 `MAT_USE_HASH_TABLE` indicates that a hash table be used to improve the 5697 searches during matrix assembly. When this flag is set, the hash table 5698 is created during the first matrix assembly. This hash table is 5699 used the next time through, during `MatSetVaules()`/`MatSetVaulesBlocked()` 5700 to improve the searching of indices. `MAT_NEW_NONZERO_LOCATIONS` flag 5701 should be used with `MAT_USE_HASH_TABLE` flag. This option is currently 5702 supported by` MATMPIBAIJ` format only. 5703 5704 `MAT_KEEP_NONZERO_PATTERN` indicates when `MatZeroRows()` is called the zeroed entries 5705 are kept in the nonzero structure 5706 5707 `MAT_IGNORE_ZERO_ENTRIES` - for `MATAIJ` and `MATIS` matrices this will stop zero values from creating 5708 a zero location in the matrix 5709 5710 `MAT_USE_INODES` - indicates using inode version of the code - works with `MATAIJ` matrix types 5711 5712 `MAT_NO_OFF_PROC_ZERO_ROWS` - you know each process will only zero its own rows. This avoids all reductions in the 5713 zero row routines and thus improves performance for very large process counts. 5714 5715 `MAT_IGNORE_LOWER_TRIANGULAR` - For `MATSBAIJ` matrices will ignore any insertions you make in the lower triangular 5716 part of the matrix (since they should match the upper triangular part). 5717 5718 `MAT_SORTED_FULL` - each process provides exactly its local rows; all column indices for a given row are passed in a 5719 single call to `MatSetValues()`, preallocation is perfect, row oriented, `INSERT_VALUES` is used. Common 5720 with finite difference schemes with non-periodic boundary conditions. 5721 5722 Developer Note: 5723 `MAT_SYMMETRY_ETERNAL`, `MAT_STRUCTURAL_SYMMETRY_ETERNAL`, and `MAT_SPD_ETERNAL` are used by `MatAssemblyEnd()` and in other 5724 places where otherwise the value of `MAT_SYMMETRIC`, `MAT_STRUCTURAL_SYMMETRIC` or `MAT_SPD` would need to be changed back 5725 to `PETSC_BOOL3_UNKNOWN` because the matrix values had changed so the code cannot be certain that the related property had 5726 not changed. 5727 5728 Level: intermediate 5729 5730 .seealso: `MatOption`, `Mat`, `MatGetOption()` 5731 @*/ 5732 PetscErrorCode MatSetOption(Mat mat, MatOption op, PetscBool flg) { 5733 PetscFunctionBegin; 5734 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5735 if (op > 0) { 5736 PetscValidLogicalCollectiveEnum(mat, op, 2); 5737 PetscValidLogicalCollectiveBool(mat, flg, 3); 5738 } 5739 5740 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); 5741 5742 switch (op) { 5743 case MAT_FORCE_DIAGONAL_ENTRIES: mat->force_diagonals = flg; PetscFunctionReturn(0); 5744 case MAT_NO_OFF_PROC_ENTRIES: mat->nooffprocentries = flg; PetscFunctionReturn(0); 5745 case MAT_SUBSET_OFF_PROC_ENTRIES: 5746 mat->assembly_subset = flg; 5747 if (!mat->assembly_subset) { /* See the same logic in VecAssembly wrt VEC_SUBSET_OFF_PROC_ENTRIES */ 5748 #if !defined(PETSC_HAVE_MPIUNI) 5749 PetscCall(MatStashScatterDestroy_BTS(&mat->stash)); 5750 #endif 5751 mat->stash.first_assembly_done = PETSC_FALSE; 5752 } 5753 PetscFunctionReturn(0); 5754 case MAT_NO_OFF_PROC_ZERO_ROWS: mat->nooffproczerorows = flg; PetscFunctionReturn(0); 5755 case MAT_SPD: 5756 if (flg) { 5757 mat->spd = PETSC_BOOL3_TRUE; 5758 mat->symmetric = PETSC_BOOL3_TRUE; 5759 mat->structurally_symmetric = PETSC_BOOL3_TRUE; 5760 } else { 5761 mat->spd = PETSC_BOOL3_FALSE; 5762 } 5763 break; 5764 case MAT_SYMMETRIC: 5765 mat->symmetric = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5766 if (flg) mat->structurally_symmetric = PETSC_BOOL3_TRUE; 5767 #if !defined(PETSC_USE_COMPLEX) 5768 mat->hermitian = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5769 #endif 5770 break; 5771 case MAT_HERMITIAN: 5772 mat->hermitian = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5773 if (flg) mat->structurally_symmetric = PETSC_BOOL3_TRUE; 5774 #if !defined(PETSC_USE_COMPLEX) 5775 mat->symmetric = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5776 #endif 5777 break; 5778 case MAT_STRUCTURALLY_SYMMETRIC: mat->structurally_symmetric = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; break; 5779 case MAT_SYMMETRY_ETERNAL: 5780 PetscCheck(mat->symmetric != PETSC_BOOL3_UNKNOWN, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Cannot set MAT_SYMMETRY_ETERNAL without first setting MAT_SYMMETRIC to true or false"); 5781 mat->symmetry_eternal = flg; 5782 if (flg) mat->structural_symmetry_eternal = PETSC_TRUE; 5783 break; 5784 case MAT_STRUCTURAL_SYMMETRY_ETERNAL: 5785 PetscCheck(mat->structurally_symmetric != PETSC_BOOL3_UNKNOWN, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Cannot set MAT_STRUCTURAL_SYMMETRY_ETERNAL without first setting MAT_STRUCTURAL_SYMMETRIC to true or false"); 5786 mat->structural_symmetry_eternal = flg; 5787 break; 5788 case MAT_SPD_ETERNAL: 5789 PetscCheck(mat->spd != PETSC_BOOL3_UNKNOWN, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Cannot set MAT_SPD_ETERNAL without first setting MAT_SPD to true or false"); 5790 mat->spd_eternal = flg; 5791 if (flg) { 5792 mat->structural_symmetry_eternal = PETSC_TRUE; 5793 mat->symmetry_eternal = PETSC_TRUE; 5794 } 5795 break; 5796 case MAT_STRUCTURE_ONLY: mat->structure_only = flg; break; 5797 case MAT_SORTED_FULL: mat->sortedfull = flg; break; 5798 default: break; 5799 } 5800 PetscTryTypeMethod(mat, setoption, op, flg); 5801 PetscFunctionReturn(0); 5802 } 5803 5804 /*@ 5805 MatGetOption - Gets a parameter option that has been set for a matrix. 5806 5807 Logically Collective on mat 5808 5809 Input Parameters: 5810 + mat - the matrix 5811 - option - the option, this only responds to certain options, check the code for which ones 5812 5813 Output Parameter: 5814 . flg - turn the option on (`PETSC_TRUE`) or off (`PETSC_FALSE`) 5815 5816 Notes: 5817 Can only be called after `MatSetSizes()` and `MatSetType()` have been set. 5818 5819 Certain option values may be unknown, for those use the routines `MatIsSymmetric()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, or 5820 `MatIsSymmetricKnown()`, `MatIsHermitianKnown()`, `MatIsStructurallySymmetricKnown()` 5821 5822 Level: intermediate 5823 5824 .seealso: `MatOption`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, 5825 `MatIsSymmetricKnown()`, `MatIsHermitianKnown()`, `MatIsStructurallySymmetricKnown()` 5826 @*/ 5827 PetscErrorCode MatGetOption(Mat mat, MatOption op, PetscBool *flg) { 5828 PetscFunctionBegin; 5829 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5830 PetscValidType(mat, 1); 5831 5832 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); 5833 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()"); 5834 5835 switch (op) { 5836 case MAT_NO_OFF_PROC_ENTRIES: *flg = mat->nooffprocentries; break; 5837 case MAT_NO_OFF_PROC_ZERO_ROWS: *flg = mat->nooffproczerorows; break; 5838 case MAT_SYMMETRIC: SETERRQ(PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Use MatIsSymmetric() or MatIsSymmetricKnown()"); break; 5839 case MAT_HERMITIAN: SETERRQ(PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Use MatIsHermitian() or MatIsHermitianKnown()"); break; 5840 case MAT_STRUCTURALLY_SYMMETRIC: SETERRQ(PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Use MatIsStructurallySymmetric() or MatIsStructurallySymmetricKnown()"); break; 5841 case MAT_SPD: SETERRQ(PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Use MatIsSPDKnown()"); break; 5842 case MAT_SYMMETRY_ETERNAL: *flg = mat->symmetry_eternal; break; 5843 case MAT_STRUCTURAL_SYMMETRY_ETERNAL: *flg = mat->symmetry_eternal; break; 5844 default: break; 5845 } 5846 PetscFunctionReturn(0); 5847 } 5848 5849 /*@ 5850 MatZeroEntries - Zeros all entries of a matrix. For sparse matrices 5851 this routine retains the old nonzero structure. 5852 5853 Logically Collective on mat 5854 5855 Input Parameters: 5856 . mat - the matrix 5857 5858 Level: intermediate 5859 5860 Note: 5861 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. 5862 See the Performance chapter of the users manual for information on preallocating matrices. 5863 5864 .seealso: `Mat`, `MatZeroRows()`, `MatZeroRowsColumns()` 5865 @*/ 5866 PetscErrorCode MatZeroEntries(Mat mat) { 5867 PetscFunctionBegin; 5868 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5869 PetscValidType(mat, 1); 5870 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 5871 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"); 5872 MatCheckPreallocated(mat, 1); 5873 5874 PetscCall(PetscLogEventBegin(MAT_ZeroEntries, mat, 0, 0, 0)); 5875 PetscUseTypeMethod(mat, zeroentries); 5876 PetscCall(PetscLogEventEnd(MAT_ZeroEntries, mat, 0, 0, 0)); 5877 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5878 PetscFunctionReturn(0); 5879 } 5880 5881 /*@ 5882 MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal) 5883 of a set of rows and columns of a matrix. 5884 5885 Collective on mat 5886 5887 Input Parameters: 5888 + mat - the matrix 5889 . numRows - the number of rows to remove 5890 . rows - the global row indices 5891 . diag - value put in the diagonal of the eliminated rows 5892 . x - optional vector of solutions for zeroed rows (other entries in vector are not used), these must be set before this call 5893 - b - optional vector of right hand side, that will be adjusted by provided solution 5894 5895 Notes: 5896 This routine, along with `MatZeroRows()`, is typically used to eliminate known Dirichlet boundary conditions from a linear system. 5897 5898 For each zeroed row, the value of the corresponding b is set to diag times the value of the corresponding x. 5899 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 5900 5901 If the resulting linear system is to be solved with `KSP` then one can (but does not have to) call `KSPSetInitialGuessNonzero()` to allow the 5902 Krylov method to take advantage of the known solution on the zeroed rows. 5903 5904 For the parallel case, all processes that share the matrix (i.e., 5905 those in the communicator used for matrix creation) MUST call this 5906 routine, regardless of whether any rows being zeroed are owned by 5907 them. 5908 5909 Unlike `MatZeroRows()` this does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5910 5911 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5912 list only rows local to itself). 5913 5914 The option `MAT_NO_OFF_PROC_ZERO_ROWS` does not apply to this routine. 5915 5916 Level: intermediate 5917 5918 .seealso: `MatZeroRowsIS()`, `MatZeroRows()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 5919 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 5920 @*/ 5921 PetscErrorCode MatZeroRowsColumns(Mat mat, PetscInt numRows, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) { 5922 PetscFunctionBegin; 5923 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5924 PetscValidType(mat, 1); 5925 if (numRows) PetscValidIntPointer(rows, 3); 5926 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 5927 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 5928 MatCheckPreallocated(mat, 1); 5929 5930 PetscUseTypeMethod(mat, zerorowscolumns, numRows, rows, diag, x, b); 5931 PetscCall(MatViewFromOptions(mat, NULL, "-mat_view")); 5932 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5933 PetscFunctionReturn(0); 5934 } 5935 5936 /*@ 5937 MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal) 5938 of a set of rows and columns of a matrix. 5939 5940 Collective on mat 5941 5942 Input Parameters: 5943 + mat - the matrix 5944 . is - the rows to zero 5945 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5946 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5947 - b - optional vector of right hand side, that will be adjusted by provided solution 5948 5949 Note: 5950 See `MatZeroRowsColumns()` for details on how this routine operates. 5951 5952 Level: intermediate 5953 5954 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 5955 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRows()`, `MatZeroRowsColumnsStencil()` 5956 @*/ 5957 PetscErrorCode MatZeroRowsColumnsIS(Mat mat, IS is, PetscScalar diag, Vec x, Vec b) { 5958 PetscInt numRows; 5959 const PetscInt *rows; 5960 5961 PetscFunctionBegin; 5962 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5963 PetscValidHeaderSpecific(is, IS_CLASSID, 2); 5964 PetscValidType(mat, 1); 5965 PetscValidType(is, 2); 5966 PetscCall(ISGetLocalSize(is, &numRows)); 5967 PetscCall(ISGetIndices(is, &rows)); 5968 PetscCall(MatZeroRowsColumns(mat, numRows, rows, diag, x, b)); 5969 PetscCall(ISRestoreIndices(is, &rows)); 5970 PetscFunctionReturn(0); 5971 } 5972 5973 /*@ 5974 MatZeroRows - Zeros all entries (except possibly the main diagonal) 5975 of a set of rows of a matrix. 5976 5977 Collective on mat 5978 5979 Input Parameters: 5980 + mat - the matrix 5981 . numRows - the number of rows to remove 5982 . rows - the global row indices 5983 . diag - value put in the diagonal of the eliminated rows 5984 . x - optional vector of solutions for zeroed rows (other entries in vector are not used), these must be set before this call 5985 - b - optional vector of right hand side, that will be adjusted by provided solution 5986 5987 Notes: 5988 This routine, along with `MatZeroRowsColumns()`, is typically used to eliminate known Dirichlet boundary conditions from a linear system. 5989 5990 For each zeroed row, the value of the corresponding b is set to diag times the value of the corresponding x. 5991 5992 If the resulting linear system is to be solved with `KSP` then one can (but does not have to) call `KSPSetInitialGuessNonzero()` to allow the 5993 Krylov method to take advantage of the known solution on the zeroed rows. 5994 5995 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) 5996 from the matrix. 5997 5998 Unlike `MatZeroRowsColumns()` for the `MATAIJ` and `MATBAIJ` matrix formats this removes the old nonzero structure, from the eliminated rows of the matrix 5999 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 6000 formats this does not alter the nonzero structure. 6001 6002 If the option `MatSetOption`(mat,`MAT_KEEP_NONZERO_PATTERN`,`PETSC_TRUE`) the nonzero structure 6003 of the matrix is not changed the values are 6004 merely zeroed. 6005 6006 The user can set a value in the diagonal entry (or for the `MATAIJ` format 6007 formats can optionally remove the main diagonal entry from the 6008 nonzero structure as well, by passing 0.0 as the final argument). 6009 6010 For the parallel case, all processes that share the matrix (i.e., 6011 those in the communicator used for matrix creation) MUST call this 6012 routine, regardless of whether any rows being zeroed are owned by 6013 them. 6014 6015 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6016 list only rows local to itself). 6017 6018 You can call `MatSetOption`(mat,`MAT_NO_OFF_PROC_ZERO_ROWS`,`PETSC_TRUE`) if each process indicates only rows it 6019 owns that are to be zeroed. This saves a global synchronization in the implementation. 6020 6021 Level: intermediate 6022 6023 .seealso: `Mat`, `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6024 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()`, `PCREDISTRIBUTE` 6025 @*/ 6026 PetscErrorCode MatZeroRows(Mat mat, PetscInt numRows, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) { 6027 PetscFunctionBegin; 6028 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6029 PetscValidType(mat, 1); 6030 if (numRows) PetscValidIntPointer(rows, 3); 6031 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 6032 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 6033 MatCheckPreallocated(mat, 1); 6034 6035 PetscUseTypeMethod(mat, zerorows, numRows, rows, diag, x, b); 6036 PetscCall(MatViewFromOptions(mat, NULL, "-mat_view")); 6037 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6038 PetscFunctionReturn(0); 6039 } 6040 6041 /*@ 6042 MatZeroRowsIS - Zeros all entries (except possibly the main diagonal) 6043 of a set of rows of a matrix. 6044 6045 Collective on Mat 6046 6047 Input Parameters: 6048 + mat - the matrix 6049 . is - index set of rows to remove (if NULL then no row is removed) 6050 . diag - value put in all diagonals of eliminated rows 6051 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6052 - b - optional vector of right hand side, that will be adjusted by provided solution 6053 6054 Note: 6055 See `MatZeroRows()` for details on how this routine operates. 6056 6057 Level: intermediate 6058 6059 .seealso: `MatZeroRows()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6060 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6061 @*/ 6062 PetscErrorCode MatZeroRowsIS(Mat mat, IS is, PetscScalar diag, Vec x, Vec b) { 6063 PetscInt numRows = 0; 6064 const PetscInt *rows = NULL; 6065 6066 PetscFunctionBegin; 6067 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6068 PetscValidType(mat, 1); 6069 if (is) { 6070 PetscValidHeaderSpecific(is, IS_CLASSID, 2); 6071 PetscCall(ISGetLocalSize(is, &numRows)); 6072 PetscCall(ISGetIndices(is, &rows)); 6073 } 6074 PetscCall(MatZeroRows(mat, numRows, rows, diag, x, b)); 6075 if (is) PetscCall(ISRestoreIndices(is, &rows)); 6076 PetscFunctionReturn(0); 6077 } 6078 6079 /*@ 6080 MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal) 6081 of a set of rows of a matrix. These rows must be local to the process. 6082 6083 Collective on mat 6084 6085 Input Parameters: 6086 + mat - the matrix 6087 . numRows - the number of rows to remove 6088 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 6089 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6090 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6091 - b - optional vector of right hand side, that will be adjusted by provided solution 6092 6093 Notes: 6094 See `MatZeroRows()` for details on how this routine operates. 6095 6096 The grid coordinates are across the entire grid, not just the local portion 6097 6098 In Fortran idxm and idxn should be declared as 6099 $ MatStencil idxm(4,m) 6100 and the values inserted using 6101 $ idxm(MatStencil_i,1) = i 6102 $ idxm(MatStencil_j,1) = j 6103 $ idxm(MatStencil_k,1) = k 6104 $ idxm(MatStencil_c,1) = c 6105 etc 6106 6107 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6108 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6109 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6110 `DM_BOUNDARY_PERIODIC` boundary type. 6111 6112 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 6113 a single value per point) you can skip filling those indices. 6114 6115 Level: intermediate 6116 6117 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsl()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6118 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6119 @*/ 6120 PetscErrorCode MatZeroRowsStencil(Mat mat, PetscInt numRows, const MatStencil rows[], PetscScalar diag, Vec x, Vec b) { 6121 PetscInt dim = mat->stencil.dim; 6122 PetscInt sdim = dim - (1 - (PetscInt)mat->stencil.noc); 6123 PetscInt *dims = mat->stencil.dims + 1; 6124 PetscInt *starts = mat->stencil.starts; 6125 PetscInt *dxm = (PetscInt *)rows; 6126 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6127 6128 PetscFunctionBegin; 6129 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6130 PetscValidType(mat, 1); 6131 if (numRows) PetscValidPointer(rows, 3); 6132 6133 PetscCall(PetscMalloc1(numRows, &jdxm)); 6134 for (i = 0; i < numRows; ++i) { 6135 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6136 for (j = 0; j < 3 - sdim; ++j) dxm++; 6137 /* Local index in X dir */ 6138 tmp = *dxm++ - starts[0]; 6139 /* Loop over remaining dimensions */ 6140 for (j = 0; j < dim - 1; ++j) { 6141 /* If nonlocal, set index to be negative */ 6142 if ((*dxm++ - starts[j + 1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6143 /* Update local index */ 6144 else tmp = tmp * dims[j] + *(dxm - 1) - starts[j + 1]; 6145 } 6146 /* Skip component slot if necessary */ 6147 if (mat->stencil.noc) dxm++; 6148 /* Local row number */ 6149 if (tmp >= 0) jdxm[numNewRows++] = tmp; 6150 } 6151 PetscCall(MatZeroRowsLocal(mat, numNewRows, jdxm, diag, x, b)); 6152 PetscCall(PetscFree(jdxm)); 6153 PetscFunctionReturn(0); 6154 } 6155 6156 /*@ 6157 MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal) 6158 of a set of rows and columns of a matrix. 6159 6160 Collective on mat 6161 6162 Input Parameters: 6163 + mat - the matrix 6164 . numRows - the number of rows/columns to remove 6165 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 6166 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6167 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6168 - b - optional vector of right hand side, that will be adjusted by provided solution 6169 6170 Notes: 6171 See `MatZeroRowsColumns()` for details on how this routine operates. 6172 6173 The grid coordinates are across the entire grid, not just the local portion 6174 6175 In Fortran idxm and idxn should be declared as 6176 $ MatStencil idxm(4,m) 6177 and the values inserted using 6178 $ idxm(MatStencil_i,1) = i 6179 $ idxm(MatStencil_j,1) = j 6180 $ idxm(MatStencil_k,1) = k 6181 $ idxm(MatStencil_c,1) = c 6182 etc 6183 6184 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6185 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6186 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6187 `DM_BOUNDARY_PERIODIC` boundary type. 6188 6189 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 6190 a single value per point) you can skip filling those indices. 6191 6192 Level: intermediate 6193 6194 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6195 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRows()` 6196 @*/ 6197 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat, PetscInt numRows, const MatStencil rows[], PetscScalar diag, Vec x, Vec b) { 6198 PetscInt dim = mat->stencil.dim; 6199 PetscInt sdim = dim - (1 - (PetscInt)mat->stencil.noc); 6200 PetscInt *dims = mat->stencil.dims + 1; 6201 PetscInt *starts = mat->stencil.starts; 6202 PetscInt *dxm = (PetscInt *)rows; 6203 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6204 6205 PetscFunctionBegin; 6206 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6207 PetscValidType(mat, 1); 6208 if (numRows) PetscValidPointer(rows, 3); 6209 6210 PetscCall(PetscMalloc1(numRows, &jdxm)); 6211 for (i = 0; i < numRows; ++i) { 6212 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6213 for (j = 0; j < 3 - sdim; ++j) dxm++; 6214 /* Local index in X dir */ 6215 tmp = *dxm++ - starts[0]; 6216 /* Loop over remaining dimensions */ 6217 for (j = 0; j < dim - 1; ++j) { 6218 /* If nonlocal, set index to be negative */ 6219 if ((*dxm++ - starts[j + 1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6220 /* Update local index */ 6221 else tmp = tmp * dims[j] + *(dxm - 1) - starts[j + 1]; 6222 } 6223 /* Skip component slot if necessary */ 6224 if (mat->stencil.noc) dxm++; 6225 /* Local row number */ 6226 if (tmp >= 0) jdxm[numNewRows++] = tmp; 6227 } 6228 PetscCall(MatZeroRowsColumnsLocal(mat, numNewRows, jdxm, diag, x, b)); 6229 PetscCall(PetscFree(jdxm)); 6230 PetscFunctionReturn(0); 6231 } 6232 6233 /*@C 6234 MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal) 6235 of a set of rows of a matrix; using local numbering of rows. 6236 6237 Collective on mat 6238 6239 Input Parameters: 6240 + mat - the matrix 6241 . numRows - the number of rows to remove 6242 . rows - the local row indices 6243 . diag - value put in all diagonals of eliminated rows 6244 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6245 - b - optional vector of right hand side, that will be adjusted by provided solution 6246 6247 Notes: 6248 Before calling `MatZeroRowsLocal()`, the user must first set the 6249 local-to-global mapping by calling MatSetLocalToGlobalMapping(), this is often already set for matrices obtained with `DMCreateMatrix()`. 6250 6251 See `MatZeroRows()` for details on how this routine operates. 6252 6253 Level: intermediate 6254 6255 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRows()`, `MatSetOption()`, 6256 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6257 @*/ 6258 PetscErrorCode MatZeroRowsLocal(Mat mat, PetscInt numRows, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) { 6259 PetscFunctionBegin; 6260 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6261 PetscValidType(mat, 1); 6262 if (numRows) PetscValidIntPointer(rows, 3); 6263 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 6264 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 6265 MatCheckPreallocated(mat, 1); 6266 6267 if (mat->ops->zerorowslocal) { 6268 PetscUseTypeMethod(mat, zerorowslocal, numRows, rows, diag, x, b); 6269 } else { 6270 IS is, newis; 6271 const PetscInt *newRows; 6272 6273 PetscCheck(mat->rmap->mapping, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Need to provide local to global mapping to matrix first"); 6274 PetscCall(ISCreateGeneral(PETSC_COMM_SELF, numRows, rows, PETSC_COPY_VALUES, &is)); 6275 PetscCall(ISLocalToGlobalMappingApplyIS(mat->rmap->mapping, is, &newis)); 6276 PetscCall(ISGetIndices(newis, &newRows)); 6277 PetscUseTypeMethod(mat, zerorows, numRows, newRows, diag, x, b); 6278 PetscCall(ISRestoreIndices(newis, &newRows)); 6279 PetscCall(ISDestroy(&newis)); 6280 PetscCall(ISDestroy(&is)); 6281 } 6282 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6283 PetscFunctionReturn(0); 6284 } 6285 6286 /*@ 6287 MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal) 6288 of a set of rows of a matrix; using local numbering of rows. 6289 6290 Collective on mat 6291 6292 Input Parameters: 6293 + mat - the matrix 6294 . is - index set of rows to remove 6295 . diag - value put in all diagonals of eliminated rows 6296 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6297 - b - optional vector of right hand side, that will be adjusted by provided solution 6298 6299 Notes: 6300 Before calling `MatZeroRowsLocalIS()`, the user must first set the 6301 local-to-global mapping by calling `MatSetLocalToGlobalMapping()`, this is often already set for matrices obtained with `DMCreateMatrix()`. 6302 6303 See `MatZeroRows()` for details on how this routine operates. 6304 6305 Level: intermediate 6306 6307 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRows()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6308 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6309 @*/ 6310 PetscErrorCode MatZeroRowsLocalIS(Mat mat, IS is, PetscScalar diag, Vec x, Vec b) { 6311 PetscInt numRows; 6312 const PetscInt *rows; 6313 6314 PetscFunctionBegin; 6315 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6316 PetscValidType(mat, 1); 6317 PetscValidHeaderSpecific(is, IS_CLASSID, 2); 6318 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 6319 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 6320 MatCheckPreallocated(mat, 1); 6321 6322 PetscCall(ISGetLocalSize(is, &numRows)); 6323 PetscCall(ISGetIndices(is, &rows)); 6324 PetscCall(MatZeroRowsLocal(mat, numRows, rows, diag, x, b)); 6325 PetscCall(ISRestoreIndices(is, &rows)); 6326 PetscFunctionReturn(0); 6327 } 6328 6329 /*@ 6330 MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal) 6331 of a set of rows and columns of a matrix; using local numbering of rows. 6332 6333 Collective on mat 6334 6335 Input Parameters: 6336 + mat - the matrix 6337 . numRows - the number of rows to remove 6338 . rows - the global row indices 6339 . diag - value put in all diagonals of eliminated rows 6340 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6341 - b - optional vector of right hand side, that will be adjusted by provided solution 6342 6343 Notes: 6344 Before calling `MatZeroRowsColumnsLocal()`, the user must first set the 6345 local-to-global mapping by calling `MatSetLocalToGlobalMapping()`, this is often already set for matrices obtained with `DMCreateMatrix()`. 6346 6347 See `MatZeroRowsColumns()` for details on how this routine operates. 6348 6349 Level: intermediate 6350 6351 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6352 `MatZeroRows()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6353 @*/ 6354 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat, PetscInt numRows, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) { 6355 IS is, newis; 6356 const PetscInt *newRows; 6357 6358 PetscFunctionBegin; 6359 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6360 PetscValidType(mat, 1); 6361 if (numRows) PetscValidIntPointer(rows, 3); 6362 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 6363 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 6364 MatCheckPreallocated(mat, 1); 6365 6366 PetscCheck(mat->cmap->mapping, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Need to provide local to global mapping to matrix first"); 6367 PetscCall(ISCreateGeneral(PETSC_COMM_SELF, numRows, rows, PETSC_COPY_VALUES, &is)); 6368 PetscCall(ISLocalToGlobalMappingApplyIS(mat->cmap->mapping, is, &newis)); 6369 PetscCall(ISGetIndices(newis, &newRows)); 6370 PetscUseTypeMethod(mat, zerorowscolumns, numRows, newRows, diag, x, b); 6371 PetscCall(ISRestoreIndices(newis, &newRows)); 6372 PetscCall(ISDestroy(&newis)); 6373 PetscCall(ISDestroy(&is)); 6374 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6375 PetscFunctionReturn(0); 6376 } 6377 6378 /*@ 6379 MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal) 6380 of a set of rows and columns of a matrix; using local numbering of rows. 6381 6382 Collective on Mat 6383 6384 Input Parameters: 6385 + mat - the matrix 6386 . is - index set of rows to remove 6387 . diag - value put in all diagonals of eliminated rows 6388 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6389 - b - optional vector of right hand side, that will be adjusted by provided solution 6390 6391 Notes: 6392 Before calling `MatZeroRowsColumnsLocalIS()`, the user must first set the 6393 local-to-global mapping by calling `MatSetLocalToGlobalMapping()`, this is often already set for matrices obtained with `DMCreateMatrix()`. 6394 6395 See `MatZeroRowsColumns()` for details on how this routine operates. 6396 6397 Level: intermediate 6398 6399 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6400 `MatZeroRowsColumnsLocal()`, `MatZeroRows()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6401 @*/ 6402 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat, IS is, PetscScalar diag, Vec x, Vec b) { 6403 PetscInt numRows; 6404 const PetscInt *rows; 6405 6406 PetscFunctionBegin; 6407 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6408 PetscValidType(mat, 1); 6409 PetscValidHeaderSpecific(is, IS_CLASSID, 2); 6410 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 6411 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 6412 MatCheckPreallocated(mat, 1); 6413 6414 PetscCall(ISGetLocalSize(is, &numRows)); 6415 PetscCall(ISGetIndices(is, &rows)); 6416 PetscCall(MatZeroRowsColumnsLocal(mat, numRows, rows, diag, x, b)); 6417 PetscCall(ISRestoreIndices(is, &rows)); 6418 PetscFunctionReturn(0); 6419 } 6420 6421 /*@C 6422 MatGetSize - Returns the numbers of rows and columns in a matrix. 6423 6424 Not Collective 6425 6426 Input Parameter: 6427 . mat - the matrix 6428 6429 Output Parameters: 6430 + m - the number of global rows 6431 - n - the number of global columns 6432 6433 Note: both output parameters can be NULL on input. 6434 6435 Level: beginner 6436 6437 .seealso: `Mat`, `MatSetSizes()`, `MatGetLocalSize()` 6438 @*/ 6439 PetscErrorCode MatGetSize(Mat mat, PetscInt *m, PetscInt *n) { 6440 PetscFunctionBegin; 6441 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6442 if (m) *m = mat->rmap->N; 6443 if (n) *n = mat->cmap->N; 6444 PetscFunctionReturn(0); 6445 } 6446 6447 /*@C 6448 MatGetLocalSize - For most matrix formats, excluding `MATELEMENTAL` and `MATSCALAPACK`, Returns the number of local rows and local columns 6449 of a matrix. For all matrices this is the local size of the left and right vectors as returned by `MatCreateVecs()`. 6450 6451 Not Collective 6452 6453 Input Parameter: 6454 . mat - the matrix 6455 6456 Output Parameters: 6457 + m - the number of local rows, use `NULL` to not obtain this value 6458 - n - the number of local columns, use `NULL` to not obtain this value 6459 6460 Level: beginner 6461 6462 .seealso: `Mat`, `MatSetSizes()`, `MatGetSize()` 6463 @*/ 6464 PetscErrorCode MatGetLocalSize(Mat mat, PetscInt *m, PetscInt *n) { 6465 PetscFunctionBegin; 6466 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6467 if (m) PetscValidIntPointer(m, 2); 6468 if (n) PetscValidIntPointer(n, 3); 6469 if (m) *m = mat->rmap->n; 6470 if (n) *n = mat->cmap->n; 6471 PetscFunctionReturn(0); 6472 } 6473 6474 /*@C 6475 MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies this matrix by that are owned by 6476 this processor. (The columns of the "diagonal block" for most sparse matrix formats). See :any:`<sec_matlayout>` for details on matrix layouts. 6477 6478 Not Collective, unless matrix has not been allocated, then collective on mat 6479 6480 Input Parameter: 6481 . mat - the matrix 6482 6483 Output Parameters: 6484 + m - the global index of the first local column, use `NULL` to not obtain this value 6485 - n - one more than the global index of the last local column, use `NULL` to not obtain this value 6486 6487 Level: developer 6488 6489 .seealso: `Mat`, `MatGetOwnershipRange()`, `MatGetOwnershipRanges()`, `MatGetOwnershipRangesColumn()`, `PetscLayout` 6490 @*/ 6491 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat, PetscInt *m, PetscInt *n) { 6492 PetscFunctionBegin; 6493 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6494 PetscValidType(mat, 1); 6495 if (m) PetscValidIntPointer(m, 2); 6496 if (n) PetscValidIntPointer(n, 3); 6497 MatCheckPreallocated(mat, 1); 6498 if (m) *m = mat->cmap->rstart; 6499 if (n) *n = mat->cmap->rend; 6500 PetscFunctionReturn(0); 6501 } 6502 6503 /*@C 6504 MatGetOwnershipRange - For matrices that own values by row, excludes `MATELEMENTAL` and `MATSCALAPACK`, returns the range of matrix rows owned by 6505 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 6506 vector product with this matrix. See :any:`<sec_matlayout>` for details on matrix layouts 6507 6508 Not Collective 6509 6510 Input Parameter: 6511 . mat - the matrix 6512 6513 Output Parameters: 6514 + m - the global index of the first local row, use `NULL` to not obtain this value 6515 - n - one more than the global index of the last local row, use `NULL` to not obtain this value 6516 6517 Note: 6518 This function requires that the matrix be preallocated. If you have not preallocated, consider using 6519 `PetscSplitOwnership`(`MPI_Comm` comm, `PetscInt` *n, `PetscInt` *N) 6520 and then `MPI_Scan()` to calculate prefix sums of the local sizes. 6521 6522 Level: beginner 6523 6524 .seealso: `MatGetOwnershipRanges()`, `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRangesColumn()`, `PetscSplitOwnership()`, `PetscSplitOwnershipBlock()`, 6525 `PetscLayout` 6526 @*/ 6527 PetscErrorCode MatGetOwnershipRange(Mat mat, PetscInt *m, PetscInt *n) { 6528 PetscFunctionBegin; 6529 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6530 PetscValidType(mat, 1); 6531 if (m) PetscValidIntPointer(m, 2); 6532 if (n) PetscValidIntPointer(n, 3); 6533 MatCheckPreallocated(mat, 1); 6534 if (m) *m = mat->rmap->rstart; 6535 if (n) *n = mat->rmap->rend; 6536 PetscFunctionReturn(0); 6537 } 6538 6539 /*@C 6540 MatGetOwnershipRanges - For matrices that own values by row, excludes `MATELEMENTAL` and `MATSCALAPACK`, returns the range of matrix rows owned by 6541 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 6542 vector product with this matrix. See :any:`<sec_matlayout>` for details on matrix layouts 6543 6544 Not Collective, unless matrix has not been allocated, then collective on mat 6545 6546 Input Parameters: 6547 . mat - the matrix 6548 6549 Output Parameters: 6550 . ranges - start of each processors portion plus one more than the total length at the end 6551 6552 Level: beginner 6553 6554 .seealso: `Mat`, `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRangesColumn()`, `PetscLayout` 6555 @*/ 6556 PetscErrorCode MatGetOwnershipRanges(Mat mat, const PetscInt **ranges) { 6557 PetscFunctionBegin; 6558 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6559 PetscValidType(mat, 1); 6560 MatCheckPreallocated(mat, 1); 6561 PetscCall(PetscLayoutGetRanges(mat->rmap, ranges)); 6562 PetscFunctionReturn(0); 6563 } 6564 6565 /*@C 6566 MatGetOwnershipRangesColumn - Returns the ranges of matrix columns associated with rows of a vector one multiplies this vector by that are owned by 6567 each processor. (The columns of the "diagonal blocks", for most sparse matrix formats). See :any:`<sec_matlayout>` for details on matrix layouts. 6568 6569 Not Collective, unless matrix has not been allocated, then collective on Mat 6570 6571 Input Parameters: 6572 . mat - the matrix 6573 6574 Output Parameters: 6575 . ranges - start of each processors portion plus one more then the total length at the end 6576 6577 Level: beginner 6578 6579 .seealso: `Mat`, `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRanges()` 6580 @*/ 6581 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat, const PetscInt **ranges) { 6582 PetscFunctionBegin; 6583 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6584 PetscValidType(mat, 1); 6585 MatCheckPreallocated(mat, 1); 6586 PetscCall(PetscLayoutGetRanges(mat->cmap, ranges)); 6587 PetscFunctionReturn(0); 6588 } 6589 6590 /*@C 6591 MatGetOwnershipIS - Get row and column ownership of a matrices' values as index sets. For most matrices, excluding `MATELEMENTAL` and `MATSCALAPACK`, this 6592 corresponds to values returned by `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`. For `MATELEMENTAL` and `MATSCALAPACK` the ownership 6593 is more complicated. See :any:`<sec_matlayout>` for details on matrix layouts. 6594 6595 Not Collective 6596 6597 Input Parameter: 6598 . A - matrix 6599 6600 Output Parameters: 6601 + rows - rows in which this process owns elements, , use `NULL` to not obtain this value 6602 - cols - columns in which this process owns elements, use `NULL` to not obtain this value 6603 6604 Level: intermediate 6605 6606 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`, `MatSetValues()`, ``MATELEMENTAL``, ``MATSCALAPACK`` 6607 @*/ 6608 PetscErrorCode MatGetOwnershipIS(Mat A, IS *rows, IS *cols) { 6609 PetscErrorCode (*f)(Mat, IS *, IS *); 6610 6611 PetscFunctionBegin; 6612 MatCheckPreallocated(A, 1); 6613 PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatGetOwnershipIS_C", &f)); 6614 if (f) { 6615 PetscCall((*f)(A, rows, cols)); 6616 } else { /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */ 6617 if (rows) PetscCall(ISCreateStride(PETSC_COMM_SELF, A->rmap->n, A->rmap->rstart, 1, rows)); 6618 if (cols) PetscCall(ISCreateStride(PETSC_COMM_SELF, A->cmap->N, 0, 1, cols)); 6619 } 6620 PetscFunctionReturn(0); 6621 } 6622 6623 /*@C 6624 MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix obtained with `MatGetFactor()` 6625 Uses levels of fill only, not drop tolerance. Use `MatLUFactorNumeric()` 6626 to complete the factorization. 6627 6628 Collective on fact 6629 6630 Input Parameters: 6631 + fact - the factorized matrix obtained with `MatGetFactor()` 6632 . mat - the matrix 6633 . row - row permutation 6634 . column - column permutation 6635 - info - structure containing 6636 $ levels - number of levels of fill. 6637 $ expected fill - as ratio of original fill. 6638 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 6639 missing diagonal entries) 6640 6641 Output Parameters: 6642 . fact - new matrix that has been symbolically factored 6643 6644 Level: developer 6645 6646 Notes: 6647 See [Matrix Factorization](sec_matfactor) for additional information. 6648 6649 Most users should employ the `KSP` interface for linear solvers 6650 instead of working directly with matrix algebra routines such as this. 6651 See, e.g., `KSPCreate()`. 6652 6653 Uses the definition of level of fill as in Y. Saad, 2003 6654 6655 Developer Note: 6656 The Fortran interface is not autogenerated as the f90 6657 interface definition cannot be generated correctly [due to `MatFactorInfo`] 6658 6659 References: 6660 . * - Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6661 6662 .seealso: [Matrix Factorization](sec_matfactor), `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()` 6663 `MatGetOrdering()`, `MatFactorInfo` 6664 @*/ 6665 PetscErrorCode MatILUFactorSymbolic(Mat fact, Mat mat, IS row, IS col, const MatFactorInfo *info) { 6666 PetscFunctionBegin; 6667 PetscValidHeaderSpecific(mat, MAT_CLASSID, 2); 6668 PetscValidType(mat, 2); 6669 if (row) PetscValidHeaderSpecific(row, IS_CLASSID, 3); 6670 if (col) PetscValidHeaderSpecific(col, IS_CLASSID, 4); 6671 PetscValidPointer(info, 5); 6672 PetscValidPointer(fact, 1); 6673 PetscCheck(info->levels >= 0, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_OUTOFRANGE, "Levels of fill negative %" PetscInt_FMT, (PetscInt)info->levels); 6674 PetscCheck(info->fill >= 1.0, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_OUTOFRANGE, "Expected fill less than 1.0 %g", (double)info->fill); 6675 if (!fact->ops->ilufactorsymbolic) { 6676 MatSolverType stype; 6677 PetscCall(MatFactorGetSolverType(fact, &stype)); 6678 SETERRQ(PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Matrix type %s symbolic ILU using solver type %s", ((PetscObject)mat)->type_name, stype); 6679 } 6680 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 6681 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 6682 MatCheckPreallocated(mat, 2); 6683 6684 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_ILUFactorSymbolic, mat, row, col, 0)); 6685 PetscCall((fact->ops->ilufactorsymbolic)(fact, mat, row, col, info)); 6686 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_ILUFactorSymbolic, mat, row, col, 0)); 6687 PetscFunctionReturn(0); 6688 } 6689 6690 /*@C 6691 MatICCFactorSymbolic - Performs symbolic incomplete 6692 Cholesky factorization for a symmetric matrix. Use 6693 `MatCholeskyFactorNumeric()` to complete the factorization. 6694 6695 Collective on fact 6696 6697 Input Parameters: 6698 + fact - the factorized matrix obtained with `MatGetFactor()` 6699 . mat - the matrix to be factored 6700 . perm - row and column permutation 6701 - info - structure containing 6702 $ levels - number of levels of fill. 6703 $ expected fill - as ratio of original fill. 6704 6705 Output Parameter: 6706 . fact - the factored matrix 6707 6708 Level: developer 6709 6710 Notes: 6711 Most users should employ the `KSP` interface for linear solvers 6712 instead of working directly with matrix algebra routines such as this. 6713 See, e.g., `KSPCreate()`. 6714 6715 This uses the definition of level of fill as in Y. Saad, 2003 6716 6717 Developer Note: 6718 The Fortran interface is not autogenerated as the f90 6719 interface definition cannot be generated correctly [due to `MatFactorInfo`] 6720 6721 References: 6722 . * - Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6723 6724 .seealso: `MatGetFactor()`, `MatCholeskyFactorNumeric()`, `MatCholeskyFactor()`, `MatFactorInfo` 6725 @*/ 6726 PetscErrorCode MatICCFactorSymbolic(Mat fact, Mat mat, IS perm, const MatFactorInfo *info) { 6727 PetscFunctionBegin; 6728 PetscValidHeaderSpecific(mat, MAT_CLASSID, 2); 6729 PetscValidType(mat, 2); 6730 if (perm) PetscValidHeaderSpecific(perm, IS_CLASSID, 3); 6731 PetscValidPointer(info, 4); 6732 PetscValidPointer(fact, 1); 6733 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 6734 PetscCheck(info->levels >= 0, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_OUTOFRANGE, "Levels negative %" PetscInt_FMT, (PetscInt)info->levels); 6735 PetscCheck(info->fill >= 1.0, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_OUTOFRANGE, "Expected fill less than 1.0 %g", (double)info->fill); 6736 if (!(fact)->ops->iccfactorsymbolic) { 6737 MatSolverType stype; 6738 PetscCall(MatFactorGetSolverType(fact, &stype)); 6739 SETERRQ(PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Matrix type %s symbolic ICC using solver type %s", ((PetscObject)mat)->type_name, stype); 6740 } 6741 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 6742 MatCheckPreallocated(mat, 2); 6743 6744 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_ICCFactorSymbolic, mat, perm, 0, 0)); 6745 PetscCall((fact->ops->iccfactorsymbolic)(fact, mat, perm, info)); 6746 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_ICCFactorSymbolic, mat, perm, 0, 0)); 6747 PetscFunctionReturn(0); 6748 } 6749 6750 /*@C 6751 MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat 6752 points to an array of valid matrices, they may be reused to store the new 6753 submatrices. 6754 6755 Collective on mat 6756 6757 Input Parameters: 6758 + mat - the matrix 6759 . n - the number of submatrixes to be extracted (on this processor, may be zero) 6760 . irow, icol - index sets of rows and columns to extract 6761 - scall - either `MAT_INITIAL_MATRIX` or `MAT_REUSE_MATRIX` 6762 6763 Output Parameter: 6764 . submat - the array of submatrices 6765 6766 Notes: 6767 `MatCreateSubMatrices()` can extract ONLY sequential submatrices 6768 (from both sequential and parallel matrices). Use `MatCreateSubMatrix()` 6769 to extract a parallel submatrix. 6770 6771 Some matrix types place restrictions on the row and column 6772 indices, such as that they be sorted or that they be equal to each other. 6773 6774 The index sets may not have duplicate entries. 6775 6776 When extracting submatrices from a parallel matrix, each processor can 6777 form a different submatrix by setting the rows and columns of its 6778 individual index sets according to the local submatrix desired. 6779 6780 When finished using the submatrices, the user should destroy 6781 them with `MatDestroySubMatrices()`. 6782 6783 `MAT_REUSE_MATRIX` can only be used when the nonzero structure of the 6784 original matrix has not changed from that last call to `MatCreateSubMatrices()`. 6785 6786 This routine creates the matrices in submat; you should NOT create them before 6787 calling it. It also allocates the array of matrix pointers submat. 6788 6789 For `MATBAIJ` matrices the index sets must respect the block structure, that is if they 6790 request one row/column in a block, they must request all rows/columns that are in 6791 that block. For example, if the block size is 2 you cannot request just row 0 and 6792 column 0. 6793 6794 Fortran Note: 6795 The Fortran interface is slightly different from that given below; it 6796 requires one to pass in as submat a `Mat` (integer) array of size at least n+1. 6797 6798 Level: advanced 6799 6800 .seealso: `Mat`, `MatDestroySubMatrices()`, `MatCreateSubMatrix()`, `MatGetRow()`, `MatGetDiagonal()`, `MatReuse` 6801 @*/ 6802 PetscErrorCode MatCreateSubMatrices(Mat mat, PetscInt n, const IS irow[], const IS icol[], MatReuse scall, Mat *submat[]) { 6803 PetscInt i; 6804 PetscBool eq; 6805 6806 PetscFunctionBegin; 6807 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6808 PetscValidType(mat, 1); 6809 if (n) { 6810 PetscValidPointer(irow, 3); 6811 for (i = 0; i < n; i++) PetscValidHeaderSpecific(irow[i], IS_CLASSID, 3); 6812 PetscValidPointer(icol, 4); 6813 for (i = 0; i < n; i++) PetscValidHeaderSpecific(icol[i], IS_CLASSID, 4); 6814 } 6815 PetscValidPointer(submat, 6); 6816 if (n && scall == MAT_REUSE_MATRIX) { 6817 PetscValidPointer(*submat, 6); 6818 for (i = 0; i < n; i++) PetscValidHeaderSpecific((*submat)[i], MAT_CLASSID, 6); 6819 } 6820 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 6821 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 6822 MatCheckPreallocated(mat, 1); 6823 PetscCall(PetscLogEventBegin(MAT_CreateSubMats, mat, 0, 0, 0)); 6824 PetscUseTypeMethod(mat, createsubmatrices, n, irow, icol, scall, submat); 6825 PetscCall(PetscLogEventEnd(MAT_CreateSubMats, mat, 0, 0, 0)); 6826 for (i = 0; i < n; i++) { 6827 (*submat)[i]->factortype = MAT_FACTOR_NONE; /* in case in place factorization was previously done on submatrix */ 6828 PetscCall(ISEqualUnsorted(irow[i], icol[i], &eq)); 6829 if (eq) PetscCall(MatPropagateSymmetryOptions(mat, (*submat)[i])); 6830 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 6831 if (mat->boundtocpu && mat->bindingpropagates) { 6832 PetscCall(MatBindToCPU((*submat)[i], PETSC_TRUE)); 6833 PetscCall(MatSetBindingPropagates((*submat)[i], PETSC_TRUE)); 6834 } 6835 #endif 6836 } 6837 PetscFunctionReturn(0); 6838 } 6839 6840 /*@C 6841 MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of `IS` that may live on subcomms). 6842 6843 Collective on mat 6844 6845 Input Parameters: 6846 + mat - the matrix 6847 . n - the number of submatrixes to be extracted 6848 . irow, icol - index sets of rows and columns to extract 6849 - scall - either `MAT_INITIAL_MATRIX` or `MAT_REUSE_MATRIX` 6850 6851 Output Parameter: 6852 . submat - the array of submatrices 6853 6854 Level: advanced 6855 6856 Note: 6857 This is used by `PCGASM` 6858 6859 .seealso: `PCGASM`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRow()`, `MatGetDiagonal()`, `MatReuse` 6860 @*/ 6861 PetscErrorCode MatCreateSubMatricesMPI(Mat mat, PetscInt n, const IS irow[], const IS icol[], MatReuse scall, Mat *submat[]) { 6862 PetscInt i; 6863 PetscBool eq; 6864 6865 PetscFunctionBegin; 6866 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6867 PetscValidType(mat, 1); 6868 if (n) { 6869 PetscValidPointer(irow, 3); 6870 PetscValidHeaderSpecific(*irow, IS_CLASSID, 3); 6871 PetscValidPointer(icol, 4); 6872 PetscValidHeaderSpecific(*icol, IS_CLASSID, 4); 6873 } 6874 PetscValidPointer(submat, 6); 6875 if (n && scall == MAT_REUSE_MATRIX) { 6876 PetscValidPointer(*submat, 6); 6877 PetscValidHeaderSpecific(**submat, MAT_CLASSID, 6); 6878 } 6879 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 6880 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 6881 MatCheckPreallocated(mat, 1); 6882 6883 PetscCall(PetscLogEventBegin(MAT_CreateSubMats, mat, 0, 0, 0)); 6884 PetscUseTypeMethod(mat, createsubmatricesmpi, n, irow, icol, scall, submat); 6885 PetscCall(PetscLogEventEnd(MAT_CreateSubMats, mat, 0, 0, 0)); 6886 for (i = 0; i < n; i++) { 6887 PetscCall(ISEqualUnsorted(irow[i], icol[i], &eq)); 6888 if (eq) PetscCall(MatPropagateSymmetryOptions(mat, (*submat)[i])); 6889 } 6890 PetscFunctionReturn(0); 6891 } 6892 6893 /*@C 6894 MatDestroyMatrices - Destroys an array of matrices. 6895 6896 Collective on mat 6897 6898 Input Parameters: 6899 + n - the number of local matrices 6900 - mat - the matrices (note that this is a pointer to the array of matrices) 6901 6902 Level: advanced 6903 6904 Note: 6905 Frees not only the matrices, but also the array that contains the matrices 6906 In Fortran will not free the array. 6907 6908 .seealso: `Mat`, `MatCreateSubMatrices()` `MatDestroySubMatrices()` 6909 @*/ 6910 PetscErrorCode MatDestroyMatrices(PetscInt n, Mat *mat[]) { 6911 PetscInt i; 6912 6913 PetscFunctionBegin; 6914 if (!*mat) PetscFunctionReturn(0); 6915 PetscCheck(n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Trying to destroy negative number of matrices %" PetscInt_FMT, n); 6916 PetscValidPointer(mat, 2); 6917 6918 for (i = 0; i < n; i++) PetscCall(MatDestroy(&(*mat)[i])); 6919 6920 /* memory is allocated even if n = 0 */ 6921 PetscCall(PetscFree(*mat)); 6922 PetscFunctionReturn(0); 6923 } 6924 6925 /*@C 6926 MatDestroySubMatrices - Destroys a set of matrices obtained with `MatCreateSubMatrices()`. 6927 6928 Collective on mat 6929 6930 Input Parameters: 6931 + n - the number of local matrices 6932 - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling 6933 sequence of MatCreateSubMatrices()) 6934 6935 Level: advanced 6936 6937 Note: 6938 Frees not only the matrices, but also the array that contains the matrices 6939 In Fortran will not free the array. 6940 6941 .seealso: `MatCreateSubMatrices()`, `MatDestroyMatrices()` 6942 @*/ 6943 PetscErrorCode MatDestroySubMatrices(PetscInt n, Mat *mat[]) { 6944 Mat mat0; 6945 6946 PetscFunctionBegin; 6947 if (!*mat) PetscFunctionReturn(0); 6948 /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */ 6949 PetscCheck(n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Trying to destroy negative number of matrices %" PetscInt_FMT, n); 6950 PetscValidPointer(mat, 2); 6951 6952 mat0 = (*mat)[0]; 6953 if (mat0 && mat0->ops->destroysubmatrices) { 6954 PetscCall((mat0->ops->destroysubmatrices)(n, mat)); 6955 } else { 6956 PetscCall(MatDestroyMatrices(n, mat)); 6957 } 6958 PetscFunctionReturn(0); 6959 } 6960 6961 /*@C 6962 MatGetSeqNonzeroStructure - Extracts the nonzero structure from a matrix and stores it, in its entirety, on each process 6963 6964 Collective on mat 6965 6966 Input Parameters: 6967 . mat - the matrix 6968 6969 Output Parameter: 6970 . matstruct - the sequential matrix with the nonzero structure of mat 6971 6972 Level: developer 6973 6974 .seealso: `Mat`, `MatDestroySeqNonzeroStructure()`, `MatCreateSubMatrices()`, `MatDestroyMatrices()` 6975 @*/ 6976 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat, Mat *matstruct) { 6977 PetscFunctionBegin; 6978 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6979 PetscValidPointer(matstruct, 2); 6980 6981 PetscValidType(mat, 1); 6982 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 6983 MatCheckPreallocated(mat, 1); 6984 6985 PetscCall(PetscLogEventBegin(MAT_GetSeqNonzeroStructure, mat, 0, 0, 0)); 6986 PetscUseTypeMethod(mat, getseqnonzerostructure, matstruct); 6987 PetscCall(PetscLogEventEnd(MAT_GetSeqNonzeroStructure, mat, 0, 0, 0)); 6988 PetscFunctionReturn(0); 6989 } 6990 6991 /*@C 6992 MatDestroySeqNonzeroStructure - Destroys matrix obtained with `MatGetSeqNonzeroStructure()`. 6993 6994 Collective on mat 6995 6996 Input Parameters: 6997 . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling 6998 sequence of `MatGetSequentialNonzeroStructure()`) 6999 7000 Level: advanced 7001 7002 Note: 7003 Frees not only the matrices, but also the array that contains the matrices 7004 7005 .seealso: `Mat`, `MatGetSeqNonzeroStructure()` 7006 @*/ 7007 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat) { 7008 PetscFunctionBegin; 7009 PetscValidPointer(mat, 1); 7010 PetscCall(MatDestroy(mat)); 7011 PetscFunctionReturn(0); 7012 } 7013 7014 /*@ 7015 MatIncreaseOverlap - Given a set of submatrices indicated by index sets, 7016 replaces the index sets by larger ones that represent submatrices with 7017 additional overlap. 7018 7019 Collective on mat 7020 7021 Input Parameters: 7022 + mat - the matrix 7023 . n - the number of index sets 7024 . is - the array of index sets (these index sets will changed during the call) 7025 - ov - the additional overlap requested 7026 7027 Options Database: 7028 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7029 7030 Level: developer 7031 7032 Developer Note: 7033 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. 7034 7035 .seealso: `Mat`, `PCASM`, `MatIncreaseOverlapSplit()`, `MatCreateSubMatrices()` 7036 @*/ 7037 PetscErrorCode MatIncreaseOverlap(Mat mat, PetscInt n, IS is[], PetscInt ov) { 7038 PetscInt i, bs, cbs; 7039 7040 PetscFunctionBegin; 7041 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7042 PetscValidType(mat, 1); 7043 PetscValidLogicalCollectiveInt(mat, n, 2); 7044 PetscCheck(n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Must have one or more domains, you have %" PetscInt_FMT, n); 7045 if (n) { 7046 PetscValidPointer(is, 3); 7047 for (i = 0; i < n; i++) PetscValidHeaderSpecific(is[i], IS_CLASSID, 3); 7048 } 7049 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 7050 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 7051 MatCheckPreallocated(mat, 1); 7052 7053 if (!ov || !n) PetscFunctionReturn(0); 7054 PetscCall(PetscLogEventBegin(MAT_IncreaseOverlap, mat, 0, 0, 0)); 7055 PetscUseTypeMethod(mat, increaseoverlap, n, is, ov); 7056 PetscCall(PetscLogEventEnd(MAT_IncreaseOverlap, mat, 0, 0, 0)); 7057 PetscCall(MatGetBlockSizes(mat, &bs, &cbs)); 7058 if (bs == cbs) { 7059 for (i = 0; i < n; i++) PetscCall(ISSetBlockSize(is[i], bs)); 7060 } 7061 PetscFunctionReturn(0); 7062 } 7063 7064 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat, IS *, PetscInt); 7065 7066 /*@ 7067 MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across 7068 a sub communicator, replaces the index sets by larger ones that represent submatrices with 7069 additional overlap. 7070 7071 Collective on mat 7072 7073 Input Parameters: 7074 + mat - the matrix 7075 . n - the number of index sets 7076 . is - the array of index sets (these index sets will changed during the call) 7077 - ov - the additional overlap requested 7078 7079 ` Options Database: 7080 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7081 7082 Level: developer 7083 7084 .seealso: `MatCreateSubMatrices()`, `MatIncreaseOverlap()` 7085 @*/ 7086 PetscErrorCode MatIncreaseOverlapSplit(Mat mat, PetscInt n, IS is[], PetscInt ov) { 7087 PetscInt i; 7088 7089 PetscFunctionBegin; 7090 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7091 PetscValidType(mat, 1); 7092 PetscCheck(n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Must have one or more domains, you have %" PetscInt_FMT, n); 7093 if (n) { 7094 PetscValidPointer(is, 3); 7095 PetscValidHeaderSpecific(*is, IS_CLASSID, 3); 7096 } 7097 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 7098 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 7099 MatCheckPreallocated(mat, 1); 7100 if (!ov) PetscFunctionReturn(0); 7101 PetscCall(PetscLogEventBegin(MAT_IncreaseOverlap, mat, 0, 0, 0)); 7102 for (i = 0; i < n; i++) PetscCall(MatIncreaseOverlapSplit_Single(mat, &is[i], ov)); 7103 PetscCall(PetscLogEventEnd(MAT_IncreaseOverlap, mat, 0, 0, 0)); 7104 PetscFunctionReturn(0); 7105 } 7106 7107 /*@ 7108 MatGetBlockSize - Returns the matrix block size. 7109 7110 Not Collective 7111 7112 Input Parameter: 7113 . mat - the matrix 7114 7115 Output Parameter: 7116 . bs - block size 7117 7118 Notes: 7119 Block row formats are `MATBAIJ` and `MATSBAIJ` ALWAYS have square block storage in the matrix. 7120 7121 If the block size has not been set yet this routine returns 1. 7122 7123 Level: intermediate 7124 7125 .seealso: `MATBAIJ`, `MATSBAIJ`, `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSizes()` 7126 @*/ 7127 PetscErrorCode MatGetBlockSize(Mat mat, PetscInt *bs) { 7128 PetscFunctionBegin; 7129 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7130 PetscValidIntPointer(bs, 2); 7131 *bs = PetscAbs(mat->rmap->bs); 7132 PetscFunctionReturn(0); 7133 } 7134 7135 /*@ 7136 MatGetBlockSizes - Returns the matrix block row and column sizes. 7137 7138 Not Collective 7139 7140 Input Parameter: 7141 . mat - the matrix 7142 7143 Output Parameters: 7144 + rbs - row block size 7145 - cbs - column block size 7146 7147 Notes: 7148 Block row formats are `MATBAIJ` and `MATSBAIJ` ALWAYS have square block storage in the matrix. 7149 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7150 7151 If a block size has not been set yet this routine returns 1. 7152 7153 Level: intermediate 7154 7155 .seealso: `MATBAIJ`, `MATSBAIJ`, `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSize()`, `MatSetBlockSizes()` 7156 @*/ 7157 PetscErrorCode MatGetBlockSizes(Mat mat, PetscInt *rbs, PetscInt *cbs) { 7158 PetscFunctionBegin; 7159 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7160 if (rbs) PetscValidIntPointer(rbs, 2); 7161 if (cbs) PetscValidIntPointer(cbs, 3); 7162 if (rbs) *rbs = PetscAbs(mat->rmap->bs); 7163 if (cbs) *cbs = PetscAbs(mat->cmap->bs); 7164 PetscFunctionReturn(0); 7165 } 7166 7167 /*@ 7168 MatSetBlockSize - Sets the matrix block size. 7169 7170 Logically Collective on mat 7171 7172 Input Parameters: 7173 + mat - the matrix 7174 - bs - block size 7175 7176 Notes: 7177 Block row formats are `MATBAIJ` and `MATSBAIJ` formats ALWAYS have square block storage in the matrix. 7178 This must be called before `MatSetUp()` or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7179 7180 For `MATAIJ` matrix format, this function can be called at a later stage, provided that the specified block size 7181 is compatible with the matrix local sizes. 7182 7183 Level: intermediate 7184 7185 .seealso: `MATBAIJ`, `MATSBAIJ`, `MATAIJ`, `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`, `MatGetBlockSizes()` 7186 @*/ 7187 PetscErrorCode MatSetBlockSize(Mat mat, PetscInt bs) { 7188 PetscFunctionBegin; 7189 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7190 PetscValidLogicalCollectiveInt(mat, bs, 2); 7191 PetscCall(MatSetBlockSizes(mat, bs, bs)); 7192 PetscFunctionReturn(0); 7193 } 7194 7195 typedef struct { 7196 PetscInt n; 7197 IS *is; 7198 Mat *mat; 7199 PetscObjectState nonzerostate; 7200 Mat C; 7201 } EnvelopeData; 7202 7203 static PetscErrorCode EnvelopeDataDestroy(EnvelopeData *edata) { 7204 for (PetscInt i = 0; i < edata->n; i++) PetscCall(ISDestroy(&edata->is[i])); 7205 PetscCall(PetscFree(edata->is)); 7206 PetscCall(PetscFree(edata)); 7207 return 0; 7208 } 7209 7210 /* 7211 MatComputeVariableBlockEnvelope - Given a matrix whose nonzeros are in blocks along the diagonal this computes and stores 7212 the sizes of these blocks in the matrix. An individual block may lie over several processes. 7213 7214 Collective on mat 7215 7216 Input Parameter: 7217 . mat - the matrix 7218 7219 Notes: 7220 There can be zeros within the blocks 7221 7222 The blocks can overlap between processes, including laying on more than two processes 7223 7224 .seealso: `Mat`, `MatInvertVariableBlockEnvelope()`, `MatSetVariableBlockSizes()` 7225 */ 7226 static PetscErrorCode MatComputeVariableBlockEnvelope(Mat mat) { 7227 PetscInt n, *sizes, *starts, i = 0, env = 0, tbs = 0, lblocks = 0, rstart, II, ln = 0, cnt = 0, cstart, cend; 7228 PetscInt *diag, *odiag, sc; 7229 VecScatter scatter; 7230 PetscScalar *seqv; 7231 const PetscScalar *parv; 7232 const PetscInt *ia, *ja; 7233 PetscBool set, flag, done; 7234 Mat AA = mat, A; 7235 MPI_Comm comm; 7236 PetscMPIInt rank, size, tag; 7237 MPI_Status status; 7238 PetscContainer container; 7239 EnvelopeData *edata; 7240 Vec seq, par; 7241 IS isglobal; 7242 7243 PetscFunctionBegin; 7244 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7245 PetscCall(MatIsSymmetricKnown(mat, &set, &flag)); 7246 if (!set || !flag) { 7247 /* TOO: only needs nonzero structure of transpose */ 7248 PetscCall(MatTranspose(mat, MAT_INITIAL_MATRIX, &AA)); 7249 PetscCall(MatAXPY(AA, 1.0, mat, DIFFERENT_NONZERO_PATTERN)); 7250 } 7251 PetscCall(MatAIJGetLocalMat(AA, &A)); 7252 PetscCall(MatGetRowIJ(A, 0, PETSC_FALSE, PETSC_FALSE, &n, &ia, &ja, &done)); 7253 PetscCheck(done, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Unable to get IJ structure from matrix"); 7254 7255 PetscCall(MatGetLocalSize(mat, &n, NULL)); 7256 PetscCall(PetscObjectGetNewTag((PetscObject)mat, &tag)); 7257 PetscCall(PetscObjectGetComm((PetscObject)mat, &comm)); 7258 PetscCallMPI(MPI_Comm_size(comm, &size)); 7259 PetscCallMPI(MPI_Comm_rank(comm, &rank)); 7260 7261 PetscCall(PetscMalloc2(n, &sizes, n, &starts)); 7262 7263 if (rank > 0) { 7264 PetscCallMPI(MPI_Recv(&env, 1, MPIU_INT, rank - 1, tag, comm, &status)); 7265 PetscCallMPI(MPI_Recv(&tbs, 1, MPIU_INT, rank - 1, tag, comm, &status)); 7266 } 7267 PetscCall(MatGetOwnershipRange(mat, &rstart, NULL)); 7268 for (i = 0; i < n; i++) { 7269 env = PetscMax(env, ja[ia[i + 1] - 1]); 7270 II = rstart + i; 7271 if (env == II) { 7272 starts[lblocks] = tbs; 7273 sizes[lblocks++] = 1 + II - tbs; 7274 tbs = 1 + II; 7275 } 7276 } 7277 if (rank < size - 1) { 7278 PetscCallMPI(MPI_Send(&env, 1, MPIU_INT, rank + 1, tag, comm)); 7279 PetscCallMPI(MPI_Send(&tbs, 1, MPIU_INT, rank + 1, tag, comm)); 7280 } 7281 7282 PetscCall(MatRestoreRowIJ(A, 0, PETSC_FALSE, PETSC_FALSE, &n, &ia, &ja, &done)); 7283 if (!set || !flag) PetscCall(MatDestroy(&AA)); 7284 PetscCall(MatDestroy(&A)); 7285 7286 PetscCall(PetscNew(&edata)); 7287 PetscCall(MatGetNonzeroState(mat, &edata->nonzerostate)); 7288 edata->n = lblocks; 7289 /* create IS needed for extracting blocks from the original matrix */ 7290 PetscCall(PetscMalloc1(lblocks, &edata->is)); 7291 for (PetscInt i = 0; i < lblocks; i++) PetscCall(ISCreateStride(PETSC_COMM_SELF, sizes[i], starts[i], 1, &edata->is[i])); 7292 7293 /* Create the resulting inverse matrix structure with preallocation information */ 7294 PetscCall(MatCreate(PetscObjectComm((PetscObject)mat), &edata->C)); 7295 PetscCall(MatSetSizes(edata->C, mat->rmap->n, mat->cmap->n, mat->rmap->N, mat->cmap->N)); 7296 PetscCall(MatSetBlockSizesFromMats(edata->C, mat, mat)); 7297 PetscCall(MatSetType(edata->C, MATAIJ)); 7298 7299 /* Communicate the start and end of each row, from each block to the correct rank */ 7300 /* TODO: Use PetscSF instead of VecScatter */ 7301 for (PetscInt i = 0; i < lblocks; i++) ln += sizes[i]; 7302 PetscCall(VecCreateSeq(PETSC_COMM_SELF, 2 * ln, &seq)); 7303 PetscCall(VecGetArrayWrite(seq, &seqv)); 7304 for (PetscInt i = 0; i < lblocks; i++) { 7305 for (PetscInt j = 0; j < sizes[i]; j++) { 7306 seqv[cnt] = starts[i]; 7307 seqv[cnt + 1] = starts[i] + sizes[i]; 7308 cnt += 2; 7309 } 7310 } 7311 PetscCall(VecRestoreArrayWrite(seq, &seqv)); 7312 PetscCallMPI(MPI_Scan(&cnt, &sc, 1, MPIU_INT, MPI_SUM, PetscObjectComm((PetscObject)mat))); 7313 sc -= cnt; 7314 PetscCall(VecCreateMPI(PetscObjectComm((PetscObject)mat), 2 * mat->rmap->n, 2 * mat->rmap->N, &par)); 7315 PetscCall(ISCreateStride(PETSC_COMM_SELF, cnt, sc, 1, &isglobal)); 7316 PetscCall(VecScatterCreate(seq, NULL, par, isglobal, &scatter)); 7317 PetscCall(ISDestroy(&isglobal)); 7318 PetscCall(VecScatterBegin(scatter, seq, par, INSERT_VALUES, SCATTER_FORWARD)); 7319 PetscCall(VecScatterEnd(scatter, seq, par, INSERT_VALUES, SCATTER_FORWARD)); 7320 PetscCall(VecScatterDestroy(&scatter)); 7321 PetscCall(VecDestroy(&seq)); 7322 PetscCall(MatGetOwnershipRangeColumn(mat, &cstart, &cend)); 7323 PetscCall(PetscMalloc2(mat->rmap->n, &diag, mat->rmap->n, &odiag)); 7324 PetscCall(VecGetArrayRead(par, &parv)); 7325 cnt = 0; 7326 PetscCall(MatGetSize(mat, NULL, &n)); 7327 for (PetscInt i = 0; i < mat->rmap->n; i++) { 7328 PetscInt start, end, d = 0, od = 0; 7329 7330 start = (PetscInt)PetscRealPart(parv[cnt]); 7331 end = (PetscInt)PetscRealPart(parv[cnt + 1]); 7332 cnt += 2; 7333 7334 if (start < cstart) { 7335 od += cstart - start + n - cend; 7336 d += cend - cstart; 7337 } else if (start < cend) { 7338 od += n - cend; 7339 d += cend - start; 7340 } else od += n - start; 7341 if (end <= cstart) { 7342 od -= cstart - end + n - cend; 7343 d -= cend - cstart; 7344 } else if (end < cend) { 7345 od -= n - cend; 7346 d -= cend - end; 7347 } else od -= n - end; 7348 7349 odiag[i] = od; 7350 diag[i] = d; 7351 } 7352 PetscCall(VecRestoreArrayRead(par, &parv)); 7353 PetscCall(VecDestroy(&par)); 7354 PetscCall(MatXAIJSetPreallocation(edata->C, mat->rmap->bs, diag, odiag, NULL, NULL)); 7355 PetscCall(PetscFree2(diag, odiag)); 7356 PetscCall(PetscFree2(sizes, starts)); 7357 7358 PetscCall(PetscContainerCreate(PETSC_COMM_SELF, &container)); 7359 PetscCall(PetscContainerSetPointer(container, edata)); 7360 PetscCall(PetscContainerSetUserDestroy(container, (PetscErrorCode(*)(void *))EnvelopeDataDestroy)); 7361 PetscCall(PetscObjectCompose((PetscObject)mat, "EnvelopeData", (PetscObject)container)); 7362 PetscCall(PetscObjectDereference((PetscObject)container)); 7363 PetscFunctionReturn(0); 7364 } 7365 7366 /*@ 7367 MatInvertVariableBlockEnvelope - set matrix C to be the inverted block diagonal of matrix A 7368 7369 Collective on A 7370 7371 Input Parameters: 7372 . A - the matrix 7373 7374 Output Parameters: 7375 . C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set. 7376 7377 Note: 7378 For efficiency the matrix A should have all the nonzero entries clustered in smallish blocks along the diagonal. 7379 7380 Level: advanced 7381 7382 .seealso: `MatInvertBlockDiagonal()`, `MatComputeBlockDiagonal()` 7383 @*/ 7384 PetscErrorCode MatInvertVariableBlockEnvelope(Mat A, MatReuse reuse, Mat *C) { 7385 PetscContainer container; 7386 EnvelopeData *edata; 7387 PetscObjectState nonzerostate; 7388 7389 PetscFunctionBegin; 7390 PetscCall(PetscObjectQuery((PetscObject)A, "EnvelopeData", (PetscObject *)&container)); 7391 if (!container) { 7392 PetscCall(MatComputeVariableBlockEnvelope(A)); 7393 PetscCall(PetscObjectQuery((PetscObject)A, "EnvelopeData", (PetscObject *)&container)); 7394 } 7395 PetscCall(PetscContainerGetPointer(container, (void **)&edata)); 7396 PetscCall(MatGetNonzeroState(A, &nonzerostate)); 7397 PetscCheck(nonzerostate <= edata->nonzerostate, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Cannot handle changes to matrix nonzero structure"); 7398 PetscCheck(reuse != MAT_REUSE_MATRIX || *C == edata->C, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "C matrix must be the same as previously output"); 7399 7400 PetscCall(MatCreateSubMatrices(A, edata->n, edata->is, edata->is, MAT_INITIAL_MATRIX, &edata->mat)); 7401 *C = edata->C; 7402 7403 for (PetscInt i = 0; i < edata->n; i++) { 7404 Mat D; 7405 PetscScalar *dvalues; 7406 7407 PetscCall(MatConvert(edata->mat[i], MATSEQDENSE, MAT_INITIAL_MATRIX, &D)); 7408 PetscCall(MatSetOption(*C, MAT_ROW_ORIENTED, PETSC_FALSE)); 7409 PetscCall(MatSeqDenseInvert(D)); 7410 PetscCall(MatDenseGetArray(D, &dvalues)); 7411 PetscCall(MatSetValuesIS(*C, edata->is[i], edata->is[i], dvalues, INSERT_VALUES)); 7412 PetscCall(MatDestroy(&D)); 7413 } 7414 PetscCall(MatDestroySubMatrices(edata->n, &edata->mat)); 7415 PetscCall(MatAssemblyBegin(*C, MAT_FINAL_ASSEMBLY)); 7416 PetscCall(MatAssemblyEnd(*C, MAT_FINAL_ASSEMBLY)); 7417 PetscFunctionReturn(0); 7418 } 7419 7420 /*@ 7421 MatSetVariableBlockSizes - Sets diagonal point-blocks of the matrix that need not be of the same size 7422 7423 Logically Collective on mat 7424 7425 Input Parameters: 7426 + mat - the matrix 7427 . nblocks - the number of blocks on this process, each block can only exist on a single process 7428 - bsizes - the block sizes 7429 7430 Notes: 7431 Currently used by `PCVPBJACOBI` for `MATAIJ` matrices 7432 7433 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. 7434 7435 Level: intermediate 7436 7437 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`, `MatGetBlockSizes()`, `MatGetVariableBlockSizes()`, 7438 `MatComputeVariableBlockEnvelope()`, `PCVPBJACOBI` 7439 @*/ 7440 PetscErrorCode MatSetVariableBlockSizes(Mat mat, PetscInt nblocks, PetscInt *bsizes) { 7441 PetscInt i, ncnt = 0, nlocal; 7442 7443 PetscFunctionBegin; 7444 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7445 PetscCheck(nblocks >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Number of local blocks must be great than or equal to zero"); 7446 PetscCall(MatGetLocalSize(mat, &nlocal, NULL)); 7447 for (i = 0; i < nblocks; i++) ncnt += bsizes[i]; 7448 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); 7449 PetscCall(PetscFree(mat->bsizes)); 7450 mat->nblocks = nblocks; 7451 PetscCall(PetscMalloc1(nblocks, &mat->bsizes)); 7452 PetscCall(PetscArraycpy(mat->bsizes, bsizes, nblocks)); 7453 PetscFunctionReturn(0); 7454 } 7455 7456 /*@C 7457 MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size 7458 7459 Logically Collective on mat 7460 7461 Input Parameter: 7462 . mat - the matrix 7463 7464 Output Parameters: 7465 + nblocks - the number of blocks on this process 7466 - bsizes - the block sizes 7467 7468 Fortran Note: 7469 Currently not supported from Fortran 7470 7471 Level: intermediate 7472 7473 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`, `MatGetBlockSizes()`, `MatSetVariableBlockSizes()`, `MatComputeVariableBlockEnvelope()` 7474 @*/ 7475 PetscErrorCode MatGetVariableBlockSizes(Mat mat, PetscInt *nblocks, const PetscInt **bsizes) { 7476 PetscFunctionBegin; 7477 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7478 *nblocks = mat->nblocks; 7479 *bsizes = mat->bsizes; 7480 PetscFunctionReturn(0); 7481 } 7482 7483 /*@ 7484 MatSetBlockSizes - Sets the matrix block row and column sizes. 7485 7486 Logically Collective on mat 7487 7488 Input Parameters: 7489 + mat - the matrix 7490 . rbs - row block size 7491 - cbs - column block size 7492 7493 Notes: 7494 Block row formats are `MATBAIJ` and `MATSBAIJ`. These formats ALWAYS have square block storage in the matrix. 7495 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7496 This must be called before `MatSetUp()` or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7497 7498 For `MATAIJ` matrix this function can be called at a later stage, provided that the specified block sizes 7499 are compatible with the matrix local sizes. 7500 7501 The row and column block size determine the blocksize of the "row" and "column" vectors returned by `MatCreateVecs()`. 7502 7503 Level: intermediate 7504 7505 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSize()`, `MatGetBlockSizes()` 7506 @*/ 7507 PetscErrorCode MatSetBlockSizes(Mat mat, PetscInt rbs, PetscInt cbs) { 7508 PetscFunctionBegin; 7509 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7510 PetscValidLogicalCollectiveInt(mat, rbs, 2); 7511 PetscValidLogicalCollectiveInt(mat, cbs, 3); 7512 PetscTryTypeMethod(mat, setblocksizes, rbs, cbs); 7513 if (mat->rmap->refcnt) { 7514 ISLocalToGlobalMapping l2g = NULL; 7515 PetscLayout nmap = NULL; 7516 7517 PetscCall(PetscLayoutDuplicate(mat->rmap, &nmap)); 7518 if (mat->rmap->mapping) PetscCall(ISLocalToGlobalMappingDuplicate(mat->rmap->mapping, &l2g)); 7519 PetscCall(PetscLayoutDestroy(&mat->rmap)); 7520 mat->rmap = nmap; 7521 mat->rmap->mapping = l2g; 7522 } 7523 if (mat->cmap->refcnt) { 7524 ISLocalToGlobalMapping l2g = NULL; 7525 PetscLayout nmap = NULL; 7526 7527 PetscCall(PetscLayoutDuplicate(mat->cmap, &nmap)); 7528 if (mat->cmap->mapping) PetscCall(ISLocalToGlobalMappingDuplicate(mat->cmap->mapping, &l2g)); 7529 PetscCall(PetscLayoutDestroy(&mat->cmap)); 7530 mat->cmap = nmap; 7531 mat->cmap->mapping = l2g; 7532 } 7533 PetscCall(PetscLayoutSetBlockSize(mat->rmap, rbs)); 7534 PetscCall(PetscLayoutSetBlockSize(mat->cmap, cbs)); 7535 PetscFunctionReturn(0); 7536 } 7537 7538 /*@ 7539 MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices 7540 7541 Logically Collective on mat 7542 7543 Input Parameters: 7544 + mat - the matrix 7545 . fromRow - matrix from which to copy row block size 7546 - fromCol - matrix from which to copy column block size (can be same as fromRow) 7547 7548 Level: developer 7549 7550 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()` 7551 @*/ 7552 PetscErrorCode MatSetBlockSizesFromMats(Mat mat, Mat fromRow, Mat fromCol) { 7553 PetscFunctionBegin; 7554 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7555 PetscValidHeaderSpecific(fromRow, MAT_CLASSID, 2); 7556 PetscValidHeaderSpecific(fromCol, MAT_CLASSID, 3); 7557 if (fromRow->rmap->bs > 0) PetscCall(PetscLayoutSetBlockSize(mat->rmap, fromRow->rmap->bs)); 7558 if (fromCol->cmap->bs > 0) PetscCall(PetscLayoutSetBlockSize(mat->cmap, fromCol->cmap->bs)); 7559 PetscFunctionReturn(0); 7560 } 7561 7562 /*@ 7563 MatResidual - Default routine to calculate the residual r = b - Ax 7564 7565 Collective on mat 7566 7567 Input Parameters: 7568 + mat - the matrix 7569 . b - the right-hand-side 7570 - x - the approximate solution 7571 7572 Output Parameter: 7573 . r - location to store the residual 7574 7575 Level: developer 7576 7577 .seealso: `Mat`, `MatMult()`, `MatMultAdd()`, `PCMGSetResidual()` 7578 @*/ 7579 PetscErrorCode MatResidual(Mat mat, Vec b, Vec x, Vec r) { 7580 PetscFunctionBegin; 7581 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7582 PetscValidHeaderSpecific(b, VEC_CLASSID, 2); 7583 PetscValidHeaderSpecific(x, VEC_CLASSID, 3); 7584 PetscValidHeaderSpecific(r, VEC_CLASSID, 4); 7585 PetscValidType(mat, 1); 7586 MatCheckPreallocated(mat, 1); 7587 PetscCall(PetscLogEventBegin(MAT_Residual, mat, 0, 0, 0)); 7588 if (!mat->ops->residual) { 7589 PetscCall(MatMult(mat, x, r)); 7590 PetscCall(VecAYPX(r, -1.0, b)); 7591 } else { 7592 PetscUseTypeMethod(mat, residual, b, x, r); 7593 } 7594 PetscCall(PetscLogEventEnd(MAT_Residual, mat, 0, 0, 0)); 7595 PetscFunctionReturn(0); 7596 } 7597 7598 /*@C 7599 MatGetRowIJ - Returns the compressed row storage i and j indices for the local rows of a sparse matrix 7600 7601 Collective on mat 7602 7603 Input Parameters: 7604 + mat - the matrix 7605 . shift - 0 or 1 indicating we want the indices starting at 0 or 1 7606 . symmetric - `PETSC_TRUE` or `PETSC_FALSE` indicating the matrix data structure should be symmetrized 7607 - inodecompressed - `PETSC_TRUE` or `PETSC_FALSE` indicats if the nonzero structure of the 7608 inodes or the nonzero elements is wanted. For `MATBAIJ` matrices the compressed version is 7609 always used. 7610 7611 Output Parameters: 7612 + n - number of local rows in the (possibly compressed) matrix, use NULL if not needed 7613 . ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix, use NULL if not needed 7614 . ja - the column indices, use NULL if not needed 7615 - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers 7616 are responsible for handling the case when done == `PETSC_FALSE` and ia and ja are not set 7617 7618 Level: developer 7619 7620 Notes: 7621 You CANNOT change any of the ia[] or ja[] values. 7622 7623 Use `MatRestoreRowIJ()` when you are finished accessing the ia[] and ja[] values. 7624 7625 Fortran Notes: 7626 In Fortran use 7627 $ 7628 $ PetscInt ia(1), ja(1) 7629 $ PetscOffset iia, jja 7630 $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr) 7631 $ ! Access the ith and jth entries via ia(iia + i) and ja(jja + j) 7632 7633 or 7634 $ 7635 $ PetscInt, pointer :: ia(:),ja(:) 7636 $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr) 7637 $ ! Access the ith and jth entries via ia(i) and ja(j) 7638 7639 .seealso: `Mat`, `MATAIJ`, `MatGetColumnIJ()`, `MatRestoreRowIJ()`, `MatSeqAIJGetArray()` 7640 @*/ 7641 PetscErrorCode MatGetRowIJ(Mat mat, PetscInt shift, PetscBool symmetric, PetscBool inodecompressed, PetscInt *n, const PetscInt *ia[], const PetscInt *ja[], PetscBool *done) { 7642 PetscFunctionBegin; 7643 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7644 PetscValidType(mat, 1); 7645 if (n) PetscValidIntPointer(n, 5); 7646 if (ia) PetscValidPointer(ia, 6); 7647 if (ja) PetscValidPointer(ja, 7); 7648 if (done) PetscValidBoolPointer(done, 8); 7649 MatCheckPreallocated(mat, 1); 7650 if (!mat->ops->getrowij && done) *done = PETSC_FALSE; 7651 else { 7652 if (done) *done = PETSC_TRUE; 7653 PetscCall(PetscLogEventBegin(MAT_GetRowIJ, mat, 0, 0, 0)); 7654 PetscUseTypeMethod(mat, getrowij, shift, symmetric, inodecompressed, n, ia, ja, done); 7655 PetscCall(PetscLogEventEnd(MAT_GetRowIJ, mat, 0, 0, 0)); 7656 } 7657 PetscFunctionReturn(0); 7658 } 7659 7660 /*@C 7661 MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices. 7662 7663 Collective on mat 7664 7665 Input Parameters: 7666 + mat - the matrix 7667 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7668 . symmetric - `PETSC_TRUE` or `PETSC_FALSE` indicating the matrix data structure should be 7669 symmetrized 7670 . inodecompressed - `PETSC_TRUE` or `PETSC_FALSE` indicating if the nonzero structure of the 7671 inodes or the nonzero elements is wanted. For `MATBAIJ` matrices the compressed version is 7672 always used. 7673 . n - number of columns in the (possibly compressed) matrix 7674 . ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix 7675 - ja - the row indices 7676 7677 Output Parameters: 7678 . done - `PETSC_TRUE` or `PETSC_FALSE`, indicating whether the values have been returned 7679 7680 Level: developer 7681 7682 .seealso: `MatGetRowIJ()`, `MatRestoreColumnIJ()` 7683 @*/ 7684 PetscErrorCode MatGetColumnIJ(Mat mat, PetscInt shift, PetscBool symmetric, PetscBool inodecompressed, PetscInt *n, const PetscInt *ia[], const PetscInt *ja[], PetscBool *done) { 7685 PetscFunctionBegin; 7686 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7687 PetscValidType(mat, 1); 7688 PetscValidIntPointer(n, 5); 7689 if (ia) PetscValidPointer(ia, 6); 7690 if (ja) PetscValidPointer(ja, 7); 7691 PetscValidBoolPointer(done, 8); 7692 MatCheckPreallocated(mat, 1); 7693 if (!mat->ops->getcolumnij) *done = PETSC_FALSE; 7694 else { 7695 *done = PETSC_TRUE; 7696 PetscUseTypeMethod(mat, getcolumnij, shift, symmetric, inodecompressed, n, ia, ja, done); 7697 } 7698 PetscFunctionReturn(0); 7699 } 7700 7701 /*@C 7702 MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with `MatGetRowIJ()`. 7703 7704 Collective on mat 7705 7706 Input Parameters: 7707 + mat - the matrix 7708 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7709 . symmetric - `PETSC_TRUE` or `PETSC_FALSE` indicating the matrix data structure should be symmetrized 7710 . inodecompressed - `PETSC_TRUE` or `PETSC_FALSE` indicating if the nonzero structure of the 7711 inodes or the nonzero elements is wanted. For `MATBAIJ` matrices the compressed version is 7712 always used. 7713 . n - size of (possibly compressed) matrix 7714 . ia - the row pointers 7715 - ja - the column indices 7716 7717 Output Parameters: 7718 . done - `PETSC_TRUE` or `PETSC_FALSE` indicated that the values have been returned 7719 7720 Note: 7721 This routine zeros out n, ia, and ja. This is to prevent accidental 7722 us of the array after it has been restored. If you pass NULL, it will 7723 not zero the pointers. Use of ia or ja after `MatRestoreRowIJ()` is invalid. 7724 7725 Level: developer 7726 7727 .seealso: `MatGetRowIJ()`, `MatRestoreColumnIJ()` 7728 @*/ 7729 PetscErrorCode MatRestoreRowIJ(Mat mat, PetscInt shift, PetscBool symmetric, PetscBool inodecompressed, PetscInt *n, const PetscInt *ia[], const PetscInt *ja[], PetscBool *done) { 7730 PetscFunctionBegin; 7731 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7732 PetscValidType(mat, 1); 7733 if (ia) PetscValidPointer(ia, 6); 7734 if (ja) PetscValidPointer(ja, 7); 7735 if (done) PetscValidBoolPointer(done, 8); 7736 MatCheckPreallocated(mat, 1); 7737 7738 if (!mat->ops->restorerowij && done) *done = PETSC_FALSE; 7739 else { 7740 if (done) *done = PETSC_TRUE; 7741 PetscUseTypeMethod(mat, restorerowij, shift, symmetric, inodecompressed, n, ia, ja, done); 7742 if (n) *n = 0; 7743 if (ia) *ia = NULL; 7744 if (ja) *ja = NULL; 7745 } 7746 PetscFunctionReturn(0); 7747 } 7748 7749 /*@C 7750 MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with `MatGetColumnIJ()`. 7751 7752 Collective on Mat 7753 7754 Input Parameters: 7755 + mat - the matrix 7756 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7757 . symmetric - `PETSC_TRUE` or `PETSC_FALSE` indicating the matrix data structure should be symmetrized 7758 - inodecompressed - `PETSC_TRUE` or `PETSC_FALSE` indicating if the nonzero structure of the 7759 inodes or the nonzero elements is wanted. For `MATBAIJ` matrices the compressed version is 7760 always used. 7761 7762 Output Parameters: 7763 + n - size of (possibly compressed) matrix 7764 . ia - the column pointers 7765 . ja - the row indices 7766 - done - `PETSC_TRUE` or `PETSC_FALSE` indicated that the values have been returned 7767 7768 Level: developer 7769 7770 .seealso: `MatGetColumnIJ()`, `MatRestoreRowIJ()` 7771 @*/ 7772 PetscErrorCode MatRestoreColumnIJ(Mat mat, PetscInt shift, PetscBool symmetric, PetscBool inodecompressed, PetscInt *n, const PetscInt *ia[], const PetscInt *ja[], PetscBool *done) { 7773 PetscFunctionBegin; 7774 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7775 PetscValidType(mat, 1); 7776 if (ia) PetscValidPointer(ia, 6); 7777 if (ja) PetscValidPointer(ja, 7); 7778 PetscValidBoolPointer(done, 8); 7779 MatCheckPreallocated(mat, 1); 7780 7781 if (!mat->ops->restorecolumnij) *done = PETSC_FALSE; 7782 else { 7783 *done = PETSC_TRUE; 7784 PetscUseTypeMethod(mat, restorecolumnij, shift, symmetric, inodecompressed, n, ia, ja, done); 7785 if (n) *n = 0; 7786 if (ia) *ia = NULL; 7787 if (ja) *ja = NULL; 7788 } 7789 PetscFunctionReturn(0); 7790 } 7791 7792 /*@C 7793 MatColoringPatch -Used inside matrix coloring routines that use `MatGetRowIJ()` and/or `MatGetColumnIJ()`. 7794 7795 Collective on mat 7796 7797 Input Parameters: 7798 + mat - the matrix 7799 . ncolors - max color value 7800 . n - number of entries in colorarray 7801 - colorarray - array indicating color for each column 7802 7803 Output Parameters: 7804 . iscoloring - coloring generated using colorarray information 7805 7806 Level: developer 7807 7808 .seealso: `MatGetRowIJ()`, `MatGetColumnIJ()` 7809 @*/ 7810 PetscErrorCode MatColoringPatch(Mat mat, PetscInt ncolors, PetscInt n, ISColoringValue colorarray[], ISColoring *iscoloring) { 7811 PetscFunctionBegin; 7812 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7813 PetscValidType(mat, 1); 7814 PetscValidIntPointer(colorarray, 4); 7815 PetscValidPointer(iscoloring, 5); 7816 MatCheckPreallocated(mat, 1); 7817 7818 if (!mat->ops->coloringpatch) { 7819 PetscCall(ISColoringCreate(PetscObjectComm((PetscObject)mat), ncolors, n, colorarray, PETSC_OWN_POINTER, iscoloring)); 7820 } else { 7821 PetscUseTypeMethod(mat, coloringpatch, ncolors, n, colorarray, iscoloring); 7822 } 7823 PetscFunctionReturn(0); 7824 } 7825 7826 /*@ 7827 MatSetUnfactored - Resets a factored matrix to be treated as unfactored. 7828 7829 Logically Collective on mat 7830 7831 Input Parameter: 7832 . mat - the factored matrix to be reset 7833 7834 Notes: 7835 This routine should be used only with factored matrices formed by in-place 7836 factorization via ILU(0) (or by in-place LU factorization for the `MATSEQDENSE` 7837 format). This option can save memory, for example, when solving nonlinear 7838 systems with a matrix-free Newton-Krylov method and a matrix-based, in-place 7839 ILU(0) preconditioner. 7840 7841 Note that one can specify in-place ILU(0) factorization by calling 7842 .vb 7843 PCType(pc,PCILU); 7844 PCFactorSeUseInPlace(pc); 7845 .ve 7846 or by using the options -pc_type ilu -pc_factor_in_place 7847 7848 In-place factorization ILU(0) can also be used as a local 7849 solver for the blocks within the block Jacobi or additive Schwarz 7850 methods (runtime option: -sub_pc_factor_in_place). See Users-Manual: ch_pc 7851 for details on setting local solver options. 7852 7853 Most users should employ the `KSP` interface for linear solvers 7854 instead of working directly with matrix algebra routines such as this. 7855 See, e.g., `KSPCreate()`. 7856 7857 Level: developer 7858 7859 .seealso: `PCFactorSetUseInPlace()`, `PCFactorGetUseInPlace()` 7860 @*/ 7861 PetscErrorCode MatSetUnfactored(Mat mat) { 7862 PetscFunctionBegin; 7863 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7864 PetscValidType(mat, 1); 7865 MatCheckPreallocated(mat, 1); 7866 mat->factortype = MAT_FACTOR_NONE; 7867 if (!mat->ops->setunfactored) PetscFunctionReturn(0); 7868 PetscUseTypeMethod(mat, setunfactored); 7869 PetscFunctionReturn(0); 7870 } 7871 7872 /*MC 7873 MatDenseGetArrayF90 - Accesses a matrix array from Fortran 7874 7875 Synopsis: 7876 MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7877 7878 Not collective 7879 7880 Input Parameter: 7881 . x - matrix 7882 7883 Output Parameters: 7884 + xx_v - the Fortran pointer to the array 7885 - ierr - error code 7886 7887 Example of Usage: 7888 .vb 7889 PetscScalar, pointer xx_v(:,:) 7890 .... 7891 call MatDenseGetArrayF90(x,xx_v,ierr) 7892 a = xx_v(3) 7893 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7894 .ve 7895 7896 Level: advanced 7897 7898 .seealso: `MatDenseRestoreArrayF90()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatSeqAIJGetArrayF90()` 7899 7900 M*/ 7901 7902 /*MC 7903 MatDenseRestoreArrayF90 - Restores a matrix array that has been 7904 accessed with `MatDenseGetArrayF90()`. 7905 7906 Synopsis: 7907 MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7908 7909 Not collective 7910 7911 Input Parameters: 7912 + x - matrix 7913 - xx_v - the Fortran90 pointer to the array 7914 7915 Output Parameter: 7916 . ierr - error code 7917 7918 Example of Usage: 7919 .vb 7920 PetscScalar, pointer xx_v(:,:) 7921 .... 7922 call MatDenseGetArrayF90(x,xx_v,ierr) 7923 a = xx_v(3) 7924 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7925 .ve 7926 7927 Level: advanced 7928 7929 .seealso: `MatDenseGetArrayF90()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatSeqAIJRestoreArrayF90()` 7930 7931 M*/ 7932 7933 /*MC 7934 MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran. 7935 7936 Synopsis: 7937 MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7938 7939 Not collective 7940 7941 Input Parameter: 7942 . x - matrix 7943 7944 Output Parameters: 7945 + xx_v - the Fortran pointer to the array 7946 - ierr - error code 7947 7948 Example of Usage: 7949 .vb 7950 PetscScalar, pointer xx_v(:) 7951 .... 7952 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 7953 a = xx_v(3) 7954 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 7955 .ve 7956 7957 Level: advanced 7958 7959 .seealso: `MatSeqAIJRestoreArrayF90()`, `MatSeqAIJGetArray()`, `MatSeqAIJRestoreArray()`, `MatDenseGetArrayF90()` 7960 7961 M*/ 7962 7963 /*MC 7964 MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been 7965 accessed with `MatSeqAIJGetArrayF90()`. 7966 7967 Synopsis: 7968 MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7969 7970 Not collective 7971 7972 Input Parameters: 7973 + x - matrix 7974 - xx_v - the Fortran90 pointer to the array 7975 7976 Output Parameter: 7977 . ierr - error code 7978 7979 Example of Usage: 7980 .vb 7981 PetscScalar, pointer xx_v(:) 7982 .... 7983 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 7984 a = xx_v(3) 7985 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 7986 .ve 7987 7988 Level: advanced 7989 7990 .seealso: `MatSeqAIJGetArrayF90()`, `MatSeqAIJGetArray()`, `MatSeqAIJRestoreArray()`, `MatDenseRestoreArrayF90()` 7991 7992 M*/ 7993 7994 /*@ 7995 MatCreateSubMatrix - Gets a single submatrix on the same number of processors 7996 as the original matrix. 7997 7998 Collective on mat 7999 8000 Input Parameters: 8001 + mat - the original matrix 8002 . isrow - parallel IS containing the rows this processor should obtain 8003 . 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. 8004 - cll - either `MAT_INITIAL_MATRIX` or `MAT_REUSE_MATRIX` 8005 8006 Output Parameter: 8007 . newmat - the new submatrix, of the same type as the old 8008 8009 Level: advanced 8010 8011 Notes: 8012 The submatrix will be able to be multiplied with vectors using the same layout as iscol. 8013 8014 Some matrix types place restrictions on the row and column indices, such 8015 as that they be sorted or that they be equal to each other. 8016 8017 The index sets may not have duplicate entries. 8018 8019 The first time this is called you should use a cll of `MAT_INITIAL_MATRIX`, 8020 the `MatCreateSubMatrix()` routine will create the newmat for you. Any additional calls 8021 to this routine with a mat of the same nonzero structure and with a call of `MAT_REUSE_MATRIX` 8022 will reuse the matrix generated the first time. You should call `MatDestroy()` on newmat when 8023 you are finished using it. 8024 8025 The communicator of the newly obtained matrix is ALWAYS the same as the communicator of 8026 the input matrix. 8027 8028 If iscol is NULL then all columns are obtained (not supported in Fortran). 8029 8030 Example usage: 8031 Consider the following 8x8 matrix with 34 non-zero values, that is 8032 assembled across 3 processors. Let's assume that proc0 owns 3 rows, 8033 proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown 8034 as follows: 8035 8036 .vb 8037 1 2 0 | 0 3 0 | 0 4 8038 Proc0 0 5 6 | 7 0 0 | 8 0 8039 9 0 10 | 11 0 0 | 12 0 8040 ------------------------------------- 8041 13 0 14 | 15 16 17 | 0 0 8042 Proc1 0 18 0 | 19 20 21 | 0 0 8043 0 0 0 | 22 23 0 | 24 0 8044 ------------------------------------- 8045 Proc2 25 26 27 | 0 0 28 | 29 0 8046 30 0 0 | 31 32 33 | 0 34 8047 .ve 8048 8049 Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is 8050 8051 .vb 8052 2 0 | 0 3 0 | 0 8053 Proc0 5 6 | 7 0 0 | 8 8054 ------------------------------- 8055 Proc1 18 0 | 19 20 21 | 0 8056 ------------------------------- 8057 Proc2 26 27 | 0 0 28 | 29 8058 0 0 | 31 32 33 | 0 8059 .ve 8060 8061 .seealso: `Mat`, `MatCreateSubMatrices()`, `MatCreateSubMatricesMPI()`, `MatCreateSubMatrixVirtual()`, `MatSubMatrixVirtualUpdate()` 8062 @*/ 8063 PetscErrorCode MatCreateSubMatrix(Mat mat, IS isrow, IS iscol, MatReuse cll, Mat *newmat) { 8064 PetscMPIInt size; 8065 Mat *local; 8066 IS iscoltmp; 8067 PetscBool flg; 8068 8069 PetscFunctionBegin; 8070 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8071 PetscValidHeaderSpecific(isrow, IS_CLASSID, 2); 8072 if (iscol) PetscValidHeaderSpecific(iscol, IS_CLASSID, 3); 8073 PetscValidPointer(newmat, 5); 8074 if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat, MAT_CLASSID, 5); 8075 PetscValidType(mat, 1); 8076 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 8077 PetscCheck(cll != MAT_IGNORE_MATRIX, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Cannot use MAT_IGNORE_MATRIX"); 8078 8079 MatCheckPreallocated(mat, 1); 8080 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size)); 8081 8082 if (!iscol || isrow == iscol) { 8083 PetscBool stride; 8084 PetscMPIInt grabentirematrix = 0, grab; 8085 PetscCall(PetscObjectTypeCompare((PetscObject)isrow, ISSTRIDE, &stride)); 8086 if (stride) { 8087 PetscInt first, step, n, rstart, rend; 8088 PetscCall(ISStrideGetInfo(isrow, &first, &step)); 8089 if (step == 1) { 8090 PetscCall(MatGetOwnershipRange(mat, &rstart, &rend)); 8091 if (rstart == first) { 8092 PetscCall(ISGetLocalSize(isrow, &n)); 8093 if (n == rend - rstart) grabentirematrix = 1; 8094 } 8095 } 8096 } 8097 PetscCall(MPIU_Allreduce(&grabentirematrix, &grab, 1, MPI_INT, MPI_MIN, PetscObjectComm((PetscObject)mat))); 8098 if (grab) { 8099 PetscCall(PetscInfo(mat, "Getting entire matrix as submatrix\n")); 8100 if (cll == MAT_INITIAL_MATRIX) { 8101 *newmat = mat; 8102 PetscCall(PetscObjectReference((PetscObject)mat)); 8103 } 8104 PetscFunctionReturn(0); 8105 } 8106 } 8107 8108 if (!iscol) { 8109 PetscCall(ISCreateStride(PetscObjectComm((PetscObject)mat), mat->cmap->n, mat->cmap->rstart, 1, &iscoltmp)); 8110 } else { 8111 iscoltmp = iscol; 8112 } 8113 8114 /* if original matrix is on just one processor then use submatrix generated */ 8115 if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) { 8116 PetscCall(MatCreateSubMatrices(mat, 1, &isrow, &iscoltmp, MAT_REUSE_MATRIX, &newmat)); 8117 goto setproperties; 8118 } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) { 8119 PetscCall(MatCreateSubMatrices(mat, 1, &isrow, &iscoltmp, MAT_INITIAL_MATRIX, &local)); 8120 *newmat = *local; 8121 PetscCall(PetscFree(local)); 8122 goto setproperties; 8123 } else if (!mat->ops->createsubmatrix) { 8124 /* Create a new matrix type that implements the operation using the full matrix */ 8125 PetscCall(PetscLogEventBegin(MAT_CreateSubMat, mat, 0, 0, 0)); 8126 switch (cll) { 8127 case MAT_INITIAL_MATRIX: PetscCall(MatCreateSubMatrixVirtual(mat, isrow, iscoltmp, newmat)); break; 8128 case MAT_REUSE_MATRIX: PetscCall(MatSubMatrixVirtualUpdate(*newmat, mat, isrow, iscoltmp)); break; 8129 default: SETERRQ(PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_OUTOFRANGE, "Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX"); 8130 } 8131 PetscCall(PetscLogEventEnd(MAT_CreateSubMat, mat, 0, 0, 0)); 8132 goto setproperties; 8133 } 8134 8135 PetscCall(PetscLogEventBegin(MAT_CreateSubMat, mat, 0, 0, 0)); 8136 PetscUseTypeMethod(mat, createsubmatrix, isrow, iscoltmp, cll, newmat); 8137 PetscCall(PetscLogEventEnd(MAT_CreateSubMat, mat, 0, 0, 0)); 8138 8139 setproperties: 8140 PetscCall(ISEqualUnsorted(isrow, iscoltmp, &flg)); 8141 if (flg) PetscCall(MatPropagateSymmetryOptions(mat, *newmat)); 8142 if (!iscol) PetscCall(ISDestroy(&iscoltmp)); 8143 if (*newmat && cll == MAT_INITIAL_MATRIX) PetscCall(PetscObjectStateIncrease((PetscObject)*newmat)); 8144 PetscFunctionReturn(0); 8145 } 8146 8147 /*@ 8148 MatPropagateSymmetryOptions - Propagates symmetry options set on a matrix to another matrix 8149 8150 Not Collective 8151 8152 Input Parameters: 8153 + A - the matrix we wish to propagate options from 8154 - B - the matrix we wish to propagate options to 8155 8156 Level: beginner 8157 8158 Note: 8159 Propagates the options associated to `MAT_SYMMETRY_ETERNAL`, `MAT_STRUCTURALLY_SYMMETRIC`, `MAT_HERMITIAN`, `MAT_SPD`, `MAT_SYMMETRIC`, and `MAT_STRUCTURAL_SYMMETRY_ETERNAL` 8160 8161 .seealso: `MatSetOption()`, `MatIsSymmetricKnown()`, `MatIsSPDKnown()`, `MatIsHermitianKnown()`, MatIsStructurallySymmetricKnown()` 8162 @*/ 8163 PetscErrorCode MatPropagateSymmetryOptions(Mat A, Mat B) { 8164 PetscFunctionBegin; 8165 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8166 PetscValidHeaderSpecific(B, MAT_CLASSID, 2); 8167 B->symmetry_eternal = A->symmetry_eternal; 8168 B->structural_symmetry_eternal = A->structural_symmetry_eternal; 8169 B->symmetric = A->symmetric; 8170 B->structurally_symmetric = A->structurally_symmetric; 8171 B->spd = A->spd; 8172 B->hermitian = A->hermitian; 8173 PetscFunctionReturn(0); 8174 } 8175 8176 /*@ 8177 MatStashSetInitialSize - sets the sizes of the matrix stash, that is 8178 used during the assembly process to store values that belong to 8179 other processors. 8180 8181 Not Collective 8182 8183 Input Parameters: 8184 + mat - the matrix 8185 . size - the initial size of the stash. 8186 - bsize - the initial size of the block-stash(if used). 8187 8188 Options Database Keys: 8189 + -matstash_initial_size <size> or <size0,size1,...sizep-1> 8190 - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1> 8191 8192 Level: intermediate 8193 8194 Notes: 8195 The block-stash is used for values set with `MatSetValuesBlocked()` while 8196 the stash is used for values set with `MatSetValues()` 8197 8198 Run with the option -info and look for output of the form 8199 MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs. 8200 to determine the appropriate value, MM, to use for size and 8201 MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs. 8202 to determine the value, BMM to use for bsize 8203 8204 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `Mat`, `MatStashGetInfo()` 8205 @*/ 8206 PetscErrorCode MatStashSetInitialSize(Mat mat, PetscInt size, PetscInt bsize) { 8207 PetscFunctionBegin; 8208 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8209 PetscValidType(mat, 1); 8210 PetscCall(MatStashSetInitialSize_Private(&mat->stash, size)); 8211 PetscCall(MatStashSetInitialSize_Private(&mat->bstash, bsize)); 8212 PetscFunctionReturn(0); 8213 } 8214 8215 /*@ 8216 MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 8217 the matrix 8218 8219 Neighbor-wise Collective on mat 8220 8221 Input Parameters: 8222 + mat - the matrix 8223 . x,y - the vectors 8224 - w - where the result is stored 8225 8226 Level: intermediate 8227 8228 Notes: 8229 w may be the same vector as y. 8230 8231 This allows one to use either the restriction or interpolation (its transpose) 8232 matrix to do the interpolation 8233 8234 .seealso: `MatMultAdd()`, `MatMultTransposeAdd()`, `MatRestrict()`, `PCMG` 8235 @*/ 8236 PetscErrorCode MatInterpolateAdd(Mat A, Vec x, Vec y, Vec w) { 8237 PetscInt M, N, Ny; 8238 8239 PetscFunctionBegin; 8240 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8241 PetscValidHeaderSpecific(x, VEC_CLASSID, 2); 8242 PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 8243 PetscValidHeaderSpecific(w, VEC_CLASSID, 4); 8244 PetscCall(MatGetSize(A, &M, &N)); 8245 PetscCall(VecGetSize(y, &Ny)); 8246 if (M == Ny) { 8247 PetscCall(MatMultAdd(A, x, y, w)); 8248 } else { 8249 PetscCall(MatMultTransposeAdd(A, x, y, w)); 8250 } 8251 PetscFunctionReturn(0); 8252 } 8253 8254 /*@ 8255 MatInterpolate - y = A*x or A'*x depending on the shape of 8256 the matrix 8257 8258 Neighbor-wise Collective on mat 8259 8260 Input Parameters: 8261 + mat - the matrix 8262 - x,y - the vectors 8263 8264 Level: intermediate 8265 8266 Note: 8267 This allows one to use either the restriction or interpolation (its transpose) 8268 matrix to do the interpolation 8269 8270 .seealso: `MatMultAdd()`, `MatMultTransposeAdd()`, `MatRestrict()`, `PCMG` 8271 @*/ 8272 PetscErrorCode MatInterpolate(Mat A, Vec x, Vec y) { 8273 PetscInt M, N, Ny; 8274 8275 PetscFunctionBegin; 8276 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8277 PetscValidHeaderSpecific(x, VEC_CLASSID, 2); 8278 PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 8279 PetscCall(MatGetSize(A, &M, &N)); 8280 PetscCall(VecGetSize(y, &Ny)); 8281 if (M == Ny) { 8282 PetscCall(MatMult(A, x, y)); 8283 } else { 8284 PetscCall(MatMultTranspose(A, x, y)); 8285 } 8286 PetscFunctionReturn(0); 8287 } 8288 8289 /*@ 8290 MatRestrict - y = A*x or A'*x 8291 8292 Neighbor-wise Collective on Mat 8293 8294 Input Parameters: 8295 + mat - the matrix 8296 - x,y - the vectors 8297 8298 Level: intermediate 8299 8300 Note: 8301 This allows one to use either the restriction or interpolation (its transpose) 8302 matrix to do the restriction 8303 8304 .seealso: `MatMultAdd()`, `MatMultTransposeAdd()`, `MatInterpolate()`, `PCMG` 8305 @*/ 8306 PetscErrorCode MatRestrict(Mat A, Vec x, Vec y) { 8307 PetscInt M, N, Ny; 8308 8309 PetscFunctionBegin; 8310 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8311 PetscValidHeaderSpecific(x, VEC_CLASSID, 2); 8312 PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 8313 PetscCall(MatGetSize(A, &M, &N)); 8314 PetscCall(VecGetSize(y, &Ny)); 8315 if (M == Ny) { 8316 PetscCall(MatMult(A, x, y)); 8317 } else { 8318 PetscCall(MatMultTranspose(A, x, y)); 8319 } 8320 PetscFunctionReturn(0); 8321 } 8322 8323 /*@ 8324 MatMatInterpolateAdd - Y = W + A*X or W + A'*X 8325 8326 Neighbor-wise Collective on Mat 8327 8328 Input Parameters: 8329 + mat - the matrix 8330 - w, x - the input dense matrices 8331 8332 Output Parameters: 8333 . y - the output dense matrix 8334 8335 Level: intermediate 8336 8337 Note: 8338 This allows one to use either the restriction or interpolation (its transpose) 8339 matrix to do the interpolation. y matrix can be reused if already created with the proper sizes, 8340 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8341 8342 .seealso: `MatInterpolateAdd()`, `MatMatInterpolate()`, `MatMatRestrict()`, `PCMG` 8343 @*/ 8344 PetscErrorCode MatMatInterpolateAdd(Mat A, Mat x, Mat w, Mat *y) { 8345 PetscInt M, N, Mx, Nx, Mo, My = 0, Ny = 0; 8346 PetscBool trans = PETSC_TRUE; 8347 MatReuse reuse = MAT_INITIAL_MATRIX; 8348 8349 PetscFunctionBegin; 8350 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8351 PetscValidHeaderSpecific(x, MAT_CLASSID, 2); 8352 PetscValidType(x, 2); 8353 if (w) PetscValidHeaderSpecific(w, MAT_CLASSID, 3); 8354 if (*y) PetscValidHeaderSpecific(*y, MAT_CLASSID, 4); 8355 PetscCall(MatGetSize(A, &M, &N)); 8356 PetscCall(MatGetSize(x, &Mx, &Nx)); 8357 if (N == Mx) trans = PETSC_FALSE; 8358 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); 8359 Mo = trans ? N : M; 8360 if (*y) { 8361 PetscCall(MatGetSize(*y, &My, &Ny)); 8362 if (Mo == My && Nx == Ny) { 8363 reuse = MAT_REUSE_MATRIX; 8364 } else { 8365 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); 8366 PetscCall(MatDestroy(y)); 8367 } 8368 } 8369 8370 if (w && *y == w) { /* this is to minimize changes in PCMG */ 8371 PetscBool flg; 8372 8373 PetscCall(PetscObjectQuery((PetscObject)*y, "__MatMatIntAdd_w", (PetscObject *)&w)); 8374 if (w) { 8375 PetscInt My, Ny, Mw, Nw; 8376 8377 PetscCall(PetscObjectTypeCompare((PetscObject)*y, ((PetscObject)w)->type_name, &flg)); 8378 PetscCall(MatGetSize(*y, &My, &Ny)); 8379 PetscCall(MatGetSize(w, &Mw, &Nw)); 8380 if (!flg || My != Mw || Ny != Nw) w = NULL; 8381 } 8382 if (!w) { 8383 PetscCall(MatDuplicate(*y, MAT_COPY_VALUES, &w)); 8384 PetscCall(PetscObjectCompose((PetscObject)*y, "__MatMatIntAdd_w", (PetscObject)w)); 8385 PetscCall(PetscObjectDereference((PetscObject)w)); 8386 } else { 8387 PetscCall(MatCopy(*y, w, UNKNOWN_NONZERO_PATTERN)); 8388 } 8389 } 8390 if (!trans) { 8391 PetscCall(MatMatMult(A, x, reuse, PETSC_DEFAULT, y)); 8392 } else { 8393 PetscCall(MatTransposeMatMult(A, x, reuse, PETSC_DEFAULT, y)); 8394 } 8395 if (w) PetscCall(MatAXPY(*y, 1.0, w, UNKNOWN_NONZERO_PATTERN)); 8396 PetscFunctionReturn(0); 8397 } 8398 8399 /*@ 8400 MatMatInterpolate - Y = A*X or A'*X 8401 8402 Neighbor-wise Collective on Mat 8403 8404 Input Parameters: 8405 + mat - the matrix 8406 - x - the input dense matrix 8407 8408 Output Parameters: 8409 . y - the output dense matrix 8410 8411 Level: intermediate 8412 8413 Note: 8414 This allows one to use either the restriction or interpolation (its transpose) 8415 matrix to do the interpolation. y matrix can be reused if already created with the proper sizes, 8416 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8417 8418 .seealso: `MatInterpolate()`, `MatRestrict()`, `MatMatRestrict()`, `PCMG` 8419 @*/ 8420 PetscErrorCode MatMatInterpolate(Mat A, Mat x, Mat *y) { 8421 PetscFunctionBegin; 8422 PetscCall(MatMatInterpolateAdd(A, x, NULL, y)); 8423 PetscFunctionReturn(0); 8424 } 8425 8426 /*@ 8427 MatMatRestrict - Y = A*X or A'*X 8428 8429 Neighbor-wise Collective on Mat 8430 8431 Input Parameters: 8432 + mat - the matrix 8433 - x - the input dense matrix 8434 8435 Output Parameters: 8436 . y - the output dense matrix 8437 8438 Level: intermediate 8439 8440 Note: 8441 This allows one to use either the restriction or interpolation (its transpose) 8442 matrix to do the restriction. y matrix can be reused if already created with the proper sizes, 8443 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8444 8445 .seealso: `MatRestrict()`, `MatInterpolate()`, `MatMatInterpolate()`, `PCMG` 8446 @*/ 8447 PetscErrorCode MatMatRestrict(Mat A, Mat x, Mat *y) { 8448 PetscFunctionBegin; 8449 PetscCall(MatMatInterpolateAdd(A, x, NULL, y)); 8450 PetscFunctionReturn(0); 8451 } 8452 8453 /*@ 8454 MatGetNullSpace - retrieves the null space of a matrix. 8455 8456 Logically Collective on mat 8457 8458 Input Parameters: 8459 + mat - the matrix 8460 - nullsp - the null space object 8461 8462 Level: developer 8463 8464 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatSetNullSpace()`, `MatNullSpace` 8465 @*/ 8466 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp) { 8467 PetscFunctionBegin; 8468 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8469 PetscValidPointer(nullsp, 2); 8470 *nullsp = (mat->symmetric == PETSC_BOOL3_TRUE && !mat->nullsp) ? mat->transnullsp : mat->nullsp; 8471 PetscFunctionReturn(0); 8472 } 8473 8474 /*@ 8475 MatSetNullSpace - attaches a null space to a matrix. 8476 8477 Logically Collective on mat 8478 8479 Input Parameters: 8480 + mat - the matrix 8481 - nullsp - the null space object 8482 8483 Level: advanced 8484 8485 Notes: 8486 This null space is used by the `KSP` linear solvers to solve singular systems. 8487 8488 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 8489 8490 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 8491 to zero but the linear system will still be solved in a least squares sense. 8492 8493 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8494 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). 8495 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 8496 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 8497 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). 8498 This \hat{b} can be obtained by calling MatNullSpaceRemove() with the null space of the transpose of the matrix. 8499 8500 If the matrix is known to be symmetric because it is an `MATSBAIJ` matrix or one as called 8501 `MatSetOption`(mat,`MAT_SYMMETRIC` or possibly `MAT_SYMMETRY_ETERNAL`,`PETSC_TRUE`); this 8502 routine also automatically calls `MatSetTransposeNullSpace()`. 8503 8504 The user should call `MatNullSpaceDestroy()`. 8505 8506 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatGetNullSpace()`, `MatSetTransposeNullSpace()`, `MatGetTransposeNullSpace()`, `MatNullSpaceRemove()`, 8507 `KSPSetPCSide()` 8508 @*/ 8509 PetscErrorCode MatSetNullSpace(Mat mat, MatNullSpace nullsp) { 8510 PetscFunctionBegin; 8511 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8512 if (nullsp) PetscValidHeaderSpecific(nullsp, MAT_NULLSPACE_CLASSID, 2); 8513 if (nullsp) PetscCall(PetscObjectReference((PetscObject)nullsp)); 8514 PetscCall(MatNullSpaceDestroy(&mat->nullsp)); 8515 mat->nullsp = nullsp; 8516 if (mat->symmetric == PETSC_BOOL3_TRUE) PetscCall(MatSetTransposeNullSpace(mat, nullsp)); 8517 PetscFunctionReturn(0); 8518 } 8519 8520 /*@ 8521 MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix. 8522 8523 Logically Collective on mat 8524 8525 Input Parameters: 8526 + mat - the matrix 8527 - nullsp - the null space object 8528 8529 Level: developer 8530 8531 .seealso: `MatNullSpace`, `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatSetTransposeNullSpace()`, `MatSetNullSpace()`, `MatGetNullSpace()` 8532 @*/ 8533 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp) { 8534 PetscFunctionBegin; 8535 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8536 PetscValidType(mat, 1); 8537 PetscValidPointer(nullsp, 2); 8538 *nullsp = (mat->symmetric == PETSC_BOOL3_TRUE && !mat->transnullsp) ? mat->nullsp : mat->transnullsp; 8539 PetscFunctionReturn(0); 8540 } 8541 8542 /*@ 8543 MatSetTransposeNullSpace - attaches the null space of a transpose of a matrix to the matrix 8544 8545 Logically Collective on mat 8546 8547 Input Parameters: 8548 + mat - the matrix 8549 - nullsp - the null space object 8550 8551 Level: advanced 8552 8553 Notes: 8554 This allows solving singular linear systems defined by the transpose of the matrix using `KSP` solvers with left preconditioning. 8555 8556 See `MatSetNullSpace()` 8557 8558 .seealso: `MatNullSpace`, `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatGetNullSpace()`, `MatSetNullSpace()`, `MatGetTransposeNullSpace()`, `MatNullSpaceRemove()`, `KSPSetPCSide()` 8559 @*/ 8560 PetscErrorCode MatSetTransposeNullSpace(Mat mat, MatNullSpace nullsp) { 8561 PetscFunctionBegin; 8562 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8563 if (nullsp) PetscValidHeaderSpecific(nullsp, MAT_NULLSPACE_CLASSID, 2); 8564 if (nullsp) PetscCall(PetscObjectReference((PetscObject)nullsp)); 8565 PetscCall(MatNullSpaceDestroy(&mat->transnullsp)); 8566 mat->transnullsp = nullsp; 8567 PetscFunctionReturn(0); 8568 } 8569 8570 /*@ 8571 MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions 8572 This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix. 8573 8574 Logically Collective on mat 8575 8576 Input Parameters: 8577 + mat - the matrix 8578 - nullsp - the null space object 8579 8580 Level: advanced 8581 8582 Notes: 8583 Overwrites any previous near null space that may have been attached 8584 8585 You can remove the null space by calling this routine with an nullsp of NULL 8586 8587 .seealso: `MatNullSpace`, `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNullSpace()`, `MatNullSpaceCreateRigidBody()`, `MatGetNearNullSpace()` 8588 @*/ 8589 PetscErrorCode MatSetNearNullSpace(Mat mat, MatNullSpace nullsp) { 8590 PetscFunctionBegin; 8591 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8592 PetscValidType(mat, 1); 8593 if (nullsp) PetscValidHeaderSpecific(nullsp, MAT_NULLSPACE_CLASSID, 2); 8594 MatCheckPreallocated(mat, 1); 8595 if (nullsp) PetscCall(PetscObjectReference((PetscObject)nullsp)); 8596 PetscCall(MatNullSpaceDestroy(&mat->nearnullsp)); 8597 mat->nearnullsp = nullsp; 8598 PetscFunctionReturn(0); 8599 } 8600 8601 /*@ 8602 MatGetNearNullSpace - Get null space attached with `MatSetNearNullSpace()` 8603 8604 Not Collective 8605 8606 Input Parameter: 8607 . mat - the matrix 8608 8609 Output Parameter: 8610 . nullsp - the null space object, NULL if not set 8611 8612 Level: advanced 8613 8614 .seealso: `MatNullSpace`, `MatSetNearNullSpace()`, `MatGetNullSpace()`, `MatNullSpaceCreate()` 8615 @*/ 8616 PetscErrorCode MatGetNearNullSpace(Mat mat, MatNullSpace *nullsp) { 8617 PetscFunctionBegin; 8618 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8619 PetscValidType(mat, 1); 8620 PetscValidPointer(nullsp, 2); 8621 MatCheckPreallocated(mat, 1); 8622 *nullsp = mat->nearnullsp; 8623 PetscFunctionReturn(0); 8624 } 8625 8626 /*@C 8627 MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix. 8628 8629 Collective on mat 8630 8631 Input Parameters: 8632 + mat - the matrix 8633 . row - row/column permutation 8634 . fill - expected fill factor >= 1.0 8635 - level - level of fill, for ICC(k) 8636 8637 Notes: 8638 Probably really in-place only when level of fill is zero, otherwise allocates 8639 new space to store factored matrix and deletes previous memory. 8640 8641 Most users should employ the `KSP` interface for linear solvers 8642 instead of working directly with matrix algebra routines such as this. 8643 See, e.g., `KSPCreate()`. 8644 8645 Level: developer 8646 8647 Developer Note: 8648 The Fortran interface is not autogenerated as the f90 8649 interface definition cannot be generated correctly [due to `MatFactorInfo`] 8650 8651 .seealso: `MatGetFactor()`, `MatICCFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()` 8652 @*/ 8653 PetscErrorCode MatICCFactor(Mat mat, IS row, const MatFactorInfo *info) { 8654 PetscFunctionBegin; 8655 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8656 PetscValidType(mat, 1); 8657 if (row) PetscValidHeaderSpecific(row, IS_CLASSID, 2); 8658 PetscValidPointer(info, 3); 8659 PetscCheck(mat->rmap->N == mat->cmap->N, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONG, "matrix must be square"); 8660 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 8661 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 8662 MatCheckPreallocated(mat, 1); 8663 PetscUseTypeMethod(mat, iccfactor, row, info); 8664 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 8665 PetscFunctionReturn(0); 8666 } 8667 8668 /*@ 8669 MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 8670 ghosted ones. 8671 8672 Not Collective 8673 8674 Input Parameters: 8675 + mat - the matrix 8676 - diag - the diagonal values, including ghost ones 8677 8678 Level: developer 8679 8680 Notes: 8681 Works only for `MATMPIAIJ` and `MATMPIBAIJ` matrices 8682 8683 This allows one to avoid during communication to perform the scaling that must be done with `MatDiagonalScale()` 8684 8685 .seealso: `MatDiagonalScale()` 8686 @*/ 8687 PetscErrorCode MatDiagonalScaleLocal(Mat mat, Vec diag) { 8688 PetscMPIInt size; 8689 8690 PetscFunctionBegin; 8691 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8692 PetscValidHeaderSpecific(diag, VEC_CLASSID, 2); 8693 PetscValidType(mat, 1); 8694 8695 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Matrix must be already assembled"); 8696 PetscCall(PetscLogEventBegin(MAT_Scale, mat, 0, 0, 0)); 8697 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size)); 8698 if (size == 1) { 8699 PetscInt n, m; 8700 PetscCall(VecGetSize(diag, &n)); 8701 PetscCall(MatGetSize(mat, NULL, &m)); 8702 if (m == n) { 8703 PetscCall(MatDiagonalScale(mat, NULL, diag)); 8704 } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Only supported for sequential matrices when no ghost points/periodic conditions"); 8705 } else { 8706 PetscUseMethod(mat, "MatDiagonalScaleLocal_C", (Mat, Vec), (mat, diag)); 8707 } 8708 PetscCall(PetscLogEventEnd(MAT_Scale, mat, 0, 0, 0)); 8709 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 8710 PetscFunctionReturn(0); 8711 } 8712 8713 /*@ 8714 MatGetInertia - Gets the inertia from a factored matrix 8715 8716 Collective on mat 8717 8718 Input Parameter: 8719 . mat - the matrix 8720 8721 Output Parameters: 8722 + nneg - number of negative eigenvalues 8723 . nzero - number of zero eigenvalues 8724 - npos - number of positive eigenvalues 8725 8726 Level: advanced 8727 8728 Note: 8729 Matrix must have been factored by `MatCholeskyFactor()` 8730 8731 .seealso: `MatGetFactor()`, `MatCholeskyFactor()` 8732 @*/ 8733 PetscErrorCode MatGetInertia(Mat mat, PetscInt *nneg, PetscInt *nzero, PetscInt *npos) { 8734 PetscFunctionBegin; 8735 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8736 PetscValidType(mat, 1); 8737 PetscCheck(mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Unfactored matrix"); 8738 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Numeric factor mat is not assembled"); 8739 PetscUseTypeMethod(mat, getinertia, nneg, nzero, npos); 8740 PetscFunctionReturn(0); 8741 } 8742 8743 /* ----------------------------------------------------------------*/ 8744 /*@C 8745 MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors 8746 8747 Neighbor-wise Collective on mat 8748 8749 Input Parameters: 8750 + mat - the factored matrix obtained with `MatGetFactor()` 8751 - b - the right-hand-side vectors 8752 8753 Output Parameter: 8754 . x - the result vectors 8755 8756 Note: 8757 The vectors b and x cannot be the same. I.e., one cannot 8758 call `MatSolves`(A,x,x). 8759 8760 Level: developer 8761 8762 .seealso: `Vecs`, `MatSolveAdd()`, `MatSolveTranspose()`, `MatSolveTransposeAdd()`, `MatSolve()` 8763 @*/ 8764 PetscErrorCode MatSolves(Mat mat, Vecs b, Vecs x) { 8765 PetscFunctionBegin; 8766 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8767 PetscValidType(mat, 1); 8768 PetscCheck(x != b, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_IDN, "x and b must be different vectors"); 8769 PetscCheck(mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Unfactored matrix"); 8770 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 8771 8772 MatCheckPreallocated(mat, 1); 8773 PetscCall(PetscLogEventBegin(MAT_Solves, mat, 0, 0, 0)); 8774 PetscUseTypeMethod(mat, solves, b, x); 8775 PetscCall(PetscLogEventEnd(MAT_Solves, mat, 0, 0, 0)); 8776 PetscFunctionReturn(0); 8777 } 8778 8779 /*@ 8780 MatIsSymmetric - Test whether a matrix is symmetric 8781 8782 Collective on mat 8783 8784 Input Parameters: 8785 + A - the matrix to test 8786 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose) 8787 8788 Output Parameters: 8789 . flg - the result 8790 8791 Notes: 8792 For real numbers `MatIsSymmetric()` and `MatIsHermitian()` return identical results 8793 8794 If the matrix does not yet know if it is symmetric or not this can be an expensive operation, also available `MatIsSymmetricKnown()` 8795 8796 One can declare that a matrix is symmetric with `MatSetOption`(mat,`MAT_SYMMETRIC`,`PETSC_TRUE`) and if it is known to remain symmetric 8797 after changes to the matrices values one can call `MatSetOption`(mat,`MAT_SYMMETRY_ETERNAL`,`PETSC_TRUE`) 8798 8799 Level: intermediate 8800 8801 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetricKnown()`, 8802 `MAT_SYMMETRIC`, `MAT_SYMMETRY_ETERNAL`, `MatSetOption()` 8803 @*/ 8804 PetscErrorCode MatIsSymmetric(Mat A, PetscReal tol, PetscBool *flg) { 8805 PetscFunctionBegin; 8806 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8807 PetscValidBoolPointer(flg, 3); 8808 8809 if (A->symmetric == PETSC_BOOL3_TRUE) *flg = PETSC_TRUE; 8810 else if (A->symmetric == PETSC_BOOL3_FALSE) *flg = PETSC_FALSE; 8811 else { 8812 if (!A->ops->issymmetric) { 8813 MatType mattype; 8814 PetscCall(MatGetType(A, &mattype)); 8815 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Matrix of type %s does not support checking for symmetric", mattype); 8816 } 8817 PetscUseTypeMethod(A, issymmetric, tol, flg); 8818 if (!tol) PetscCall(MatSetOption(A, MAT_SYMMETRIC, *flg)); 8819 } 8820 PetscFunctionReturn(0); 8821 } 8822 8823 /*@ 8824 MatIsHermitian - Test whether a matrix is Hermitian 8825 8826 Collective on Mat 8827 8828 Input Parameters: 8829 + A - the matrix to test 8830 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian) 8831 8832 Output Parameters: 8833 . flg - the result 8834 8835 Level: intermediate 8836 8837 Notes: 8838 For real numbers `MatIsSymmetric()` and `MatIsHermitian()` return identical results 8839 8840 If the matrix does not yet know if it is Hermitian or not this can be an expensive operation, also available `MatIsHermitianKnown()` 8841 8842 One can declare that a matrix is Hermitian with `MatSetOption`(mat,`MAT_HERMITIAN`,`PETSC_TRUE`) and if it is known to remain Hermitian 8843 after changes to the matrices values one can call `MatSetOption`(mat,`MAT_SYMEMTRY_ETERNAL`,`PETSC_TRUE`) 8844 8845 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitianKnown()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, 8846 `MatIsSymmetricKnown()`, `MatIsSymmetric()`, `MAT_HERMITIAN`, `MAT_SYMMETRY_ETERNAL`, `MatSetOption()` 8847 @*/ 8848 PetscErrorCode MatIsHermitian(Mat A, PetscReal tol, PetscBool *flg) { 8849 PetscFunctionBegin; 8850 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8851 PetscValidBoolPointer(flg, 3); 8852 8853 if (A->hermitian == PETSC_BOOL3_TRUE) *flg = PETSC_TRUE; 8854 else if (A->hermitian == PETSC_BOOL3_FALSE) *flg = PETSC_FALSE; 8855 else { 8856 if (!A->ops->ishermitian) { 8857 MatType mattype; 8858 PetscCall(MatGetType(A, &mattype)); 8859 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Matrix of type %s does not support checking for hermitian", mattype); 8860 } 8861 PetscUseTypeMethod(A, ishermitian, tol, flg); 8862 if (!tol) PetscCall(MatSetOption(A, MAT_HERMITIAN, *flg)); 8863 } 8864 PetscFunctionReturn(0); 8865 } 8866 8867 /*@ 8868 MatIsSymmetricKnown - Checks if a matrix knows if it is symmetric or not and its symmetric state 8869 8870 Not Collective 8871 8872 Input Parameter: 8873 . A - the matrix to check 8874 8875 Output Parameters: 8876 + set - `PETSC_TRUE` if the matrix knows its symmetry state (this tells you if the next flag is valid) 8877 - flg - the result (only valid if set is `PETSC_TRUE`) 8878 8879 Level: advanced 8880 8881 Notes: 8882 Does not check the matrix values directly, so this may return unknown (set = `PETSC_FALSE`). Use `MatIsSymmetric()` 8883 if you want it explicitly checked 8884 8885 One can declare that a matrix is symmetric with `MatSetOption`(mat,`MAT_SYMMETRIC`,`PETSC_TRUE`) and if it is known to remain symmetric 8886 after changes to the matrices values one can call `MatSetOption`(mat,`MAT_SYMMETRY_ETERNAL`,`PETSC_TRUE`) 8887 8888 .seealso: `MAT_SYMMETRY_ETERNAL`, `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitianKnown()` 8889 @*/ 8890 PetscErrorCode MatIsSymmetricKnown(Mat A, PetscBool *set, PetscBool *flg) { 8891 PetscFunctionBegin; 8892 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8893 PetscValidBoolPointer(set, 2); 8894 PetscValidBoolPointer(flg, 3); 8895 if (A->symmetric != PETSC_BOOL3_UNKNOWN) { 8896 *set = PETSC_TRUE; 8897 *flg = PetscBool3ToBool(A->symmetric); 8898 } else { 8899 *set = PETSC_FALSE; 8900 } 8901 PetscFunctionReturn(0); 8902 } 8903 8904 /*@ 8905 MatIsSPDKnown - Checks if a matrix knows if it is symmetric positive definite or not and its symmetric positive definite state 8906 8907 Not Collective 8908 8909 Input Parameter: 8910 . A - the matrix to check 8911 8912 Output Parameters: 8913 + set - `PETSC_TRUE` if the matrix knows its symmetric positive definite state (this tells you if the next flag is valid) 8914 - flg - the result (only valid if set is `PETSC_TRUE`) 8915 8916 Level: advanced 8917 8918 Notes: 8919 Does not check the matrix values directly, so this may return unknown (set = `PETSC_FALSE`). 8920 8921 One can declare that a matrix is SPD with `MatSetOption`(mat,`MAT_SPD`,`PETSC_TRUE`) and if it is known to remain SPD 8922 after changes to the matrices values one can call `MatSetOption`(mat,`MAT_SPD_ETERNAL`,`PETSC_TRUE`) 8923 8924 .seealso: `MAT_SPD_ETERNAL`, `MAT_SPD`, `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitianKnown()` 8925 @*/ 8926 PetscErrorCode MatIsSPDKnown(Mat A, PetscBool *set, PetscBool *flg) { 8927 PetscFunctionBegin; 8928 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8929 PetscValidBoolPointer(set, 2); 8930 PetscValidBoolPointer(flg, 3); 8931 if (A->spd != PETSC_BOOL3_UNKNOWN) { 8932 *set = PETSC_TRUE; 8933 *flg = PetscBool3ToBool(A->spd); 8934 } else { 8935 *set = PETSC_FALSE; 8936 } 8937 PetscFunctionReturn(0); 8938 } 8939 8940 /*@ 8941 MatIsHermitianKnown - Checks if a matrix knows if it is Hermitian or not and its Hermitian state 8942 8943 Not Collective 8944 8945 Input Parameter: 8946 . A - the matrix to check 8947 8948 Output Parameters: 8949 + set - `PETSC_TRUE` if the matrix knows its Hermitian state (this tells you if the next flag is valid) 8950 - flg - the result (only valid if set is `PETSC_TRUE`) 8951 8952 Level: advanced 8953 8954 Notes: 8955 Does not check the matrix values directly, so this may return unknown (set = `PETSC_FALSE`). Use `MatIsHermitian()` 8956 if you want it explicitly checked 8957 8958 One can declare that a matrix is Hermitian with `MatSetOption`(mat,`MAT_HERMITIAN`,`PETSC_TRUE`) and if it is known to remain Hermitian 8959 after changes to the matrices values one can call `MatSetOption`(mat,`MAT_SYMMETRY_ETERNAL`,`PETSC_TRUE`) 8960 8961 .seealso: `MAT_SYMMETRY_ETERNAL`, `MAT_HERMITIAN`, `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()` 8962 @*/ 8963 PetscErrorCode MatIsHermitianKnown(Mat A, PetscBool *set, PetscBool *flg) { 8964 PetscFunctionBegin; 8965 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8966 PetscValidBoolPointer(set, 2); 8967 PetscValidBoolPointer(flg, 3); 8968 if (A->hermitian != PETSC_BOOL3_UNKNOWN) { 8969 *set = PETSC_TRUE; 8970 *flg = PetscBool3ToBool(A->hermitian); 8971 } else { 8972 *set = PETSC_FALSE; 8973 } 8974 PetscFunctionReturn(0); 8975 } 8976 8977 /*@ 8978 MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric 8979 8980 Collective on Mat 8981 8982 Input Parameter: 8983 . A - the matrix to test 8984 8985 Output Parameters: 8986 . flg - the result 8987 8988 Notes: 8989 If the matrix does yet know it is structurally symmetric this can be an expensive operation, also available `MatIsStructurallySymmetricKnown()` 8990 8991 One can declare that a matrix is structurally symmetric with `MatSetOption`(mat,`MAT_STRUCTURALLY_SYMMETRIC`,`PETSC_TRUE`) and if it is known to remain structurally 8992 symmetric after changes to the matrices values one can call `MatSetOption`(mat,`MAT_STRUCTURAL_SYMMETRY_ETERNAL`,`PETSC_TRUE`) 8993 8994 Level: intermediate 8995 8996 .seealso: `MAT_STRUCTURALLY_SYMMETRIC`, `MAT_STRUCTURAL_SYMMETRY_ETERNAL`, `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsSymmetric()`, `MatSetOption()`, `MatIsStructurallySymmetricKnown()` 8997 @*/ 8998 PetscErrorCode MatIsStructurallySymmetric(Mat A, PetscBool *flg) { 8999 PetscFunctionBegin; 9000 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 9001 PetscValidBoolPointer(flg, 2); 9002 if (A->structurally_symmetric != PETSC_BOOL3_UNKNOWN) { 9003 *flg = PetscBool3ToBool(A->structurally_symmetric); 9004 } else { 9005 PetscUseTypeMethod(A, isstructurallysymmetric, flg); 9006 PetscCall(MatSetOption(A, MAT_STRUCTURALLY_SYMMETRIC, *flg)); 9007 } 9008 PetscFunctionReturn(0); 9009 } 9010 9011 /*@ 9012 MatIsStructurallySymmetricKnown - Checks if a matrix knows if it is structurally symmetric or not and its structurally symmetric state 9013 9014 Not Collective 9015 9016 Input Parameter: 9017 . A - the matrix to check 9018 9019 Output Parameters: 9020 + set - PETSC_TRUE if the matrix knows its structurally symmetric state (this tells you if the next flag is valid) 9021 - flg - the result (only valid if set is PETSC_TRUE) 9022 9023 Level: advanced 9024 9025 Notes: 9026 One can declare that a matrix is structurally symmetric with `MatSetOption`(mat,`MAT_STRUCTURALLY_SYMMETRIC`,`PETSC_TRUE`) and if it is known to remain structurally 9027 symmetric after changes to the matrices values one can call `MatSetOption`(mat,`MAT_STRUCTURAL_SYMMETRY_ETERNAL`,`PETSC_TRUE`) 9028 9029 Use `MatIsStructurallySymmetric()` to explicitly check if a matrix is structurally symmetric (this is an expensive operation) 9030 9031 .seealso: `MAT_STRUCTURALLY_SYMMETRIC`, `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitianKnown()` 9032 @*/ 9033 PetscErrorCode MatIsStructurallySymmetricKnown(Mat A, PetscBool *set, PetscBool *flg) { 9034 PetscFunctionBegin; 9035 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 9036 PetscValidBoolPointer(set, 2); 9037 PetscValidBoolPointer(flg, 3); 9038 if (A->structurally_symmetric != PETSC_BOOL3_UNKNOWN) { 9039 *set = PETSC_TRUE; 9040 *flg = PetscBool3ToBool(A->structurally_symmetric); 9041 } else { 9042 *set = PETSC_FALSE; 9043 } 9044 PetscFunctionReturn(0); 9045 } 9046 9047 /*@ 9048 MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need 9049 to be communicated to other processors during the `MatAssemblyBegin()`/`MatAssemblyEnd()` process 9050 9051 Not collective 9052 9053 Input Parameter: 9054 . mat - the matrix 9055 9056 Output Parameters: 9057 + nstash - the size of the stash 9058 . reallocs - the number of additional mallocs incurred. 9059 . bnstash - the size of the block stash 9060 - breallocs - the number of additional mallocs incurred.in the block stash 9061 9062 Level: advanced 9063 9064 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `Mat`, `MatStashSetInitialSize()` 9065 @*/ 9066 PetscErrorCode MatStashGetInfo(Mat mat, PetscInt *nstash, PetscInt *reallocs, PetscInt *bnstash, PetscInt *breallocs) { 9067 PetscFunctionBegin; 9068 PetscCall(MatStashGetInfo_Private(&mat->stash, nstash, reallocs)); 9069 PetscCall(MatStashGetInfo_Private(&mat->bstash, bnstash, breallocs)); 9070 PetscFunctionReturn(0); 9071 } 9072 9073 /*@C 9074 MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same 9075 parallel layout, `PetscLayout` for rows and columns 9076 9077 Collective on mat 9078 9079 Input Parameter: 9080 . mat - the matrix 9081 9082 Output Parameters: 9083 + right - (optional) vector that the matrix can be multiplied against 9084 - left - (optional) vector that the matrix vector product can be stored in 9085 9086 Notes: 9087 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()`. 9088 9089 These are new vectors which are not owned by the mat, they should be destroyed in `VecDestroy()` when no longer needed 9090 9091 Level: advanced 9092 9093 .seealso: `Mat`, `Vec`, `VecCreate()`, `VecDestroy()`, `DMCreateGlobalVector()` 9094 @*/ 9095 PetscErrorCode MatCreateVecs(Mat mat, Vec *right, Vec *left) { 9096 PetscFunctionBegin; 9097 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 9098 PetscValidType(mat, 1); 9099 if (mat->ops->getvecs) { 9100 PetscUseTypeMethod(mat, getvecs, right, left); 9101 } else { 9102 PetscInt rbs, cbs; 9103 PetscCall(MatGetBlockSizes(mat, &rbs, &cbs)); 9104 if (right) { 9105 PetscCheck(mat->cmap->n >= 0, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "PetscLayout for columns not yet setup"); 9106 PetscCall(VecCreate(PetscObjectComm((PetscObject)mat), right)); 9107 PetscCall(VecSetSizes(*right, mat->cmap->n, PETSC_DETERMINE)); 9108 PetscCall(VecSetBlockSize(*right, cbs)); 9109 PetscCall(VecSetType(*right, mat->defaultvectype)); 9110 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 9111 if (mat->boundtocpu && mat->bindingpropagates) { 9112 PetscCall(VecSetBindingPropagates(*right, PETSC_TRUE)); 9113 PetscCall(VecBindToCPU(*right, PETSC_TRUE)); 9114 } 9115 #endif 9116 PetscCall(PetscLayoutReference(mat->cmap, &(*right)->map)); 9117 } 9118 if (left) { 9119 PetscCheck(mat->rmap->n >= 0, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "PetscLayout for rows not yet setup"); 9120 PetscCall(VecCreate(PetscObjectComm((PetscObject)mat), left)); 9121 PetscCall(VecSetSizes(*left, mat->rmap->n, PETSC_DETERMINE)); 9122 PetscCall(VecSetBlockSize(*left, rbs)); 9123 PetscCall(VecSetType(*left, mat->defaultvectype)); 9124 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 9125 if (mat->boundtocpu && mat->bindingpropagates) { 9126 PetscCall(VecSetBindingPropagates(*left, PETSC_TRUE)); 9127 PetscCall(VecBindToCPU(*left, PETSC_TRUE)); 9128 } 9129 #endif 9130 PetscCall(PetscLayoutReference(mat->rmap, &(*left)->map)); 9131 } 9132 } 9133 PetscFunctionReturn(0); 9134 } 9135 9136 /*@C 9137 MatFactorInfoInitialize - Initializes a `MatFactorInfo` data structure 9138 with default values. 9139 9140 Not Collective 9141 9142 Input Parameters: 9143 . info - the `MatFactorInfo` data structure 9144 9145 Notes: 9146 The solvers are generally used through the `KSP` and `PC` objects, for example 9147 `PCLU`, `PCILU`, `PCCHOLESKY`, `PCICC` 9148 9149 Once the data structure is initialized one may change certain entries as desired for the particular factorization to be performed 9150 9151 Level: developer 9152 9153 Developer Note: 9154 The Fortran interface is not autogenerated as the f90 9155 interface definition cannot be generated correctly [due to `MatFactorInfo`] 9156 9157 .seealso: `MatGetFactor()`, `MatFactorInfo` 9158 @*/ 9159 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info) { 9160 PetscFunctionBegin; 9161 PetscCall(PetscMemzero(info, sizeof(MatFactorInfo))); 9162 PetscFunctionReturn(0); 9163 } 9164 9165 /*@ 9166 MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed 9167 9168 Collective on mat 9169 9170 Input Parameters: 9171 + mat - the factored matrix 9172 - is - the index set defining the Schur indices (0-based) 9173 9174 Notes: 9175 Call `MatFactorSolveSchurComplement()` or `MatFactorSolveSchurComplementTranspose()` after this call to solve a Schur complement system. 9176 9177 You can call `MatFactorGetSchurComplement()` or `MatFactorCreateSchurComplement()` after this call. 9178 9179 This functionality is only supported for `MATSOLVERMUMPS` and `MATSOLVERMKL_PARDISO` 9180 9181 Level: advanced 9182 9183 .seealso: `MatGetFactor()`, `MatFactorGetSchurComplement()`, `MatFactorRestoreSchurComplement()`, `MatFactorCreateSchurComplement()`, `MatFactorSolveSchurComplement()`, 9184 `MatFactorSolveSchurComplementTranspose()`, `MatFactorSolveSchurComplement()`, `MATSOLVERMUMPS`, `MATSOLVERMKL_PARDISO` 9185 9186 @*/ 9187 PetscErrorCode MatFactorSetSchurIS(Mat mat, IS is) { 9188 PetscErrorCode (*f)(Mat, IS); 9189 9190 PetscFunctionBegin; 9191 PetscValidType(mat, 1); 9192 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 9193 PetscValidType(is, 2); 9194 PetscValidHeaderSpecific(is, IS_CLASSID, 2); 9195 PetscCheckSameComm(mat, 1, is, 2); 9196 PetscCheck(mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Only for factored matrix"); 9197 PetscCall(PetscObjectQueryFunction((PetscObject)mat, "MatFactorSetSchurIS_C", &f)); 9198 PetscCheck(f, PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "The selected MatSolverType does not support Schur complement computation. You should use MATSOLVERMUMPS or MATSOLVERMKL_PARDISO"); 9199 PetscCall(MatDestroy(&mat->schur)); 9200 PetscCall((*f)(mat, is)); 9201 PetscCheck(mat->schur, PetscObjectComm((PetscObject)mat), PETSC_ERR_PLIB, "Schur complement has not been created"); 9202 PetscFunctionReturn(0); 9203 } 9204 9205 /*@ 9206 MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step 9207 9208 Logically Collective on mat 9209 9210 Input Parameters: 9211 + F - the factored matrix obtained by calling `MatGetFactor()` 9212 . S - location where to return the Schur complement, can be NULL 9213 - status - the status of the Schur complement matrix, can be NULL 9214 9215 Notes: 9216 You must call `MatFactorSetSchurIS()` before calling this routine. 9217 9218 This functionality is only supported for `MATSOLVERMUMPS` and `MATSOLVERMKL_PARDISO` 9219 9220 The routine provides a copy of the Schur matrix stored within the solver data structures. 9221 The caller must destroy the object when it is no longer needed. 9222 If `MatFactorInvertSchurComplement()` has been called, the routine gets back the inverse. 9223 9224 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) 9225 9226 See `MatCreateSchurComplement()` or `MatGetSchurComplement()` for ways to create virtual or approximate Schur complements. 9227 9228 Developer Note: 9229 The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc 9230 matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix. 9231 9232 Level: advanced 9233 9234 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorGetSchurComplement()`, `MatFactorSchurStatus`, `MATSOLVERMUMPS`, `MATSOLVERMKL_PARDISO` 9235 @*/ 9236 PetscErrorCode MatFactorCreateSchurComplement(Mat F, Mat *S, MatFactorSchurStatus *status) { 9237 PetscFunctionBegin; 9238 PetscValidHeaderSpecific(F, MAT_CLASSID, 1); 9239 if (S) PetscValidPointer(S, 2); 9240 if (status) PetscValidPointer(status, 3); 9241 if (S) { 9242 PetscErrorCode (*f)(Mat, Mat *); 9243 9244 PetscCall(PetscObjectQueryFunction((PetscObject)F, "MatFactorCreateSchurComplement_C", &f)); 9245 if (f) { 9246 PetscCall((*f)(F, S)); 9247 } else { 9248 PetscCall(MatDuplicate(F->schur, MAT_COPY_VALUES, S)); 9249 } 9250 } 9251 if (status) *status = F->schur_status; 9252 PetscFunctionReturn(0); 9253 } 9254 9255 /*@ 9256 MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix 9257 9258 Logically Collective on mat 9259 9260 Input Parameters: 9261 + F - the factored matrix obtained by calling `MatGetFactor()` 9262 . *S - location where to return the Schur complement, can be NULL 9263 - status - the status of the Schur complement matrix, can be NULL 9264 9265 Notes: 9266 You must call `MatFactorSetSchurIS()` before calling this routine. 9267 9268 Schur complement mode is currently implemented for sequential matrices with factor type of `MATSOLVERMUMPS` 9269 9270 The routine returns a the Schur Complement stored within the data strutures of the solver. 9271 9272 If `MatFactorInvertSchurComplement()` has previously been called, the returned matrix is actually the inverse of the Schur complement. 9273 9274 The returned matrix should not be destroyed; the caller should call `MatFactorRestoreSchurComplement()` when the object is no longer needed. 9275 9276 Use `MatFactorCreateSchurComplement()` to create a copy of the Schur complement matrix that is within a factored matrix 9277 9278 See `MatCreateSchurComplement()` or `MatGetSchurComplement()` for ways to create virtual or approximate Schur complements. 9279 9280 Level: advanced 9281 9282 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorRestoreSchurComplement()`, `MatFactorCreateSchurComplement()`, `MatFactorSchurStatus` 9283 @*/ 9284 PetscErrorCode MatFactorGetSchurComplement(Mat F, Mat *S, MatFactorSchurStatus *status) { 9285 PetscFunctionBegin; 9286 PetscValidHeaderSpecific(F, MAT_CLASSID, 1); 9287 if (S) PetscValidPointer(S, 2); 9288 if (status) PetscValidPointer(status, 3); 9289 if (S) *S = F->schur; 9290 if (status) *status = F->schur_status; 9291 PetscFunctionReturn(0); 9292 } 9293 9294 /*@ 9295 MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to `MatFactorGetSchurComplement()` 9296 9297 Logically Collective on mat 9298 9299 Input Parameters: 9300 + F - the factored matrix obtained by calling `MatGetFactor()` 9301 . *S - location where the Schur complement is stored 9302 - status - the status of the Schur complement matrix (see `MatFactorSchurStatus`) 9303 9304 Level: advanced 9305 9306 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorRestoreSchurComplement()`, `MatFactorCreateSchurComplement()`, `MatFactorSchurStatus` 9307 @*/ 9308 PetscErrorCode MatFactorRestoreSchurComplement(Mat F, Mat *S, MatFactorSchurStatus status) { 9309 PetscFunctionBegin; 9310 PetscValidHeaderSpecific(F, MAT_CLASSID, 1); 9311 if (S) { 9312 PetscValidHeaderSpecific(*S, MAT_CLASSID, 2); 9313 *S = NULL; 9314 } 9315 F->schur_status = status; 9316 PetscCall(MatFactorUpdateSchurStatus_Private(F)); 9317 PetscFunctionReturn(0); 9318 } 9319 9320 /*@ 9321 MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step 9322 9323 Logically Collective on mat 9324 9325 Input Parameters: 9326 + F - the factored matrix obtained by calling `MatGetFactor()` 9327 . rhs - location where the right hand side of the Schur complement system is stored 9328 - sol - location where the solution of the Schur complement system has to be returned 9329 9330 Notes: 9331 The sizes of the vectors should match the size of the Schur complement 9332 9333 Must be called after `MatFactorSetSchurIS()` 9334 9335 Level: advanced 9336 9337 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorSolveSchurComplement()` 9338 @*/ 9339 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol) { 9340 PetscFunctionBegin; 9341 PetscValidType(F, 1); 9342 PetscValidType(rhs, 2); 9343 PetscValidType(sol, 3); 9344 PetscValidHeaderSpecific(F, MAT_CLASSID, 1); 9345 PetscValidHeaderSpecific(rhs, VEC_CLASSID, 2); 9346 PetscValidHeaderSpecific(sol, VEC_CLASSID, 3); 9347 PetscCheckSameComm(F, 1, rhs, 2); 9348 PetscCheckSameComm(F, 1, sol, 3); 9349 PetscCall(MatFactorFactorizeSchurComplement(F)); 9350 switch (F->schur_status) { 9351 case MAT_FACTOR_SCHUR_FACTORED: PetscCall(MatSolveTranspose(F->schur, rhs, sol)); break; 9352 case MAT_FACTOR_SCHUR_INVERTED: PetscCall(MatMultTranspose(F->schur, rhs, sol)); break; 9353 default: SETERRQ(PetscObjectComm((PetscObject)F), PETSC_ERR_SUP, "Unhandled MatFactorSchurStatus %d", F->schur_status); 9354 } 9355 PetscFunctionReturn(0); 9356 } 9357 9358 /*@ 9359 MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step 9360 9361 Logically Collective on mat 9362 9363 Input Parameters: 9364 + F - the factored matrix obtained by calling `MatGetFactor()` 9365 . rhs - location where the right hand side of the Schur complement system is stored 9366 - sol - location where the solution of the Schur complement system has to be returned 9367 9368 Notes: 9369 The sizes of the vectors should match the size of the Schur complement 9370 9371 Must be called after `MatFactorSetSchurIS()` 9372 9373 Level: advanced 9374 9375 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorSolveSchurComplementTranspose()` 9376 @*/ 9377 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol) { 9378 PetscFunctionBegin; 9379 PetscValidType(F, 1); 9380 PetscValidType(rhs, 2); 9381 PetscValidType(sol, 3); 9382 PetscValidHeaderSpecific(F, MAT_CLASSID, 1); 9383 PetscValidHeaderSpecific(rhs, VEC_CLASSID, 2); 9384 PetscValidHeaderSpecific(sol, VEC_CLASSID, 3); 9385 PetscCheckSameComm(F, 1, rhs, 2); 9386 PetscCheckSameComm(F, 1, sol, 3); 9387 PetscCall(MatFactorFactorizeSchurComplement(F)); 9388 switch (F->schur_status) { 9389 case MAT_FACTOR_SCHUR_FACTORED: PetscCall(MatSolve(F->schur, rhs, sol)); break; 9390 case MAT_FACTOR_SCHUR_INVERTED: PetscCall(MatMult(F->schur, rhs, sol)); break; 9391 default: SETERRQ(PetscObjectComm((PetscObject)F), PETSC_ERR_SUP, "Unhandled MatFactorSchurStatus %d", F->schur_status); 9392 } 9393 PetscFunctionReturn(0); 9394 } 9395 9396 /*@ 9397 MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step 9398 9399 Logically Collective on F 9400 9401 Input Parameters: 9402 . F - the factored matrix obtained by calling `MatGetFactor()` 9403 9404 Notes: 9405 Must be called after `MatFactorSetSchurIS()`. 9406 9407 Call `MatFactorGetSchurComplement()` or `MatFactorCreateSchurComplement()` AFTER this call to actually compute the inverse and get access to it. 9408 9409 Level: advanced 9410 9411 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorGetSchurComplement()`, `MatFactorCreateSchurComplement()` 9412 @*/ 9413 PetscErrorCode MatFactorInvertSchurComplement(Mat F) { 9414 PetscFunctionBegin; 9415 PetscValidType(F, 1); 9416 PetscValidHeaderSpecific(F, MAT_CLASSID, 1); 9417 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0); 9418 PetscCall(MatFactorFactorizeSchurComplement(F)); 9419 PetscCall(MatFactorInvertSchurComplement_Private(F)); 9420 F->schur_status = MAT_FACTOR_SCHUR_INVERTED; 9421 PetscFunctionReturn(0); 9422 } 9423 9424 /*@ 9425 MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step 9426 9427 Logically Collective on mat 9428 9429 Input Parameters: 9430 . F - the factored matrix obtained by calling `MatGetFactor()` 9431 9432 Note: 9433 Must be called after `MatFactorSetSchurIS()` 9434 9435 Level: advanced 9436 9437 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorInvertSchurComplement()` 9438 @*/ 9439 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F) { 9440 PetscFunctionBegin; 9441 PetscValidType(F, 1); 9442 PetscValidHeaderSpecific(F, MAT_CLASSID, 1); 9443 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0); 9444 PetscCall(MatFactorFactorizeSchurComplement_Private(F)); 9445 F->schur_status = MAT_FACTOR_SCHUR_FACTORED; 9446 PetscFunctionReturn(0); 9447 } 9448 9449 /*@ 9450 MatPtAP - Creates the matrix product C = P^T * A * P 9451 9452 Neighbor-wise Collective on A 9453 9454 Input Parameters: 9455 + A - the matrix 9456 . P - the projection matrix 9457 . scall - either `MAT_INITIAL_MATRIX` or `MAT_REUSE_MATRIX` 9458 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use `PETSC_DEFAULT` if you do not have a good estimate 9459 if the result is a dense matrix this is irrelevant 9460 9461 Output Parameters: 9462 . C - the product matrix 9463 9464 Notes: 9465 C will be created and must be destroyed by the user with `MatDestroy()`. 9466 9467 An alternative approach to this function is to use `MatProductCreate()` and set the desired options before the computation is done 9468 9469 Developer Note: 9470 For matrix types without special implementation the function fallbacks to `MatMatMult()` followed by `MatTransposeMatMult()`. 9471 9472 Level: intermediate 9473 9474 .seealso: `MatProductCreate()`, `MatMatMult()`, `MatRARt()` 9475 @*/ 9476 PetscErrorCode MatPtAP(Mat A, Mat P, MatReuse scall, PetscReal fill, Mat *C) { 9477 PetscFunctionBegin; 9478 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*C, 5); 9479 PetscCheck(scall != MAT_INPLACE_MATRIX, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Inplace product not supported"); 9480 9481 if (scall == MAT_INITIAL_MATRIX) { 9482 PetscCall(MatProductCreate(A, P, NULL, C)); 9483 PetscCall(MatProductSetType(*C, MATPRODUCT_PtAP)); 9484 PetscCall(MatProductSetAlgorithm(*C, "default")); 9485 PetscCall(MatProductSetFill(*C, fill)); 9486 9487 (*C)->product->api_user = PETSC_TRUE; 9488 PetscCall(MatProductSetFromOptions(*C)); 9489 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); 9490 PetscCall(MatProductSymbolic(*C)); 9491 } else { /* scall == MAT_REUSE_MATRIX */ 9492 PetscCall(MatProductReplaceMats(A, P, NULL, *C)); 9493 } 9494 9495 PetscCall(MatProductNumeric(*C)); 9496 (*C)->symmetric = A->symmetric; 9497 (*C)->spd = A->spd; 9498 PetscFunctionReturn(0); 9499 } 9500 9501 /*@ 9502 MatRARt - Creates the matrix product C = R * A * R^T 9503 9504 Neighbor-wise Collective on A 9505 9506 Input Parameters: 9507 + A - the matrix 9508 . R - the projection matrix 9509 . scall - either `MAT_INITIAL_MATRIX` or `MAT_REUSE_MATRIX` 9510 - fill - expected fill as ratio of nnz(C)/nnz(A), use `PETSC_DEFAULT` if you do not have a good estimate 9511 if the result is a dense matrix this is irrelevant 9512 9513 Output Parameters: 9514 . C - the product matrix 9515 9516 Notes: 9517 C will be created and must be destroyed by the user with `MatDestroy()`. 9518 9519 An alternative approach to this function is to use `MatProductCreate()` and set the desired options before the computation is done 9520 9521 This routine is currently only implemented for pairs of `MATAIJ` matrices and classes 9522 which inherit from `MATAIJ`. Due to PETSc sparse matrix block row distribution among processes, 9523 parallel MatRARt is implemented via explicit transpose of R, which could be very expensive. 9524 We recommend using MatPtAP(). 9525 9526 Level: intermediate 9527 9528 .seealso: `MatProductCreate()`, `MatMatMult()`, `MatPtAP()` 9529 @*/ 9530 PetscErrorCode MatRARt(Mat A, Mat R, MatReuse scall, PetscReal fill, Mat *C) { 9531 PetscFunctionBegin; 9532 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*C, 5); 9533 PetscCheck(scall != MAT_INPLACE_MATRIX, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Inplace product not supported"); 9534 9535 if (scall == MAT_INITIAL_MATRIX) { 9536 PetscCall(MatProductCreate(A, R, NULL, C)); 9537 PetscCall(MatProductSetType(*C, MATPRODUCT_RARt)); 9538 PetscCall(MatProductSetAlgorithm(*C, "default")); 9539 PetscCall(MatProductSetFill(*C, fill)); 9540 9541 (*C)->product->api_user = PETSC_TRUE; 9542 PetscCall(MatProductSetFromOptions(*C)); 9543 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); 9544 PetscCall(MatProductSymbolic(*C)); 9545 } else { /* scall == MAT_REUSE_MATRIX */ 9546 PetscCall(MatProductReplaceMats(A, R, NULL, *C)); 9547 } 9548 9549 PetscCall(MatProductNumeric(*C)); 9550 if (A->symmetric == PETSC_BOOL3_TRUE) PetscCall(MatSetOption(*C, MAT_SYMMETRIC, PETSC_TRUE)); 9551 PetscFunctionReturn(0); 9552 } 9553 9554 static PetscErrorCode MatProduct_Private(Mat A, Mat B, MatReuse scall, PetscReal fill, MatProductType ptype, Mat *C) { 9555 PetscFunctionBegin; 9556 PetscCheck(scall != MAT_INPLACE_MATRIX, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Inplace product not supported"); 9557 9558 if (scall == MAT_INITIAL_MATRIX) { 9559 PetscCall(PetscInfo(A, "Calling MatProduct API with MAT_INITIAL_MATRIX and product type %s\n", MatProductTypes[ptype])); 9560 PetscCall(MatProductCreate(A, B, NULL, C)); 9561 PetscCall(MatProductSetType(*C, ptype)); 9562 PetscCall(MatProductSetAlgorithm(*C, MATPRODUCTALGORITHMDEFAULT)); 9563 PetscCall(MatProductSetFill(*C, fill)); 9564 9565 (*C)->product->api_user = PETSC_TRUE; 9566 PetscCall(MatProductSetFromOptions(*C)); 9567 PetscCall(MatProductSymbolic(*C)); 9568 } else { /* scall == MAT_REUSE_MATRIX */ 9569 Mat_Product *product = (*C)->product; 9570 PetscBool isdense; 9571 9572 PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)(*C), &isdense, MATSEQDENSE, MATMPIDENSE, "")); 9573 if (isdense && product && product->type != ptype) { 9574 PetscCall(MatProductClear(*C)); 9575 product = NULL; 9576 } 9577 PetscCall(PetscInfo(A, "Calling MatProduct API with MAT_REUSE_MATRIX %s product present and product type %s\n", product ? "with" : "without", MatProductTypes[ptype])); 9578 if (!product) { /* user provide the dense matrix *C without calling MatProductCreate() or reusing it from previous calls */ 9579 if (isdense) { 9580 PetscCall(MatProductCreate_Private(A, B, NULL, *C)); 9581 product = (*C)->product; 9582 product->fill = fill; 9583 product->api_user = PETSC_TRUE; 9584 product->clear = PETSC_TRUE; 9585 9586 PetscCall(MatProductSetType(*C, ptype)); 9587 PetscCall(MatProductSetFromOptions(*C)); 9588 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); 9589 PetscCall(MatProductSymbolic(*C)); 9590 } else SETERRQ(PetscObjectComm((PetscObject)(*C)), PETSC_ERR_SUP, "Call MatProductCreate() first"); 9591 } else { /* user may change input matrices A or B when REUSE */ 9592 PetscCall(MatProductReplaceMats(A, B, NULL, *C)); 9593 } 9594 } 9595 PetscCall(MatProductNumeric(*C)); 9596 PetscFunctionReturn(0); 9597 } 9598 9599 /*@ 9600 MatMatMult - Performs matrix-matrix multiplication C=A*B. 9601 9602 Neighbor-wise Collective on A 9603 9604 Input Parameters: 9605 + A - the left matrix 9606 . B - the right matrix 9607 . scall - either `MAT_INITIAL_MATRIX` or `MAT_REUSE_MATRIX` 9608 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use `PETSC_DEFAULT` if you do not have a good estimate 9609 if the result is a dense matrix this is irrelevant 9610 9611 Output Parameters: 9612 . C - the product matrix 9613 9614 Notes: 9615 Unless scall is `MAT_REUSE_MATRIX` C will be created. 9616 9617 `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 9618 call to this function with `MAT_INITIAL_MATRIX`. 9619 9620 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value actually needed. 9621 9622 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`, 9623 rather than first having `MatMatMult()` create it for you. You can NEVER do this if the matrix C is sparse. 9624 9625 Example of Usage: 9626 .vb 9627 MatProductCreate(A,B,NULL,&C); 9628 MatProductSetType(C,MATPRODUCT_AB); 9629 MatProductSymbolic(C); 9630 MatProductNumeric(C); // compute C=A * B 9631 MatProductReplaceMats(A1,B1,NULL,C); // compute C=A1 * B1 9632 MatProductNumeric(C); 9633 MatProductReplaceMats(A2,NULL,NULL,C); // compute C=A2 * B1 9634 MatProductNumeric(C); 9635 .ve 9636 9637 Level: intermediate 9638 9639 .seealso: `MatProductType`, `MATPRODUCT_AB`, `MatTransposeMatMult()`, `MatMatTransposeMult()`, `MatPtAP()`, `MatProductCreate()`, `MatProductSymbolic()`, `MatProductReplaceMats()`, `MatProductNumeric()` 9640 @*/ 9641 PetscErrorCode MatMatMult(Mat A, Mat B, MatReuse scall, PetscReal fill, Mat *C) { 9642 PetscFunctionBegin; 9643 PetscCall(MatProduct_Private(A, B, scall, fill, MATPRODUCT_AB, C)); 9644 PetscFunctionReturn(0); 9645 } 9646 9647 /*@ 9648 MatMatTransposeMult - Performs matrix-matrix multiplication C=A*B^T. 9649 9650 Neighbor-wise Collective on A 9651 9652 Input Parameters: 9653 + A - the left matrix 9654 . B - the right matrix 9655 . scall - either `MAT_INITIAL_MATRIX` or `MAT_REUSE_MATRIX` 9656 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use `PETSC_DEFAULT` if not known 9657 9658 Output Parameters: 9659 . C - the product matrix 9660 9661 Notes: 9662 C will be created if `MAT_INITIAL_MATRIX` and must be destroyed by the user with `MatDestroy()`. 9663 9664 `MAT_REUSE_MATRIX` can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9665 9666 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9667 actually needed. 9668 9669 This routine is currently only implemented for pairs of `MATSEQAIJ` matrices, for the `MATSEQDENSE` class, 9670 and for pairs of `MATMPIDENSE` matrices. 9671 9672 This routine is shorthand for using `MatProductCreate()` with the `MatProductType` of `MATPRODUCT_ABt` 9673 9674 Options Database Keys: 9675 . -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorithms for `MATMPIDENSE` matrices: the 9676 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity; 9677 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity. 9678 9679 Level: intermediate 9680 9681 .seealso: `MatProductCreate()`, `MATPRODUCT_ABt`, `MatMatMult()`, `MatTransposeMatMult()` `MatPtAP()`, `MatProductCreate()`, `MatProductAlgorithm`, `MatProductType`, `MATPRODUCT_ABt` 9682 @*/ 9683 PetscErrorCode MatMatTransposeMult(Mat A, Mat B, MatReuse scall, PetscReal fill, Mat *C) { 9684 PetscFunctionBegin; 9685 PetscCall(MatProduct_Private(A, B, scall, fill, MATPRODUCT_ABt, C)); 9686 if (A == B) PetscCall(MatSetOption(*C, MAT_SYMMETRIC, PETSC_TRUE)); 9687 PetscFunctionReturn(0); 9688 } 9689 9690 /*@ 9691 MatTransposeMatMult - Performs matrix-matrix multiplication C=A^T*B. 9692 9693 Neighbor-wise Collective on A 9694 9695 Input Parameters: 9696 + A - the left matrix 9697 . B - the right matrix 9698 . scall - either `MAT_INITIAL_MATRIX` or `MAT_REUSE_MATRIX` 9699 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use `PETSC_DEFAULT` if not known 9700 9701 Output Parameters: 9702 . C - the product matrix 9703 9704 Notes: 9705 C will be created if `MAT_INITIAL_MATRIX` and must be destroyed by the user with `MatDestroy()`. 9706 9707 `MAT_REUSE_MATRIX` can only be used if the matrices A and B have the same nonzero pattern as in the previous call. 9708 9709 This routine is shorthand for using `MatProductCreate()` with the `MatProductType` of `MATPRODUCT_AtB` 9710 9711 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9712 actually needed. 9713 9714 This routine is currently implemented for pairs of `MATAIJ` matrices and pairs of `MATSEQDENSE` matrices and classes 9715 which inherit from `MATSEQAIJ`. C will be of the same type as the input matrices. 9716 9717 Level: intermediate 9718 9719 .seealso: `MatProductCreate()`, `MATPRODUCT_AtB`, `MatMatMult()`, `MatMatTransposeMult()`, `MatPtAP()` 9720 @*/ 9721 PetscErrorCode MatTransposeMatMult(Mat A, Mat B, MatReuse scall, PetscReal fill, Mat *C) { 9722 PetscFunctionBegin; 9723 PetscCall(MatProduct_Private(A, B, scall, fill, MATPRODUCT_AtB, C)); 9724 PetscFunctionReturn(0); 9725 } 9726 9727 /*@ 9728 MatMatMatMult - Performs matrix-matrix-matrix multiplication D=A*B*C. 9729 9730 Neighbor-wise Collective on A 9731 9732 Input Parameters: 9733 + A - the left matrix 9734 . B - the middle matrix 9735 . C - the right matrix 9736 . scall - either `MAT_INITIAL_MATRIX` or `MAT_REUSE_MATRIX` 9737 - 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 9738 if the result is a dense matrix this is irrelevant 9739 9740 Output Parameters: 9741 . D - the product matrix 9742 9743 Notes: 9744 Unless scall is `MAT_REUSE_MATRIX` D will be created. 9745 9746 `MAT_REUSE_MATRIX` can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call 9747 9748 This routine is shorthand for using `MatProductCreate()` with the `MatProductType` of `MATPRODUCT_ABC` 9749 9750 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9751 actually needed. 9752 9753 If you have many matrices with the same non-zero structure to multiply, you 9754 should use `MAT_REUSE_MATRIX` in all calls but the first 9755 9756 Level: intermediate 9757 9758 .seealso: `MatProductCreate()`, `MATPRODUCT_ABC`, `MatMatMult`, `MatPtAP()`, `MatMatTransposeMult()`, `MatTransposeMatMult()` 9759 @*/ 9760 PetscErrorCode MatMatMatMult(Mat A, Mat B, Mat C, MatReuse scall, PetscReal fill, Mat *D) { 9761 PetscFunctionBegin; 9762 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*D, 6); 9763 PetscCheck(scall != MAT_INPLACE_MATRIX, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Inplace product not supported"); 9764 9765 if (scall == MAT_INITIAL_MATRIX) { 9766 PetscCall(MatProductCreate(A, B, C, D)); 9767 PetscCall(MatProductSetType(*D, MATPRODUCT_ABC)); 9768 PetscCall(MatProductSetAlgorithm(*D, "default")); 9769 PetscCall(MatProductSetFill(*D, fill)); 9770 9771 (*D)->product->api_user = PETSC_TRUE; 9772 PetscCall(MatProductSetFromOptions(*D)); 9773 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, 9774 ((PetscObject)C)->type_name); 9775 PetscCall(MatProductSymbolic(*D)); 9776 } else { /* user may change input matrices when REUSE */ 9777 PetscCall(MatProductReplaceMats(A, B, C, *D)); 9778 } 9779 PetscCall(MatProductNumeric(*D)); 9780 PetscFunctionReturn(0); 9781 } 9782 9783 /*@ 9784 MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators. 9785 9786 Collective on mat 9787 9788 Input Parameters: 9789 + mat - the matrix 9790 . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices) 9791 . subcomm - MPI communicator split from the communicator where mat resides in (or `MPI_COMM_NULL` if nsubcomm is used) 9792 - reuse - either `MAT_INITIAL_MATRIX` or `MAT_REUSE_MATRIX` 9793 9794 Output Parameter: 9795 . matredundant - redundant matrix 9796 9797 Notes: 9798 `MAT_REUSE_MATRIX` can only be used when the nonzero structure of the 9799 original matrix has not changed from that last call to MatCreateRedundantMatrix(). 9800 9801 This routine creates the duplicated matrices in the subcommunicators; you should NOT create them before 9802 calling it. 9803 9804 `PetscSubcommCreate()` can be used to manage the creation of the subcomm but need not be. 9805 9806 Level: advanced 9807 9808 .seealso: `MatDestroy()`, `PetscSubcommCreate()`, `PetscSubComm` 9809 @*/ 9810 PetscErrorCode MatCreateRedundantMatrix(Mat mat, PetscInt nsubcomm, MPI_Comm subcomm, MatReuse reuse, Mat *matredundant) { 9811 MPI_Comm comm; 9812 PetscMPIInt size; 9813 PetscInt mloc_sub, nloc_sub, rstart, rend, M = mat->rmap->N, N = mat->cmap->N, bs = mat->rmap->bs; 9814 Mat_Redundant *redund = NULL; 9815 PetscSubcomm psubcomm = NULL; 9816 MPI_Comm subcomm_in = subcomm; 9817 Mat *matseq; 9818 IS isrow, iscol; 9819 PetscBool newsubcomm = PETSC_FALSE; 9820 9821 PetscFunctionBegin; 9822 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 9823 if (nsubcomm && reuse == MAT_REUSE_MATRIX) { 9824 PetscValidPointer(*matredundant, 5); 9825 PetscValidHeaderSpecific(*matredundant, MAT_CLASSID, 5); 9826 } 9827 9828 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size)); 9829 if (size == 1 || nsubcomm == 1) { 9830 if (reuse == MAT_INITIAL_MATRIX) { 9831 PetscCall(MatDuplicate(mat, MAT_COPY_VALUES, matredundant)); 9832 } else { 9833 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"); 9834 PetscCall(MatCopy(mat, *matredundant, SAME_NONZERO_PATTERN)); 9835 } 9836 PetscFunctionReturn(0); 9837 } 9838 9839 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 9840 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 9841 MatCheckPreallocated(mat, 1); 9842 9843 PetscCall(PetscLogEventBegin(MAT_RedundantMat, mat, 0, 0, 0)); 9844 if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */ 9845 /* create psubcomm, then get subcomm */ 9846 PetscCall(PetscObjectGetComm((PetscObject)mat, &comm)); 9847 PetscCallMPI(MPI_Comm_size(comm, &size)); 9848 PetscCheck(nsubcomm >= 1 && nsubcomm <= size, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "nsubcomm must between 1 and %d", size); 9849 9850 PetscCall(PetscSubcommCreate(comm, &psubcomm)); 9851 PetscCall(PetscSubcommSetNumber(psubcomm, nsubcomm)); 9852 PetscCall(PetscSubcommSetType(psubcomm, PETSC_SUBCOMM_CONTIGUOUS)); 9853 PetscCall(PetscSubcommSetFromOptions(psubcomm)); 9854 PetscCall(PetscCommDuplicate(PetscSubcommChild(psubcomm), &subcomm, NULL)); 9855 newsubcomm = PETSC_TRUE; 9856 PetscCall(PetscSubcommDestroy(&psubcomm)); 9857 } 9858 9859 /* get isrow, iscol and a local sequential matrix matseq[0] */ 9860 if (reuse == MAT_INITIAL_MATRIX) { 9861 mloc_sub = PETSC_DECIDE; 9862 nloc_sub = PETSC_DECIDE; 9863 if (bs < 1) { 9864 PetscCall(PetscSplitOwnership(subcomm, &mloc_sub, &M)); 9865 PetscCall(PetscSplitOwnership(subcomm, &nloc_sub, &N)); 9866 } else { 9867 PetscCall(PetscSplitOwnershipBlock(subcomm, bs, &mloc_sub, &M)); 9868 PetscCall(PetscSplitOwnershipBlock(subcomm, bs, &nloc_sub, &N)); 9869 } 9870 PetscCallMPI(MPI_Scan(&mloc_sub, &rend, 1, MPIU_INT, MPI_SUM, subcomm)); 9871 rstart = rend - mloc_sub; 9872 PetscCall(ISCreateStride(PETSC_COMM_SELF, mloc_sub, rstart, 1, &isrow)); 9873 PetscCall(ISCreateStride(PETSC_COMM_SELF, N, 0, 1, &iscol)); 9874 } else { /* reuse == MAT_REUSE_MATRIX */ 9875 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"); 9876 /* retrieve subcomm */ 9877 PetscCall(PetscObjectGetComm((PetscObject)(*matredundant), &subcomm)); 9878 redund = (*matredundant)->redundant; 9879 isrow = redund->isrow; 9880 iscol = redund->iscol; 9881 matseq = redund->matseq; 9882 } 9883 PetscCall(MatCreateSubMatrices(mat, 1, &isrow, &iscol, reuse, &matseq)); 9884 9885 /* get matredundant over subcomm */ 9886 if (reuse == MAT_INITIAL_MATRIX) { 9887 PetscCall(MatCreateMPIMatConcatenateSeqMat(subcomm, matseq[0], nloc_sub, reuse, matredundant)); 9888 9889 /* create a supporting struct and attach it to C for reuse */ 9890 PetscCall(PetscNew(&redund)); 9891 (*matredundant)->redundant = redund; 9892 redund->isrow = isrow; 9893 redund->iscol = iscol; 9894 redund->matseq = matseq; 9895 if (newsubcomm) { 9896 redund->subcomm = subcomm; 9897 } else { 9898 redund->subcomm = MPI_COMM_NULL; 9899 } 9900 } else { 9901 PetscCall(MatCreateMPIMatConcatenateSeqMat(subcomm, matseq[0], PETSC_DECIDE, reuse, matredundant)); 9902 } 9903 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 9904 if (matseq[0]->boundtocpu && matseq[0]->bindingpropagates) { 9905 PetscCall(MatBindToCPU(*matredundant, PETSC_TRUE)); 9906 PetscCall(MatSetBindingPropagates(*matredundant, PETSC_TRUE)); 9907 } 9908 #endif 9909 PetscCall(PetscLogEventEnd(MAT_RedundantMat, mat, 0, 0, 0)); 9910 PetscFunctionReturn(0); 9911 } 9912 9913 /*@C 9914 MatGetMultiProcBlock - Create multiple 'parallel submatrices' from 9915 a given `Mat`. Each submatrix can span multiple procs. 9916 9917 Collective on mat 9918 9919 Input Parameters: 9920 + mat - the matrix 9921 . subcomm - the subcommunicator obtained by MPI_Com_split(comm) 9922 - scall - either `MAT_INITIAL_MATRIX` or `MAT_REUSE_MATRIX` 9923 9924 Output Parameter: 9925 . subMat - 'parallel submatrices each spans a given subcomm 9926 9927 Notes: 9928 The submatrix partition across processors is dictated by 'subComm' a 9929 communicator obtained by MPI_comm_split() or via `PetscSubcommCreate()`. The subComm 9930 is not restriced to be grouped with consecutive original ranks. 9931 9932 Due the MPI_Comm_split() usage, the parallel layout of the submatrices 9933 map directly to the layout of the original matrix [wrt the local 9934 row,col partitioning]. So the original 'DiagonalMat' naturally maps 9935 into the 'DiagonalMat' of the subMat, hence it is used directly from 9936 the subMat. However the offDiagMat looses some columns - and this is 9937 reconstructed with `MatSetValues()` 9938 9939 This is used by `PCBJACOBI` when a single block spans multiple MPI ranks 9940 9941 Level: advanced 9942 9943 .seealso: `MatCreateRedundantMatrix()`, `MatCreateSubMatrices()`, `PCBJACOBI` 9944 @*/ 9945 PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall, Mat *subMat) { 9946 PetscMPIInt commsize, subCommSize; 9947 9948 PetscFunctionBegin; 9949 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat), &commsize)); 9950 PetscCallMPI(MPI_Comm_size(subComm, &subCommSize)); 9951 PetscCheck(subCommSize <= commsize, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_OUTOFRANGE, "CommSize %d < SubCommZize %d", commsize, subCommSize); 9952 9953 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"); 9954 PetscCall(PetscLogEventBegin(MAT_GetMultiProcBlock, mat, 0, 0, 0)); 9955 PetscUseTypeMethod(mat, getmultiprocblock, subComm, scall, subMat); 9956 PetscCall(PetscLogEventEnd(MAT_GetMultiProcBlock, mat, 0, 0, 0)); 9957 PetscFunctionReturn(0); 9958 } 9959 9960 /*@ 9961 MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering 9962 9963 Not Collective 9964 9965 Input Parameters: 9966 + mat - matrix to extract local submatrix from 9967 . isrow - local row indices for submatrix 9968 - iscol - local column indices for submatrix 9969 9970 Output Parameter: 9971 . submat - the submatrix 9972 9973 Level: intermediate 9974 9975 Notes: 9976 The submat should be returned with `MatRestoreLocalSubMatrix()`. 9977 9978 Depending on the format of mat, the returned submat may not implement `MatMult()`. Its communicator may be 9979 the same as mat, it may be `PETSC_COMM_SELF`, or some other subcomm of mat's. 9980 9981 The submat always implements `MatSetValuesLocal()`. If isrow and iscol have the same block size, then 9982 `MatSetValuesBlockedLocal()` will also be implemented. 9983 9984 The mat must have had a `ISLocalToGlobalMapping` provided to it with `MatSetLocalToGlobalMapping()`. 9985 Matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided. 9986 9987 .seealso: `MatRestoreLocalSubMatrix()`, `MatCreateLocalRef()`, `MatSetLocalToGlobalMapping()` 9988 @*/ 9989 PetscErrorCode MatGetLocalSubMatrix(Mat mat, IS isrow, IS iscol, Mat *submat) { 9990 PetscFunctionBegin; 9991 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 9992 PetscValidHeaderSpecific(isrow, IS_CLASSID, 2); 9993 PetscValidHeaderSpecific(iscol, IS_CLASSID, 3); 9994 PetscCheckSameComm(isrow, 2, iscol, 3); 9995 PetscValidPointer(submat, 4); 9996 PetscCheck(mat->rmap->mapping, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Matrix must have local to global mapping provided before this call"); 9997 9998 if (mat->ops->getlocalsubmatrix) { 9999 PetscUseTypeMethod(mat, getlocalsubmatrix, isrow, iscol, submat); 10000 } else { 10001 PetscCall(MatCreateLocalRef(mat, isrow, iscol, submat)); 10002 } 10003 PetscFunctionReturn(0); 10004 } 10005 10006 /*@ 10007 MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering obtained with `MatGetLocalSubMatrix()` 10008 10009 Not Collective 10010 10011 Input Parameters: 10012 + mat - matrix to extract local submatrix from 10013 . isrow - local row indices for submatrix 10014 . iscol - local column indices for submatrix 10015 - submat - the submatrix 10016 10017 Level: intermediate 10018 10019 .seealso: `MatGetLocalSubMatrix()` 10020 @*/ 10021 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat, IS isrow, IS iscol, Mat *submat) { 10022 PetscFunctionBegin; 10023 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 10024 PetscValidHeaderSpecific(isrow, IS_CLASSID, 2); 10025 PetscValidHeaderSpecific(iscol, IS_CLASSID, 3); 10026 PetscCheckSameComm(isrow, 2, iscol, 3); 10027 PetscValidPointer(submat, 4); 10028 if (*submat) PetscValidHeaderSpecific(*submat, MAT_CLASSID, 4); 10029 10030 if (mat->ops->restorelocalsubmatrix) { 10031 PetscUseTypeMethod(mat, restorelocalsubmatrix, isrow, iscol, submat); 10032 } else { 10033 PetscCall(MatDestroy(submat)); 10034 } 10035 *submat = NULL; 10036 PetscFunctionReturn(0); 10037 } 10038 10039 /* --------------------------------------------------------*/ 10040 /*@ 10041 MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix 10042 10043 Collective on mat 10044 10045 Input Parameter: 10046 . mat - the matrix 10047 10048 Output Parameter: 10049 . is - if any rows have zero diagonals this contains the list of them 10050 10051 Level: developer 10052 10053 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 10054 @*/ 10055 PetscErrorCode MatFindZeroDiagonals(Mat mat, IS *is) { 10056 PetscFunctionBegin; 10057 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 10058 PetscValidType(mat, 1); 10059 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 10060 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 10061 10062 if (!mat->ops->findzerodiagonals) { 10063 Vec diag; 10064 const PetscScalar *a; 10065 PetscInt *rows; 10066 PetscInt rStart, rEnd, r, nrow = 0; 10067 10068 PetscCall(MatCreateVecs(mat, &diag, NULL)); 10069 PetscCall(MatGetDiagonal(mat, diag)); 10070 PetscCall(MatGetOwnershipRange(mat, &rStart, &rEnd)); 10071 PetscCall(VecGetArrayRead(diag, &a)); 10072 for (r = 0; r < rEnd - rStart; ++r) 10073 if (a[r] == 0.0) ++nrow; 10074 PetscCall(PetscMalloc1(nrow, &rows)); 10075 nrow = 0; 10076 for (r = 0; r < rEnd - rStart; ++r) 10077 if (a[r] == 0.0) rows[nrow++] = r + rStart; 10078 PetscCall(VecRestoreArrayRead(diag, &a)); 10079 PetscCall(VecDestroy(&diag)); 10080 PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)mat), nrow, rows, PETSC_OWN_POINTER, is)); 10081 } else { 10082 PetscUseTypeMethod(mat, findzerodiagonals, is); 10083 } 10084 PetscFunctionReturn(0); 10085 } 10086 10087 /*@ 10088 MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size) 10089 10090 Collective on mat 10091 10092 Input Parameter: 10093 . mat - the matrix 10094 10095 Output Parameter: 10096 . is - contains the list of rows with off block diagonal entries 10097 10098 Level: developer 10099 10100 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 10101 @*/ 10102 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat, IS *is) { 10103 PetscFunctionBegin; 10104 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 10105 PetscValidType(mat, 1); 10106 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 10107 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 10108 10109 PetscUseTypeMethod(mat, findoffblockdiagonalentries, is); 10110 PetscFunctionReturn(0); 10111 } 10112 10113 /*@C 10114 MatInvertBlockDiagonal - Inverts the block diagonal entries. 10115 10116 Collective on mat 10117 10118 Input Parameters: 10119 . mat - the matrix 10120 10121 Output Parameters: 10122 . values - the block inverses in column major order (FORTRAN-like) 10123 10124 Notes: 10125 The size of the blocks is determined by the block size of the matrix. 10126 10127 The blocks never overlap between two MPI ranks, use `MatInvertVariableBlockEnvelope()` for that case 10128 10129 The blocks all have the same size, use `MatInvertVariableBlockDiagonal()` for variable block size 10130 10131 Fortran Note: 10132 This routine is not available from Fortran. 10133 10134 Level: advanced 10135 10136 .seealso: `MatInvertVariableBlockEnvelope()`, `MatInvertBlockDiagonalMat()` 10137 @*/ 10138 PetscErrorCode MatInvertBlockDiagonal(Mat mat, const PetscScalar **values) { 10139 PetscFunctionBegin; 10140 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 10141 PetscCheck(mat->assembled, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 10142 PetscCheck(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 10143 PetscUseTypeMethod(mat, invertblockdiagonal, values); 10144 PetscFunctionReturn(0); 10145 } 10146 10147 /*@C 10148 MatInvertVariableBlockDiagonal - Inverts the point block diagonal entries. 10149 10150 Collective on mat 10151 10152 Input Parameters: 10153 + mat - the matrix 10154 . nblocks - the number of blocks on the process, set with `MatSetVariableBlockSizes()` 10155 - bsizes - the size of each block on the process, set with `MatSetVariableBlockSizes()` 10156 10157 Output Parameters: 10158 . values - the block inverses in column major order (FORTRAN-like) 10159 10160 Notes: 10161 Use `MatInvertBlockDiagonal()` if all blocks have the same size 10162 10163 The blocks never overlap between two MPI ranks, use `MatInvertVariableBlockEnvelope()` for that case 10164 10165 Fortran Note: 10166 This routine is not available from Fortran. 10167 10168 Level: advanced 10169 10170 .seealso: `MatInvertBlockDiagonal()`, `MatSetVariableBlockSizes()`, `MatInvertVariableBlockEnvelope()` 10171 @*/ 10172 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat, PetscInt nblocks, const PetscInt *bsizes, PetscScalar *values) { 10173 PetscFunctionBegin; 10174 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 10175 PetscCheck(mat->assembled, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 10176 PetscCheck(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 10177 PetscUseTypeMethod(mat, invertvariableblockdiagonal, nblocks, bsizes, values); 10178 PetscFunctionReturn(0); 10179 } 10180 10181 /*@ 10182 MatInvertBlockDiagonalMat - set the values of matrix C to be the inverted block diagonal of matrix A 10183 10184 Collective on Mat 10185 10186 Input Parameters: 10187 + A - the matrix 10188 - C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set. 10189 10190 Note: 10191 The blocksize of the matrix is used to determine the blocks on the diagonal of C 10192 10193 Level: advanced 10194 10195 .seealso: `MatInvertBlockDiagonal()` 10196 @*/ 10197 PetscErrorCode MatInvertBlockDiagonalMat(Mat A, Mat C) { 10198 const PetscScalar *vals; 10199 PetscInt *dnnz; 10200 PetscInt m, rstart, rend, bs, i, j; 10201 10202 PetscFunctionBegin; 10203 PetscCall(MatInvertBlockDiagonal(A, &vals)); 10204 PetscCall(MatGetBlockSize(A, &bs)); 10205 PetscCall(MatGetLocalSize(A, &m, NULL)); 10206 PetscCall(MatSetLayouts(C, A->rmap, A->cmap)); 10207 PetscCall(PetscMalloc1(m / bs, &dnnz)); 10208 for (j = 0; j < m / bs; j++) dnnz[j] = 1; 10209 PetscCall(MatXAIJSetPreallocation(C, bs, dnnz, NULL, NULL, NULL)); 10210 PetscCall(PetscFree(dnnz)); 10211 PetscCall(MatGetOwnershipRange(C, &rstart, &rend)); 10212 PetscCall(MatSetOption(C, MAT_ROW_ORIENTED, PETSC_FALSE)); 10213 for (i = rstart / bs; i < rend / bs; i++) PetscCall(MatSetValuesBlocked(C, 1, &i, 1, &i, &vals[(i - rstart / bs) * bs * bs], INSERT_VALUES)); 10214 PetscCall(MatAssemblyBegin(C, MAT_FINAL_ASSEMBLY)); 10215 PetscCall(MatAssemblyEnd(C, MAT_FINAL_ASSEMBLY)); 10216 PetscCall(MatSetOption(C, MAT_ROW_ORIENTED, PETSC_TRUE)); 10217 PetscFunctionReturn(0); 10218 } 10219 10220 /*@C 10221 MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created 10222 via `MatTransposeColoringCreate()`. 10223 10224 Collective on c 10225 10226 Input Parameter: 10227 . c - coloring context 10228 10229 Level: intermediate 10230 10231 .seealso: `MatTransposeColoringCreate()` 10232 @*/ 10233 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c) { 10234 MatTransposeColoring matcolor = *c; 10235 10236 PetscFunctionBegin; 10237 if (!matcolor) PetscFunctionReturn(0); 10238 if (--((PetscObject)matcolor)->refct > 0) { 10239 matcolor = NULL; 10240 PetscFunctionReturn(0); 10241 } 10242 10243 PetscCall(PetscFree3(matcolor->ncolumns, matcolor->nrows, matcolor->colorforrow)); 10244 PetscCall(PetscFree(matcolor->rows)); 10245 PetscCall(PetscFree(matcolor->den2sp)); 10246 PetscCall(PetscFree(matcolor->colorforcol)); 10247 PetscCall(PetscFree(matcolor->columns)); 10248 if (matcolor->brows > 0) PetscCall(PetscFree(matcolor->lstart)); 10249 PetscCall(PetscHeaderDestroy(c)); 10250 PetscFunctionReturn(0); 10251 } 10252 10253 /*@C 10254 MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which 10255 a `MatTransposeColoring` context has been created, computes a dense B^T by applying 10256 `MatTransposeColoring` to sparse B. 10257 10258 Collective on coloring 10259 10260 Input Parameters: 10261 + B - sparse matrix B 10262 . Btdense - symbolic dense matrix B^T 10263 - coloring - coloring context created with `MatTransposeColoringCreate()` 10264 10265 Output Parameter: 10266 . Btdense - dense matrix B^T 10267 10268 Level: developer 10269 10270 Note: 10271 These are used internally for some implementations of `MatRARt()` 10272 10273 .seealso: `MatTransposeColoringCreate()`, `MatTransposeColoringDestroy()`, `MatTransColoringApplyDenToSp()` 10274 10275 @*/ 10276 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring, Mat B, Mat Btdense) { 10277 PetscFunctionBegin; 10278 PetscValidHeaderSpecific(B, MAT_CLASSID, 2); 10279 PetscValidHeaderSpecific(Btdense, MAT_CLASSID, 3); 10280 PetscValidHeaderSpecific(coloring, MAT_TRANSPOSECOLORING_CLASSID, 1); 10281 10282 PetscCall((B->ops->transcoloringapplysptoden)(coloring, B, Btdense)); 10283 PetscFunctionReturn(0); 10284 } 10285 10286 /*@C 10287 MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which 10288 a `MatTransposeColoring` context has been created and a dense matrix Cden=A*Btdense 10289 in which Btdens is obtained from `MatTransColoringApplySpToDen()`, recover sparse matrix 10290 Csp from Cden. 10291 10292 Collective on matcoloring 10293 10294 Input Parameters: 10295 + coloring - coloring context created with `MatTransposeColoringCreate()` 10296 - Cden - matrix product of a sparse matrix and a dense matrix Btdense 10297 10298 Output Parameter: 10299 . Csp - sparse matrix 10300 10301 Level: developer 10302 10303 Note: 10304 These are used internally for some implementations of `MatRARt()` 10305 10306 .seealso: `MatTransposeColoringCreate()`, `MatTransposeColoringDestroy()`, `MatTransColoringApplySpToDen()` 10307 10308 @*/ 10309 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring, Mat Cden, Mat Csp) { 10310 PetscFunctionBegin; 10311 PetscValidHeaderSpecific(matcoloring, MAT_TRANSPOSECOLORING_CLASSID, 1); 10312 PetscValidHeaderSpecific(Cden, MAT_CLASSID, 2); 10313 PetscValidHeaderSpecific(Csp, MAT_CLASSID, 3); 10314 10315 PetscCall((Csp->ops->transcoloringapplydentosp)(matcoloring, Cden, Csp)); 10316 PetscCall(MatAssemblyBegin(Csp, MAT_FINAL_ASSEMBLY)); 10317 PetscCall(MatAssemblyEnd(Csp, MAT_FINAL_ASSEMBLY)); 10318 PetscFunctionReturn(0); 10319 } 10320 10321 /*@C 10322 MatTransposeColoringCreate - Creates a matrix coloring context for the matrix product C=A*B^T. 10323 10324 Collective on mat 10325 10326 Input Parameters: 10327 + mat - the matrix product C 10328 - iscoloring - the coloring of the matrix; usually obtained with `MatColoringCreate()` or `DMCreateColoring()` 10329 10330 Output Parameter: 10331 . color - the new coloring context 10332 10333 Level: intermediate 10334 10335 .seealso: `MatTransposeColoringDestroy()`, `MatTransColoringApplySpToDen()`, 10336 `MatTransColoringApplyDenToSp()` 10337 @*/ 10338 PetscErrorCode MatTransposeColoringCreate(Mat mat, ISColoring iscoloring, MatTransposeColoring *color) { 10339 MatTransposeColoring c; 10340 MPI_Comm comm; 10341 10342 PetscFunctionBegin; 10343 PetscCall(PetscLogEventBegin(MAT_TransposeColoringCreate, mat, 0, 0, 0)); 10344 PetscCall(PetscObjectGetComm((PetscObject)mat, &comm)); 10345 PetscCall(PetscHeaderCreate(c, MAT_TRANSPOSECOLORING_CLASSID, "MatTransposeColoring", "Matrix product C=A*B^T via coloring", "Mat", comm, MatTransposeColoringDestroy, NULL)); 10346 10347 c->ctype = iscoloring->ctype; 10348 if (mat->ops->transposecoloringcreate) { 10349 PetscUseTypeMethod(mat, transposecoloringcreate, iscoloring, c); 10350 } else SETERRQ(PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Code not yet written for matrix type %s", ((PetscObject)mat)->type_name); 10351 10352 *color = c; 10353 PetscCall(PetscLogEventEnd(MAT_TransposeColoringCreate, mat, 0, 0, 0)); 10354 PetscFunctionReturn(0); 10355 } 10356 10357 /*@ 10358 MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the 10359 matrix has had no new nonzero locations added to (or removed from) the matrix since the previous call then the value will be the 10360 same, otherwise it will be larger 10361 10362 Not Collective 10363 10364 Input Parameter: 10365 . A - the matrix 10366 10367 Output Parameter: 10368 . state - the current state 10369 10370 Notes: 10371 You can only compare states from two different calls to the SAME matrix, you cannot compare calls between 10372 different matrices 10373 10374 Use `PetscObjectStateGet()` to check for changes to the numerical values in a matrix 10375 10376 Use the result of `PetscObjectGetId()` to compare if a previously checked matrix is the same as the current matrix, do not compare object pointers. 10377 10378 Level: intermediate 10379 10380 .seealso: `PetscObjectStateGet()`, `PetscObjectGetId()` 10381 @*/ 10382 PetscErrorCode MatGetNonzeroState(Mat mat, PetscObjectState *state) { 10383 PetscFunctionBegin; 10384 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 10385 *state = mat->nonzerostate; 10386 PetscFunctionReturn(0); 10387 } 10388 10389 /*@ 10390 MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential 10391 matrices from each processor 10392 10393 Collective 10394 10395 Input Parameters: 10396 + comm - the communicators the parallel matrix will live on 10397 . seqmat - the input sequential matrices 10398 . n - number of local columns (or `PETSC_DECIDE`) 10399 - reuse - either `MAT_INITIAL_MATRIX` or `MAT_REUSE_MATRIX` 10400 10401 Output Parameter: 10402 . mpimat - the parallel matrix generated 10403 10404 Level: developer 10405 10406 Note: 10407 The number of columns of the matrix in EACH processor MUST be the same. 10408 10409 .seealso: `Mat` 10410 @*/ 10411 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm, Mat seqmat, PetscInt n, MatReuse reuse, Mat *mpimat) { 10412 PetscMPIInt size; 10413 10414 PetscFunctionBegin; 10415 PetscCallMPI(MPI_Comm_size(comm, &size)); 10416 if (size == 1) { 10417 if (reuse == MAT_INITIAL_MATRIX) { 10418 PetscCall(MatDuplicate(seqmat, MAT_COPY_VALUES, mpimat)); 10419 } else { 10420 PetscCall(MatCopy(seqmat, *mpimat, SAME_NONZERO_PATTERN)); 10421 } 10422 PetscFunctionReturn(0); 10423 } 10424 10425 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"); 10426 10427 PetscCall(PetscLogEventBegin(MAT_Merge, seqmat, 0, 0, 0)); 10428 PetscCall((*seqmat->ops->creatempimatconcatenateseqmat)(comm, seqmat, n, reuse, mpimat)); 10429 PetscCall(PetscLogEventEnd(MAT_Merge, seqmat, 0, 0, 0)); 10430 PetscFunctionReturn(0); 10431 } 10432 10433 /*@ 10434 MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent ranks' ownership ranges. 10435 10436 Collective on A 10437 10438 Input Parameters: 10439 + A - the matrix to create subdomains from 10440 - N - requested number of subdomains 10441 10442 Output Parameters: 10443 + n - number of subdomains resulting on this rank 10444 - iss - `IS` list with indices of subdomains on this rank 10445 10446 Level: advanced 10447 10448 Note: 10449 The number of subdomains must be smaller than the communicator size 10450 10451 .seealso: `Mat`, `IS` 10452 @*/ 10453 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A, PetscInt N, PetscInt *n, IS *iss[]) { 10454 MPI_Comm comm, subcomm; 10455 PetscMPIInt size, rank, color; 10456 PetscInt rstart, rend, k; 10457 10458 PetscFunctionBegin; 10459 PetscCall(PetscObjectGetComm((PetscObject)A, &comm)); 10460 PetscCallMPI(MPI_Comm_size(comm, &size)); 10461 PetscCallMPI(MPI_Comm_rank(comm, &rank)); 10462 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); 10463 *n = 1; 10464 k = ((PetscInt)size) / N + ((PetscInt)size % N > 0); /* There are up to k ranks to a color */ 10465 color = rank / k; 10466 PetscCallMPI(MPI_Comm_split(comm, color, rank, &subcomm)); 10467 PetscCall(PetscMalloc1(1, iss)); 10468 PetscCall(MatGetOwnershipRange(A, &rstart, &rend)); 10469 PetscCall(ISCreateStride(subcomm, rend - rstart, rstart, 1, iss[0])); 10470 PetscCallMPI(MPI_Comm_free(&subcomm)); 10471 PetscFunctionReturn(0); 10472 } 10473 10474 /*@ 10475 MatGalerkin - Constructs the coarse grid problem matrix via Galerkin projection. 10476 10477 If the interpolation and restriction operators are the same, uses `MatPtAP()`. 10478 If they are not the same, uses `MatMatMatMult()`. 10479 10480 Once the coarse grid problem is constructed, correct for interpolation operators 10481 that are not of full rank, which can legitimately happen in the case of non-nested 10482 geometric multigrid. 10483 10484 Input Parameters: 10485 + restrct - restriction operator 10486 . dA - fine grid matrix 10487 . interpolate - interpolation operator 10488 . reuse - either `MAT_INITIAL_MATRIX` or `MAT_REUSE_MATRIX` 10489 - fill - expected fill, use `PETSC_DEFAULT` if you do not have a good estimate 10490 10491 Output Parameters: 10492 . A - the Galerkin coarse matrix 10493 10494 Options Database Key: 10495 . -pc_mg_galerkin <both,pmat,mat,none> - for what matrices the Galerkin process should be used 10496 10497 Level: developer 10498 10499 .seealso: `MatPtAP()`, `MatMatMatMult()` 10500 @*/ 10501 PetscErrorCode MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A) { 10502 IS zerorows; 10503 Vec diag; 10504 10505 PetscFunctionBegin; 10506 PetscCheck(reuse != MAT_INPLACE_MATRIX, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Inplace product not supported"); 10507 /* Construct the coarse grid matrix */ 10508 if (interpolate == restrct) { 10509 PetscCall(MatPtAP(dA, interpolate, reuse, fill, A)); 10510 } else { 10511 PetscCall(MatMatMatMult(restrct, dA, interpolate, reuse, fill, A)); 10512 } 10513 10514 /* If the interpolation matrix is not of full rank, A will have zero rows. 10515 This can legitimately happen in the case of non-nested geometric multigrid. 10516 In that event, we set the rows of the matrix to the rows of the identity, 10517 ignoring the equations (as the RHS will also be zero). */ 10518 10519 PetscCall(MatFindZeroRows(*A, &zerorows)); 10520 10521 if (zerorows != NULL) { /* if there are any zero rows */ 10522 PetscCall(MatCreateVecs(*A, &diag, NULL)); 10523 PetscCall(MatGetDiagonal(*A, diag)); 10524 PetscCall(VecISSet(diag, zerorows, 1.0)); 10525 PetscCall(MatDiagonalSet(*A, diag, INSERT_VALUES)); 10526 PetscCall(VecDestroy(&diag)); 10527 PetscCall(ISDestroy(&zerorows)); 10528 } 10529 PetscFunctionReturn(0); 10530 } 10531 10532 /*@C 10533 MatSetOperation - Allows user to set a matrix operation for any matrix type 10534 10535 Logically Collective on mat 10536 10537 Input Parameters: 10538 + mat - the matrix 10539 . op - the name of the operation 10540 - f - the function that provides the operation 10541 10542 Level: developer 10543 10544 Usage: 10545 $ extern PetscErrorCode usermult(Mat,Vec,Vec); 10546 $ PetscCall(MatCreateXXX(comm,...&A); 10547 $ PetscCall(MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult); 10548 10549 Notes: 10550 See the file include/petscmat.h for a complete list of matrix 10551 operations, which all have the form MATOP_<OPERATION>, where 10552 <OPERATION> is the name (in all capital letters) of the 10553 user interface routine (e.g., MatMult() -> MATOP_MULT). 10554 10555 All user-provided functions (except for `MATOP_DESTROY`) should have the same calling 10556 sequence as the usual matrix interface routines, since they 10557 are intended to be accessed via the usual matrix interface 10558 routines, e.g., 10559 $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 10560 10561 In particular each function MUST return an error code of 0 on success and 10562 nonzero on failure. 10563 10564 This routine is distinct from `MatShellSetOperation()` in that it can be called on any matrix type. 10565 10566 .seealso: `MatGetOperation()`, `MatCreateShell()`, `MatShellSetContext()`, `MatShellSetOperation()` 10567 @*/ 10568 PetscErrorCode MatSetOperation(Mat mat, MatOperation op, void (*f)(void)) { 10569 PetscFunctionBegin; 10570 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 10571 if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) mat->ops->viewnative = mat->ops->view; 10572 (((void (**)(void))mat->ops)[op]) = f; 10573 PetscFunctionReturn(0); 10574 } 10575 10576 /*@C 10577 MatGetOperation - Gets a matrix operation for any matrix type. 10578 10579 Not Collective 10580 10581 Input Parameters: 10582 + mat - the matrix 10583 - op - the name of the operation 10584 10585 Output Parameter: 10586 . f - the function that provides the operation 10587 10588 Level: developer 10589 10590 Usage: 10591 $ PetscErrorCode (*usermult)(Mat,Vec,Vec); 10592 $ MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult); 10593 10594 Notes: 10595 See the file include/petscmat.h for a complete list of matrix 10596 operations, which all have the form MATOP_<OPERATION>, where 10597 <OPERATION> is the name (in all capital letters) of the 10598 user interface routine (e.g., `MatMult()` -> `MATOP_MULT`). 10599 10600 This routine is distinct from `MatShellGetOperation()` in that it can be called on any matrix type. 10601 10602 .seealso: `MatSetOperation()`, `MatCreateShell()`, `MatShellGetContext()`, `MatShellGetOperation()` 10603 @*/ 10604 PetscErrorCode MatGetOperation(Mat mat, MatOperation op, void (**f)(void)) { 10605 PetscFunctionBegin; 10606 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 10607 *f = (((void (**)(void))mat->ops)[op]); 10608 PetscFunctionReturn(0); 10609 } 10610 10611 /*@ 10612 MatHasOperation - Determines whether the given matrix supports the particular operation. 10613 10614 Not Collective 10615 10616 Input Parameters: 10617 + mat - the matrix 10618 - op - the operation, for example, `MATOP_GET_DIAGONAL` 10619 10620 Output Parameter: 10621 . has - either `PETSC_TRUE` or `PETSC_FALSE` 10622 10623 Level: advanced 10624 10625 Note: 10626 See the file include/petscmat.h for a complete list of matrix 10627 operations, which all have the form MATOP_<OPERATION>, where 10628 <OPERATION> is the name (in all capital letters) of the 10629 user-level routine. E.g., `MatNorm()` -> `MATOP_NORM`. 10630 10631 .seealso: `MatCreateShell()`, `MatGetOperation()`, `MatSetOperation()` 10632 @*/ 10633 PetscErrorCode MatHasOperation(Mat mat, MatOperation op, PetscBool *has) { 10634 PetscFunctionBegin; 10635 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 10636 PetscValidBoolPointer(has, 3); 10637 if (mat->ops->hasoperation) { 10638 PetscUseTypeMethod(mat, hasoperation, op, has); 10639 } else { 10640 if (((void **)mat->ops)[op]) *has = PETSC_TRUE; 10641 else { 10642 *has = PETSC_FALSE; 10643 if (op == MATOP_CREATE_SUBMATRIX) { 10644 PetscMPIInt size; 10645 10646 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size)); 10647 if (size == 1) PetscCall(MatHasOperation(mat, MATOP_CREATE_SUBMATRICES, has)); 10648 } 10649 } 10650 } 10651 PetscFunctionReturn(0); 10652 } 10653 10654 /*@ 10655 MatHasCongruentLayouts - Determines whether the rows and columns layouts of the matrix are congruent 10656 10657 Collective on mat 10658 10659 Input Parameters: 10660 . mat - the matrix 10661 10662 Output Parameter: 10663 . cong - either `PETSC_TRUE` or `PETSC_FALSE` 10664 10665 Level: beginner 10666 10667 .seealso: `MatCreate()`, `MatSetSizes()`, `PetscLayout` 10668 @*/ 10669 PetscErrorCode MatHasCongruentLayouts(Mat mat, PetscBool *cong) { 10670 PetscFunctionBegin; 10671 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 10672 PetscValidType(mat, 1); 10673 PetscValidBoolPointer(cong, 2); 10674 if (!mat->rmap || !mat->cmap) { 10675 *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE; 10676 PetscFunctionReturn(0); 10677 } 10678 if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */ 10679 PetscCall(PetscLayoutSetUp(mat->rmap)); 10680 PetscCall(PetscLayoutSetUp(mat->cmap)); 10681 PetscCall(PetscLayoutCompare(mat->rmap, mat->cmap, cong)); 10682 if (*cong) mat->congruentlayouts = 1; 10683 else mat->congruentlayouts = 0; 10684 } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE; 10685 PetscFunctionReturn(0); 10686 } 10687 10688 PetscErrorCode MatSetInf(Mat A) { 10689 PetscFunctionBegin; 10690 PetscUseTypeMethod(A, setinf); 10691 PetscFunctionReturn(0); 10692 } 10693 10694 /*C 10695 MatCreateGraph - create a scalar matrix (that is a matrix with one vertex for each block vertex in the original matrix), for use in graph algorithms 10696 10697 Collective on mat 10698 10699 Input Parameters: 10700 + A - the matrix 10701 - sym - `PETSC_TRUE` indicates that the graph will be symmetrized 10702 . scale - `PETSC_TRUE` indicates that the graph will be scaled with the diagonal 10703 10704 Output Parameter: 10705 . graph - the resulting graph 10706 10707 Level: advanced 10708 10709 .seealso: `MatCreate()`, `MatFilter()` 10710 */ 10711 PETSC_EXTERN PetscErrorCode MatCreateGraph(Mat A, PetscBool sym, PetscBool scale, Mat *graph) { 10712 PetscFunctionBegin; 10713 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 10714 PetscValidType(A, 1); 10715 PetscValidPointer(graph, 3); 10716 PetscUseTypeMethod(A, creategraph, sym, scale, graph); 10717 PetscFunctionReturn(0); 10718 } 10719 10720 /*C 10721 MatFilter - filters a matrices values with an absolut value equal to or below a give threshold 10722 10723 Collective on mat 10724 10725 Input Parameter: 10726 . value - filter value - < 0: does nothing; == 0: removes only 0.0 entries; otherwise: removes entries <= value 10727 10728 Input/Output Parameter: 10729 . A - the `Mat` to filter in place 10730 10731 Level: developer 10732 10733 Note: 10734 This is called before graph coarsers are called in `PCGAMG` 10735 10736 .seealso: `MatCreate()`, `MatCreateGraph()` 10737 */ 10738 PETSC_EXTERN PetscErrorCode MatFilter(Mat G, PetscReal value, Mat *F) { 10739 PetscFunctionBegin; 10740 PetscValidHeaderSpecific(G, MAT_CLASSID, 1); 10741 PetscValidType(G, 1); 10742 PetscValidPointer(F, 3); 10743 if (value >= 0.0) PetscCall((G->ops->filter)(G, value, F)); 10744 PetscFunctionReturn(0); 10745 } 10746