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(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(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(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(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(PetscLogObjectParent((PetscObject)mat, (PetscObject)tmp)); 3842 PetscCall(VecCopy(x, tmp)); 3843 PetscCall(MatSolve(mat, b, x)); 3844 PetscCall(VecAXPY(x, one, tmp)); 3845 PetscCall(VecDestroy(&tmp)); 3846 } 3847 } 3848 PetscCall(PetscLogEventEnd(MAT_SolveAdd, mat, b, x, y)); 3849 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3850 PetscFunctionReturn(0); 3851 } 3852 3853 /*@ 3854 MatSolveTranspose - Solves A' x = b, given a factored matrix. 3855 3856 Neighbor-wise Collective on mat 3857 3858 Input Parameters: 3859 + mat - the factored matrix 3860 - b - the right-hand-side vector 3861 3862 Output Parameter: 3863 . x - the result vector 3864 3865 Notes: 3866 The vectors b and x cannot be the same. I.e., one cannot 3867 call `MatSolveTranspose`(A,x,x). 3868 3869 Most users should employ the `KSP` interface for linear solvers 3870 instead of working directly with matrix algebra routines such as this. 3871 See, e.g., `KSPCreate()`. 3872 3873 Level: developer 3874 3875 .seealso: `MatGetFactor()`, `KSP`, `MatSolve()`, `MatSolveAdd()`, `MatSolveTransposeAdd()` 3876 @*/ 3877 PetscErrorCode MatSolveTranspose(Mat mat, Vec b, Vec x) { 3878 PetscErrorCode (*f)(Mat, Vec, Vec) = (!mat->ops->solvetranspose && mat->symmetric) ? mat->ops->solve : mat->ops->solvetranspose; 3879 3880 PetscFunctionBegin; 3881 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 3882 PetscValidType(mat, 1); 3883 PetscValidHeaderSpecific(b, VEC_CLASSID, 2); 3884 PetscValidHeaderSpecific(x, VEC_CLASSID, 3); 3885 PetscCheckSameComm(mat, 1, b, 2); 3886 PetscCheckSameComm(mat, 1, x, 3); 3887 PetscCheck(x != b, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_IDN, "x and b must be different vectors"); 3888 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); 3889 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); 3890 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3891 MatCheckPreallocated(mat, 1); 3892 PetscCall(PetscLogEventBegin(MAT_SolveTranspose, mat, b, x, 0)); 3893 if (mat->factorerrortype) { 3894 PetscCall(PetscInfo(mat, "MatFactorError %d\n", mat->factorerrortype)); 3895 PetscCall(VecSetInf(x)); 3896 } else { 3897 PetscCheck(f, PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Matrix type %s", ((PetscObject)mat)->type_name); 3898 PetscCall((*f)(mat, b, x)); 3899 } 3900 PetscCall(PetscLogEventEnd(MAT_SolveTranspose, mat, b, x, 0)); 3901 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3902 PetscFunctionReturn(0); 3903 } 3904 3905 /*@ 3906 MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a 3907 factored matrix. 3908 3909 Neighbor-wise Collective on mat 3910 3911 Input Parameters: 3912 + mat - the factored matrix 3913 . b - the right-hand-side vector 3914 - y - the vector to be added to 3915 3916 Output Parameter: 3917 . x - the result vector 3918 3919 Note: 3920 The vectors b and x cannot be the same. I.e., one cannot 3921 call `MatSolveTransposeAdd`(A,x,y,x). 3922 3923 Level: developer 3924 3925 .seealso: `MatGetFactor()`, `MatSolve()`, `MatSolveAdd()`, `MatSolveTranspose()` 3926 @*/ 3927 PetscErrorCode MatSolveTransposeAdd(Mat mat, Vec b, Vec y, Vec x) { 3928 PetscScalar one = 1.0; 3929 Vec tmp; 3930 PetscErrorCode (*f)(Mat, Vec, Vec, Vec) = (!mat->ops->solvetransposeadd && mat->symmetric) ? mat->ops->solveadd : mat->ops->solvetransposeadd; 3931 3932 PetscFunctionBegin; 3933 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 3934 PetscValidType(mat, 1); 3935 PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 3936 PetscValidHeaderSpecific(b, VEC_CLASSID, 2); 3937 PetscValidHeaderSpecific(x, VEC_CLASSID, 4); 3938 PetscCheckSameComm(mat, 1, b, 2); 3939 PetscCheckSameComm(mat, 1, y, 3); 3940 PetscCheckSameComm(mat, 1, x, 4); 3941 PetscCheck(x != b, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_IDN, "x and b must be different vectors"); 3942 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); 3943 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); 3944 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); 3945 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); 3946 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3947 MatCheckPreallocated(mat, 1); 3948 3949 PetscCall(PetscLogEventBegin(MAT_SolveTransposeAdd, mat, b, x, y)); 3950 if (mat->factorerrortype) { 3951 PetscCall(PetscInfo(mat, "MatFactorError %d\n", mat->factorerrortype)); 3952 PetscCall(VecSetInf(x)); 3953 } else if (f) { 3954 PetscCall((*f)(mat, b, y, x)); 3955 } else { 3956 /* do the solve then the add manually */ 3957 if (x != y) { 3958 PetscCall(MatSolveTranspose(mat, b, x)); 3959 PetscCall(VecAXPY(x, one, y)); 3960 } else { 3961 PetscCall(VecDuplicate(x, &tmp)); 3962 PetscCall(PetscLogObjectParent((PetscObject)mat, (PetscObject)tmp)); 3963 PetscCall(VecCopy(x, tmp)); 3964 PetscCall(MatSolveTranspose(mat, b, x)); 3965 PetscCall(VecAXPY(x, one, tmp)); 3966 PetscCall(VecDestroy(&tmp)); 3967 } 3968 } 3969 PetscCall(PetscLogEventEnd(MAT_SolveTransposeAdd, mat, b, x, y)); 3970 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3971 PetscFunctionReturn(0); 3972 } 3973 /* ----------------------------------------------------------------*/ 3974 3975 /*@ 3976 MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps. 3977 3978 Neighbor-wise Collective on mat 3979 3980 Input Parameters: 3981 + mat - the matrix 3982 . b - the right hand side 3983 . omega - the relaxation factor 3984 . flag - flag indicating the type of SOR (see below) 3985 . shift - diagonal shift 3986 . its - the number of iterations 3987 - lits - the number of local iterations 3988 3989 Output Parameter: 3990 . x - the solution (can contain an initial guess, use option `SOR_ZERO_INITIAL_GUESS` to indicate no guess) 3991 3992 SOR Flags: 3993 + `SOR_FORWARD_SWEEP` - forward SOR 3994 . `SOR_BACKWARD_SWEEP` - backward SOR 3995 . `SOR_SYMMETRIC_SWEEP` - SSOR (symmetric SOR) 3996 . `SOR_LOCAL_FORWARD_SWEEP` - local forward SOR 3997 . `SOR_LOCAL_BACKWARD_SWEEP` - local forward SOR 3998 . `SOR_LOCAL_SYMMETRIC_SWEEP` - local SSOR 3999 . `SOR_EISENSTAT` - SOR with Eisenstat trick 4000 . `SOR_APPLY_UPPER`, `SOR_APPLY_LOWER` - applies 4001 upper/lower triangular part of matrix to 4002 vector (with omega) 4003 - `SOR_ZERO_INITIAL_GUESS` - zero initial guess 4004 4005 Notes: 4006 `SOR_LOCAL_FORWARD_SWEEP`, `SOR_LOCAL_BACKWARD_SWEEP`, and 4007 `SOR_LOCAL_SYMMETRIC_SWEEP` perform separate independent smoothings 4008 on each processor. 4009 4010 Application programmers will not generally use `MatSOR()` directly, 4011 but instead will employ the `KSP`/`PC` interface. 4012 4013 For `MATBAIJ`, `MATSBAIJ`, and `MATAIJ` matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing 4014 4015 Most users should employ the `KSP` interface for linear solvers 4016 instead of working directly with matrix algebra routines such as this. 4017 See, e.g., `KSPCreate()`. 4018 4019 Vectors x and b CANNOT be the same 4020 4021 Notes for Advanced Users: 4022 The flags are implemented as bitwise inclusive or operations. 4023 For example, use (`SOR_ZERO_INITIAL_GUESS` | `SOR_SYMMETRIC_SWEEP`) 4024 to specify a zero initial guess for SSOR. 4025 4026 Developer Note: 4027 We should add block SOR support for `MATAIJ` matrices with block size set to great than one and no inodes 4028 4029 Level: developer 4030 4031 .seealso: `Mat`, `MatMult()`, `KSP`, `PC`, `MatGetFactor()` 4032 @*/ 4033 PetscErrorCode MatSOR(Mat mat, Vec b, PetscReal omega, MatSORType flag, PetscReal shift, PetscInt its, PetscInt lits, Vec x) { 4034 PetscFunctionBegin; 4035 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4036 PetscValidType(mat, 1); 4037 PetscValidHeaderSpecific(b, VEC_CLASSID, 2); 4038 PetscValidHeaderSpecific(x, VEC_CLASSID, 8); 4039 PetscCheckSameComm(mat, 1, b, 2); 4040 PetscCheckSameComm(mat, 1, x, 8); 4041 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 4042 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 4043 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); 4044 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); 4045 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); 4046 PetscCheck(its > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Relaxation requires global its %" PetscInt_FMT " positive", its); 4047 PetscCheck(lits > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Relaxation requires local its %" PetscInt_FMT " positive", lits); 4048 PetscCheck(b != x, PETSC_COMM_SELF, PETSC_ERR_ARG_IDN, "b and x vector cannot be the same"); 4049 4050 MatCheckPreallocated(mat, 1); 4051 PetscCall(PetscLogEventBegin(MAT_SOR, mat, b, x, 0)); 4052 PetscUseTypeMethod(mat, sor, b, omega, flag, shift, its, lits, x); 4053 PetscCall(PetscLogEventEnd(MAT_SOR, mat, b, x, 0)); 4054 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 4055 PetscFunctionReturn(0); 4056 } 4057 4058 /* 4059 Default matrix copy routine. 4060 */ 4061 PetscErrorCode MatCopy_Basic(Mat A, Mat B, MatStructure str) { 4062 PetscInt i, rstart = 0, rend = 0, nz; 4063 const PetscInt *cwork; 4064 const PetscScalar *vwork; 4065 4066 PetscFunctionBegin; 4067 if (B->assembled) PetscCall(MatZeroEntries(B)); 4068 if (str == SAME_NONZERO_PATTERN) { 4069 PetscCall(MatGetOwnershipRange(A, &rstart, &rend)); 4070 for (i = rstart; i < rend; i++) { 4071 PetscCall(MatGetRow(A, i, &nz, &cwork, &vwork)); 4072 PetscCall(MatSetValues(B, 1, &i, nz, cwork, vwork, INSERT_VALUES)); 4073 PetscCall(MatRestoreRow(A, i, &nz, &cwork, &vwork)); 4074 } 4075 } else { 4076 PetscCall(MatAYPX(B, 0.0, A, str)); 4077 } 4078 PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 4079 PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 4080 PetscFunctionReturn(0); 4081 } 4082 4083 /*@ 4084 MatCopy - Copies a matrix to another matrix. 4085 4086 Collective on A 4087 4088 Input Parameters: 4089 + A - the matrix 4090 - str - `SAME_NONZERO_PATTERN` or `DIFFERENT_NONZERO_PATTERN` 4091 4092 Output Parameter: 4093 . B - where the copy is put 4094 4095 Notes: 4096 If you use `SAME_NONZERO_PATTERN `then the two matrices must have the same nonzero pattern or the routine will crash. 4097 4098 `MatCopy()` copies the matrix entries of a matrix to another existing 4099 matrix (after first zeroing the second matrix). A related routine is 4100 `MatConvert()`, which first creates a new matrix and then copies the data. 4101 4102 Level: intermediate 4103 4104 .seealso: `Mat`, `MatConvert()`, `MatDuplicate()` 4105 @*/ 4106 PetscErrorCode MatCopy(Mat A, Mat B, MatStructure str) { 4107 PetscInt i; 4108 4109 PetscFunctionBegin; 4110 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 4111 PetscValidHeaderSpecific(B, MAT_CLASSID, 2); 4112 PetscValidType(A, 1); 4113 PetscValidType(B, 2); 4114 PetscCheckSameComm(A, 1, B, 2); 4115 MatCheckPreallocated(B, 2); 4116 PetscCheck(A->assembled, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 4117 PetscCheck(!A->factortype, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 4118 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, 4119 A->cmap->N, B->cmap->N); 4120 MatCheckPreallocated(A, 1); 4121 if (A == B) PetscFunctionReturn(0); 4122 4123 PetscCall(PetscLogEventBegin(MAT_Copy, A, B, 0, 0)); 4124 if (A->ops->copy) PetscUseTypeMethod(A, copy, B, str); 4125 else PetscCall(MatCopy_Basic(A, B, str)); 4126 4127 B->stencil.dim = A->stencil.dim; 4128 B->stencil.noc = A->stencil.noc; 4129 for (i = 0; i <= A->stencil.dim; i++) { 4130 B->stencil.dims[i] = A->stencil.dims[i]; 4131 B->stencil.starts[i] = A->stencil.starts[i]; 4132 } 4133 4134 PetscCall(PetscLogEventEnd(MAT_Copy, A, B, 0, 0)); 4135 PetscCall(PetscObjectStateIncrease((PetscObject)B)); 4136 PetscFunctionReturn(0); 4137 } 4138 4139 /*@C 4140 MatConvert - Converts a matrix to another matrix, either of the same 4141 or different type. 4142 4143 Collective on mat 4144 4145 Input Parameters: 4146 + mat - the matrix 4147 . newtype - new matrix type. Use `MATSAME` to create a new matrix of the 4148 same type as the original matrix. 4149 - reuse - denotes if the destination matrix is to be created or reused. 4150 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 4151 `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). 4152 4153 Output Parameter: 4154 . M - pointer to place new matrix 4155 4156 Notes: 4157 `MatConvert()` first creates a new matrix and then copies the data from 4158 the first matrix. A related routine is `MatCopy()`, which copies the matrix 4159 entries of one matrix to another already existing matrix context. 4160 4161 Cannot be used to convert a sequential matrix to parallel or parallel to sequential, 4162 the MPI communicator of the generated matrix is always the same as the communicator 4163 of the input matrix. 4164 4165 Level: intermediate 4166 4167 .seealso: `Mat`, `MatCopy()`, `MatDuplicate()`, `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, `MAT_INPLACE_MATRIX` 4168 @*/ 4169 PetscErrorCode MatConvert(Mat mat, MatType newtype, MatReuse reuse, Mat *M) { 4170 PetscBool sametype, issame, flg; 4171 PetscBool3 issymmetric, ishermitian; 4172 char convname[256], mtype[256]; 4173 Mat B; 4174 4175 PetscFunctionBegin; 4176 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4177 PetscValidType(mat, 1); 4178 PetscValidPointer(M, 4); 4179 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 4180 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 4181 MatCheckPreallocated(mat, 1); 4182 4183 PetscCall(PetscOptionsGetString(((PetscObject)mat)->options, ((PetscObject)mat)->prefix, "-matconvert_type", mtype, sizeof(mtype), &flg)); 4184 if (flg) newtype = mtype; 4185 4186 PetscCall(PetscObjectTypeCompare((PetscObject)mat, newtype, &sametype)); 4187 PetscCall(PetscStrcmp(newtype, "same", &issame)); 4188 PetscCheck(!(reuse == MAT_INPLACE_MATRIX) || !(mat != *M), PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "MAT_INPLACE_MATRIX requires same input and output matrix"); 4189 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"); 4190 4191 if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) { 4192 PetscCall(PetscInfo(mat, "Early return for inplace %s %d %d\n", ((PetscObject)mat)->type_name, sametype, issame)); 4193 PetscFunctionReturn(0); 4194 } 4195 4196 /* Cache Mat options because some converters use MatHeaderReplace */ 4197 issymmetric = mat->symmetric; 4198 ishermitian = mat->hermitian; 4199 4200 if ((sametype || issame) && (reuse == MAT_INITIAL_MATRIX) && mat->ops->duplicate) { 4201 PetscCall(PetscInfo(mat, "Calling duplicate for initial matrix %s %d %d\n", ((PetscObject)mat)->type_name, sametype, issame)); 4202 PetscUseTypeMethod(mat, duplicate, MAT_COPY_VALUES, M); 4203 } else { 4204 PetscErrorCode (*conv)(Mat, MatType, MatReuse, Mat *) = NULL; 4205 const char *prefix[3] = {"seq", "mpi", ""}; 4206 PetscInt i; 4207 /* 4208 Order of precedence: 4209 0) See if newtype is a superclass of the current matrix. 4210 1) See if a specialized converter is known to the current matrix. 4211 2) See if a specialized converter is known to the desired matrix class. 4212 3) See if a good general converter is registered for the desired class 4213 (as of 6/27/03 only MATMPIADJ falls into this category). 4214 4) See if a good general converter is known for the current matrix. 4215 5) Use a really basic converter. 4216 */ 4217 4218 /* 0) See if newtype is a superclass of the current matrix. 4219 i.e mat is mpiaij and newtype is aij */ 4220 for (i = 0; i < 2; i++) { 4221 PetscCall(PetscStrncpy(convname, prefix[i], sizeof(convname))); 4222 PetscCall(PetscStrlcat(convname, newtype, sizeof(convname))); 4223 PetscCall(PetscStrcmp(convname, ((PetscObject)mat)->type_name, &flg)); 4224 PetscCall(PetscInfo(mat, "Check superclass %s %s -> %d\n", convname, ((PetscObject)mat)->type_name, flg)); 4225 if (flg) { 4226 if (reuse == MAT_INPLACE_MATRIX) { 4227 PetscCall(PetscInfo(mat, "Early return\n")); 4228 PetscFunctionReturn(0); 4229 } else if (reuse == MAT_INITIAL_MATRIX && mat->ops->duplicate) { 4230 PetscCall(PetscInfo(mat, "Calling MatDuplicate\n")); 4231 PetscUseTypeMethod(mat, duplicate, MAT_COPY_VALUES, M); 4232 PetscFunctionReturn(0); 4233 } else if (reuse == MAT_REUSE_MATRIX && mat->ops->copy) { 4234 PetscCall(PetscInfo(mat, "Calling MatCopy\n")); 4235 PetscCall(MatCopy(mat, *M, SAME_NONZERO_PATTERN)); 4236 PetscFunctionReturn(0); 4237 } 4238 } 4239 } 4240 /* 1) See if a specialized converter is known to the current matrix and the desired class */ 4241 for (i = 0; i < 3; i++) { 4242 PetscCall(PetscStrncpy(convname, "MatConvert_", sizeof(convname))); 4243 PetscCall(PetscStrlcat(convname, ((PetscObject)mat)->type_name, sizeof(convname))); 4244 PetscCall(PetscStrlcat(convname, "_", sizeof(convname))); 4245 PetscCall(PetscStrlcat(convname, prefix[i], sizeof(convname))); 4246 PetscCall(PetscStrlcat(convname, issame ? ((PetscObject)mat)->type_name : newtype, sizeof(convname))); 4247 PetscCall(PetscStrlcat(convname, "_C", sizeof(convname))); 4248 PetscCall(PetscObjectQueryFunction((PetscObject)mat, convname, &conv)); 4249 PetscCall(PetscInfo(mat, "Check specialized (1) %s (%s) -> %d\n", convname, ((PetscObject)mat)->type_name, !!conv)); 4250 if (conv) goto foundconv; 4251 } 4252 4253 /* 2) See if a specialized converter is known to the desired matrix class. */ 4254 PetscCall(MatCreate(PetscObjectComm((PetscObject)mat), &B)); 4255 PetscCall(MatSetSizes(B, mat->rmap->n, mat->cmap->n, mat->rmap->N, mat->cmap->N)); 4256 PetscCall(MatSetType(B, newtype)); 4257 for (i = 0; i < 3; i++) { 4258 PetscCall(PetscStrncpy(convname, "MatConvert_", sizeof(convname))); 4259 PetscCall(PetscStrlcat(convname, ((PetscObject)mat)->type_name, sizeof(convname))); 4260 PetscCall(PetscStrlcat(convname, "_", sizeof(convname))); 4261 PetscCall(PetscStrlcat(convname, prefix[i], sizeof(convname))); 4262 PetscCall(PetscStrlcat(convname, newtype, sizeof(convname))); 4263 PetscCall(PetscStrlcat(convname, "_C", sizeof(convname))); 4264 PetscCall(PetscObjectQueryFunction((PetscObject)B, convname, &conv)); 4265 PetscCall(PetscInfo(mat, "Check specialized (2) %s (%s) -> %d\n", convname, ((PetscObject)B)->type_name, !!conv)); 4266 if (conv) { 4267 PetscCall(MatDestroy(&B)); 4268 goto foundconv; 4269 } 4270 } 4271 4272 /* 3) See if a good general converter is registered for the desired class */ 4273 conv = B->ops->convertfrom; 4274 PetscCall(PetscInfo(mat, "Check convertfrom (%s) -> %d\n", ((PetscObject)B)->type_name, !!conv)); 4275 PetscCall(MatDestroy(&B)); 4276 if (conv) goto foundconv; 4277 4278 /* 4) See if a good general converter is known for the current matrix */ 4279 if (mat->ops->convert) conv = mat->ops->convert; 4280 PetscCall(PetscInfo(mat, "Check general convert (%s) -> %d\n", ((PetscObject)mat)->type_name, !!conv)); 4281 if (conv) goto foundconv; 4282 4283 /* 5) Use a really basic converter. */ 4284 PetscCall(PetscInfo(mat, "Using MatConvert_Basic\n")); 4285 conv = MatConvert_Basic; 4286 4287 foundconv: 4288 PetscCall(PetscLogEventBegin(MAT_Convert, mat, 0, 0, 0)); 4289 PetscCall((*conv)(mat, newtype, reuse, M)); 4290 if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) { 4291 /* the block sizes must be same if the mappings are copied over */ 4292 (*M)->rmap->bs = mat->rmap->bs; 4293 (*M)->cmap->bs = mat->cmap->bs; 4294 PetscCall(PetscObjectReference((PetscObject)mat->rmap->mapping)); 4295 PetscCall(PetscObjectReference((PetscObject)mat->cmap->mapping)); 4296 (*M)->rmap->mapping = mat->rmap->mapping; 4297 (*M)->cmap->mapping = mat->cmap->mapping; 4298 } 4299 (*M)->stencil.dim = mat->stencil.dim; 4300 (*M)->stencil.noc = mat->stencil.noc; 4301 for (i = 0; i <= mat->stencil.dim; i++) { 4302 (*M)->stencil.dims[i] = mat->stencil.dims[i]; 4303 (*M)->stencil.starts[i] = mat->stencil.starts[i]; 4304 } 4305 PetscCall(PetscLogEventEnd(MAT_Convert, mat, 0, 0, 0)); 4306 } 4307 PetscCall(PetscObjectStateIncrease((PetscObject)*M)); 4308 4309 /* Copy Mat options */ 4310 if (issymmetric == PETSC_BOOL3_TRUE) PetscCall(MatSetOption(*M, MAT_SYMMETRIC, PETSC_TRUE)); 4311 else if (issymmetric == PETSC_BOOL3_FALSE) PetscCall(MatSetOption(*M, MAT_SYMMETRIC, PETSC_FALSE)); 4312 if (ishermitian == PETSC_BOOL3_TRUE) PetscCall(MatSetOption(*M, MAT_HERMITIAN, PETSC_TRUE)); 4313 else if (ishermitian == PETSC_BOOL3_FALSE) PetscCall(MatSetOption(*M, MAT_HERMITIAN, PETSC_FALSE)); 4314 PetscFunctionReturn(0); 4315 } 4316 4317 /*@C 4318 MatFactorGetSolverType - Returns name of the package providing the factorization routines 4319 4320 Not Collective 4321 4322 Input Parameter: 4323 . mat - the matrix, must be a factored matrix 4324 4325 Output Parameter: 4326 . type - the string name of the package (do not free this string) 4327 4328 Note: 4329 In Fortran you pass in a empty string and the package name will be copied into it. 4330 (Make sure the string is long enough) 4331 4332 Level: intermediate 4333 4334 .seealso: [Matrix Factorization](sec_matfactor), `MatGetFactor()`, `MatSolverType`, `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()` 4335 @*/ 4336 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type) { 4337 PetscErrorCode (*conv)(Mat, MatSolverType *); 4338 4339 PetscFunctionBegin; 4340 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4341 PetscValidType(mat, 1); 4342 PetscValidPointer(type, 2); 4343 PetscCheck(mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Only for factored matrix"); 4344 PetscCall(PetscObjectQueryFunction((PetscObject)mat, "MatFactorGetSolverType_C", &conv)); 4345 if (conv) PetscCall((*conv)(mat, type)); 4346 else *type = MATSOLVERPETSC; 4347 PetscFunctionReturn(0); 4348 } 4349 4350 typedef struct _MatSolverTypeForSpecifcType *MatSolverTypeForSpecifcType; 4351 struct _MatSolverTypeForSpecifcType { 4352 MatType mtype; 4353 /* no entry for MAT_FACTOR_NONE */ 4354 PetscErrorCode (*createfactor[MAT_FACTOR_NUM_TYPES - 1])(Mat, MatFactorType, Mat *); 4355 MatSolverTypeForSpecifcType next; 4356 }; 4357 4358 typedef struct _MatSolverTypeHolder *MatSolverTypeHolder; 4359 struct _MatSolverTypeHolder { 4360 char *name; 4361 MatSolverTypeForSpecifcType handlers; 4362 MatSolverTypeHolder next; 4363 }; 4364 4365 static MatSolverTypeHolder MatSolverTypeHolders = NULL; 4366 4367 /*@C 4368 MatSolverTypeRegister - Registers a `MatSolverType` that works for a particular matrix type 4369 4370 Input Parameters: 4371 + package - name of the package, for example petsc or superlu 4372 . mtype - the matrix type that works with this package 4373 . ftype - the type of factorization supported by the package 4374 - createfactor - routine that will create the factored matrix ready to be used 4375 4376 Level: developer 4377 4378 .seealso: [Matrix Factorization](sec_matfactor), `MatFactorGetSolverType()`, `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()` 4379 @*/ 4380 PetscErrorCode MatSolverTypeRegister(MatSolverType package, MatType mtype, MatFactorType ftype, PetscErrorCode (*createfactor)(Mat, MatFactorType, Mat *)) { 4381 MatSolverTypeHolder next = MatSolverTypeHolders, prev = NULL; 4382 PetscBool flg; 4383 MatSolverTypeForSpecifcType inext, iprev = NULL; 4384 4385 PetscFunctionBegin; 4386 PetscCall(MatInitializePackage()); 4387 if (!next) { 4388 PetscCall(PetscNew(&MatSolverTypeHolders)); 4389 PetscCall(PetscStrallocpy(package, &MatSolverTypeHolders->name)); 4390 PetscCall(PetscNew(&MatSolverTypeHolders->handlers)); 4391 PetscCall(PetscStrallocpy(mtype, (char **)&MatSolverTypeHolders->handlers->mtype)); 4392 MatSolverTypeHolders->handlers->createfactor[(int)ftype - 1] = createfactor; 4393 PetscFunctionReturn(0); 4394 } 4395 while (next) { 4396 PetscCall(PetscStrcasecmp(package, next->name, &flg)); 4397 if (flg) { 4398 PetscCheck(next->handlers, PETSC_COMM_SELF, PETSC_ERR_PLIB, "MatSolverTypeHolder is missing handlers"); 4399 inext = next->handlers; 4400 while (inext) { 4401 PetscCall(PetscStrcasecmp(mtype, inext->mtype, &flg)); 4402 if (flg) { 4403 inext->createfactor[(int)ftype - 1] = createfactor; 4404 PetscFunctionReturn(0); 4405 } 4406 iprev = inext; 4407 inext = inext->next; 4408 } 4409 PetscCall(PetscNew(&iprev->next)); 4410 PetscCall(PetscStrallocpy(mtype, (char **)&iprev->next->mtype)); 4411 iprev->next->createfactor[(int)ftype - 1] = createfactor; 4412 PetscFunctionReturn(0); 4413 } 4414 prev = next; 4415 next = next->next; 4416 } 4417 PetscCall(PetscNew(&prev->next)); 4418 PetscCall(PetscStrallocpy(package, &prev->next->name)); 4419 PetscCall(PetscNew(&prev->next->handlers)); 4420 PetscCall(PetscStrallocpy(mtype, (char **)&prev->next->handlers->mtype)); 4421 prev->next->handlers->createfactor[(int)ftype - 1] = createfactor; 4422 PetscFunctionReturn(0); 4423 } 4424 4425 /*@C 4426 MatSolverTypeGet - Gets the function that creates the factor matrix if it exist 4427 4428 Input Parameters: 4429 + type - name of the package, for example petsc or superlu 4430 . ftype - the type of factorization supported by the type 4431 - mtype - the matrix type that works with this type 4432 4433 Output Parameters: 4434 + foundtype - `PETSC_TRUE` if the type was registered 4435 . foundmtype - `PETSC_TRUE` if the type supports the requested mtype 4436 - createfactor - routine that will create the factored matrix ready to be used or NULL if not found 4437 4438 Level: developer 4439 4440 .seealso: `MatFactorType`, `MatType`, `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatSolverTypeRegister()`, `MatGetFactor()` 4441 @*/ 4442 PetscErrorCode MatSolverTypeGet(MatSolverType type, MatType mtype, MatFactorType ftype, PetscBool *foundtype, PetscBool *foundmtype, PetscErrorCode (**createfactor)(Mat, MatFactorType, Mat *)) { 4443 MatSolverTypeHolder next = MatSolverTypeHolders; 4444 PetscBool flg; 4445 MatSolverTypeForSpecifcType inext; 4446 4447 PetscFunctionBegin; 4448 if (foundtype) *foundtype = PETSC_FALSE; 4449 if (foundmtype) *foundmtype = PETSC_FALSE; 4450 if (createfactor) *createfactor = NULL; 4451 4452 if (type) { 4453 while (next) { 4454 PetscCall(PetscStrcasecmp(type, next->name, &flg)); 4455 if (flg) { 4456 if (foundtype) *foundtype = PETSC_TRUE; 4457 inext = next->handlers; 4458 while (inext) { 4459 PetscCall(PetscStrbeginswith(mtype, inext->mtype, &flg)); 4460 if (flg) { 4461 if (foundmtype) *foundmtype = PETSC_TRUE; 4462 if (createfactor) *createfactor = inext->createfactor[(int)ftype - 1]; 4463 PetscFunctionReturn(0); 4464 } 4465 inext = inext->next; 4466 } 4467 } 4468 next = next->next; 4469 } 4470 } else { 4471 while (next) { 4472 inext = next->handlers; 4473 while (inext) { 4474 PetscCall(PetscStrcmp(mtype, inext->mtype, &flg)); 4475 if (flg && inext->createfactor[(int)ftype - 1]) { 4476 if (foundtype) *foundtype = PETSC_TRUE; 4477 if (foundmtype) *foundmtype = PETSC_TRUE; 4478 if (createfactor) *createfactor = inext->createfactor[(int)ftype - 1]; 4479 PetscFunctionReturn(0); 4480 } 4481 inext = inext->next; 4482 } 4483 next = next->next; 4484 } 4485 /* try with base classes inext->mtype */ 4486 next = MatSolverTypeHolders; 4487 while (next) { 4488 inext = next->handlers; 4489 while (inext) { 4490 PetscCall(PetscStrbeginswith(mtype, inext->mtype, &flg)); 4491 if (flg && inext->createfactor[(int)ftype - 1]) { 4492 if (foundtype) *foundtype = PETSC_TRUE; 4493 if (foundmtype) *foundmtype = PETSC_TRUE; 4494 if (createfactor) *createfactor = inext->createfactor[(int)ftype - 1]; 4495 PetscFunctionReturn(0); 4496 } 4497 inext = inext->next; 4498 } 4499 next = next->next; 4500 } 4501 } 4502 PetscFunctionReturn(0); 4503 } 4504 4505 PetscErrorCode MatSolverTypeDestroy(void) { 4506 MatSolverTypeHolder next = MatSolverTypeHolders, prev; 4507 MatSolverTypeForSpecifcType inext, iprev; 4508 4509 PetscFunctionBegin; 4510 while (next) { 4511 PetscCall(PetscFree(next->name)); 4512 inext = next->handlers; 4513 while (inext) { 4514 PetscCall(PetscFree(inext->mtype)); 4515 iprev = inext; 4516 inext = inext->next; 4517 PetscCall(PetscFree(iprev)); 4518 } 4519 prev = next; 4520 next = next->next; 4521 PetscCall(PetscFree(prev)); 4522 } 4523 MatSolverTypeHolders = NULL; 4524 PetscFunctionReturn(0); 4525 } 4526 4527 /*@C 4528 MatFactorGetCanUseOrdering - Indicates if the factorization can use the ordering provided in `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()` 4529 4530 Logically Collective on mat 4531 4532 Input Parameters: 4533 . mat - the matrix 4534 4535 Output Parameters: 4536 . flg - `PETSC_TRUE` if uses the ordering 4537 4538 Note: 4539 Most internal PETSc factorizations use the ordering passed to the factorization routine but external 4540 packages do not, thus we want to skip generating the ordering when it is not needed or used. 4541 4542 Level: developer 4543 4544 .seealso: [Matrix Factorization](sec_matfactor), `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()` 4545 @*/ 4546 PetscErrorCode MatFactorGetCanUseOrdering(Mat mat, PetscBool *flg) { 4547 PetscFunctionBegin; 4548 *flg = mat->canuseordering; 4549 PetscFunctionReturn(0); 4550 } 4551 4552 /*@C 4553 MatFactorGetPreferredOrdering - The preferred ordering for a particular matrix factor object 4554 4555 Logically Collective on mat 4556 4557 Input Parameters: 4558 . mat - the matrix obtained with `MatGetFactor()` 4559 4560 Output Parameters: 4561 . otype - the preferred type 4562 4563 Level: developer 4564 4565 .seealso: [Matrix Factorization](sec_matfactor), `MatFactorType`, `MatOrderingType`, `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()` 4566 @*/ 4567 PetscErrorCode MatFactorGetPreferredOrdering(Mat mat, MatFactorType ftype, MatOrderingType *otype) { 4568 PetscFunctionBegin; 4569 *otype = mat->preferredordering[ftype]; 4570 PetscCheck(*otype, PETSC_COMM_SELF, PETSC_ERR_PLIB, "MatFactor did not have a preferred ordering"); 4571 PetscFunctionReturn(0); 4572 } 4573 4574 /*@C 4575 MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic() 4576 4577 Collective on mat 4578 4579 Input Parameters: 4580 + mat - the matrix 4581 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4582 - ftype - factor type, `MAT_FACTOR_LU`, `MAT_FACTOR_CHOLESKY`, `MAT_FACTOR_ICC`, `MAT_FACTOR_ILU`, `MAT_FACTOR_QR` 4583 4584 Output Parameters: 4585 . f - the factor matrix used with MatXXFactorSymbolic() calls 4586 4587 Options Database Key: 4588 . -mat_factor_bind_factorization <host, device> - Where to do matrix factorization? Default is device (might consume more device memory. 4589 One can choose host to save device memory). Currently only supported with `MATSEQAIJCUSPARSE` matrices. 4590 4591 Notes: 4592 Users usually access the factorization solvers via `KSP` 4593 4594 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4595 such as pastix, superlu, mumps etc. 4596 4597 PETSc must have been ./configure to use the external solver, using the option --download-package 4598 4599 Some of the packages have options for controlling the factorization, these are in the form -prefix_mat_packagename_packageoption 4600 where prefix is normally obtained from the calling `KSP`/`PC`. If `MatGetFactor()` is called directly one can set 4601 call `MatSetOptionsPrefixFactor()` on the originating matrix or `MatSetOptionsPrefix()` on the resulting factor matrix. 4602 4603 Developer Note: 4604 This should actually be called `MatCreateFactor()` since it creates a new factor object 4605 4606 Level: intermediate 4607 4608 .seealso: [Matrix Factorization](sec_matfactor), `KSP`, `MatSolverType`, `MatFactorType`, `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatFactorGetCanUseOrdering()`, `MatSolverTypeRegister()`, 4609 `MAT_FACTOR_LU`, `MAT_FACTOR_CHOLESKY`, `MAT_FACTOR_ICC`, `MAT_FACTOR_ILU`, `MAT_FACTOR_QR` 4610 @*/ 4611 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type, MatFactorType ftype, Mat *f) { 4612 PetscBool foundtype, foundmtype; 4613 PetscErrorCode (*conv)(Mat, MatFactorType, Mat *); 4614 4615 PetscFunctionBegin; 4616 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4617 PetscValidType(mat, 1); 4618 4619 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 4620 MatCheckPreallocated(mat, 1); 4621 4622 PetscCall(MatSolverTypeGet(type, ((PetscObject)mat)->type_name, ftype, &foundtype, &foundmtype, &conv)); 4623 if (!foundtype) { 4624 if (type) { 4625 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], 4626 ((PetscObject)mat)->type_name, type); 4627 } else { 4628 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); 4629 } 4630 } 4631 PetscCheck(foundmtype, PetscObjectComm((PetscObject)mat), PETSC_ERR_MISSING_FACTOR, "MatSolverType %s does not support matrix type %s", type, ((PetscObject)mat)->type_name); 4632 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); 4633 4634 PetscCall((*conv)(mat, ftype, f)); 4635 if (mat->factorprefix) PetscCall(MatSetOptionsPrefix(*f, mat->factorprefix)); 4636 PetscFunctionReturn(0); 4637 } 4638 4639 /*@C 4640 MatGetFactorAvailable - Returns a a flag if matrix supports particular type and factor type 4641 4642 Not Collective 4643 4644 Input Parameters: 4645 + mat - the matrix 4646 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4647 - ftype - factor type, `MAT_FACTOR_LU`, `MAT_FACTOR_CHOLESKY`, `MAT_FACTOR_ICC`, `MAT_FACTOR_ILU`, `MAT_FACTOR_QR` 4648 4649 Output Parameter: 4650 . flg - PETSC_TRUE if the factorization is available 4651 4652 Notes: 4653 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4654 such as pastix, superlu, mumps etc. 4655 4656 PETSc must have been ./configure to use the external solver, using the option --download-package 4657 4658 Developer Note: 4659 This should actually be called MatCreateFactorAvailable() since MatGetFactor() creates a new factor object 4660 4661 Level: intermediate 4662 4663 .seealso: [Matrix Factorization](sec_matfactor), `MatSolverType`, `MatFactorType`, `MatGetFactor()`, `MatCopy()`, `MatDuplicate()`, `MatGetFactor()`, `MatSolverTypeRegister()`, 4664 `MAT_FACTOR_LU`, `MAT_FACTOR_CHOLESKY`, `MAT_FACTOR_ICC`, `MAT_FACTOR_ILU`, `MAT_FACTOR_QR` 4665 @*/ 4666 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type, MatFactorType ftype, PetscBool *flg) { 4667 PetscErrorCode (*gconv)(Mat, MatFactorType, Mat *); 4668 4669 PetscFunctionBegin; 4670 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4671 PetscValidType(mat, 1); 4672 PetscValidBoolPointer(flg, 4); 4673 4674 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 4675 MatCheckPreallocated(mat, 1); 4676 4677 PetscCall(MatSolverTypeGet(type, ((PetscObject)mat)->type_name, ftype, NULL, NULL, &gconv)); 4678 *flg = gconv ? PETSC_TRUE : PETSC_FALSE; 4679 PetscFunctionReturn(0); 4680 } 4681 4682 /*@ 4683 MatDuplicate - Duplicates a matrix including the non-zero structure. 4684 4685 Collective on mat 4686 4687 Input Parameters: 4688 + mat - the matrix 4689 - op - One of `MAT_DO_NOT_COPY_VALUES`, `MAT_COPY_VALUES`, or `MAT_SHARE_NONZERO_PATTERN`. 4690 See the manual page for `MatDuplicateOption()` for an explanation of these options. 4691 4692 Output Parameter: 4693 . M - pointer to place new matrix 4694 4695 Level: intermediate 4696 4697 Notes: 4698 You cannot change the nonzero pattern for the parent or child matrix if you use `MAT_SHARE_NONZERO_PATTERN`. 4699 4700 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. 4701 4702 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 4703 is duplicated and the internal data structures created for the reuse of previous matrix operations are not duplicated. 4704 User should not use `MatDuplicate()` to create new matrix M if M is intended to be reused as the product of matrix operation. 4705 4706 .seealso: `MatCopy()`, `MatConvert()`, `MatDuplicateOption` 4707 @*/ 4708 PetscErrorCode MatDuplicate(Mat mat, MatDuplicateOption op, Mat *M) { 4709 Mat B; 4710 VecType vtype; 4711 PetscInt i; 4712 PetscObject dm; 4713 void (*viewf)(void); 4714 4715 PetscFunctionBegin; 4716 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4717 PetscValidType(mat, 1); 4718 PetscValidPointer(M, 3); 4719 PetscCheck(op != MAT_COPY_VALUES || mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "MAT_COPY_VALUES not allowed for unassembled matrix"); 4720 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 4721 MatCheckPreallocated(mat, 1); 4722 4723 *M = NULL; 4724 PetscCall(PetscLogEventBegin(MAT_Convert, mat, 0, 0, 0)); 4725 PetscUseTypeMethod(mat, duplicate, op, M); 4726 PetscCall(PetscLogEventEnd(MAT_Convert, mat, 0, 0, 0)); 4727 B = *M; 4728 4729 PetscCall(MatGetOperation(mat, MATOP_VIEW, &viewf)); 4730 if (viewf) PetscCall(MatSetOperation(B, MATOP_VIEW, viewf)); 4731 PetscCall(MatGetVecType(mat, &vtype)); 4732 PetscCall(MatSetVecType(B, vtype)); 4733 4734 B->stencil.dim = mat->stencil.dim; 4735 B->stencil.noc = mat->stencil.noc; 4736 for (i = 0; i <= mat->stencil.dim; i++) { 4737 B->stencil.dims[i] = mat->stencil.dims[i]; 4738 B->stencil.starts[i] = mat->stencil.starts[i]; 4739 } 4740 4741 B->nooffproczerorows = mat->nooffproczerorows; 4742 B->nooffprocentries = mat->nooffprocentries; 4743 4744 PetscCall(PetscObjectQuery((PetscObject)mat, "__PETSc_dm", &dm)); 4745 if (dm) PetscCall(PetscObjectCompose((PetscObject)B, "__PETSc_dm", dm)); 4746 PetscCall(PetscObjectStateIncrease((PetscObject)B)); 4747 PetscFunctionReturn(0); 4748 } 4749 4750 /*@ 4751 MatGetDiagonal - Gets the diagonal of a matrix as a `Vec` 4752 4753 Logically Collective on mat 4754 4755 Input Parameters: 4756 + mat - the matrix 4757 - v - the vector for storing the diagonal 4758 4759 Output Parameter: 4760 . v - the diagonal of the matrix 4761 4762 Level: intermediate 4763 4764 Note: 4765 Currently only correct in parallel for square matrices. 4766 4767 .seealso: `Mat`, `Vec`, `MatGetRow()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMaxAbs()` 4768 @*/ 4769 PetscErrorCode MatGetDiagonal(Mat mat, Vec v) { 4770 PetscFunctionBegin; 4771 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4772 PetscValidType(mat, 1); 4773 PetscValidHeaderSpecific(v, VEC_CLASSID, 2); 4774 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 4775 MatCheckPreallocated(mat, 1); 4776 4777 PetscUseTypeMethod(mat, getdiagonal, v); 4778 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 4779 PetscFunctionReturn(0); 4780 } 4781 4782 /*@C 4783 MatGetRowMin - Gets the minimum value (of the real part) of each 4784 row of the matrix 4785 4786 Logically Collective on mat 4787 4788 Input Parameter: 4789 . mat - the matrix 4790 4791 Output Parameters: 4792 + v - the vector for storing the maximums 4793 - idx - the indices of the column found for each row (optional) 4794 4795 Level: intermediate 4796 4797 Note: 4798 The result of this call are the same as if one converted the matrix to dense format 4799 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4800 4801 This code is only implemented for a couple of matrix formats. 4802 4803 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMaxAbs()`, `MatGetRowMinAbs()`, 4804 `MatGetRowMax()` 4805 @*/ 4806 PetscErrorCode MatGetRowMin(Mat mat, Vec v, PetscInt idx[]) { 4807 PetscFunctionBegin; 4808 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4809 PetscValidType(mat, 1); 4810 PetscValidHeaderSpecific(v, VEC_CLASSID, 2); 4811 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 4812 4813 if (!mat->cmap->N) { 4814 PetscCall(VecSet(v, PETSC_MAX_REAL)); 4815 if (idx) { 4816 PetscInt i, m = mat->rmap->n; 4817 for (i = 0; i < m; i++) idx[i] = -1; 4818 } 4819 } else { 4820 MatCheckPreallocated(mat, 1); 4821 } 4822 PetscUseTypeMethod(mat, getrowmin, v, idx); 4823 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 4824 PetscFunctionReturn(0); 4825 } 4826 4827 /*@C 4828 MatGetRowMinAbs - Gets the minimum value (in absolute value) of each 4829 row of the matrix 4830 4831 Logically Collective on mat 4832 4833 Input Parameter: 4834 . mat - the matrix 4835 4836 Output Parameters: 4837 + v - the vector for storing the minimums 4838 - idx - the indices of the column found for each row (or NULL if not needed) 4839 4840 Level: intermediate 4841 4842 Notes: 4843 if a row is completely empty or has only 0.0 values then the idx[] value for that 4844 row is 0 (the first column). 4845 4846 This code is only implemented for a couple of matrix formats. 4847 4848 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMax()`, `MatGetRowMaxAbs()`, `MatGetRowMin()` 4849 @*/ 4850 PetscErrorCode MatGetRowMinAbs(Mat mat, Vec v, PetscInt idx[]) { 4851 PetscFunctionBegin; 4852 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4853 PetscValidType(mat, 1); 4854 PetscValidHeaderSpecific(v, VEC_CLASSID, 2); 4855 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 4856 PetscCheck(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 4857 4858 if (!mat->cmap->N) { 4859 PetscCall(VecSet(v, 0.0)); 4860 if (idx) { 4861 PetscInt i, m = mat->rmap->n; 4862 for (i = 0; i < m; i++) idx[i] = -1; 4863 } 4864 } else { 4865 MatCheckPreallocated(mat, 1); 4866 if (idx) PetscCall(PetscArrayzero(idx, mat->rmap->n)); 4867 PetscUseTypeMethod(mat, getrowminabs, v, idx); 4868 } 4869 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 4870 PetscFunctionReturn(0); 4871 } 4872 4873 /*@C 4874 MatGetRowMax - Gets the maximum value (of the real part) of each 4875 row of the matrix 4876 4877 Logically Collective on mat 4878 4879 Input Parameter: 4880 . mat - the matrix 4881 4882 Output Parameters: 4883 + v - the vector for storing the maximums 4884 - idx - the indices of the column found for each row (optional) 4885 4886 Level: intermediate 4887 4888 Notes: 4889 The result of this call are the same as if one converted the matrix to dense format 4890 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4891 4892 This code is only implemented for a couple of matrix formats. 4893 4894 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMaxAbs()`, `MatGetRowMin()`, `MatGetRowMinAbs()` 4895 @*/ 4896 PetscErrorCode MatGetRowMax(Mat mat, Vec v, PetscInt idx[]) { 4897 PetscFunctionBegin; 4898 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4899 PetscValidType(mat, 1); 4900 PetscValidHeaderSpecific(v, VEC_CLASSID, 2); 4901 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 4902 4903 if (!mat->cmap->N) { 4904 PetscCall(VecSet(v, PETSC_MIN_REAL)); 4905 if (idx) { 4906 PetscInt i, m = mat->rmap->n; 4907 for (i = 0; i < m; i++) idx[i] = -1; 4908 } 4909 } else { 4910 MatCheckPreallocated(mat, 1); 4911 PetscUseTypeMethod(mat, getrowmax, v, idx); 4912 } 4913 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 4914 PetscFunctionReturn(0); 4915 } 4916 4917 /*@C 4918 MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each 4919 row of the matrix 4920 4921 Logically Collective on mat 4922 4923 Input Parameter: 4924 . mat - the matrix 4925 4926 Output Parameters: 4927 + v - the vector for storing the maximums 4928 - idx - the indices of the column found for each row (or NULL if not needed) 4929 4930 Level: intermediate 4931 4932 Notes: 4933 if a row is completely empty or has only 0.0 values then the idx[] value for that 4934 row is 0 (the first column). 4935 4936 This code is only implemented for a couple of matrix formats. 4937 4938 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMax()`, `MatGetRowMin()`, `MatGetRowMinAbs()` 4939 @*/ 4940 PetscErrorCode MatGetRowMaxAbs(Mat mat, Vec v, PetscInt idx[]) { 4941 PetscFunctionBegin; 4942 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4943 PetscValidType(mat, 1); 4944 PetscValidHeaderSpecific(v, VEC_CLASSID, 2); 4945 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 4946 4947 if (!mat->cmap->N) { 4948 PetscCall(VecSet(v, 0.0)); 4949 if (idx) { 4950 PetscInt i, m = mat->rmap->n; 4951 for (i = 0; i < m; i++) idx[i] = -1; 4952 } 4953 } else { 4954 MatCheckPreallocated(mat, 1); 4955 if (idx) PetscCall(PetscArrayzero(idx, mat->rmap->n)); 4956 PetscUseTypeMethod(mat, getrowmaxabs, v, idx); 4957 } 4958 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 4959 PetscFunctionReturn(0); 4960 } 4961 4962 /*@ 4963 MatGetRowSum - Gets the sum of each row of the matrix 4964 4965 Logically or Neighborhood Collective on mat 4966 4967 Input Parameters: 4968 . mat - the matrix 4969 4970 Output Parameter: 4971 . v - the vector for storing the sum of rows 4972 4973 Level: intermediate 4974 4975 Notes: 4976 This code is slow since it is not currently specialized for different formats 4977 4978 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMax()`, `MatGetRowMin()`, `MatGetRowMaxAbs()`, `MatGetRowMinAbs()` 4979 @*/ 4980 PetscErrorCode MatGetRowSum(Mat mat, Vec v) { 4981 Vec ones; 4982 4983 PetscFunctionBegin; 4984 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4985 PetscValidType(mat, 1); 4986 PetscValidHeaderSpecific(v, VEC_CLASSID, 2); 4987 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 4988 MatCheckPreallocated(mat, 1); 4989 PetscCall(MatCreateVecs(mat, &ones, NULL)); 4990 PetscCall(VecSet(ones, 1.)); 4991 PetscCall(MatMult(mat, ones, v)); 4992 PetscCall(VecDestroy(&ones)); 4993 PetscFunctionReturn(0); 4994 } 4995 4996 /*@ 4997 MatTransposeSetPrecursor - Set the matrix from which the second matrix will receive numerical transpose data with a call to `MatTranspose`(A,`MAT_REUSE_MATRIX`,&B) 4998 when B was not obtained with `MatTranspose`(A,`MAT_INITIAL_MATRIX`,&B) 4999 5000 Collective on mat 5001 5002 Input Parameter: 5003 . mat - the matrix to provide the transpose 5004 5005 Output Parameter: 5006 . 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 5007 5008 Level: advanced 5009 5010 Note: 5011 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 5012 routine allows bypassing that call. 5013 5014 .seealso: `MatTransposeSymbolic()`, `MatTranspose()`, `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse`, `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, `MAT_INPLACE_MATRIX` 5015 @*/ 5016 PetscErrorCode MatTransposeSetPrecursor(Mat mat, Mat B) { 5017 PetscContainer rB = NULL; 5018 MatParentState *rb = NULL; 5019 5020 PetscFunctionBegin; 5021 PetscCall(PetscNew(&rb)); 5022 rb->id = ((PetscObject)mat)->id; 5023 rb->state = 0; 5024 PetscCall(MatGetNonzeroState(mat, &rb->nonzerostate)); 5025 PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)B), &rB)); 5026 PetscCall(PetscContainerSetPointer(rB, rb)); 5027 PetscCall(PetscContainerSetUserDestroy(rB, PetscContainerUserDestroyDefault)); 5028 PetscCall(PetscObjectCompose((PetscObject)B, "MatTransposeParent", (PetscObject)rB)); 5029 PetscCall(PetscObjectDereference((PetscObject)rB)); 5030 PetscFunctionReturn(0); 5031 } 5032 5033 /*@ 5034 MatTranspose - Computes an in-place or out-of-place transpose of a matrix. 5035 5036 Collective on mat 5037 5038 Input Parameters: 5039 + mat - the matrix to transpose 5040 - reuse - either `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, or `MAT_INPLACE_MATRIX` 5041 5042 Output Parameter: 5043 . B - the transpose 5044 5045 Notes: 5046 If you use `MAT_INPLACE_MATRIX` then you must pass in &mat for B 5047 5048 `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 5049 transpose, call `MatTransposeSetPrecursor`(mat,B) before calling this routine. 5050 5051 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. 5052 5053 Consider using `MatCreateTranspose()` instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed. 5054 5055 If mat is unchanged from the last call this function returns immediately without recomputing the result 5056 5057 If you only need the symbolic transpose, and not the numerical values, use `MatTransposeSymbolic()` 5058 5059 Level: intermediate 5060 5061 .seealso: `MatTransposeSetPrecursor()`, `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse`, `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, `MAT_INPLACE_MATRIX`, 5062 `MatTransposeSymbolic()` 5063 @*/ 5064 PetscErrorCode MatTranspose(Mat mat, MatReuse reuse, Mat *B) { 5065 PetscContainer rB = NULL; 5066 MatParentState *rb = NULL; 5067 5068 PetscFunctionBegin; 5069 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5070 PetscValidType(mat, 1); 5071 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 5072 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 5073 PetscCheck(reuse != MAT_INPLACE_MATRIX || mat == *B, PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "MAT_INPLACE_MATRIX requires last matrix to match first"); 5074 PetscCheck(reuse != MAT_REUSE_MATRIX || mat != *B, PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Perhaps you mean MAT_INPLACE_MATRIX"); 5075 MatCheckPreallocated(mat, 1); 5076 if (reuse == MAT_REUSE_MATRIX) { 5077 PetscCall(PetscObjectQuery((PetscObject)*B, "MatTransposeParent", (PetscObject *)&rB)); 5078 PetscCheck(rB, PetscObjectComm((PetscObject)*B), PETSC_ERR_ARG_WRONG, "Reuse matrix used was not generated from call to MatTranspose(). Suggest MatTransposeSetPrecursor()."); 5079 PetscCall(PetscContainerGetPointer(rB, (void **)&rb)); 5080 PetscCheck(rb->id == ((PetscObject)mat)->id, PetscObjectComm((PetscObject)*B), PETSC_ERR_ARG_WRONG, "Reuse matrix used was not generated from input matrix"); 5081 if (rb->state == ((PetscObject)mat)->state) PetscFunctionReturn(0); 5082 } 5083 5084 PetscCall(PetscLogEventBegin(MAT_Transpose, mat, 0, 0, 0)); 5085 if (reuse != MAT_INPLACE_MATRIX || mat->symmetric != PETSC_BOOL3_TRUE) { 5086 PetscUseTypeMethod(mat, transpose, reuse, B); 5087 PetscCall(PetscObjectStateIncrease((PetscObject)*B)); 5088 } 5089 PetscCall(PetscLogEventEnd(MAT_Transpose, mat, 0, 0, 0)); 5090 5091 if (reuse == MAT_INITIAL_MATRIX) PetscCall(MatTransposeSetPrecursor(mat, *B)); 5092 if (reuse != MAT_INPLACE_MATRIX) { 5093 PetscCall(PetscObjectQuery((PetscObject)*B, "MatTransposeParent", (PetscObject *)&rB)); 5094 PetscCall(PetscContainerGetPointer(rB, (void **)&rb)); 5095 rb->state = ((PetscObject)mat)->state; 5096 rb->nonzerostate = mat->nonzerostate; 5097 } 5098 PetscFunctionReturn(0); 5099 } 5100 5101 /*@ 5102 MatTransposeSymbolic - Computes the symbolic part of the transpose of a matrix. 5103 5104 Collective on A 5105 5106 Input Parameters: 5107 . A - the matrix to transpose 5108 5109 Output Parameter: 5110 . 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 5111 numerical portion. 5112 5113 Level: intermediate 5114 5115 Note: 5116 This is not supported for many matrix types, use `MatTranspose()` in those cases 5117 5118 .seealso: `MatTransposeSetPrecursor()`, `MatTranspose()`, `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse`, `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, `MAT_INPLACE_MATRIX` 5119 @*/ 5120 PetscErrorCode MatTransposeSymbolic(Mat A, Mat *B) { 5121 PetscFunctionBegin; 5122 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 5123 PetscValidType(A, 1); 5124 PetscCheck(A->assembled, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 5125 PetscCheck(!A->factortype, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 5126 PetscCheck(A->ops->transposesymbolic, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Mat type %s", ((PetscObject)A)->type_name); 5127 PetscCall(PetscLogEventBegin(MAT_Transpose, A, 0, 0, 0)); 5128 PetscCall((*A->ops->transposesymbolic)(A, B)); 5129 PetscCall(PetscLogEventEnd(MAT_Transpose, A, 0, 0, 0)); 5130 5131 PetscCall(MatTransposeSetPrecursor(A, *B)); 5132 PetscFunctionReturn(0); 5133 } 5134 5135 PetscErrorCode MatTransposeCheckNonzeroState_Private(Mat A, Mat B) { 5136 PetscContainer rB; 5137 MatParentState *rb; 5138 5139 PetscFunctionBegin; 5140 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 5141 PetscValidType(A, 1); 5142 PetscCheck(A->assembled, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 5143 PetscCheck(!A->factortype, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 5144 PetscCall(PetscObjectQuery((PetscObject)B, "MatTransposeParent", (PetscObject *)&rB)); 5145 PetscCheck(rB, PetscObjectComm((PetscObject)B), PETSC_ERR_ARG_WRONG, "Reuse matrix used was not generated from call to MatTranspose()"); 5146 PetscCall(PetscContainerGetPointer(rB, (void **)&rb)); 5147 PetscCheck(rb->id == ((PetscObject)A)->id, PetscObjectComm((PetscObject)B), PETSC_ERR_ARG_WRONG, "Reuse matrix used was not generated from input matrix"); 5148 PetscCheck(rb->nonzerostate == A->nonzerostate, PetscObjectComm((PetscObject)B), PETSC_ERR_ARG_WRONGSTATE, "Reuse matrix has changed nonzero structure"); 5149 PetscFunctionReturn(0); 5150 } 5151 5152 /*@ 5153 MatIsTranspose - Test whether a matrix is another one's transpose, 5154 or its own, in which case it tests symmetry. 5155 5156 Collective on A 5157 5158 Input Parameters: 5159 + A - the matrix to test 5160 - B - the matrix to test against, this can equal the first parameter 5161 5162 Output Parameters: 5163 . flg - the result 5164 5165 Notes: 5166 Only available for `MATAIJ` matrices. 5167 5168 The sequential algorithm has a running time of the order of the number of nonzeros; the parallel 5169 test involves parallel copies of the block-offdiagonal parts of the matrix. 5170 5171 Level: intermediate 5172 5173 .seealso: `MatTranspose()`, `MatIsSymmetric()`, `MatIsHermitian()` 5174 @*/ 5175 PetscErrorCode MatIsTranspose(Mat A, Mat B, PetscReal tol, PetscBool *flg) { 5176 PetscErrorCode (*f)(Mat, Mat, PetscReal, PetscBool *), (*g)(Mat, Mat, PetscReal, PetscBool *); 5177 5178 PetscFunctionBegin; 5179 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 5180 PetscValidHeaderSpecific(B, MAT_CLASSID, 2); 5181 PetscValidBoolPointer(flg, 4); 5182 PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatIsTranspose_C", &f)); 5183 PetscCall(PetscObjectQueryFunction((PetscObject)B, "MatIsTranspose_C", &g)); 5184 *flg = PETSC_FALSE; 5185 if (f && g) { 5186 PetscCheck(f == g, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_NOTSAMETYPE, "Matrices do not have the same comparator for symmetry test"); 5187 PetscCall((*f)(A, B, tol, flg)); 5188 } else { 5189 MatType mattype; 5190 5191 PetscCall(MatGetType(f ? B : A, &mattype)); 5192 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Matrix of type %s does not support checking for transpose", mattype); 5193 } 5194 PetscFunctionReturn(0); 5195 } 5196 5197 /*@ 5198 MatHermitianTranspose - Computes an in-place or out-of-place Hermitian transpose of a matrix in complex conjugate. 5199 5200 Collective on mat 5201 5202 Input Parameters: 5203 + mat - the matrix to transpose and complex conjugate 5204 - reuse - either `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, or `MAT_INPLACE_MATRIX` 5205 5206 Output Parameter: 5207 . B - the Hermitian transpose 5208 5209 Level: intermediate 5210 5211 .seealso: `MatTranspose()`, `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse` 5212 @*/ 5213 PetscErrorCode MatHermitianTranspose(Mat mat, MatReuse reuse, Mat *B) { 5214 PetscFunctionBegin; 5215 PetscCall(MatTranspose(mat, reuse, B)); 5216 #if defined(PETSC_USE_COMPLEX) 5217 PetscCall(MatConjugate(*B)); 5218 #endif 5219 PetscFunctionReturn(0); 5220 } 5221 5222 /*@ 5223 MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose, 5224 5225 Collective on A 5226 5227 Input Parameters: 5228 + A - the matrix to test 5229 - B - the matrix to test against, this can equal the first parameter 5230 5231 Output Parameters: 5232 . flg - the result 5233 5234 Notes: 5235 Only available for `MATAIJ` matrices. 5236 5237 The sequential algorithm 5238 has a running time of the order of the number of nonzeros; the parallel 5239 test involves parallel copies of the block-offdiagonal parts of the matrix. 5240 5241 Level: intermediate 5242 5243 .seealso: `MatTranspose()`, `MatIsSymmetric()`, `MatIsHermitian()`, `MatIsTranspose()` 5244 @*/ 5245 PetscErrorCode MatIsHermitianTranspose(Mat A, Mat B, PetscReal tol, PetscBool *flg) { 5246 PetscErrorCode (*f)(Mat, Mat, PetscReal, PetscBool *), (*g)(Mat, Mat, PetscReal, PetscBool *); 5247 5248 PetscFunctionBegin; 5249 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 5250 PetscValidHeaderSpecific(B, MAT_CLASSID, 2); 5251 PetscValidBoolPointer(flg, 4); 5252 PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatIsHermitianTranspose_C", &f)); 5253 PetscCall(PetscObjectQueryFunction((PetscObject)B, "MatIsHermitianTranspose_C", &g)); 5254 if (f && g) { 5255 PetscCheck(f != g, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_NOTSAMETYPE, "Matrices do not have the same comparator for Hermitian test"); 5256 PetscCall((*f)(A, B, tol, flg)); 5257 } 5258 PetscFunctionReturn(0); 5259 } 5260 5261 /*@ 5262 MatPermute - Creates a new matrix with rows and columns permuted from the 5263 original. 5264 5265 Collective on mat 5266 5267 Input Parameters: 5268 + mat - the matrix to permute 5269 . row - row permutation, each processor supplies only the permutation for its rows 5270 - col - column permutation, each processor supplies only the permutation for its columns 5271 5272 Output Parameters: 5273 . B - the permuted matrix 5274 5275 Level: advanced 5276 5277 Note: 5278 The index sets map from row/col of permuted matrix to row/col of original matrix. 5279 The index sets should be on the same communicator as mat and have the same local sizes. 5280 5281 Developer Note: 5282 If you want to implement `MatPermute()` for a matrix type, and your approach doesn't 5283 exploit the fact that row and col are permutations, consider implementing the 5284 more general `MatCreateSubMatrix()` instead. 5285 5286 .seealso: `MatGetOrdering()`, `ISAllGather()`, `MatCreateSubMatrix()` 5287 @*/ 5288 PetscErrorCode MatPermute(Mat mat, IS row, IS col, Mat *B) { 5289 PetscFunctionBegin; 5290 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5291 PetscValidType(mat, 1); 5292 PetscValidHeaderSpecific(row, IS_CLASSID, 2); 5293 PetscValidHeaderSpecific(col, IS_CLASSID, 3); 5294 PetscValidPointer(B, 4); 5295 PetscCheckSameComm(mat, 1, row, 2); 5296 if (row != col) PetscCheckSameComm(row, 2, col, 3); 5297 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 5298 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 5299 PetscCheck(mat->ops->permute || mat->ops->createsubmatrix, PETSC_COMM_SELF, PETSC_ERR_SUP, "MatPermute not available for Mat type %s", ((PetscObject)mat)->type_name); 5300 MatCheckPreallocated(mat, 1); 5301 5302 if (mat->ops->permute) { 5303 PetscUseTypeMethod(mat, permute, row, col, B); 5304 PetscCall(PetscObjectStateIncrease((PetscObject)*B)); 5305 } else { 5306 PetscCall(MatCreateSubMatrix(mat, row, col, MAT_INITIAL_MATRIX, B)); 5307 } 5308 PetscFunctionReturn(0); 5309 } 5310 5311 /*@ 5312 MatEqual - Compares two matrices. 5313 5314 Collective on A 5315 5316 Input Parameters: 5317 + A - the first matrix 5318 - B - the second matrix 5319 5320 Output Parameter: 5321 . flg - `PETSC_TRUE` if the matrices are equal; `PETSC_FALSE` otherwise. 5322 5323 Level: intermediate 5324 5325 .seealso: `Mat` 5326 @*/ 5327 PetscErrorCode MatEqual(Mat A, Mat B, PetscBool *flg) { 5328 PetscFunctionBegin; 5329 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 5330 PetscValidHeaderSpecific(B, MAT_CLASSID, 2); 5331 PetscValidType(A, 1); 5332 PetscValidType(B, 2); 5333 PetscValidBoolPointer(flg, 3); 5334 PetscCheckSameComm(A, 1, B, 2); 5335 MatCheckPreallocated(A, 1); 5336 MatCheckPreallocated(B, 2); 5337 PetscCheck(A->assembled, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 5338 PetscCheck(B->assembled, PetscObjectComm((PetscObject)B), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 5339 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, 5340 B->cmap->N); 5341 if (A->ops->equal && A->ops->equal == B->ops->equal) { 5342 PetscUseTypeMethod(A, equal, B, flg); 5343 } else { 5344 PetscCall(MatMultEqual(A, B, 10, flg)); 5345 } 5346 PetscFunctionReturn(0); 5347 } 5348 5349 /*@ 5350 MatDiagonalScale - Scales a matrix on the left and right by diagonal 5351 matrices that are stored as vectors. Either of the two scaling 5352 matrices can be NULL. 5353 5354 Collective on mat 5355 5356 Input Parameters: 5357 + mat - the matrix to be scaled 5358 . l - the left scaling vector (or NULL) 5359 - r - the right scaling vector (or NULL) 5360 5361 Note: 5362 `MatDiagonalScale()` computes A = LAR, where 5363 L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector) 5364 The L scales the rows of the matrix, the R scales the columns of the matrix. 5365 5366 Level: intermediate 5367 5368 .seealso: `Mat`, `MatScale()`, `MatShift()`, `MatDiagonalSet()` 5369 @*/ 5370 PetscErrorCode MatDiagonalScale(Mat mat, Vec l, Vec r) { 5371 PetscFunctionBegin; 5372 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5373 PetscValidType(mat, 1); 5374 if (l) { 5375 PetscValidHeaderSpecific(l, VEC_CLASSID, 2); 5376 PetscCheckSameComm(mat, 1, l, 2); 5377 } 5378 if (r) { 5379 PetscValidHeaderSpecific(r, VEC_CLASSID, 3); 5380 PetscCheckSameComm(mat, 1, r, 3); 5381 } 5382 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 5383 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 5384 MatCheckPreallocated(mat, 1); 5385 if (!l && !r) PetscFunctionReturn(0); 5386 5387 PetscCall(PetscLogEventBegin(MAT_Scale, mat, 0, 0, 0)); 5388 PetscUseTypeMethod(mat, diagonalscale, l, r); 5389 PetscCall(PetscLogEventEnd(MAT_Scale, mat, 0, 0, 0)); 5390 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5391 if (l != r) mat->symmetric = PETSC_BOOL3_FALSE; 5392 PetscFunctionReturn(0); 5393 } 5394 5395 /*@ 5396 MatScale - Scales all elements of a matrix by a given number. 5397 5398 Logically Collective on mat 5399 5400 Input Parameters: 5401 + mat - the matrix to be scaled 5402 - a - the scaling value 5403 5404 Output Parameter: 5405 . mat - the scaled matrix 5406 5407 Level: intermediate 5408 5409 .seealso: `Mat`, `MatDiagonalScale()` 5410 @*/ 5411 PetscErrorCode MatScale(Mat mat, PetscScalar a) { 5412 PetscFunctionBegin; 5413 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5414 PetscValidType(mat, 1); 5415 PetscCheck(a == (PetscScalar)1.0 || mat->ops->scale, PETSC_COMM_SELF, PETSC_ERR_SUP, "Mat type %s", ((PetscObject)mat)->type_name); 5416 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 5417 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 5418 PetscValidLogicalCollectiveScalar(mat, a, 2); 5419 MatCheckPreallocated(mat, 1); 5420 5421 PetscCall(PetscLogEventBegin(MAT_Scale, mat, 0, 0, 0)); 5422 if (a != (PetscScalar)1.0) { 5423 PetscUseTypeMethod(mat, scale, a); 5424 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5425 } 5426 PetscCall(PetscLogEventEnd(MAT_Scale, mat, 0, 0, 0)); 5427 PetscFunctionReturn(0); 5428 } 5429 5430 /*@ 5431 MatNorm - Calculates various norms of a matrix. 5432 5433 Collective on mat 5434 5435 Input Parameters: 5436 + mat - the matrix 5437 - type - the type of norm, `NORM_1`, `NORM_FROBENIUS`, `NORM_INFINITY` 5438 5439 Output Parameter: 5440 . nrm - the resulting norm 5441 5442 Level: intermediate 5443 5444 .seealso: `Mat` 5445 @*/ 5446 PetscErrorCode MatNorm(Mat mat, NormType type, PetscReal *nrm) { 5447 PetscFunctionBegin; 5448 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5449 PetscValidType(mat, 1); 5450 PetscValidRealPointer(nrm, 3); 5451 5452 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 5453 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 5454 MatCheckPreallocated(mat, 1); 5455 5456 PetscUseTypeMethod(mat, norm, type, nrm); 5457 PetscFunctionReturn(0); 5458 } 5459 5460 /* 5461 This variable is used to prevent counting of MatAssemblyBegin() that 5462 are called from within a MatAssemblyEnd(). 5463 */ 5464 static PetscInt MatAssemblyEnd_InUse = 0; 5465 /*@ 5466 MatAssemblyBegin - Begins assembling the matrix. This routine should 5467 be called after completing all calls to `MatSetValues()`. 5468 5469 Collective on mat 5470 5471 Input Parameters: 5472 + mat - the matrix 5473 - type - type of assembly, either `MAT_FLUSH_ASSEMBLY` or `MAT_FINAL_ASSEMBLY` 5474 5475 Notes: 5476 `MatSetValues()` generally caches the values that belong to other MPI ranks. The matrix is ready to 5477 use only after `MatAssemblyBegin()` and `MatAssemblyEnd()` have been called. 5478 5479 Use `MAT_FLUSH_ASSEMBLY` when switching between `ADD_VALUES` and `INSERT_VALUES` 5480 in `MatSetValues()`; use `MAT_FINAL_ASSEMBLY` for the final assembly before 5481 using the matrix. 5482 5483 ALL processes that share a matrix MUST call `MatAssemblyBegin()` and `MatAssemblyEnd()` the SAME NUMBER of times, and each time with the 5484 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 5485 a global collective operation requring all processes that share the matrix. 5486 5487 Space for preallocated nonzeros that is not filled by a call to `MatSetValues()` or a related routine are compressed 5488 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5489 before `MAT_FINAL_ASSEMBLY` so the space is not compressed out. 5490 5491 Level: beginner 5492 5493 .seealso: `Mat`, `MatAssemblyEnd()`, `MatSetValues()`, `MatAssembled()` 5494 @*/ 5495 PetscErrorCode MatAssemblyBegin(Mat mat, MatAssemblyType type) { 5496 PetscFunctionBegin; 5497 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5498 PetscValidType(mat, 1); 5499 MatCheckPreallocated(mat, 1); 5500 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix.\nDid you forget to call MatSetUnfactored()?"); 5501 if (mat->assembled) { 5502 mat->was_assembled = PETSC_TRUE; 5503 mat->assembled = PETSC_FALSE; 5504 } 5505 5506 if (!MatAssemblyEnd_InUse) { 5507 PetscCall(PetscLogEventBegin(MAT_AssemblyBegin, mat, 0, 0, 0)); 5508 PetscTryTypeMethod(mat, assemblybegin, type); 5509 PetscCall(PetscLogEventEnd(MAT_AssemblyBegin, mat, 0, 0, 0)); 5510 } else PetscTryTypeMethod(mat, assemblybegin, type); 5511 PetscFunctionReturn(0); 5512 } 5513 5514 /*@ 5515 MatAssembled - Indicates if a matrix has been assembled and is ready for 5516 use; for example, in matrix-vector product. 5517 5518 Not Collective 5519 5520 Input Parameter: 5521 . mat - the matrix 5522 5523 Output Parameter: 5524 . assembled - `PETSC_TRUE` or `PETSC_FALSE` 5525 5526 Level: advanced 5527 5528 .seealso: `Mat`, `MatAssemblyEnd()`, `MatSetValues()`, `MatAssemblyBegin()` 5529 @*/ 5530 PetscErrorCode MatAssembled(Mat mat, PetscBool *assembled) { 5531 PetscFunctionBegin; 5532 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5533 PetscValidBoolPointer(assembled, 2); 5534 *assembled = mat->assembled; 5535 PetscFunctionReturn(0); 5536 } 5537 5538 /*@ 5539 MatAssemblyEnd - Completes assembling the matrix. This routine should 5540 be called after `MatAssemblyBegin()`. 5541 5542 Collective on Mat 5543 5544 Input Parameters: 5545 + mat - the matrix 5546 - type - type of assembly, either `MAT_FLUSH_ASSEMBLY` or `MAT_FINAL_ASSEMBLY` 5547 5548 Options Database Keys: 5549 + -mat_view ::ascii_info - Prints info on matrix at conclusion of `MatEndAssembly()` 5550 . -mat_view ::ascii_info_detail - Prints more detailed info 5551 . -mat_view - Prints matrix in ASCII format 5552 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 5553 . -mat_view draw - draws nonzero structure of matrix, using `MatView()` and `PetscDrawOpenX()`. 5554 . -display <name> - Sets display name (default is host) 5555 . -draw_pause <sec> - Sets number of seconds to pause after display 5556 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See [Using MATLAB with PETSc](ch_matlab)) 5557 . -viewer_socket_machine <machine> - Machine to use for socket 5558 . -viewer_socket_port <port> - Port number to use for socket 5559 - -mat_view binary:filename[:append] - Save matrix to file in binary format 5560 5561 Level: beginner 5562 5563 .seealso: `Mat`, `MatAssemblyBegin()`, `MatSetValues()`, `PetscDrawOpenX()`, `PetscDrawCreate()`, `MatView()`, `MatAssembled()`, `PetscViewerSocketOpen()` 5564 @*/ 5565 PetscErrorCode MatAssemblyEnd(Mat mat, MatAssemblyType type) { 5566 static PetscInt inassm = 0; 5567 PetscBool flg = PETSC_FALSE; 5568 5569 PetscFunctionBegin; 5570 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5571 PetscValidType(mat, 1); 5572 5573 inassm++; 5574 MatAssemblyEnd_InUse++; 5575 if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */ 5576 PetscCall(PetscLogEventBegin(MAT_AssemblyEnd, mat, 0, 0, 0)); 5577 PetscTryTypeMethod(mat, assemblyend, type); 5578 PetscCall(PetscLogEventEnd(MAT_AssemblyEnd, mat, 0, 0, 0)); 5579 } else PetscTryTypeMethod(mat, assemblyend, type); 5580 5581 /* Flush assembly is not a true assembly */ 5582 if (type != MAT_FLUSH_ASSEMBLY) { 5583 if (mat->num_ass) { 5584 if (!mat->symmetry_eternal) { 5585 mat->symmetric = PETSC_BOOL3_UNKNOWN; 5586 mat->hermitian = PETSC_BOOL3_UNKNOWN; 5587 } 5588 if (!mat->structural_symmetry_eternal && mat->ass_nonzerostate != mat->nonzerostate) mat->structurally_symmetric = PETSC_BOOL3_UNKNOWN; 5589 if (!mat->spd_eternal) mat->spd = PETSC_BOOL3_UNKNOWN; 5590 } 5591 mat->num_ass++; 5592 mat->assembled = PETSC_TRUE; 5593 mat->ass_nonzerostate = mat->nonzerostate; 5594 } 5595 5596 mat->insertmode = NOT_SET_VALUES; 5597 MatAssemblyEnd_InUse--; 5598 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5599 if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) { 5600 PetscCall(MatViewFromOptions(mat, NULL, "-mat_view")); 5601 5602 if (mat->checksymmetryonassembly) { 5603 PetscCall(MatIsSymmetric(mat, mat->checksymmetrytol, &flg)); 5604 if (flg) { 5605 PetscCall(PetscPrintf(PetscObjectComm((PetscObject)mat), "Matrix is symmetric (tolerance %g)\n", (double)mat->checksymmetrytol)); 5606 } else { 5607 PetscCall(PetscPrintf(PetscObjectComm((PetscObject)mat), "Matrix is not symmetric (tolerance %g)\n", (double)mat->checksymmetrytol)); 5608 } 5609 } 5610 if (mat->nullsp && mat->checknullspaceonassembly) PetscCall(MatNullSpaceTest(mat->nullsp, mat, NULL)); 5611 } 5612 inassm--; 5613 PetscFunctionReturn(0); 5614 } 5615 5616 /*@ 5617 MatSetOption - Sets a parameter option for a matrix. Some options 5618 may be specific to certain storage formats. Some options 5619 determine how values will be inserted (or added). Sorted, 5620 row-oriented input will generally assemble the fastest. The default 5621 is row-oriented. 5622 5623 Logically Collective on mat for certain operations, such as `MAT_SPD`, not collective for `MAT_ROW_ORIENTED`, see `MatOption` 5624 5625 Input Parameters: 5626 + mat - the matrix 5627 . option - the option, one of those listed below (and possibly others), 5628 - flg - turn the option on (`PETSC_TRUE`) or off (`PETSC_FALSE`) 5629 5630 Options Describing Matrix Structure: 5631 + `MAT_SPD` - symmetric positive definite 5632 . `MAT_SYMMETRIC` - symmetric in terms of both structure and value 5633 . `MAT_HERMITIAN` - transpose is the complex conjugation 5634 . `MAT_STRUCTURALLY_SYMMETRIC` - symmetric nonzero structure 5635 . `MAT_SYMMETRY_ETERNAL` - indicates the symmetry (or Hermitian structure) or its absence will persist through any changes to the matrix 5636 . `MAT_STRUCTURAL_SYMMETRY_ETERNAL` - indicates the structural symmetry or its absence will persist through any changes to the matrix 5637 - `MAT_SPD_ETERNAL` - indicates the value of `MAT_SPD` (true or false) will persist through any changes to the matrix 5638 5639 These are not really options of the matrix, they are knowledge about the structure of the matrix that users may provide so that they 5640 do not need to be computed (usually at a high cost) 5641 5642 Options For Use with `MatSetValues()`: 5643 Insert a logically dense subblock, which can be 5644 . `MAT_ROW_ORIENTED` - row-oriented (default) 5645 5646 Note these options reflect the data you pass in with `MatSetValues()`; it has 5647 nothing to do with how the data is stored internally in the matrix 5648 data structure. 5649 5650 When (re)assembling a matrix, we can restrict the input for 5651 efficiency/debugging purposes. These options include 5652 + `MAT_NEW_NONZERO_LOCATIONS` - additional insertions will be allowed if they generate a new nonzero (slow) 5653 . `MAT_FORCE_DIAGONAL_ENTRIES` - forces diagonal entries to be allocated 5654 . `MAT_IGNORE_OFF_PROC_ENTRIES` - drops off-processor entries 5655 . `MAT_NEW_NONZERO_LOCATION_ERR` - generates an error for new matrix entry 5656 . `MAT_USE_HASH_TABLE` - uses a hash table to speed up matrix assembly 5657 . `MAT_NO_OFF_PROC_ENTRIES` - you know each process will only set values for its own rows, will generate an error if 5658 any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves 5659 performance for very large process counts. 5660 - `MAT_SUBSET_OFF_PROC_ENTRIES` - you know that the first assembly after setting this flag will set a superset 5661 of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly 5662 functions, instead sending only neighbor messages. 5663 5664 Notes: 5665 Except for `MAT_UNUSED_NONZERO_LOCATION_ERR` and `MAT_ROW_ORIENTED` all processes that share the matrix must pass the same value in flg! 5666 5667 Some options are relevant only for particular matrix types and 5668 are thus ignored by others. Other options are not supported by 5669 certain matrix types and will generate an error message if set. 5670 5671 If using a Fortran 77 module to compute a matrix, one may need to 5672 use the column-oriented option (or convert to the row-oriented 5673 format). 5674 5675 `MAT_NEW_NONZERO_LOCATIONS` set to `PETSC_FALSE` indicates that any add or insertion 5676 that would generate a new entry in the nonzero structure is instead 5677 ignored. Thus, if memory has not alredy been allocated for this particular 5678 data, then the insertion is ignored. For dense matrices, in which 5679 the entire array is allocated, no entries are ever ignored. 5680 Set after the first `MatAssemblyEnd()`. If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5681 5682 `MAT_NEW_NONZERO_LOCATION_ERR` set to PETSC_TRUE indicates that any add or insertion 5683 that would generate a new entry in the nonzero structure instead produces 5684 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 5685 5686 `MAT_NEW_NONZERO_ALLOCATION_ERR` set to `PETSC_TRUE` indicates that any add or insertion 5687 that would generate a new entry that has not been preallocated will 5688 instead produce an error. (Currently supported for `MATAIJ` and `MATBAIJ` formats 5689 only.) This is a useful flag when debugging matrix memory preallocation. 5690 If this option is set then the `MatAssemblyBegin()`/`MatAssemblyEnd()` processes has one less global reduction 5691 5692 `MAT_IGNORE_OFF_PROC_ENTRIES` set to `PETSC_TRUE` indicates entries destined for 5693 other processors should be dropped, rather than stashed. 5694 This is useful if you know that the "owning" processor is also 5695 always generating the correct matrix entries, so that PETSc need 5696 not transfer duplicate entries generated on another processor. 5697 5698 `MAT_USE_HASH_TABLE` indicates that a hash table be used to improve the 5699 searches during matrix assembly. When this flag is set, the hash table 5700 is created during the first matrix assembly. This hash table is 5701 used the next time through, during `MatSetVaules()`/`MatSetVaulesBlocked()` 5702 to improve the searching of indices. `MAT_NEW_NONZERO_LOCATIONS` flag 5703 should be used with `MAT_USE_HASH_TABLE` flag. This option is currently 5704 supported by` MATMPIBAIJ` format only. 5705 5706 `MAT_KEEP_NONZERO_PATTERN` indicates when `MatZeroRows()` is called the zeroed entries 5707 are kept in the nonzero structure 5708 5709 `MAT_IGNORE_ZERO_ENTRIES` - for `MATAIJ` and `MATIS` matrices this will stop zero values from creating 5710 a zero location in the matrix 5711 5712 `MAT_USE_INODES` - indicates using inode version of the code - works with `MATAIJ` matrix types 5713 5714 `MAT_NO_OFF_PROC_ZERO_ROWS` - you know each process will only zero its own rows. This avoids all reductions in the 5715 zero row routines and thus improves performance for very large process counts. 5716 5717 `MAT_IGNORE_LOWER_TRIANGULAR` - For `MATSBAIJ` matrices will ignore any insertions you make in the lower triangular 5718 part of the matrix (since they should match the upper triangular part). 5719 5720 `MAT_SORTED_FULL` - each process provides exactly its local rows; all column indices for a given row are passed in a 5721 single call to `MatSetValues()`, preallocation is perfect, row oriented, `INSERT_VALUES` is used. Common 5722 with finite difference schemes with non-periodic boundary conditions. 5723 5724 Developer Note: 5725 `MAT_SYMMETRY_ETERNAL`, `MAT_STRUCTURAL_SYMMETRY_ETERNAL`, and `MAT_SPD_ETERNAL` are used by `MatAssemblyEnd()` and in other 5726 places where otherwise the value of `MAT_SYMMETRIC`, `MAT_STRUCTURAL_SYMMETRIC` or `MAT_SPD` would need to be changed back 5727 to `PETSC_BOOL3_UNKNOWN` because the matrix values had changed so the code cannot be certain that the related property had 5728 not changed. 5729 5730 Level: intermediate 5731 5732 .seealso: `MatOption`, `Mat`, `MatGetOption()` 5733 @*/ 5734 PetscErrorCode MatSetOption(Mat mat, MatOption op, PetscBool flg) { 5735 PetscFunctionBegin; 5736 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5737 if (op > 0) { 5738 PetscValidLogicalCollectiveEnum(mat, op, 2); 5739 PetscValidLogicalCollectiveBool(mat, flg, 3); 5740 } 5741 5742 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); 5743 5744 switch (op) { 5745 case MAT_FORCE_DIAGONAL_ENTRIES: mat->force_diagonals = flg; PetscFunctionReturn(0); 5746 case MAT_NO_OFF_PROC_ENTRIES: mat->nooffprocentries = flg; PetscFunctionReturn(0); 5747 case MAT_SUBSET_OFF_PROC_ENTRIES: 5748 mat->assembly_subset = flg; 5749 if (!mat->assembly_subset) { /* See the same logic in VecAssembly wrt VEC_SUBSET_OFF_PROC_ENTRIES */ 5750 #if !defined(PETSC_HAVE_MPIUNI) 5751 PetscCall(MatStashScatterDestroy_BTS(&mat->stash)); 5752 #endif 5753 mat->stash.first_assembly_done = PETSC_FALSE; 5754 } 5755 PetscFunctionReturn(0); 5756 case MAT_NO_OFF_PROC_ZERO_ROWS: mat->nooffproczerorows = flg; PetscFunctionReturn(0); 5757 case MAT_SPD: 5758 if (flg) { 5759 mat->spd = PETSC_BOOL3_TRUE; 5760 mat->symmetric = PETSC_BOOL3_TRUE; 5761 mat->structurally_symmetric = PETSC_BOOL3_TRUE; 5762 } else { 5763 mat->spd = PETSC_BOOL3_FALSE; 5764 } 5765 break; 5766 case MAT_SYMMETRIC: 5767 mat->symmetric = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5768 if (flg) mat->structurally_symmetric = PETSC_BOOL3_TRUE; 5769 #if !defined(PETSC_USE_COMPLEX) 5770 mat->hermitian = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5771 #endif 5772 break; 5773 case MAT_HERMITIAN: 5774 mat->hermitian = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5775 if (flg) mat->structurally_symmetric = PETSC_BOOL3_TRUE; 5776 #if !defined(PETSC_USE_COMPLEX) 5777 mat->symmetric = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5778 #endif 5779 break; 5780 case MAT_STRUCTURALLY_SYMMETRIC: mat->structurally_symmetric = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; break; 5781 case MAT_SYMMETRY_ETERNAL: 5782 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"); 5783 mat->symmetry_eternal = flg; 5784 if (flg) mat->structural_symmetry_eternal = PETSC_TRUE; 5785 break; 5786 case MAT_STRUCTURAL_SYMMETRY_ETERNAL: 5787 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"); 5788 mat->structural_symmetry_eternal = flg; 5789 break; 5790 case MAT_SPD_ETERNAL: 5791 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"); 5792 mat->spd_eternal = flg; 5793 if (flg) { 5794 mat->structural_symmetry_eternal = PETSC_TRUE; 5795 mat->symmetry_eternal = PETSC_TRUE; 5796 } 5797 break; 5798 case MAT_STRUCTURE_ONLY: mat->structure_only = flg; break; 5799 case MAT_SORTED_FULL: mat->sortedfull = flg; break; 5800 default: break; 5801 } 5802 PetscTryTypeMethod(mat, setoption, op, flg); 5803 PetscFunctionReturn(0); 5804 } 5805 5806 /*@ 5807 MatGetOption - Gets a parameter option that has been set for a matrix. 5808 5809 Logically Collective on mat 5810 5811 Input Parameters: 5812 + mat - the matrix 5813 - option - the option, this only responds to certain options, check the code for which ones 5814 5815 Output Parameter: 5816 . flg - turn the option on (`PETSC_TRUE`) or off (`PETSC_FALSE`) 5817 5818 Notes: 5819 Can only be called after `MatSetSizes()` and `MatSetType()` have been set. 5820 5821 Certain option values may be unknown, for those use the routines `MatIsSymmetric()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, or 5822 `MatIsSymmetricKnown()`, `MatIsHermitianKnown()`, `MatIsStructurallySymmetricKnown()` 5823 5824 Level: intermediate 5825 5826 .seealso: `MatOption`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, 5827 `MatIsSymmetricKnown()`, `MatIsHermitianKnown()`, `MatIsStructurallySymmetricKnown()` 5828 @*/ 5829 PetscErrorCode MatGetOption(Mat mat, MatOption op, PetscBool *flg) { 5830 PetscFunctionBegin; 5831 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5832 PetscValidType(mat, 1); 5833 5834 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); 5835 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()"); 5836 5837 switch (op) { 5838 case MAT_NO_OFF_PROC_ENTRIES: *flg = mat->nooffprocentries; break; 5839 case MAT_NO_OFF_PROC_ZERO_ROWS: *flg = mat->nooffproczerorows; break; 5840 case MAT_SYMMETRIC: SETERRQ(PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Use MatIsSymmetric() or MatIsSymmetricKnown()"); break; 5841 case MAT_HERMITIAN: SETERRQ(PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Use MatIsHermitian() or MatIsHermitianKnown()"); break; 5842 case MAT_STRUCTURALLY_SYMMETRIC: SETERRQ(PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Use MatIsStructurallySymmetric() or MatIsStructurallySymmetricKnown()"); break; 5843 case MAT_SPD: SETERRQ(PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Use MatIsSPDKnown()"); break; 5844 case MAT_SYMMETRY_ETERNAL: *flg = mat->symmetry_eternal; break; 5845 case MAT_STRUCTURAL_SYMMETRY_ETERNAL: *flg = mat->symmetry_eternal; break; 5846 default: break; 5847 } 5848 PetscFunctionReturn(0); 5849 } 5850 5851 /*@ 5852 MatZeroEntries - Zeros all entries of a matrix. For sparse matrices 5853 this routine retains the old nonzero structure. 5854 5855 Logically Collective on mat 5856 5857 Input Parameters: 5858 . mat - the matrix 5859 5860 Level: intermediate 5861 5862 Note: 5863 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. 5864 See the Performance chapter of the users manual for information on preallocating matrices. 5865 5866 .seealso: `Mat`, `MatZeroRows()`, `MatZeroRowsColumns()` 5867 @*/ 5868 PetscErrorCode MatZeroEntries(Mat mat) { 5869 PetscFunctionBegin; 5870 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5871 PetscValidType(mat, 1); 5872 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 5873 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"); 5874 MatCheckPreallocated(mat, 1); 5875 5876 PetscCall(PetscLogEventBegin(MAT_ZeroEntries, mat, 0, 0, 0)); 5877 PetscUseTypeMethod(mat, zeroentries); 5878 PetscCall(PetscLogEventEnd(MAT_ZeroEntries, mat, 0, 0, 0)); 5879 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5880 PetscFunctionReturn(0); 5881 } 5882 5883 /*@ 5884 MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal) 5885 of a set of rows and columns of a matrix. 5886 5887 Collective on mat 5888 5889 Input Parameters: 5890 + mat - the matrix 5891 . numRows - the number of rows to remove 5892 . rows - the global row indices 5893 . diag - value put in the diagonal of the eliminated rows 5894 . x - optional vector of solutions for zeroed rows (other entries in vector are not used), these must be set before this call 5895 - b - optional vector of right hand side, that will be adjusted by provided solution 5896 5897 Notes: 5898 This routine, along with `MatZeroRows()`, is typically used to eliminate known Dirichlet boundary conditions from a linear system. 5899 5900 For each zeroed row, the value of the corresponding b is set to diag times the value of the corresponding x. 5901 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 5902 5903 If the resulting linear system is to be solved with `KSP` then one can (but does not have to) call `KSPSetInitialGuessNonzero()` to allow the 5904 Krylov method to take advantage of the known solution on the zeroed rows. 5905 5906 For the parallel case, all processes that share the matrix (i.e., 5907 those in the communicator used for matrix creation) MUST call this 5908 routine, regardless of whether any rows being zeroed are owned by 5909 them. 5910 5911 Unlike `MatZeroRows()` this does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5912 5913 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5914 list only rows local to itself). 5915 5916 The option `MAT_NO_OFF_PROC_ZERO_ROWS` does not apply to this routine. 5917 5918 Level: intermediate 5919 5920 .seealso: `MatZeroRowsIS()`, `MatZeroRows()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 5921 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 5922 @*/ 5923 PetscErrorCode MatZeroRowsColumns(Mat mat, PetscInt numRows, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) { 5924 PetscFunctionBegin; 5925 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5926 PetscValidType(mat, 1); 5927 if (numRows) PetscValidIntPointer(rows, 3); 5928 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 5929 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 5930 MatCheckPreallocated(mat, 1); 5931 5932 PetscUseTypeMethod(mat, zerorowscolumns, numRows, rows, diag, x, b); 5933 PetscCall(MatViewFromOptions(mat, NULL, "-mat_view")); 5934 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5935 PetscFunctionReturn(0); 5936 } 5937 5938 /*@ 5939 MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal) 5940 of a set of rows and columns of a matrix. 5941 5942 Collective on mat 5943 5944 Input Parameters: 5945 + mat - the matrix 5946 . is - the rows to zero 5947 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5948 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5949 - b - optional vector of right hand side, that will be adjusted by provided solution 5950 5951 Note: 5952 See `MatZeroRowsColumns()` for details on how this routine operates. 5953 5954 Level: intermediate 5955 5956 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 5957 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRows()`, `MatZeroRowsColumnsStencil()` 5958 @*/ 5959 PetscErrorCode MatZeroRowsColumnsIS(Mat mat, IS is, PetscScalar diag, Vec x, Vec b) { 5960 PetscInt numRows; 5961 const PetscInt *rows; 5962 5963 PetscFunctionBegin; 5964 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5965 PetscValidHeaderSpecific(is, IS_CLASSID, 2); 5966 PetscValidType(mat, 1); 5967 PetscValidType(is, 2); 5968 PetscCall(ISGetLocalSize(is, &numRows)); 5969 PetscCall(ISGetIndices(is, &rows)); 5970 PetscCall(MatZeroRowsColumns(mat, numRows, rows, diag, x, b)); 5971 PetscCall(ISRestoreIndices(is, &rows)); 5972 PetscFunctionReturn(0); 5973 } 5974 5975 /*@ 5976 MatZeroRows - Zeros all entries (except possibly the main diagonal) 5977 of a set of rows of a matrix. 5978 5979 Collective on mat 5980 5981 Input Parameters: 5982 + mat - the matrix 5983 . numRows - the number of rows to remove 5984 . rows - the global row indices 5985 . diag - value put in the diagonal of the eliminated rows 5986 . x - optional vector of solutions for zeroed rows (other entries in vector are not used), these must be set before this call 5987 - b - optional vector of right hand side, that will be adjusted by provided solution 5988 5989 Notes: 5990 This routine, along with `MatZeroRowsColumns()`, is typically used to eliminate known Dirichlet boundary conditions from a linear system. 5991 5992 For each zeroed row, the value of the corresponding b is set to diag times the value of the corresponding x. 5993 5994 If the resulting linear system is to be solved with `KSP` then one can (but does not have to) call `KSPSetInitialGuessNonzero()` to allow the 5995 Krylov method to take advantage of the known solution on the zeroed rows. 5996 5997 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) 5998 from the matrix. 5999 6000 Unlike `MatZeroRowsColumns()` for the `MATAIJ` and `MATBAIJ` matrix formats this removes the old nonzero structure, from the eliminated rows of the matrix 6001 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 6002 formats this does not alter the nonzero structure. 6003 6004 If the option `MatSetOption`(mat,`MAT_KEEP_NONZERO_PATTERN`,`PETSC_TRUE`) the nonzero structure 6005 of the matrix is not changed the values are 6006 merely zeroed. 6007 6008 The user can set a value in the diagonal entry (or for the `MATAIJ` format 6009 formats can optionally remove the main diagonal entry from the 6010 nonzero structure as well, by passing 0.0 as the final argument). 6011 6012 For the parallel case, all processes that share the matrix (i.e., 6013 those in the communicator used for matrix creation) MUST call this 6014 routine, regardless of whether any rows being zeroed are owned by 6015 them. 6016 6017 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6018 list only rows local to itself). 6019 6020 You can call `MatSetOption`(mat,`MAT_NO_OFF_PROC_ZERO_ROWS`,`PETSC_TRUE`) if each process indicates only rows it 6021 owns that are to be zeroed. This saves a global synchronization in the implementation. 6022 6023 Level: intermediate 6024 6025 .seealso: `Mat`, `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6026 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()`, `PCREDISTRIBUTE` 6027 @*/ 6028 PetscErrorCode MatZeroRows(Mat mat, PetscInt numRows, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) { 6029 PetscFunctionBegin; 6030 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6031 PetscValidType(mat, 1); 6032 if (numRows) PetscValidIntPointer(rows, 3); 6033 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 6034 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 6035 MatCheckPreallocated(mat, 1); 6036 6037 PetscUseTypeMethod(mat, zerorows, numRows, rows, diag, x, b); 6038 PetscCall(MatViewFromOptions(mat, NULL, "-mat_view")); 6039 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6040 PetscFunctionReturn(0); 6041 } 6042 6043 /*@ 6044 MatZeroRowsIS - Zeros all entries (except possibly the main diagonal) 6045 of a set of rows of a matrix. 6046 6047 Collective on Mat 6048 6049 Input Parameters: 6050 + mat - the matrix 6051 . is - index set of rows to remove (if NULL then no row is removed) 6052 . diag - value put in all diagonals of eliminated rows 6053 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6054 - b - optional vector of right hand side, that will be adjusted by provided solution 6055 6056 Note: 6057 See `MatZeroRows()` for details on how this routine operates. 6058 6059 Level: intermediate 6060 6061 .seealso: `MatZeroRows()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6062 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6063 @*/ 6064 PetscErrorCode MatZeroRowsIS(Mat mat, IS is, PetscScalar diag, Vec x, Vec b) { 6065 PetscInt numRows = 0; 6066 const PetscInt *rows = NULL; 6067 6068 PetscFunctionBegin; 6069 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6070 PetscValidType(mat, 1); 6071 if (is) { 6072 PetscValidHeaderSpecific(is, IS_CLASSID, 2); 6073 PetscCall(ISGetLocalSize(is, &numRows)); 6074 PetscCall(ISGetIndices(is, &rows)); 6075 } 6076 PetscCall(MatZeroRows(mat, numRows, rows, diag, x, b)); 6077 if (is) PetscCall(ISRestoreIndices(is, &rows)); 6078 PetscFunctionReturn(0); 6079 } 6080 6081 /*@ 6082 MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal) 6083 of a set of rows of a matrix. These rows must be local to the process. 6084 6085 Collective on mat 6086 6087 Input Parameters: 6088 + mat - the matrix 6089 . numRows - the number of rows to remove 6090 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 6091 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6092 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6093 - b - optional vector of right hand side, that will be adjusted by provided solution 6094 6095 Notes: 6096 See `MatZeroRows()` for details on how this routine operates. 6097 6098 The grid coordinates are across the entire grid, not just the local portion 6099 6100 In Fortran idxm and idxn should be declared as 6101 $ MatStencil idxm(4,m) 6102 and the values inserted using 6103 $ idxm(MatStencil_i,1) = i 6104 $ idxm(MatStencil_j,1) = j 6105 $ idxm(MatStencil_k,1) = k 6106 $ idxm(MatStencil_c,1) = c 6107 etc 6108 6109 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6110 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6111 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6112 `DM_BOUNDARY_PERIODIC` boundary type. 6113 6114 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 6115 a single value per point) you can skip filling those indices. 6116 6117 Level: intermediate 6118 6119 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsl()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6120 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6121 @*/ 6122 PetscErrorCode MatZeroRowsStencil(Mat mat, PetscInt numRows, const MatStencil rows[], PetscScalar diag, Vec x, Vec b) { 6123 PetscInt dim = mat->stencil.dim; 6124 PetscInt sdim = dim - (1 - (PetscInt)mat->stencil.noc); 6125 PetscInt *dims = mat->stencil.dims + 1; 6126 PetscInt *starts = mat->stencil.starts; 6127 PetscInt *dxm = (PetscInt *)rows; 6128 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6129 6130 PetscFunctionBegin; 6131 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6132 PetscValidType(mat, 1); 6133 if (numRows) PetscValidPointer(rows, 3); 6134 6135 PetscCall(PetscMalloc1(numRows, &jdxm)); 6136 for (i = 0; i < numRows; ++i) { 6137 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6138 for (j = 0; j < 3 - sdim; ++j) dxm++; 6139 /* Local index in X dir */ 6140 tmp = *dxm++ - starts[0]; 6141 /* Loop over remaining dimensions */ 6142 for (j = 0; j < dim - 1; ++j) { 6143 /* If nonlocal, set index to be negative */ 6144 if ((*dxm++ - starts[j + 1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6145 /* Update local index */ 6146 else tmp = tmp * dims[j] + *(dxm - 1) - starts[j + 1]; 6147 } 6148 /* Skip component slot if necessary */ 6149 if (mat->stencil.noc) dxm++; 6150 /* Local row number */ 6151 if (tmp >= 0) jdxm[numNewRows++] = tmp; 6152 } 6153 PetscCall(MatZeroRowsLocal(mat, numNewRows, jdxm, diag, x, b)); 6154 PetscCall(PetscFree(jdxm)); 6155 PetscFunctionReturn(0); 6156 } 6157 6158 /*@ 6159 MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal) 6160 of a set of rows and columns of a matrix. 6161 6162 Collective on mat 6163 6164 Input Parameters: 6165 + mat - the matrix 6166 . numRows - the number of rows/columns to remove 6167 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 6168 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6169 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6170 - b - optional vector of right hand side, that will be adjusted by provided solution 6171 6172 Notes: 6173 See `MatZeroRowsColumns()` for details on how this routine operates. 6174 6175 The grid coordinates are across the entire grid, not just the local portion 6176 6177 In Fortran idxm and idxn should be declared as 6178 $ MatStencil idxm(4,m) 6179 and the values inserted using 6180 $ idxm(MatStencil_i,1) = i 6181 $ idxm(MatStencil_j,1) = j 6182 $ idxm(MatStencil_k,1) = k 6183 $ idxm(MatStencil_c,1) = c 6184 etc 6185 6186 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6187 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6188 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6189 `DM_BOUNDARY_PERIODIC` boundary type. 6190 6191 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 6192 a single value per point) you can skip filling those indices. 6193 6194 Level: intermediate 6195 6196 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6197 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRows()` 6198 @*/ 6199 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat, PetscInt numRows, const MatStencil rows[], PetscScalar diag, Vec x, Vec b) { 6200 PetscInt dim = mat->stencil.dim; 6201 PetscInt sdim = dim - (1 - (PetscInt)mat->stencil.noc); 6202 PetscInt *dims = mat->stencil.dims + 1; 6203 PetscInt *starts = mat->stencil.starts; 6204 PetscInt *dxm = (PetscInt *)rows; 6205 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6206 6207 PetscFunctionBegin; 6208 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6209 PetscValidType(mat, 1); 6210 if (numRows) PetscValidPointer(rows, 3); 6211 6212 PetscCall(PetscMalloc1(numRows, &jdxm)); 6213 for (i = 0; i < numRows; ++i) { 6214 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6215 for (j = 0; j < 3 - sdim; ++j) dxm++; 6216 /* Local index in X dir */ 6217 tmp = *dxm++ - starts[0]; 6218 /* Loop over remaining dimensions */ 6219 for (j = 0; j < dim - 1; ++j) { 6220 /* If nonlocal, set index to be negative */ 6221 if ((*dxm++ - starts[j + 1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6222 /* Update local index */ 6223 else tmp = tmp * dims[j] + *(dxm - 1) - starts[j + 1]; 6224 } 6225 /* Skip component slot if necessary */ 6226 if (mat->stencil.noc) dxm++; 6227 /* Local row number */ 6228 if (tmp >= 0) jdxm[numNewRows++] = tmp; 6229 } 6230 PetscCall(MatZeroRowsColumnsLocal(mat, numNewRows, jdxm, diag, x, b)); 6231 PetscCall(PetscFree(jdxm)); 6232 PetscFunctionReturn(0); 6233 } 6234 6235 /*@C 6236 MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal) 6237 of a set of rows of a matrix; using local numbering of rows. 6238 6239 Collective on mat 6240 6241 Input Parameters: 6242 + mat - the matrix 6243 . numRows - the number of rows to remove 6244 . rows - the local row indices 6245 . diag - value put in all diagonals of eliminated rows 6246 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6247 - b - optional vector of right hand side, that will be adjusted by provided solution 6248 6249 Notes: 6250 Before calling `MatZeroRowsLocal()`, the user must first set the 6251 local-to-global mapping by calling MatSetLocalToGlobalMapping(), this is often already set for matrices obtained with `DMCreateMatrix()`. 6252 6253 See `MatZeroRows()` for details on how this routine operates. 6254 6255 Level: intermediate 6256 6257 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRows()`, `MatSetOption()`, 6258 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6259 @*/ 6260 PetscErrorCode MatZeroRowsLocal(Mat mat, PetscInt numRows, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) { 6261 PetscFunctionBegin; 6262 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6263 PetscValidType(mat, 1); 6264 if (numRows) PetscValidIntPointer(rows, 3); 6265 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 6266 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 6267 MatCheckPreallocated(mat, 1); 6268 6269 if (mat->ops->zerorowslocal) { 6270 PetscUseTypeMethod(mat, zerorowslocal, numRows, rows, diag, x, b); 6271 } else { 6272 IS is, newis; 6273 const PetscInt *newRows; 6274 6275 PetscCheck(mat->rmap->mapping, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Need to provide local to global mapping to matrix first"); 6276 PetscCall(ISCreateGeneral(PETSC_COMM_SELF, numRows, rows, PETSC_COPY_VALUES, &is)); 6277 PetscCall(ISLocalToGlobalMappingApplyIS(mat->rmap->mapping, is, &newis)); 6278 PetscCall(ISGetIndices(newis, &newRows)); 6279 PetscUseTypeMethod(mat, zerorows, numRows, newRows, diag, x, b); 6280 PetscCall(ISRestoreIndices(newis, &newRows)); 6281 PetscCall(ISDestroy(&newis)); 6282 PetscCall(ISDestroy(&is)); 6283 } 6284 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6285 PetscFunctionReturn(0); 6286 } 6287 6288 /*@ 6289 MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal) 6290 of a set of rows of a matrix; using local numbering of rows. 6291 6292 Collective on mat 6293 6294 Input Parameters: 6295 + mat - the matrix 6296 . is - index set of rows to remove 6297 . diag - value put in all diagonals of eliminated rows 6298 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6299 - b - optional vector of right hand side, that will be adjusted by provided solution 6300 6301 Notes: 6302 Before calling `MatZeroRowsLocalIS()`, the user must first set the 6303 local-to-global mapping by calling `MatSetLocalToGlobalMapping()`, this is often already set for matrices obtained with `DMCreateMatrix()`. 6304 6305 See `MatZeroRows()` for details on how this routine operates. 6306 6307 Level: intermediate 6308 6309 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRows()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6310 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6311 @*/ 6312 PetscErrorCode MatZeroRowsLocalIS(Mat mat, IS is, PetscScalar diag, Vec x, Vec b) { 6313 PetscInt numRows; 6314 const PetscInt *rows; 6315 6316 PetscFunctionBegin; 6317 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6318 PetscValidType(mat, 1); 6319 PetscValidHeaderSpecific(is, IS_CLASSID, 2); 6320 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 6321 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 6322 MatCheckPreallocated(mat, 1); 6323 6324 PetscCall(ISGetLocalSize(is, &numRows)); 6325 PetscCall(ISGetIndices(is, &rows)); 6326 PetscCall(MatZeroRowsLocal(mat, numRows, rows, diag, x, b)); 6327 PetscCall(ISRestoreIndices(is, &rows)); 6328 PetscFunctionReturn(0); 6329 } 6330 6331 /*@ 6332 MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal) 6333 of a set of rows and columns of a matrix; using local numbering of rows. 6334 6335 Collective on mat 6336 6337 Input Parameters: 6338 + mat - the matrix 6339 . numRows - the number of rows to remove 6340 . rows - the global row indices 6341 . diag - value put in all diagonals of eliminated rows 6342 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6343 - b - optional vector of right hand side, that will be adjusted by provided solution 6344 6345 Notes: 6346 Before calling `MatZeroRowsColumnsLocal()`, the user must first set the 6347 local-to-global mapping by calling `MatSetLocalToGlobalMapping()`, this is often already set for matrices obtained with `DMCreateMatrix()`. 6348 6349 See `MatZeroRowsColumns()` for details on how this routine operates. 6350 6351 Level: intermediate 6352 6353 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6354 `MatZeroRows()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6355 @*/ 6356 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat, PetscInt numRows, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) { 6357 IS is, newis; 6358 const PetscInt *newRows; 6359 6360 PetscFunctionBegin; 6361 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6362 PetscValidType(mat, 1); 6363 if (numRows) PetscValidIntPointer(rows, 3); 6364 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 6365 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 6366 MatCheckPreallocated(mat, 1); 6367 6368 PetscCheck(mat->cmap->mapping, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Need to provide local to global mapping to matrix first"); 6369 PetscCall(ISCreateGeneral(PETSC_COMM_SELF, numRows, rows, PETSC_COPY_VALUES, &is)); 6370 PetscCall(ISLocalToGlobalMappingApplyIS(mat->cmap->mapping, is, &newis)); 6371 PetscCall(ISGetIndices(newis, &newRows)); 6372 PetscUseTypeMethod(mat, zerorowscolumns, numRows, newRows, diag, x, b); 6373 PetscCall(ISRestoreIndices(newis, &newRows)); 6374 PetscCall(ISDestroy(&newis)); 6375 PetscCall(ISDestroy(&is)); 6376 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6377 PetscFunctionReturn(0); 6378 } 6379 6380 /*@ 6381 MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal) 6382 of a set of rows and columns of a matrix; using local numbering of rows. 6383 6384 Collective on Mat 6385 6386 Input Parameters: 6387 + mat - the matrix 6388 . is - index set of rows to remove 6389 . diag - value put in all diagonals of eliminated rows 6390 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6391 - b - optional vector of right hand side, that will be adjusted by provided solution 6392 6393 Notes: 6394 Before calling `MatZeroRowsColumnsLocalIS()`, the user must first set the 6395 local-to-global mapping by calling `MatSetLocalToGlobalMapping()`, this is often already set for matrices obtained with `DMCreateMatrix()`. 6396 6397 See `MatZeroRowsColumns()` for details on how this routine operates. 6398 6399 Level: intermediate 6400 6401 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6402 `MatZeroRowsColumnsLocal()`, `MatZeroRows()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6403 @*/ 6404 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat, IS is, PetscScalar diag, Vec x, Vec b) { 6405 PetscInt numRows; 6406 const PetscInt *rows; 6407 6408 PetscFunctionBegin; 6409 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6410 PetscValidType(mat, 1); 6411 PetscValidHeaderSpecific(is, IS_CLASSID, 2); 6412 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 6413 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 6414 MatCheckPreallocated(mat, 1); 6415 6416 PetscCall(ISGetLocalSize(is, &numRows)); 6417 PetscCall(ISGetIndices(is, &rows)); 6418 PetscCall(MatZeroRowsColumnsLocal(mat, numRows, rows, diag, x, b)); 6419 PetscCall(ISRestoreIndices(is, &rows)); 6420 PetscFunctionReturn(0); 6421 } 6422 6423 /*@C 6424 MatGetSize - Returns the numbers of rows and columns in a matrix. 6425 6426 Not Collective 6427 6428 Input Parameter: 6429 . mat - the matrix 6430 6431 Output Parameters: 6432 + m - the number of global rows 6433 - n - the number of global columns 6434 6435 Note: both output parameters can be NULL on input. 6436 6437 Level: beginner 6438 6439 .seealso: `Mat`, `MatSetSizes()`, `MatGetLocalSize()` 6440 @*/ 6441 PetscErrorCode MatGetSize(Mat mat, PetscInt *m, PetscInt *n) { 6442 PetscFunctionBegin; 6443 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6444 if (m) *m = mat->rmap->N; 6445 if (n) *n = mat->cmap->N; 6446 PetscFunctionReturn(0); 6447 } 6448 6449 /*@C 6450 MatGetLocalSize - For most matrix formats, excluding `MATELEMENTAL` and `MATSCALAPACK`, Returns the number of local rows and local columns 6451 of a matrix. For all matrices this is the local size of the left and right vectors as returned by `MatCreateVecs()`. 6452 6453 Not Collective 6454 6455 Input Parameter: 6456 . mat - the matrix 6457 6458 Output Parameters: 6459 + m - the number of local rows, use `NULL` to not obtain this value 6460 - n - the number of local columns, use `NULL` to not obtain this value 6461 6462 Level: beginner 6463 6464 .seealso: `Mat`, `MatSetSizes()`, `MatGetSize()` 6465 @*/ 6466 PetscErrorCode MatGetLocalSize(Mat mat, PetscInt *m, PetscInt *n) { 6467 PetscFunctionBegin; 6468 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6469 if (m) PetscValidIntPointer(m, 2); 6470 if (n) PetscValidIntPointer(n, 3); 6471 if (m) *m = mat->rmap->n; 6472 if (n) *n = mat->cmap->n; 6473 PetscFunctionReturn(0); 6474 } 6475 6476 /*@C 6477 MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies this matrix by that are owned by 6478 this processor. (The columns of the "diagonal block" for most sparse matrix formats). See :any:`<sec_matlayout>` for details on matrix layouts. 6479 6480 Not Collective, unless matrix has not been allocated, then collective on mat 6481 6482 Input Parameter: 6483 . mat - the matrix 6484 6485 Output Parameters: 6486 + m - the global index of the first local column, use `NULL` to not obtain this value 6487 - n - one more than the global index of the last local column, use `NULL` to not obtain this value 6488 6489 Level: developer 6490 6491 .seealso: `Mat`, `MatGetOwnershipRange()`, `MatGetOwnershipRanges()`, `MatGetOwnershipRangesColumn()`, `PetscLayout` 6492 @*/ 6493 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat, PetscInt *m, PetscInt *n) { 6494 PetscFunctionBegin; 6495 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6496 PetscValidType(mat, 1); 6497 if (m) PetscValidIntPointer(m, 2); 6498 if (n) PetscValidIntPointer(n, 3); 6499 MatCheckPreallocated(mat, 1); 6500 if (m) *m = mat->cmap->rstart; 6501 if (n) *n = mat->cmap->rend; 6502 PetscFunctionReturn(0); 6503 } 6504 6505 /*@C 6506 MatGetOwnershipRange - For matrices that own values by row, excludes `MATELEMENTAL` and `MATSCALAPACK`, returns the range of matrix rows owned by 6507 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 6508 vector product with this matrix. See :any:`<sec_matlayout>` for details on matrix layouts 6509 6510 Not Collective 6511 6512 Input Parameter: 6513 . mat - the matrix 6514 6515 Output Parameters: 6516 + m - the global index of the first local row, use `NULL` to not obtain this value 6517 - n - one more than the global index of the last local row, use `NULL` to not obtain this value 6518 6519 Note: 6520 This function requires that the matrix be preallocated. If you have not preallocated, consider using 6521 `PetscSplitOwnership`(`MPI_Comm` comm, `PetscInt` *n, `PetscInt` *N) 6522 and then `MPI_Scan()` to calculate prefix sums of the local sizes. 6523 6524 Level: beginner 6525 6526 .seealso: `MatGetOwnershipRanges()`, `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRangesColumn()`, `PetscSplitOwnership()`, `PetscSplitOwnershipBlock()`, 6527 `PetscLayout` 6528 @*/ 6529 PetscErrorCode MatGetOwnershipRange(Mat mat, PetscInt *m, PetscInt *n) { 6530 PetscFunctionBegin; 6531 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6532 PetscValidType(mat, 1); 6533 if (m) PetscValidIntPointer(m, 2); 6534 if (n) PetscValidIntPointer(n, 3); 6535 MatCheckPreallocated(mat, 1); 6536 if (m) *m = mat->rmap->rstart; 6537 if (n) *n = mat->rmap->rend; 6538 PetscFunctionReturn(0); 6539 } 6540 6541 /*@C 6542 MatGetOwnershipRanges - For matrices that own values by row, excludes `MATELEMENTAL` and `MATSCALAPACK`, returns the range of matrix rows owned by 6543 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 6544 vector product with this matrix. See :any:`<sec_matlayout>` for details on matrix layouts 6545 6546 Not Collective, unless matrix has not been allocated, then collective on mat 6547 6548 Input Parameters: 6549 . mat - the matrix 6550 6551 Output Parameters: 6552 . ranges - start of each processors portion plus one more than the total length at the end 6553 6554 Level: beginner 6555 6556 .seealso: `Mat`, `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRangesColumn()`, `PetscLayout` 6557 @*/ 6558 PetscErrorCode MatGetOwnershipRanges(Mat mat, const PetscInt **ranges) { 6559 PetscFunctionBegin; 6560 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6561 PetscValidType(mat, 1); 6562 MatCheckPreallocated(mat, 1); 6563 PetscCall(PetscLayoutGetRanges(mat->rmap, ranges)); 6564 PetscFunctionReturn(0); 6565 } 6566 6567 /*@C 6568 MatGetOwnershipRangesColumn - Returns the ranges of matrix columns associated with rows of a vector one multiplies this vector by that are owned by 6569 each processor. (The columns of the "diagonal blocks", for most sparse matrix formats). See :any:`<sec_matlayout>` for details on matrix layouts. 6570 6571 Not Collective, unless matrix has not been allocated, then collective on Mat 6572 6573 Input Parameters: 6574 . mat - the matrix 6575 6576 Output Parameters: 6577 . ranges - start of each processors portion plus one more then the total length at the end 6578 6579 Level: beginner 6580 6581 .seealso: `Mat`, `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRanges()` 6582 @*/ 6583 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat, const PetscInt **ranges) { 6584 PetscFunctionBegin; 6585 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6586 PetscValidType(mat, 1); 6587 MatCheckPreallocated(mat, 1); 6588 PetscCall(PetscLayoutGetRanges(mat->cmap, ranges)); 6589 PetscFunctionReturn(0); 6590 } 6591 6592 /*@C 6593 MatGetOwnershipIS - Get row and column ownership of a matrices' values as index sets. For most matrices, excluding `MATELEMENTAL` and `MATSCALAPACK`, this 6594 corresponds to values returned by `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`. For `MATELEMENTAL` and `MATSCALAPACK` the ownership 6595 is more complicated. See :any:`<sec_matlayout>` for details on matrix layouts. 6596 6597 Not Collective 6598 6599 Input Parameter: 6600 . A - matrix 6601 6602 Output Parameters: 6603 + rows - rows in which this process owns elements, , use `NULL` to not obtain this value 6604 - cols - columns in which this process owns elements, use `NULL` to not obtain this value 6605 6606 Level: intermediate 6607 6608 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`, `MatSetValues()`, ``MATELEMENTAL``, ``MATSCALAPACK`` 6609 @*/ 6610 PetscErrorCode MatGetOwnershipIS(Mat A, IS *rows, IS *cols) { 6611 PetscErrorCode (*f)(Mat, IS *, IS *); 6612 6613 PetscFunctionBegin; 6614 MatCheckPreallocated(A, 1); 6615 PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatGetOwnershipIS_C", &f)); 6616 if (f) { 6617 PetscCall((*f)(A, rows, cols)); 6618 } else { /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */ 6619 if (rows) PetscCall(ISCreateStride(PETSC_COMM_SELF, A->rmap->n, A->rmap->rstart, 1, rows)); 6620 if (cols) PetscCall(ISCreateStride(PETSC_COMM_SELF, A->cmap->N, 0, 1, cols)); 6621 } 6622 PetscFunctionReturn(0); 6623 } 6624 6625 /*@C 6626 MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix obtained with `MatGetFactor()` 6627 Uses levels of fill only, not drop tolerance. Use `MatLUFactorNumeric()` 6628 to complete the factorization. 6629 6630 Collective on fact 6631 6632 Input Parameters: 6633 + fact - the factorized matrix obtained with `MatGetFactor()` 6634 . mat - the matrix 6635 . row - row permutation 6636 . column - column permutation 6637 - info - structure containing 6638 $ levels - number of levels of fill. 6639 $ expected fill - as ratio of original fill. 6640 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 6641 missing diagonal entries) 6642 6643 Output Parameters: 6644 . fact - new matrix that has been symbolically factored 6645 6646 Level: developer 6647 6648 Notes: 6649 See [Matrix Factorization](sec_matfactor) for additional information. 6650 6651 Most users should employ the `KSP` interface for linear solvers 6652 instead of working directly with matrix algebra routines such as this. 6653 See, e.g., `KSPCreate()`. 6654 6655 Uses the definition of level of fill as in Y. Saad, 2003 6656 6657 Developer Note: 6658 The Fortran interface is not autogenerated as the f90 6659 interface definition cannot be generated correctly [due to `MatFactorInfo`] 6660 6661 References: 6662 . * - Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6663 6664 .seealso: [Matrix Factorization](sec_matfactor), `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()` 6665 `MatGetOrdering()`, `MatFactorInfo` 6666 @*/ 6667 PetscErrorCode MatILUFactorSymbolic(Mat fact, Mat mat, IS row, IS col, const MatFactorInfo *info) { 6668 PetscFunctionBegin; 6669 PetscValidHeaderSpecific(mat, MAT_CLASSID, 2); 6670 PetscValidType(mat, 2); 6671 if (row) PetscValidHeaderSpecific(row, IS_CLASSID, 3); 6672 if (col) PetscValidHeaderSpecific(col, IS_CLASSID, 4); 6673 PetscValidPointer(info, 5); 6674 PetscValidPointer(fact, 1); 6675 PetscCheck(info->levels >= 0, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_OUTOFRANGE, "Levels of fill negative %" PetscInt_FMT, (PetscInt)info->levels); 6676 PetscCheck(info->fill >= 1.0, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_OUTOFRANGE, "Expected fill less than 1.0 %g", (double)info->fill); 6677 if (!fact->ops->ilufactorsymbolic) { 6678 MatSolverType stype; 6679 PetscCall(MatFactorGetSolverType(fact, &stype)); 6680 SETERRQ(PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Matrix type %s symbolic ILU using solver type %s", ((PetscObject)mat)->type_name, stype); 6681 } 6682 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 6683 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 6684 MatCheckPreallocated(mat, 2); 6685 6686 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_ILUFactorSymbolic, mat, row, col, 0)); 6687 PetscCall((fact->ops->ilufactorsymbolic)(fact, mat, row, col, info)); 6688 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_ILUFactorSymbolic, mat, row, col, 0)); 6689 PetscFunctionReturn(0); 6690 } 6691 6692 /*@C 6693 MatICCFactorSymbolic - Performs symbolic incomplete 6694 Cholesky factorization for a symmetric matrix. Use 6695 `MatCholeskyFactorNumeric()` to complete the factorization. 6696 6697 Collective on fact 6698 6699 Input Parameters: 6700 + fact - the factorized matrix obtained with `MatGetFactor()` 6701 . mat - the matrix to be factored 6702 . perm - row and column permutation 6703 - info - structure containing 6704 $ levels - number of levels of fill. 6705 $ expected fill - as ratio of original fill. 6706 6707 Output Parameter: 6708 . fact - the factored matrix 6709 6710 Level: developer 6711 6712 Notes: 6713 Most users should employ the `KSP` interface for linear solvers 6714 instead of working directly with matrix algebra routines such as this. 6715 See, e.g., `KSPCreate()`. 6716 6717 This uses the definition of level of fill as in Y. Saad, 2003 6718 6719 Developer Note: 6720 The Fortran interface is not autogenerated as the f90 6721 interface definition cannot be generated correctly [due to `MatFactorInfo`] 6722 6723 References: 6724 . * - Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6725 6726 .seealso: `MatGetFactor()`, `MatCholeskyFactorNumeric()`, `MatCholeskyFactor()`, `MatFactorInfo` 6727 @*/ 6728 PetscErrorCode MatICCFactorSymbolic(Mat fact, Mat mat, IS perm, const MatFactorInfo *info) { 6729 PetscFunctionBegin; 6730 PetscValidHeaderSpecific(mat, MAT_CLASSID, 2); 6731 PetscValidType(mat, 2); 6732 if (perm) PetscValidHeaderSpecific(perm, IS_CLASSID, 3); 6733 PetscValidPointer(info, 4); 6734 PetscValidPointer(fact, 1); 6735 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 6736 PetscCheck(info->levels >= 0, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_OUTOFRANGE, "Levels negative %" PetscInt_FMT, (PetscInt)info->levels); 6737 PetscCheck(info->fill >= 1.0, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_OUTOFRANGE, "Expected fill less than 1.0 %g", (double)info->fill); 6738 if (!(fact)->ops->iccfactorsymbolic) { 6739 MatSolverType stype; 6740 PetscCall(MatFactorGetSolverType(fact, &stype)); 6741 SETERRQ(PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Matrix type %s symbolic ICC using solver type %s", ((PetscObject)mat)->type_name, stype); 6742 } 6743 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 6744 MatCheckPreallocated(mat, 2); 6745 6746 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_ICCFactorSymbolic, mat, perm, 0, 0)); 6747 PetscCall((fact->ops->iccfactorsymbolic)(fact, mat, perm, info)); 6748 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_ICCFactorSymbolic, mat, perm, 0, 0)); 6749 PetscFunctionReturn(0); 6750 } 6751 6752 /*@C 6753 MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat 6754 points to an array of valid matrices, they may be reused to store the new 6755 submatrices. 6756 6757 Collective on mat 6758 6759 Input Parameters: 6760 + mat - the matrix 6761 . n - the number of submatrixes to be extracted (on this processor, may be zero) 6762 . irow, icol - index sets of rows and columns to extract 6763 - scall - either `MAT_INITIAL_MATRIX` or `MAT_REUSE_MATRIX` 6764 6765 Output Parameter: 6766 . submat - the array of submatrices 6767 6768 Notes: 6769 `MatCreateSubMatrices()` can extract ONLY sequential submatrices 6770 (from both sequential and parallel matrices). Use `MatCreateSubMatrix()` 6771 to extract a parallel submatrix. 6772 6773 Some matrix types place restrictions on the row and column 6774 indices, such as that they be sorted or that they be equal to each other. 6775 6776 The index sets may not have duplicate entries. 6777 6778 When extracting submatrices from a parallel matrix, each processor can 6779 form a different submatrix by setting the rows and columns of its 6780 individual index sets according to the local submatrix desired. 6781 6782 When finished using the submatrices, the user should destroy 6783 them with `MatDestroySubMatrices()`. 6784 6785 `MAT_REUSE_MATRIX` can only be used when the nonzero structure of the 6786 original matrix has not changed from that last call to `MatCreateSubMatrices()`. 6787 6788 This routine creates the matrices in submat; you should NOT create them before 6789 calling it. It also allocates the array of matrix pointers submat. 6790 6791 For `MATBAIJ` matrices the index sets must respect the block structure, that is if they 6792 request one row/column in a block, they must request all rows/columns that are in 6793 that block. For example, if the block size is 2 you cannot request just row 0 and 6794 column 0. 6795 6796 Fortran Note: 6797 The Fortran interface is slightly different from that given below; it 6798 requires one to pass in as submat a `Mat` (integer) array of size at least n+1. 6799 6800 Level: advanced 6801 6802 .seealso: `Mat`, `MatDestroySubMatrices()`, `MatCreateSubMatrix()`, `MatGetRow()`, `MatGetDiagonal()`, `MatReuse` 6803 @*/ 6804 PetscErrorCode MatCreateSubMatrices(Mat mat, PetscInt n, const IS irow[], const IS icol[], MatReuse scall, Mat *submat[]) { 6805 PetscInt i; 6806 PetscBool eq; 6807 6808 PetscFunctionBegin; 6809 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6810 PetscValidType(mat, 1); 6811 if (n) { 6812 PetscValidPointer(irow, 3); 6813 for (i = 0; i < n; i++) PetscValidHeaderSpecific(irow[i], IS_CLASSID, 3); 6814 PetscValidPointer(icol, 4); 6815 for (i = 0; i < n; i++) PetscValidHeaderSpecific(icol[i], IS_CLASSID, 4); 6816 } 6817 PetscValidPointer(submat, 6); 6818 if (n && scall == MAT_REUSE_MATRIX) { 6819 PetscValidPointer(*submat, 6); 6820 for (i = 0; i < n; i++) PetscValidHeaderSpecific((*submat)[i], MAT_CLASSID, 6); 6821 } 6822 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 6823 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 6824 MatCheckPreallocated(mat, 1); 6825 PetscCall(PetscLogEventBegin(MAT_CreateSubMats, mat, 0, 0, 0)); 6826 PetscUseTypeMethod(mat, createsubmatrices, n, irow, icol, scall, submat); 6827 PetscCall(PetscLogEventEnd(MAT_CreateSubMats, mat, 0, 0, 0)); 6828 for (i = 0; i < n; i++) { 6829 (*submat)[i]->factortype = MAT_FACTOR_NONE; /* in case in place factorization was previously done on submatrix */ 6830 PetscCall(ISEqualUnsorted(irow[i], icol[i], &eq)); 6831 if (eq) PetscCall(MatPropagateSymmetryOptions(mat, (*submat)[i])); 6832 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 6833 if (mat->boundtocpu && mat->bindingpropagates) { 6834 PetscCall(MatBindToCPU((*submat)[i], PETSC_TRUE)); 6835 PetscCall(MatSetBindingPropagates((*submat)[i], PETSC_TRUE)); 6836 } 6837 #endif 6838 } 6839 PetscFunctionReturn(0); 6840 } 6841 6842 /*@C 6843 MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of `IS` that may live on subcomms). 6844 6845 Collective on mat 6846 6847 Input Parameters: 6848 + mat - the matrix 6849 . n - the number of submatrixes to be extracted 6850 . irow, icol - index sets of rows and columns to extract 6851 - scall - either `MAT_INITIAL_MATRIX` or `MAT_REUSE_MATRIX` 6852 6853 Output Parameter: 6854 . submat - the array of submatrices 6855 6856 Level: advanced 6857 6858 Note: 6859 This is used by `PCGASM` 6860 6861 .seealso: `PCGASM`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRow()`, `MatGetDiagonal()`, `MatReuse` 6862 @*/ 6863 PetscErrorCode MatCreateSubMatricesMPI(Mat mat, PetscInt n, const IS irow[], const IS icol[], MatReuse scall, Mat *submat[]) { 6864 PetscInt i; 6865 PetscBool eq; 6866 6867 PetscFunctionBegin; 6868 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6869 PetscValidType(mat, 1); 6870 if (n) { 6871 PetscValidPointer(irow, 3); 6872 PetscValidHeaderSpecific(*irow, IS_CLASSID, 3); 6873 PetscValidPointer(icol, 4); 6874 PetscValidHeaderSpecific(*icol, IS_CLASSID, 4); 6875 } 6876 PetscValidPointer(submat, 6); 6877 if (n && scall == MAT_REUSE_MATRIX) { 6878 PetscValidPointer(*submat, 6); 6879 PetscValidHeaderSpecific(**submat, MAT_CLASSID, 6); 6880 } 6881 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 6882 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 6883 MatCheckPreallocated(mat, 1); 6884 6885 PetscCall(PetscLogEventBegin(MAT_CreateSubMats, mat, 0, 0, 0)); 6886 PetscUseTypeMethod(mat, createsubmatricesmpi, n, irow, icol, scall, submat); 6887 PetscCall(PetscLogEventEnd(MAT_CreateSubMats, mat, 0, 0, 0)); 6888 for (i = 0; i < n; i++) { 6889 PetscCall(ISEqualUnsorted(irow[i], icol[i], &eq)); 6890 if (eq) PetscCall(MatPropagateSymmetryOptions(mat, (*submat)[i])); 6891 } 6892 PetscFunctionReturn(0); 6893 } 6894 6895 /*@C 6896 MatDestroyMatrices - Destroys an array of matrices. 6897 6898 Collective on mat 6899 6900 Input Parameters: 6901 + n - the number of local matrices 6902 - mat - the matrices (note that this is a pointer to the array of matrices) 6903 6904 Level: advanced 6905 6906 Note: 6907 Frees not only the matrices, but also the array that contains the matrices 6908 In Fortran will not free the array. 6909 6910 .seealso: `Mat`, `MatCreateSubMatrices()` `MatDestroySubMatrices()` 6911 @*/ 6912 PetscErrorCode MatDestroyMatrices(PetscInt n, Mat *mat[]) { 6913 PetscInt i; 6914 6915 PetscFunctionBegin; 6916 if (!*mat) PetscFunctionReturn(0); 6917 PetscCheck(n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Trying to destroy negative number of matrices %" PetscInt_FMT, n); 6918 PetscValidPointer(mat, 2); 6919 6920 for (i = 0; i < n; i++) PetscCall(MatDestroy(&(*mat)[i])); 6921 6922 /* memory is allocated even if n = 0 */ 6923 PetscCall(PetscFree(*mat)); 6924 PetscFunctionReturn(0); 6925 } 6926 6927 /*@C 6928 MatDestroySubMatrices - Destroys a set of matrices obtained with `MatCreateSubMatrices()`. 6929 6930 Collective on mat 6931 6932 Input Parameters: 6933 + n - the number of local matrices 6934 - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling 6935 sequence of MatCreateSubMatrices()) 6936 6937 Level: advanced 6938 6939 Note: 6940 Frees not only the matrices, but also the array that contains the matrices 6941 In Fortran will not free the array. 6942 6943 .seealso: `MatCreateSubMatrices()`, `MatDestroyMatrices()` 6944 @*/ 6945 PetscErrorCode MatDestroySubMatrices(PetscInt n, Mat *mat[]) { 6946 Mat mat0; 6947 6948 PetscFunctionBegin; 6949 if (!*mat) PetscFunctionReturn(0); 6950 /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */ 6951 PetscCheck(n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Trying to destroy negative number of matrices %" PetscInt_FMT, n); 6952 PetscValidPointer(mat, 2); 6953 6954 mat0 = (*mat)[0]; 6955 if (mat0 && mat0->ops->destroysubmatrices) { 6956 PetscCall((mat0->ops->destroysubmatrices)(n, mat)); 6957 } else { 6958 PetscCall(MatDestroyMatrices(n, mat)); 6959 } 6960 PetscFunctionReturn(0); 6961 } 6962 6963 /*@C 6964 MatGetSeqNonzeroStructure - Extracts the nonzero structure from a matrix and stores it, in its entirety, on each process 6965 6966 Collective on mat 6967 6968 Input Parameters: 6969 . mat - the matrix 6970 6971 Output Parameter: 6972 . matstruct - the sequential matrix with the nonzero structure of mat 6973 6974 Level: developer 6975 6976 .seealso: `Mat`, `MatDestroySeqNonzeroStructure()`, `MatCreateSubMatrices()`, `MatDestroyMatrices()` 6977 @*/ 6978 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat, Mat *matstruct) { 6979 PetscFunctionBegin; 6980 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6981 PetscValidPointer(matstruct, 2); 6982 6983 PetscValidType(mat, 1); 6984 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 6985 MatCheckPreallocated(mat, 1); 6986 6987 PetscCall(PetscLogEventBegin(MAT_GetSeqNonzeroStructure, mat, 0, 0, 0)); 6988 PetscUseTypeMethod(mat, getseqnonzerostructure, matstruct); 6989 PetscCall(PetscLogEventEnd(MAT_GetSeqNonzeroStructure, mat, 0, 0, 0)); 6990 PetscFunctionReturn(0); 6991 } 6992 6993 /*@C 6994 MatDestroySeqNonzeroStructure - Destroys matrix obtained with `MatGetSeqNonzeroStructure()`. 6995 6996 Collective on mat 6997 6998 Input Parameters: 6999 . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling 7000 sequence of `MatGetSequentialNonzeroStructure()`) 7001 7002 Level: advanced 7003 7004 Note: 7005 Frees not only the matrices, but also the array that contains the matrices 7006 7007 .seealso: `Mat`, `MatGetSeqNonzeroStructure()` 7008 @*/ 7009 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat) { 7010 PetscFunctionBegin; 7011 PetscValidPointer(mat, 1); 7012 PetscCall(MatDestroy(mat)); 7013 PetscFunctionReturn(0); 7014 } 7015 7016 /*@ 7017 MatIncreaseOverlap - Given a set of submatrices indicated by index sets, 7018 replaces the index sets by larger ones that represent submatrices with 7019 additional overlap. 7020 7021 Collective on mat 7022 7023 Input Parameters: 7024 + mat - the matrix 7025 . n - the number of index sets 7026 . is - the array of index sets (these index sets will changed during the call) 7027 - ov - the additional overlap requested 7028 7029 Options Database: 7030 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7031 7032 Level: developer 7033 7034 Developer Note: 7035 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. 7036 7037 .seealso: `Mat`, `PCASM`, `MatIncreaseOverlapSplit()`, `MatCreateSubMatrices()` 7038 @*/ 7039 PetscErrorCode MatIncreaseOverlap(Mat mat, PetscInt n, IS is[], PetscInt ov) { 7040 PetscInt i, bs, cbs; 7041 7042 PetscFunctionBegin; 7043 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7044 PetscValidType(mat, 1); 7045 PetscValidLogicalCollectiveInt(mat, n, 2); 7046 PetscCheck(n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Must have one or more domains, you have %" PetscInt_FMT, n); 7047 if (n) { 7048 PetscValidPointer(is, 3); 7049 for (i = 0; i < n; i++) PetscValidHeaderSpecific(is[i], IS_CLASSID, 3); 7050 } 7051 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 7052 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 7053 MatCheckPreallocated(mat, 1); 7054 7055 if (!ov || !n) PetscFunctionReturn(0); 7056 PetscCall(PetscLogEventBegin(MAT_IncreaseOverlap, mat, 0, 0, 0)); 7057 PetscUseTypeMethod(mat, increaseoverlap, n, is, ov); 7058 PetscCall(PetscLogEventEnd(MAT_IncreaseOverlap, mat, 0, 0, 0)); 7059 PetscCall(MatGetBlockSizes(mat, &bs, &cbs)); 7060 if (bs == cbs) { 7061 for (i = 0; i < n; i++) PetscCall(ISSetBlockSize(is[i], bs)); 7062 } 7063 PetscFunctionReturn(0); 7064 } 7065 7066 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat, IS *, PetscInt); 7067 7068 /*@ 7069 MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across 7070 a sub communicator, replaces the index sets by larger ones that represent submatrices with 7071 additional overlap. 7072 7073 Collective on mat 7074 7075 Input Parameters: 7076 + mat - the matrix 7077 . n - the number of index sets 7078 . is - the array of index sets (these index sets will changed during the call) 7079 - ov - the additional overlap requested 7080 7081 ` Options Database: 7082 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7083 7084 Level: developer 7085 7086 .seealso: `MatCreateSubMatrices()`, `MatIncreaseOverlap()` 7087 @*/ 7088 PetscErrorCode MatIncreaseOverlapSplit(Mat mat, PetscInt n, IS is[], PetscInt ov) { 7089 PetscInt i; 7090 7091 PetscFunctionBegin; 7092 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7093 PetscValidType(mat, 1); 7094 PetscCheck(n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Must have one or more domains, you have %" PetscInt_FMT, n); 7095 if (n) { 7096 PetscValidPointer(is, 3); 7097 PetscValidHeaderSpecific(*is, IS_CLASSID, 3); 7098 } 7099 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 7100 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 7101 MatCheckPreallocated(mat, 1); 7102 if (!ov) PetscFunctionReturn(0); 7103 PetscCall(PetscLogEventBegin(MAT_IncreaseOverlap, mat, 0, 0, 0)); 7104 for (i = 0; i < n; i++) PetscCall(MatIncreaseOverlapSplit_Single(mat, &is[i], ov)); 7105 PetscCall(PetscLogEventEnd(MAT_IncreaseOverlap, mat, 0, 0, 0)); 7106 PetscFunctionReturn(0); 7107 } 7108 7109 /*@ 7110 MatGetBlockSize - Returns the matrix block size. 7111 7112 Not Collective 7113 7114 Input Parameter: 7115 . mat - the matrix 7116 7117 Output Parameter: 7118 . bs - block size 7119 7120 Notes: 7121 Block row formats are `MATBAIJ` and `MATSBAIJ` ALWAYS have square block storage in the matrix. 7122 7123 If the block size has not been set yet this routine returns 1. 7124 7125 Level: intermediate 7126 7127 .seealso: `MATBAIJ`, `MATSBAIJ`, `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSizes()` 7128 @*/ 7129 PetscErrorCode MatGetBlockSize(Mat mat, PetscInt *bs) { 7130 PetscFunctionBegin; 7131 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7132 PetscValidIntPointer(bs, 2); 7133 *bs = PetscAbs(mat->rmap->bs); 7134 PetscFunctionReturn(0); 7135 } 7136 7137 /*@ 7138 MatGetBlockSizes - Returns the matrix block row and column sizes. 7139 7140 Not Collective 7141 7142 Input Parameter: 7143 . mat - the matrix 7144 7145 Output Parameters: 7146 + rbs - row block size 7147 - cbs - column block size 7148 7149 Notes: 7150 Block row formats are `MATBAIJ` and `MATSBAIJ` ALWAYS have square block storage in the matrix. 7151 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7152 7153 If a block size has not been set yet this routine returns 1. 7154 7155 Level: intermediate 7156 7157 .seealso: `MATBAIJ`, `MATSBAIJ`, `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSize()`, `MatSetBlockSizes()` 7158 @*/ 7159 PetscErrorCode MatGetBlockSizes(Mat mat, PetscInt *rbs, PetscInt *cbs) { 7160 PetscFunctionBegin; 7161 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7162 if (rbs) PetscValidIntPointer(rbs, 2); 7163 if (cbs) PetscValidIntPointer(cbs, 3); 7164 if (rbs) *rbs = PetscAbs(mat->rmap->bs); 7165 if (cbs) *cbs = PetscAbs(mat->cmap->bs); 7166 PetscFunctionReturn(0); 7167 } 7168 7169 /*@ 7170 MatSetBlockSize - Sets the matrix block size. 7171 7172 Logically Collective on mat 7173 7174 Input Parameters: 7175 + mat - the matrix 7176 - bs - block size 7177 7178 Notes: 7179 Block row formats are `MATBAIJ` and `MATSBAIJ` formats ALWAYS have square block storage in the matrix. 7180 This must be called before `MatSetUp()` or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7181 7182 For `MATAIJ` matrix format, this function can be called at a later stage, provided that the specified block size 7183 is compatible with the matrix local sizes. 7184 7185 Level: intermediate 7186 7187 .seealso: `MATBAIJ`, `MATSBAIJ`, `MATAIJ`, `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`, `MatGetBlockSizes()` 7188 @*/ 7189 PetscErrorCode MatSetBlockSize(Mat mat, PetscInt bs) { 7190 PetscFunctionBegin; 7191 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7192 PetscValidLogicalCollectiveInt(mat, bs, 2); 7193 PetscCall(MatSetBlockSizes(mat, bs, bs)); 7194 PetscFunctionReturn(0); 7195 } 7196 7197 typedef struct { 7198 PetscInt n; 7199 IS *is; 7200 Mat *mat; 7201 PetscObjectState nonzerostate; 7202 Mat C; 7203 } EnvelopeData; 7204 7205 static PetscErrorCode EnvelopeDataDestroy(EnvelopeData *edata) { 7206 for (PetscInt i = 0; i < edata->n; i++) PetscCall(ISDestroy(&edata->is[i])); 7207 PetscCall(PetscFree(edata->is)); 7208 PetscCall(PetscFree(edata)); 7209 return 0; 7210 } 7211 7212 /* 7213 MatComputeVariableBlockEnvelope - Given a matrix whose nonzeros are in blocks along the diagonal this computes and stores 7214 the sizes of these blocks in the matrix. An individual block may lie over several processes. 7215 7216 Collective on mat 7217 7218 Input Parameter: 7219 . mat - the matrix 7220 7221 Notes: 7222 There can be zeros within the blocks 7223 7224 The blocks can overlap between processes, including laying on more than two processes 7225 7226 .seealso: `Mat`, `MatInvertVariableBlockEnvelope()`, `MatSetVariableBlockSizes()` 7227 */ 7228 static PetscErrorCode MatComputeVariableBlockEnvelope(Mat mat) { 7229 PetscInt n, *sizes, *starts, i = 0, env = 0, tbs = 0, lblocks = 0, rstart, II, ln = 0, cnt = 0, cstart, cend; 7230 PetscInt *diag, *odiag, sc; 7231 VecScatter scatter; 7232 PetscScalar *seqv; 7233 const PetscScalar *parv; 7234 const PetscInt *ia, *ja; 7235 PetscBool set, flag, done; 7236 Mat AA = mat, A; 7237 MPI_Comm comm; 7238 PetscMPIInt rank, size, tag; 7239 MPI_Status status; 7240 PetscContainer container; 7241 EnvelopeData *edata; 7242 Vec seq, par; 7243 IS isglobal; 7244 7245 PetscFunctionBegin; 7246 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7247 PetscCall(MatIsSymmetricKnown(mat, &set, &flag)); 7248 if (!set || !flag) { 7249 /* TOO: only needs nonzero structure of transpose */ 7250 PetscCall(MatTranspose(mat, MAT_INITIAL_MATRIX, &AA)); 7251 PetscCall(MatAXPY(AA, 1.0, mat, DIFFERENT_NONZERO_PATTERN)); 7252 } 7253 PetscCall(MatAIJGetLocalMat(AA, &A)); 7254 PetscCall(MatGetRowIJ(A, 0, PETSC_FALSE, PETSC_FALSE, &n, &ia, &ja, &done)); 7255 PetscCheck(done, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Unable to get IJ structure from matrix"); 7256 7257 PetscCall(MatGetLocalSize(mat, &n, NULL)); 7258 PetscCall(PetscObjectGetNewTag((PetscObject)mat, &tag)); 7259 PetscCall(PetscObjectGetComm((PetscObject)mat, &comm)); 7260 PetscCallMPI(MPI_Comm_size(comm, &size)); 7261 PetscCallMPI(MPI_Comm_rank(comm, &rank)); 7262 7263 PetscCall(PetscMalloc2(n, &sizes, n, &starts)); 7264 7265 if (rank > 0) { 7266 PetscCallMPI(MPI_Recv(&env, 1, MPIU_INT, rank - 1, tag, comm, &status)); 7267 PetscCallMPI(MPI_Recv(&tbs, 1, MPIU_INT, rank - 1, tag, comm, &status)); 7268 } 7269 PetscCall(MatGetOwnershipRange(mat, &rstart, NULL)); 7270 for (i = 0; i < n; i++) { 7271 env = PetscMax(env, ja[ia[i + 1] - 1]); 7272 II = rstart + i; 7273 if (env == II) { 7274 starts[lblocks] = tbs; 7275 sizes[lblocks++] = 1 + II - tbs; 7276 tbs = 1 + II; 7277 } 7278 } 7279 if (rank < size - 1) { 7280 PetscCallMPI(MPI_Send(&env, 1, MPIU_INT, rank + 1, tag, comm)); 7281 PetscCallMPI(MPI_Send(&tbs, 1, MPIU_INT, rank + 1, tag, comm)); 7282 } 7283 7284 PetscCall(MatRestoreRowIJ(A, 0, PETSC_FALSE, PETSC_FALSE, &n, &ia, &ja, &done)); 7285 if (!set || !flag) PetscCall(MatDestroy(&AA)); 7286 PetscCall(MatDestroy(&A)); 7287 7288 PetscCall(PetscNew(&edata)); 7289 PetscCall(MatGetNonzeroState(mat, &edata->nonzerostate)); 7290 edata->n = lblocks; 7291 /* create IS needed for extracting blocks from the original matrix */ 7292 PetscCall(PetscMalloc1(lblocks, &edata->is)); 7293 for (PetscInt i = 0; i < lblocks; i++) PetscCall(ISCreateStride(PETSC_COMM_SELF, sizes[i], starts[i], 1, &edata->is[i])); 7294 7295 /* Create the resulting inverse matrix structure with preallocation information */ 7296 PetscCall(MatCreate(PetscObjectComm((PetscObject)mat), &edata->C)); 7297 PetscCall(MatSetSizes(edata->C, mat->rmap->n, mat->cmap->n, mat->rmap->N, mat->cmap->N)); 7298 PetscCall(MatSetBlockSizesFromMats(edata->C, mat, mat)); 7299 PetscCall(MatSetType(edata->C, MATAIJ)); 7300 7301 /* Communicate the start and end of each row, from each block to the correct rank */ 7302 /* TODO: Use PetscSF instead of VecScatter */ 7303 for (PetscInt i = 0; i < lblocks; i++) ln += sizes[i]; 7304 PetscCall(VecCreateSeq(PETSC_COMM_SELF, 2 * ln, &seq)); 7305 PetscCall(VecGetArrayWrite(seq, &seqv)); 7306 for (PetscInt i = 0; i < lblocks; i++) { 7307 for (PetscInt j = 0; j < sizes[i]; j++) { 7308 seqv[cnt] = starts[i]; 7309 seqv[cnt + 1] = starts[i] + sizes[i]; 7310 cnt += 2; 7311 } 7312 } 7313 PetscCall(VecRestoreArrayWrite(seq, &seqv)); 7314 PetscCallMPI(MPI_Scan(&cnt, &sc, 1, MPIU_INT, MPI_SUM, PetscObjectComm((PetscObject)mat))); 7315 sc -= cnt; 7316 PetscCall(VecCreateMPI(PetscObjectComm((PetscObject)mat), 2 * mat->rmap->n, 2 * mat->rmap->N, &par)); 7317 PetscCall(ISCreateStride(PETSC_COMM_SELF, cnt, sc, 1, &isglobal)); 7318 PetscCall(VecScatterCreate(seq, NULL, par, isglobal, &scatter)); 7319 PetscCall(ISDestroy(&isglobal)); 7320 PetscCall(VecScatterBegin(scatter, seq, par, INSERT_VALUES, SCATTER_FORWARD)); 7321 PetscCall(VecScatterEnd(scatter, seq, par, INSERT_VALUES, SCATTER_FORWARD)); 7322 PetscCall(VecScatterDestroy(&scatter)); 7323 PetscCall(VecDestroy(&seq)); 7324 PetscCall(MatGetOwnershipRangeColumn(mat, &cstart, &cend)); 7325 PetscCall(PetscMalloc2(mat->rmap->n, &diag, mat->rmap->n, &odiag)); 7326 PetscCall(VecGetArrayRead(par, &parv)); 7327 cnt = 0; 7328 PetscCall(MatGetSize(mat, NULL, &n)); 7329 for (PetscInt i = 0; i < mat->rmap->n; i++) { 7330 PetscInt start, end, d = 0, od = 0; 7331 7332 start = (PetscInt)PetscRealPart(parv[cnt]); 7333 end = (PetscInt)PetscRealPart(parv[cnt + 1]); 7334 cnt += 2; 7335 7336 if (start < cstart) { 7337 od += cstart - start + n - cend; 7338 d += cend - cstart; 7339 } else if (start < cend) { 7340 od += n - cend; 7341 d += cend - start; 7342 } else od += n - start; 7343 if (end <= cstart) { 7344 od -= cstart - end + n - cend; 7345 d -= cend - cstart; 7346 } else if (end < cend) { 7347 od -= n - cend; 7348 d -= cend - end; 7349 } else od -= n - end; 7350 7351 odiag[i] = od; 7352 diag[i] = d; 7353 } 7354 PetscCall(VecRestoreArrayRead(par, &parv)); 7355 PetscCall(VecDestroy(&par)); 7356 PetscCall(MatXAIJSetPreallocation(edata->C, mat->rmap->bs, diag, odiag, NULL, NULL)); 7357 PetscCall(PetscFree2(diag, odiag)); 7358 PetscCall(PetscFree2(sizes, starts)); 7359 7360 PetscCall(PetscContainerCreate(PETSC_COMM_SELF, &container)); 7361 PetscCall(PetscContainerSetPointer(container, edata)); 7362 PetscCall(PetscContainerSetUserDestroy(container, (PetscErrorCode(*)(void *))EnvelopeDataDestroy)); 7363 PetscCall(PetscObjectCompose((PetscObject)mat, "EnvelopeData", (PetscObject)container)); 7364 PetscCall(PetscObjectDereference((PetscObject)container)); 7365 PetscFunctionReturn(0); 7366 } 7367 7368 /*@ 7369 MatInvertVariableBlockEnvelope - set matrix C to be the inverted block diagonal of matrix A 7370 7371 Collective on A 7372 7373 Input Parameters: 7374 . A - the matrix 7375 7376 Output Parameters: 7377 . C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set. 7378 7379 Note: 7380 For efficiency the matrix A should have all the nonzero entries clustered in smallish blocks along the diagonal. 7381 7382 Level: advanced 7383 7384 .seealso: `MatInvertBlockDiagonal()`, `MatComputeBlockDiagonal()` 7385 @*/ 7386 PetscErrorCode MatInvertVariableBlockEnvelope(Mat A, MatReuse reuse, Mat *C) { 7387 PetscContainer container; 7388 EnvelopeData *edata; 7389 PetscObjectState nonzerostate; 7390 7391 PetscFunctionBegin; 7392 PetscCall(PetscObjectQuery((PetscObject)A, "EnvelopeData", (PetscObject *)&container)); 7393 if (!container) { 7394 PetscCall(MatComputeVariableBlockEnvelope(A)); 7395 PetscCall(PetscObjectQuery((PetscObject)A, "EnvelopeData", (PetscObject *)&container)); 7396 } 7397 PetscCall(PetscContainerGetPointer(container, (void **)&edata)); 7398 PetscCall(MatGetNonzeroState(A, &nonzerostate)); 7399 PetscCheck(nonzerostate <= edata->nonzerostate, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Cannot handle changes to matrix nonzero structure"); 7400 PetscCheck(reuse != MAT_REUSE_MATRIX || *C == edata->C, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "C matrix must be the same as previously output"); 7401 7402 PetscCall(MatCreateSubMatrices(A, edata->n, edata->is, edata->is, MAT_INITIAL_MATRIX, &edata->mat)); 7403 *C = edata->C; 7404 7405 for (PetscInt i = 0; i < edata->n; i++) { 7406 Mat D; 7407 PetscScalar *dvalues; 7408 7409 PetscCall(MatConvert(edata->mat[i], MATSEQDENSE, MAT_INITIAL_MATRIX, &D)); 7410 PetscCall(MatSetOption(*C, MAT_ROW_ORIENTED, PETSC_FALSE)); 7411 PetscCall(MatSeqDenseInvert(D)); 7412 PetscCall(MatDenseGetArray(D, &dvalues)); 7413 PetscCall(MatSetValuesIS(*C, edata->is[i], edata->is[i], dvalues, INSERT_VALUES)); 7414 PetscCall(MatDestroy(&D)); 7415 } 7416 PetscCall(MatDestroySubMatrices(edata->n, &edata->mat)); 7417 PetscCall(MatAssemblyBegin(*C, MAT_FINAL_ASSEMBLY)); 7418 PetscCall(MatAssemblyEnd(*C, MAT_FINAL_ASSEMBLY)); 7419 PetscFunctionReturn(0); 7420 } 7421 7422 /*@ 7423 MatSetVariableBlockSizes - Sets diagonal point-blocks of the matrix that need not be of the same size 7424 7425 Logically Collective on mat 7426 7427 Input Parameters: 7428 + mat - the matrix 7429 . nblocks - the number of blocks on this process, each block can only exist on a single process 7430 - bsizes - the block sizes 7431 7432 Notes: 7433 Currently used by `PCVPBJACOBI` for `MATAIJ` matrices 7434 7435 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. 7436 7437 Level: intermediate 7438 7439 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`, `MatGetBlockSizes()`, `MatGetVariableBlockSizes()`, 7440 `MatComputeVariableBlockEnvelope()`, `PCVPBJACOBI` 7441 @*/ 7442 PetscErrorCode MatSetVariableBlockSizes(Mat mat, PetscInt nblocks, PetscInt *bsizes) { 7443 PetscInt i, ncnt = 0, nlocal; 7444 7445 PetscFunctionBegin; 7446 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7447 PetscCheck(nblocks >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Number of local blocks must be great than or equal to zero"); 7448 PetscCall(MatGetLocalSize(mat, &nlocal, NULL)); 7449 for (i = 0; i < nblocks; i++) ncnt += bsizes[i]; 7450 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); 7451 PetscCall(PetscFree(mat->bsizes)); 7452 mat->nblocks = nblocks; 7453 PetscCall(PetscMalloc1(nblocks, &mat->bsizes)); 7454 PetscCall(PetscArraycpy(mat->bsizes, bsizes, nblocks)); 7455 PetscFunctionReturn(0); 7456 } 7457 7458 /*@C 7459 MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size 7460 7461 Logically Collective on mat 7462 7463 Input Parameter: 7464 . mat - the matrix 7465 7466 Output Parameters: 7467 + nblocks - the number of blocks on this process 7468 - bsizes - the block sizes 7469 7470 Fortran Note: 7471 Currently not supported from Fortran 7472 7473 Level: intermediate 7474 7475 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`, `MatGetBlockSizes()`, `MatSetVariableBlockSizes()`, `MatComputeVariableBlockEnvelope()` 7476 @*/ 7477 PetscErrorCode MatGetVariableBlockSizes(Mat mat, PetscInt *nblocks, const PetscInt **bsizes) { 7478 PetscFunctionBegin; 7479 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7480 *nblocks = mat->nblocks; 7481 *bsizes = mat->bsizes; 7482 PetscFunctionReturn(0); 7483 } 7484 7485 /*@ 7486 MatSetBlockSizes - Sets the matrix block row and column sizes. 7487 7488 Logically Collective on mat 7489 7490 Input Parameters: 7491 + mat - the matrix 7492 . rbs - row block size 7493 - cbs - column block size 7494 7495 Notes: 7496 Block row formats are `MATBAIJ` and `MATSBAIJ`. These formats ALWAYS have square block storage in the matrix. 7497 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7498 This must be called before `MatSetUp()` or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7499 7500 For `MATAIJ` matrix this function can be called at a later stage, provided that the specified block sizes 7501 are compatible with the matrix local sizes. 7502 7503 The row and column block size determine the blocksize of the "row" and "column" vectors returned by `MatCreateVecs()`. 7504 7505 Level: intermediate 7506 7507 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSize()`, `MatGetBlockSizes()` 7508 @*/ 7509 PetscErrorCode MatSetBlockSizes(Mat mat, PetscInt rbs, PetscInt cbs) { 7510 PetscFunctionBegin; 7511 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7512 PetscValidLogicalCollectiveInt(mat, rbs, 2); 7513 PetscValidLogicalCollectiveInt(mat, cbs, 3); 7514 PetscTryTypeMethod(mat, setblocksizes, rbs, cbs); 7515 if (mat->rmap->refcnt) { 7516 ISLocalToGlobalMapping l2g = NULL; 7517 PetscLayout nmap = NULL; 7518 7519 PetscCall(PetscLayoutDuplicate(mat->rmap, &nmap)); 7520 if (mat->rmap->mapping) PetscCall(ISLocalToGlobalMappingDuplicate(mat->rmap->mapping, &l2g)); 7521 PetscCall(PetscLayoutDestroy(&mat->rmap)); 7522 mat->rmap = nmap; 7523 mat->rmap->mapping = l2g; 7524 } 7525 if (mat->cmap->refcnt) { 7526 ISLocalToGlobalMapping l2g = NULL; 7527 PetscLayout nmap = NULL; 7528 7529 PetscCall(PetscLayoutDuplicate(mat->cmap, &nmap)); 7530 if (mat->cmap->mapping) PetscCall(ISLocalToGlobalMappingDuplicate(mat->cmap->mapping, &l2g)); 7531 PetscCall(PetscLayoutDestroy(&mat->cmap)); 7532 mat->cmap = nmap; 7533 mat->cmap->mapping = l2g; 7534 } 7535 PetscCall(PetscLayoutSetBlockSize(mat->rmap, rbs)); 7536 PetscCall(PetscLayoutSetBlockSize(mat->cmap, cbs)); 7537 PetscFunctionReturn(0); 7538 } 7539 7540 /*@ 7541 MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices 7542 7543 Logically Collective on mat 7544 7545 Input Parameters: 7546 + mat - the matrix 7547 . fromRow - matrix from which to copy row block size 7548 - fromCol - matrix from which to copy column block size (can be same as fromRow) 7549 7550 Level: developer 7551 7552 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()` 7553 @*/ 7554 PetscErrorCode MatSetBlockSizesFromMats(Mat mat, Mat fromRow, Mat fromCol) { 7555 PetscFunctionBegin; 7556 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7557 PetscValidHeaderSpecific(fromRow, MAT_CLASSID, 2); 7558 PetscValidHeaderSpecific(fromCol, MAT_CLASSID, 3); 7559 if (fromRow->rmap->bs > 0) PetscCall(PetscLayoutSetBlockSize(mat->rmap, fromRow->rmap->bs)); 7560 if (fromCol->cmap->bs > 0) PetscCall(PetscLayoutSetBlockSize(mat->cmap, fromCol->cmap->bs)); 7561 PetscFunctionReturn(0); 7562 } 7563 7564 /*@ 7565 MatResidual - Default routine to calculate the residual r = b - Ax 7566 7567 Collective on mat 7568 7569 Input Parameters: 7570 + mat - the matrix 7571 . b - the right-hand-side 7572 - x - the approximate solution 7573 7574 Output Parameter: 7575 . r - location to store the residual 7576 7577 Level: developer 7578 7579 .seealso: `Mat`, `MatMult()`, `MatMultAdd()`, `PCMGSetResidual()` 7580 @*/ 7581 PetscErrorCode MatResidual(Mat mat, Vec b, Vec x, Vec r) { 7582 PetscFunctionBegin; 7583 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7584 PetscValidHeaderSpecific(b, VEC_CLASSID, 2); 7585 PetscValidHeaderSpecific(x, VEC_CLASSID, 3); 7586 PetscValidHeaderSpecific(r, VEC_CLASSID, 4); 7587 PetscValidType(mat, 1); 7588 MatCheckPreallocated(mat, 1); 7589 PetscCall(PetscLogEventBegin(MAT_Residual, mat, 0, 0, 0)); 7590 if (!mat->ops->residual) { 7591 PetscCall(MatMult(mat, x, r)); 7592 PetscCall(VecAYPX(r, -1.0, b)); 7593 } else { 7594 PetscUseTypeMethod(mat, residual, b, x, r); 7595 } 7596 PetscCall(PetscLogEventEnd(MAT_Residual, mat, 0, 0, 0)); 7597 PetscFunctionReturn(0); 7598 } 7599 7600 /*@C 7601 MatGetRowIJ - Returns the compressed row storage i and j indices for the local rows of a sparse matrix 7602 7603 Collective on mat 7604 7605 Input Parameters: 7606 + mat - the matrix 7607 . shift - 0 or 1 indicating we want the indices starting at 0 or 1 7608 . symmetric - `PETSC_TRUE` or `PETSC_FALSE` indicating the matrix data structure should be symmetrized 7609 - inodecompressed - `PETSC_TRUE` or `PETSC_FALSE` indicats if the nonzero structure of the 7610 inodes or the nonzero elements is wanted. For `MATBAIJ` matrices the compressed version is 7611 always used. 7612 7613 Output Parameters: 7614 + n - number of local rows in the (possibly compressed) matrix, use NULL if not needed 7615 . 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 7616 . ja - the column indices, use NULL if not needed 7617 - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers 7618 are responsible for handling the case when done == `PETSC_FALSE` and ia and ja are not set 7619 7620 Level: developer 7621 7622 Notes: 7623 You CANNOT change any of the ia[] or ja[] values. 7624 7625 Use `MatRestoreRowIJ()` when you are finished accessing the ia[] and ja[] values. 7626 7627 Fortran Notes: 7628 In Fortran use 7629 $ 7630 $ PetscInt ia(1), ja(1) 7631 $ PetscOffset iia, jja 7632 $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr) 7633 $ ! Access the ith and jth entries via ia(iia + i) and ja(jja + j) 7634 7635 or 7636 $ 7637 $ PetscInt, pointer :: ia(:),ja(:) 7638 $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr) 7639 $ ! Access the ith and jth entries via ia(i) and ja(j) 7640 7641 .seealso: `Mat`, `MATAIJ`, `MatGetColumnIJ()`, `MatRestoreRowIJ()`, `MatSeqAIJGetArray()` 7642 @*/ 7643 PetscErrorCode MatGetRowIJ(Mat mat, PetscInt shift, PetscBool symmetric, PetscBool inodecompressed, PetscInt *n, const PetscInt *ia[], const PetscInt *ja[], PetscBool *done) { 7644 PetscFunctionBegin; 7645 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7646 PetscValidType(mat, 1); 7647 if (n) PetscValidIntPointer(n, 5); 7648 if (ia) PetscValidPointer(ia, 6); 7649 if (ja) PetscValidPointer(ja, 7); 7650 if (done) PetscValidBoolPointer(done, 8); 7651 MatCheckPreallocated(mat, 1); 7652 if (!mat->ops->getrowij && done) *done = PETSC_FALSE; 7653 else { 7654 if (done) *done = PETSC_TRUE; 7655 PetscCall(PetscLogEventBegin(MAT_GetRowIJ, mat, 0, 0, 0)); 7656 PetscUseTypeMethod(mat, getrowij, shift, symmetric, inodecompressed, n, ia, ja, done); 7657 PetscCall(PetscLogEventEnd(MAT_GetRowIJ, mat, 0, 0, 0)); 7658 } 7659 PetscFunctionReturn(0); 7660 } 7661 7662 /*@C 7663 MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices. 7664 7665 Collective on mat 7666 7667 Input Parameters: 7668 + mat - the matrix 7669 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7670 . symmetric - `PETSC_TRUE` or `PETSC_FALSE` indicating the matrix data structure should be 7671 symmetrized 7672 . inodecompressed - `PETSC_TRUE` or `PETSC_FALSE` indicating if the nonzero structure of the 7673 inodes or the nonzero elements is wanted. For `MATBAIJ` matrices the compressed version is 7674 always used. 7675 . n - number of columns in the (possibly compressed) matrix 7676 . ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix 7677 - ja - the row indices 7678 7679 Output Parameters: 7680 . done - `PETSC_TRUE` or `PETSC_FALSE`, indicating whether the values have been returned 7681 7682 Level: developer 7683 7684 .seealso: `MatGetRowIJ()`, `MatRestoreColumnIJ()` 7685 @*/ 7686 PetscErrorCode MatGetColumnIJ(Mat mat, PetscInt shift, PetscBool symmetric, PetscBool inodecompressed, PetscInt *n, const PetscInt *ia[], const PetscInt *ja[], PetscBool *done) { 7687 PetscFunctionBegin; 7688 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7689 PetscValidType(mat, 1); 7690 PetscValidIntPointer(n, 5); 7691 if (ia) PetscValidPointer(ia, 6); 7692 if (ja) PetscValidPointer(ja, 7); 7693 PetscValidBoolPointer(done, 8); 7694 MatCheckPreallocated(mat, 1); 7695 if (!mat->ops->getcolumnij) *done = PETSC_FALSE; 7696 else { 7697 *done = PETSC_TRUE; 7698 PetscUseTypeMethod(mat, getcolumnij, shift, symmetric, inodecompressed, n, ia, ja, done); 7699 } 7700 PetscFunctionReturn(0); 7701 } 7702 7703 /*@C 7704 MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with `MatGetRowIJ()`. 7705 7706 Collective on mat 7707 7708 Input Parameters: 7709 + mat - the matrix 7710 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7711 . symmetric - `PETSC_TRUE` or `PETSC_FALSE` indicating the matrix data structure should be symmetrized 7712 . inodecompressed - `PETSC_TRUE` or `PETSC_FALSE` indicating if the nonzero structure of the 7713 inodes or the nonzero elements is wanted. For `MATBAIJ` matrices the compressed version is 7714 always used. 7715 . n - size of (possibly compressed) matrix 7716 . ia - the row pointers 7717 - ja - the column indices 7718 7719 Output Parameters: 7720 . done - `PETSC_TRUE` or `PETSC_FALSE` indicated that the values have been returned 7721 7722 Note: 7723 This routine zeros out n, ia, and ja. This is to prevent accidental 7724 us of the array after it has been restored. If you pass NULL, it will 7725 not zero the pointers. Use of ia or ja after `MatRestoreRowIJ()` is invalid. 7726 7727 Level: developer 7728 7729 .seealso: `MatGetRowIJ()`, `MatRestoreColumnIJ()` 7730 @*/ 7731 PetscErrorCode MatRestoreRowIJ(Mat mat, PetscInt shift, PetscBool symmetric, PetscBool inodecompressed, PetscInt *n, const PetscInt *ia[], const PetscInt *ja[], PetscBool *done) { 7732 PetscFunctionBegin; 7733 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7734 PetscValidType(mat, 1); 7735 if (ia) PetscValidPointer(ia, 6); 7736 if (ja) PetscValidPointer(ja, 7); 7737 if (done) PetscValidBoolPointer(done, 8); 7738 MatCheckPreallocated(mat, 1); 7739 7740 if (!mat->ops->restorerowij && done) *done = PETSC_FALSE; 7741 else { 7742 if (done) *done = PETSC_TRUE; 7743 PetscUseTypeMethod(mat, restorerowij, shift, symmetric, inodecompressed, n, ia, ja, done); 7744 if (n) *n = 0; 7745 if (ia) *ia = NULL; 7746 if (ja) *ja = NULL; 7747 } 7748 PetscFunctionReturn(0); 7749 } 7750 7751 /*@C 7752 MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with `MatGetColumnIJ()`. 7753 7754 Collective on Mat 7755 7756 Input Parameters: 7757 + mat - the matrix 7758 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7759 . symmetric - `PETSC_TRUE` or `PETSC_FALSE` indicating the matrix data structure should be symmetrized 7760 - inodecompressed - `PETSC_TRUE` or `PETSC_FALSE` indicating if the nonzero structure of the 7761 inodes or the nonzero elements is wanted. For `MATBAIJ` matrices the compressed version is 7762 always used. 7763 7764 Output Parameters: 7765 + n - size of (possibly compressed) matrix 7766 . ia - the column pointers 7767 . ja - the row indices 7768 - done - `PETSC_TRUE` or `PETSC_FALSE` indicated that the values have been returned 7769 7770 Level: developer 7771 7772 .seealso: `MatGetColumnIJ()`, `MatRestoreRowIJ()` 7773 @*/ 7774 PetscErrorCode MatRestoreColumnIJ(Mat mat, PetscInt shift, PetscBool symmetric, PetscBool inodecompressed, PetscInt *n, const PetscInt *ia[], const PetscInt *ja[], PetscBool *done) { 7775 PetscFunctionBegin; 7776 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7777 PetscValidType(mat, 1); 7778 if (ia) PetscValidPointer(ia, 6); 7779 if (ja) PetscValidPointer(ja, 7); 7780 PetscValidBoolPointer(done, 8); 7781 MatCheckPreallocated(mat, 1); 7782 7783 if (!mat->ops->restorecolumnij) *done = PETSC_FALSE; 7784 else { 7785 *done = PETSC_TRUE; 7786 PetscUseTypeMethod(mat, restorecolumnij, shift, symmetric, inodecompressed, n, ia, ja, done); 7787 if (n) *n = 0; 7788 if (ia) *ia = NULL; 7789 if (ja) *ja = NULL; 7790 } 7791 PetscFunctionReturn(0); 7792 } 7793 7794 /*@C 7795 MatColoringPatch -Used inside matrix coloring routines that use `MatGetRowIJ()` and/or `MatGetColumnIJ()`. 7796 7797 Collective on mat 7798 7799 Input Parameters: 7800 + mat - the matrix 7801 . ncolors - max color value 7802 . n - number of entries in colorarray 7803 - colorarray - array indicating color for each column 7804 7805 Output Parameters: 7806 . iscoloring - coloring generated using colorarray information 7807 7808 Level: developer 7809 7810 .seealso: `MatGetRowIJ()`, `MatGetColumnIJ()` 7811 @*/ 7812 PetscErrorCode MatColoringPatch(Mat mat, PetscInt ncolors, PetscInt n, ISColoringValue colorarray[], ISColoring *iscoloring) { 7813 PetscFunctionBegin; 7814 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7815 PetscValidType(mat, 1); 7816 PetscValidIntPointer(colorarray, 4); 7817 PetscValidPointer(iscoloring, 5); 7818 MatCheckPreallocated(mat, 1); 7819 7820 if (!mat->ops->coloringpatch) { 7821 PetscCall(ISColoringCreate(PetscObjectComm((PetscObject)mat), ncolors, n, colorarray, PETSC_OWN_POINTER, iscoloring)); 7822 } else { 7823 PetscUseTypeMethod(mat, coloringpatch, ncolors, n, colorarray, iscoloring); 7824 } 7825 PetscFunctionReturn(0); 7826 } 7827 7828 /*@ 7829 MatSetUnfactored - Resets a factored matrix to be treated as unfactored. 7830 7831 Logically Collective on mat 7832 7833 Input Parameter: 7834 . mat - the factored matrix to be reset 7835 7836 Notes: 7837 This routine should be used only with factored matrices formed by in-place 7838 factorization via ILU(0) (or by in-place LU factorization for the `MATSEQDENSE` 7839 format). This option can save memory, for example, when solving nonlinear 7840 systems with a matrix-free Newton-Krylov method and a matrix-based, in-place 7841 ILU(0) preconditioner. 7842 7843 Note that one can specify in-place ILU(0) factorization by calling 7844 .vb 7845 PCType(pc,PCILU); 7846 PCFactorSeUseInPlace(pc); 7847 .ve 7848 or by using the options -pc_type ilu -pc_factor_in_place 7849 7850 In-place factorization ILU(0) can also be used as a local 7851 solver for the blocks within the block Jacobi or additive Schwarz 7852 methods (runtime option: -sub_pc_factor_in_place). See Users-Manual: ch_pc 7853 for details on setting local solver options. 7854 7855 Most users should employ the `KSP` interface for linear solvers 7856 instead of working directly with matrix algebra routines such as this. 7857 See, e.g., `KSPCreate()`. 7858 7859 Level: developer 7860 7861 .seealso: `PCFactorSetUseInPlace()`, `PCFactorGetUseInPlace()` 7862 @*/ 7863 PetscErrorCode MatSetUnfactored(Mat mat) { 7864 PetscFunctionBegin; 7865 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7866 PetscValidType(mat, 1); 7867 MatCheckPreallocated(mat, 1); 7868 mat->factortype = MAT_FACTOR_NONE; 7869 if (!mat->ops->setunfactored) PetscFunctionReturn(0); 7870 PetscUseTypeMethod(mat, setunfactored); 7871 PetscFunctionReturn(0); 7872 } 7873 7874 /*MC 7875 MatDenseGetArrayF90 - Accesses a matrix array from Fortran 7876 7877 Synopsis: 7878 MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7879 7880 Not collective 7881 7882 Input Parameter: 7883 . x - matrix 7884 7885 Output Parameters: 7886 + xx_v - the Fortran pointer to the array 7887 - ierr - error code 7888 7889 Example of Usage: 7890 .vb 7891 PetscScalar, pointer xx_v(:,:) 7892 .... 7893 call MatDenseGetArrayF90(x,xx_v,ierr) 7894 a = xx_v(3) 7895 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7896 .ve 7897 7898 Level: advanced 7899 7900 .seealso: `MatDenseRestoreArrayF90()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatSeqAIJGetArrayF90()` 7901 7902 M*/ 7903 7904 /*MC 7905 MatDenseRestoreArrayF90 - Restores a matrix array that has been 7906 accessed with `MatDenseGetArrayF90()`. 7907 7908 Synopsis: 7909 MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7910 7911 Not collective 7912 7913 Input Parameters: 7914 + x - matrix 7915 - xx_v - the Fortran90 pointer to the array 7916 7917 Output Parameter: 7918 . ierr - error code 7919 7920 Example of Usage: 7921 .vb 7922 PetscScalar, pointer xx_v(:,:) 7923 .... 7924 call MatDenseGetArrayF90(x,xx_v,ierr) 7925 a = xx_v(3) 7926 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7927 .ve 7928 7929 Level: advanced 7930 7931 .seealso: `MatDenseGetArrayF90()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatSeqAIJRestoreArrayF90()` 7932 7933 M*/ 7934 7935 /*MC 7936 MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran. 7937 7938 Synopsis: 7939 MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7940 7941 Not collective 7942 7943 Input Parameter: 7944 . x - matrix 7945 7946 Output Parameters: 7947 + xx_v - the Fortran pointer to the array 7948 - ierr - error code 7949 7950 Example of Usage: 7951 .vb 7952 PetscScalar, pointer xx_v(:) 7953 .... 7954 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 7955 a = xx_v(3) 7956 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 7957 .ve 7958 7959 Level: advanced 7960 7961 .seealso: `MatSeqAIJRestoreArrayF90()`, `MatSeqAIJGetArray()`, `MatSeqAIJRestoreArray()`, `MatDenseGetArrayF90()` 7962 7963 M*/ 7964 7965 /*MC 7966 MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been 7967 accessed with `MatSeqAIJGetArrayF90()`. 7968 7969 Synopsis: 7970 MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7971 7972 Not collective 7973 7974 Input Parameters: 7975 + x - matrix 7976 - xx_v - the Fortran90 pointer to the array 7977 7978 Output Parameter: 7979 . ierr - error code 7980 7981 Example of Usage: 7982 .vb 7983 PetscScalar, pointer xx_v(:) 7984 .... 7985 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 7986 a = xx_v(3) 7987 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 7988 .ve 7989 7990 Level: advanced 7991 7992 .seealso: `MatSeqAIJGetArrayF90()`, `MatSeqAIJGetArray()`, `MatSeqAIJRestoreArray()`, `MatDenseRestoreArrayF90()` 7993 7994 M*/ 7995 7996 /*@ 7997 MatCreateSubMatrix - Gets a single submatrix on the same number of processors 7998 as the original matrix. 7999 8000 Collective on mat 8001 8002 Input Parameters: 8003 + mat - the original matrix 8004 . isrow - parallel IS containing the rows this processor should obtain 8005 . 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. 8006 - cll - either `MAT_INITIAL_MATRIX` or `MAT_REUSE_MATRIX` 8007 8008 Output Parameter: 8009 . newmat - the new submatrix, of the same type as the old 8010 8011 Level: advanced 8012 8013 Notes: 8014 The submatrix will be able to be multiplied with vectors using the same layout as iscol. 8015 8016 Some matrix types place restrictions on the row and column indices, such 8017 as that they be sorted or that they be equal to each other. 8018 8019 The index sets may not have duplicate entries. 8020 8021 The first time this is called you should use a cll of `MAT_INITIAL_MATRIX`, 8022 the `MatCreateSubMatrix()` routine will create the newmat for you. Any additional calls 8023 to this routine with a mat of the same nonzero structure and with a call of `MAT_REUSE_MATRIX` 8024 will reuse the matrix generated the first time. You should call `MatDestroy()` on newmat when 8025 you are finished using it. 8026 8027 The communicator of the newly obtained matrix is ALWAYS the same as the communicator of 8028 the input matrix. 8029 8030 If iscol is NULL then all columns are obtained (not supported in Fortran). 8031 8032 Example usage: 8033 Consider the following 8x8 matrix with 34 non-zero values, that is 8034 assembled across 3 processors. Let's assume that proc0 owns 3 rows, 8035 proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown 8036 as follows: 8037 8038 .vb 8039 1 2 0 | 0 3 0 | 0 4 8040 Proc0 0 5 6 | 7 0 0 | 8 0 8041 9 0 10 | 11 0 0 | 12 0 8042 ------------------------------------- 8043 13 0 14 | 15 16 17 | 0 0 8044 Proc1 0 18 0 | 19 20 21 | 0 0 8045 0 0 0 | 22 23 0 | 24 0 8046 ------------------------------------- 8047 Proc2 25 26 27 | 0 0 28 | 29 0 8048 30 0 0 | 31 32 33 | 0 34 8049 .ve 8050 8051 Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is 8052 8053 .vb 8054 2 0 | 0 3 0 | 0 8055 Proc0 5 6 | 7 0 0 | 8 8056 ------------------------------- 8057 Proc1 18 0 | 19 20 21 | 0 8058 ------------------------------- 8059 Proc2 26 27 | 0 0 28 | 29 8060 0 0 | 31 32 33 | 0 8061 .ve 8062 8063 .seealso: `Mat`, `MatCreateSubMatrices()`, `MatCreateSubMatricesMPI()`, `MatCreateSubMatrixVirtual()`, `MatSubMatrixVirtualUpdate()` 8064 @*/ 8065 PetscErrorCode MatCreateSubMatrix(Mat mat, IS isrow, IS iscol, MatReuse cll, Mat *newmat) { 8066 PetscMPIInt size; 8067 Mat *local; 8068 IS iscoltmp; 8069 PetscBool flg; 8070 8071 PetscFunctionBegin; 8072 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8073 PetscValidHeaderSpecific(isrow, IS_CLASSID, 2); 8074 if (iscol) PetscValidHeaderSpecific(iscol, IS_CLASSID, 3); 8075 PetscValidPointer(newmat, 5); 8076 if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat, MAT_CLASSID, 5); 8077 PetscValidType(mat, 1); 8078 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 8079 PetscCheck(cll != MAT_IGNORE_MATRIX, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Cannot use MAT_IGNORE_MATRIX"); 8080 8081 MatCheckPreallocated(mat, 1); 8082 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size)); 8083 8084 if (!iscol || isrow == iscol) { 8085 PetscBool stride; 8086 PetscMPIInt grabentirematrix = 0, grab; 8087 PetscCall(PetscObjectTypeCompare((PetscObject)isrow, ISSTRIDE, &stride)); 8088 if (stride) { 8089 PetscInt first, step, n, rstart, rend; 8090 PetscCall(ISStrideGetInfo(isrow, &first, &step)); 8091 if (step == 1) { 8092 PetscCall(MatGetOwnershipRange(mat, &rstart, &rend)); 8093 if (rstart == first) { 8094 PetscCall(ISGetLocalSize(isrow, &n)); 8095 if (n == rend - rstart) grabentirematrix = 1; 8096 } 8097 } 8098 } 8099 PetscCall(MPIU_Allreduce(&grabentirematrix, &grab, 1, MPI_INT, MPI_MIN, PetscObjectComm((PetscObject)mat))); 8100 if (grab) { 8101 PetscCall(PetscInfo(mat, "Getting entire matrix as submatrix\n")); 8102 if (cll == MAT_INITIAL_MATRIX) { 8103 *newmat = mat; 8104 PetscCall(PetscObjectReference((PetscObject)mat)); 8105 } 8106 PetscFunctionReturn(0); 8107 } 8108 } 8109 8110 if (!iscol) { 8111 PetscCall(ISCreateStride(PetscObjectComm((PetscObject)mat), mat->cmap->n, mat->cmap->rstart, 1, &iscoltmp)); 8112 } else { 8113 iscoltmp = iscol; 8114 } 8115 8116 /* if original matrix is on just one processor then use submatrix generated */ 8117 if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) { 8118 PetscCall(MatCreateSubMatrices(mat, 1, &isrow, &iscoltmp, MAT_REUSE_MATRIX, &newmat)); 8119 goto setproperties; 8120 } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) { 8121 PetscCall(MatCreateSubMatrices(mat, 1, &isrow, &iscoltmp, MAT_INITIAL_MATRIX, &local)); 8122 *newmat = *local; 8123 PetscCall(PetscFree(local)); 8124 goto setproperties; 8125 } else if (!mat->ops->createsubmatrix) { 8126 /* Create a new matrix type that implements the operation using the full matrix */ 8127 PetscCall(PetscLogEventBegin(MAT_CreateSubMat, mat, 0, 0, 0)); 8128 switch (cll) { 8129 case MAT_INITIAL_MATRIX: PetscCall(MatCreateSubMatrixVirtual(mat, isrow, iscoltmp, newmat)); break; 8130 case MAT_REUSE_MATRIX: PetscCall(MatSubMatrixVirtualUpdate(*newmat, mat, isrow, iscoltmp)); break; 8131 default: SETERRQ(PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_OUTOFRANGE, "Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX"); 8132 } 8133 PetscCall(PetscLogEventEnd(MAT_CreateSubMat, mat, 0, 0, 0)); 8134 goto setproperties; 8135 } 8136 8137 PetscCall(PetscLogEventBegin(MAT_CreateSubMat, mat, 0, 0, 0)); 8138 PetscUseTypeMethod(mat, createsubmatrix, isrow, iscoltmp, cll, newmat); 8139 PetscCall(PetscLogEventEnd(MAT_CreateSubMat, mat, 0, 0, 0)); 8140 8141 setproperties: 8142 PetscCall(ISEqualUnsorted(isrow, iscoltmp, &flg)); 8143 if (flg) PetscCall(MatPropagateSymmetryOptions(mat, *newmat)); 8144 if (!iscol) PetscCall(ISDestroy(&iscoltmp)); 8145 if (*newmat && cll == MAT_INITIAL_MATRIX) PetscCall(PetscObjectStateIncrease((PetscObject)*newmat)); 8146 PetscFunctionReturn(0); 8147 } 8148 8149 /*@ 8150 MatPropagateSymmetryOptions - Propagates symmetry options set on a matrix to another matrix 8151 8152 Not Collective 8153 8154 Input Parameters: 8155 + A - the matrix we wish to propagate options from 8156 - B - the matrix we wish to propagate options to 8157 8158 Level: beginner 8159 8160 Note: 8161 Propagates the options associated to `MAT_SYMMETRY_ETERNAL`, `MAT_STRUCTURALLY_SYMMETRIC`, `MAT_HERMITIAN`, `MAT_SPD`, `MAT_SYMMETRIC`, and `MAT_STRUCTURAL_SYMMETRY_ETERNAL` 8162 8163 .seealso: `MatSetOption()`, `MatIsSymmetricKnown()`, `MatIsSPDKnown()`, `MatIsHermitianKnown()`, MatIsStructurallySymmetricKnown()` 8164 @*/ 8165 PetscErrorCode MatPropagateSymmetryOptions(Mat A, Mat B) { 8166 PetscFunctionBegin; 8167 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8168 PetscValidHeaderSpecific(B, MAT_CLASSID, 2); 8169 B->symmetry_eternal = A->symmetry_eternal; 8170 B->structural_symmetry_eternal = A->structural_symmetry_eternal; 8171 B->symmetric = A->symmetric; 8172 B->structurally_symmetric = A->structurally_symmetric; 8173 B->spd = A->spd; 8174 B->hermitian = A->hermitian; 8175 PetscFunctionReturn(0); 8176 } 8177 8178 /*@ 8179 MatStashSetInitialSize - sets the sizes of the matrix stash, that is 8180 used during the assembly process to store values that belong to 8181 other processors. 8182 8183 Not Collective 8184 8185 Input Parameters: 8186 + mat - the matrix 8187 . size - the initial size of the stash. 8188 - bsize - the initial size of the block-stash(if used). 8189 8190 Options Database Keys: 8191 + -matstash_initial_size <size> or <size0,size1,...sizep-1> 8192 - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1> 8193 8194 Level: intermediate 8195 8196 Notes: 8197 The block-stash is used for values set with `MatSetValuesBlocked()` while 8198 the stash is used for values set with `MatSetValues()` 8199 8200 Run with the option -info and look for output of the form 8201 MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs. 8202 to determine the appropriate value, MM, to use for size and 8203 MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs. 8204 to determine the value, BMM to use for bsize 8205 8206 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `Mat`, `MatStashGetInfo()` 8207 @*/ 8208 PetscErrorCode MatStashSetInitialSize(Mat mat, PetscInt size, PetscInt bsize) { 8209 PetscFunctionBegin; 8210 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8211 PetscValidType(mat, 1); 8212 PetscCall(MatStashSetInitialSize_Private(&mat->stash, size)); 8213 PetscCall(MatStashSetInitialSize_Private(&mat->bstash, bsize)); 8214 PetscFunctionReturn(0); 8215 } 8216 8217 /*@ 8218 MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 8219 the matrix 8220 8221 Neighbor-wise Collective on mat 8222 8223 Input Parameters: 8224 + mat - the matrix 8225 . x,y - the vectors 8226 - w - where the result is stored 8227 8228 Level: intermediate 8229 8230 Notes: 8231 w may be the same vector as y. 8232 8233 This allows one to use either the restriction or interpolation (its transpose) 8234 matrix to do the interpolation 8235 8236 .seealso: `MatMultAdd()`, `MatMultTransposeAdd()`, `MatRestrict()`, `PCMG` 8237 @*/ 8238 PetscErrorCode MatInterpolateAdd(Mat A, Vec x, Vec y, Vec w) { 8239 PetscInt M, N, Ny; 8240 8241 PetscFunctionBegin; 8242 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8243 PetscValidHeaderSpecific(x, VEC_CLASSID, 2); 8244 PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 8245 PetscValidHeaderSpecific(w, VEC_CLASSID, 4); 8246 PetscCall(MatGetSize(A, &M, &N)); 8247 PetscCall(VecGetSize(y, &Ny)); 8248 if (M == Ny) { 8249 PetscCall(MatMultAdd(A, x, y, w)); 8250 } else { 8251 PetscCall(MatMultTransposeAdd(A, x, y, w)); 8252 } 8253 PetscFunctionReturn(0); 8254 } 8255 8256 /*@ 8257 MatInterpolate - y = A*x or A'*x depending on the shape of 8258 the matrix 8259 8260 Neighbor-wise Collective on mat 8261 8262 Input Parameters: 8263 + mat - the matrix 8264 - x,y - the vectors 8265 8266 Level: intermediate 8267 8268 Note: 8269 This allows one to use either the restriction or interpolation (its transpose) 8270 matrix to do the interpolation 8271 8272 .seealso: `MatMultAdd()`, `MatMultTransposeAdd()`, `MatRestrict()`, `PCMG` 8273 @*/ 8274 PetscErrorCode MatInterpolate(Mat A, Vec x, Vec y) { 8275 PetscInt M, N, Ny; 8276 8277 PetscFunctionBegin; 8278 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8279 PetscValidHeaderSpecific(x, VEC_CLASSID, 2); 8280 PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 8281 PetscCall(MatGetSize(A, &M, &N)); 8282 PetscCall(VecGetSize(y, &Ny)); 8283 if (M == Ny) { 8284 PetscCall(MatMult(A, x, y)); 8285 } else { 8286 PetscCall(MatMultTranspose(A, x, y)); 8287 } 8288 PetscFunctionReturn(0); 8289 } 8290 8291 /*@ 8292 MatRestrict - y = A*x or A'*x 8293 8294 Neighbor-wise Collective on Mat 8295 8296 Input Parameters: 8297 + mat - the matrix 8298 - x,y - the vectors 8299 8300 Level: intermediate 8301 8302 Note: 8303 This allows one to use either the restriction or interpolation (its transpose) 8304 matrix to do the restriction 8305 8306 .seealso: `MatMultAdd()`, `MatMultTransposeAdd()`, `MatInterpolate()`, `PCMG` 8307 @*/ 8308 PetscErrorCode MatRestrict(Mat A, Vec x, Vec y) { 8309 PetscInt M, N, Ny; 8310 8311 PetscFunctionBegin; 8312 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8313 PetscValidHeaderSpecific(x, VEC_CLASSID, 2); 8314 PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 8315 PetscCall(MatGetSize(A, &M, &N)); 8316 PetscCall(VecGetSize(y, &Ny)); 8317 if (M == Ny) { 8318 PetscCall(MatMult(A, x, y)); 8319 } else { 8320 PetscCall(MatMultTranspose(A, x, y)); 8321 } 8322 PetscFunctionReturn(0); 8323 } 8324 8325 /*@ 8326 MatMatInterpolateAdd - Y = W + A*X or W + A'*X 8327 8328 Neighbor-wise Collective on Mat 8329 8330 Input Parameters: 8331 + mat - the matrix 8332 - w, x - the input dense matrices 8333 8334 Output Parameters: 8335 . y - the output dense matrix 8336 8337 Level: intermediate 8338 8339 Note: 8340 This allows one to use either the restriction or interpolation (its transpose) 8341 matrix to do the interpolation. y matrix can be reused if already created with the proper sizes, 8342 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8343 8344 .seealso: `MatInterpolateAdd()`, `MatMatInterpolate()`, `MatMatRestrict()`, `PCMG` 8345 @*/ 8346 PetscErrorCode MatMatInterpolateAdd(Mat A, Mat x, Mat w, Mat *y) { 8347 PetscInt M, N, Mx, Nx, Mo, My = 0, Ny = 0; 8348 PetscBool trans = PETSC_TRUE; 8349 MatReuse reuse = MAT_INITIAL_MATRIX; 8350 8351 PetscFunctionBegin; 8352 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8353 PetscValidHeaderSpecific(x, MAT_CLASSID, 2); 8354 PetscValidType(x, 2); 8355 if (w) PetscValidHeaderSpecific(w, MAT_CLASSID, 3); 8356 if (*y) PetscValidHeaderSpecific(*y, MAT_CLASSID, 4); 8357 PetscCall(MatGetSize(A, &M, &N)); 8358 PetscCall(MatGetSize(x, &Mx, &Nx)); 8359 if (N == Mx) trans = PETSC_FALSE; 8360 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); 8361 Mo = trans ? N : M; 8362 if (*y) { 8363 PetscCall(MatGetSize(*y, &My, &Ny)); 8364 if (Mo == My && Nx == Ny) { 8365 reuse = MAT_REUSE_MATRIX; 8366 } else { 8367 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); 8368 PetscCall(MatDestroy(y)); 8369 } 8370 } 8371 8372 if (w && *y == w) { /* this is to minimize changes in PCMG */ 8373 PetscBool flg; 8374 8375 PetscCall(PetscObjectQuery((PetscObject)*y, "__MatMatIntAdd_w", (PetscObject *)&w)); 8376 if (w) { 8377 PetscInt My, Ny, Mw, Nw; 8378 8379 PetscCall(PetscObjectTypeCompare((PetscObject)*y, ((PetscObject)w)->type_name, &flg)); 8380 PetscCall(MatGetSize(*y, &My, &Ny)); 8381 PetscCall(MatGetSize(w, &Mw, &Nw)); 8382 if (!flg || My != Mw || Ny != Nw) w = NULL; 8383 } 8384 if (!w) { 8385 PetscCall(MatDuplicate(*y, MAT_COPY_VALUES, &w)); 8386 PetscCall(PetscObjectCompose((PetscObject)*y, "__MatMatIntAdd_w", (PetscObject)w)); 8387 PetscCall(PetscLogObjectParent((PetscObject)*y, (PetscObject)w)); 8388 PetscCall(PetscObjectDereference((PetscObject)w)); 8389 } else { 8390 PetscCall(MatCopy(*y, w, UNKNOWN_NONZERO_PATTERN)); 8391 } 8392 } 8393 if (!trans) { 8394 PetscCall(MatMatMult(A, x, reuse, PETSC_DEFAULT, y)); 8395 } else { 8396 PetscCall(MatTransposeMatMult(A, x, reuse, PETSC_DEFAULT, y)); 8397 } 8398 if (w) PetscCall(MatAXPY(*y, 1.0, w, UNKNOWN_NONZERO_PATTERN)); 8399 PetscFunctionReturn(0); 8400 } 8401 8402 /*@ 8403 MatMatInterpolate - Y = A*X or A'*X 8404 8405 Neighbor-wise Collective on Mat 8406 8407 Input Parameters: 8408 + mat - the matrix 8409 - x - the input dense matrix 8410 8411 Output Parameters: 8412 . y - the output dense matrix 8413 8414 Level: intermediate 8415 8416 Note: 8417 This allows one to use either the restriction or interpolation (its transpose) 8418 matrix to do the interpolation. y matrix can be reused if already created with the proper sizes, 8419 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8420 8421 .seealso: `MatInterpolate()`, `MatRestrict()`, `MatMatRestrict()`, `PCMG` 8422 @*/ 8423 PetscErrorCode MatMatInterpolate(Mat A, Mat x, Mat *y) { 8424 PetscFunctionBegin; 8425 PetscCall(MatMatInterpolateAdd(A, x, NULL, y)); 8426 PetscFunctionReturn(0); 8427 } 8428 8429 /*@ 8430 MatMatRestrict - Y = A*X or A'*X 8431 8432 Neighbor-wise Collective on Mat 8433 8434 Input Parameters: 8435 + mat - the matrix 8436 - x - the input dense matrix 8437 8438 Output Parameters: 8439 . y - the output dense matrix 8440 8441 Level: intermediate 8442 8443 Note: 8444 This allows one to use either the restriction or interpolation (its transpose) 8445 matrix to do the restriction. y matrix can be reused if already created with the proper sizes, 8446 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8447 8448 .seealso: `MatRestrict()`, `MatInterpolate()`, `MatMatInterpolate()`, `PCMG` 8449 @*/ 8450 PetscErrorCode MatMatRestrict(Mat A, Mat x, Mat *y) { 8451 PetscFunctionBegin; 8452 PetscCall(MatMatInterpolateAdd(A, x, NULL, y)); 8453 PetscFunctionReturn(0); 8454 } 8455 8456 /*@ 8457 MatGetNullSpace - retrieves the null space of a matrix. 8458 8459 Logically Collective on mat 8460 8461 Input Parameters: 8462 + mat - the matrix 8463 - nullsp - the null space object 8464 8465 Level: developer 8466 8467 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatSetNullSpace()`, `MatNullSpace` 8468 @*/ 8469 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp) { 8470 PetscFunctionBegin; 8471 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8472 PetscValidPointer(nullsp, 2); 8473 *nullsp = (mat->symmetric == PETSC_BOOL3_TRUE && !mat->nullsp) ? mat->transnullsp : mat->nullsp; 8474 PetscFunctionReturn(0); 8475 } 8476 8477 /*@ 8478 MatSetNullSpace - attaches a null space to a matrix. 8479 8480 Logically Collective on mat 8481 8482 Input Parameters: 8483 + mat - the matrix 8484 - nullsp - the null space object 8485 8486 Level: advanced 8487 8488 Notes: 8489 This null space is used by the `KSP` linear solvers to solve singular systems. 8490 8491 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 8492 8493 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 8494 to zero but the linear system will still be solved in a least squares sense. 8495 8496 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8497 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). 8498 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 8499 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 8500 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). 8501 This \hat{b} can be obtained by calling MatNullSpaceRemove() with the null space of the transpose of the matrix. 8502 8503 If the matrix is known to be symmetric because it is an `MATSBAIJ` matrix or one as called 8504 `MatSetOption`(mat,`MAT_SYMMETRIC` or possibly `MAT_SYMMETRY_ETERNAL`,`PETSC_TRUE`); this 8505 routine also automatically calls `MatSetTransposeNullSpace()`. 8506 8507 The user should call `MatNullSpaceDestroy()`. 8508 8509 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatGetNullSpace()`, `MatSetTransposeNullSpace()`, `MatGetTransposeNullSpace()`, `MatNullSpaceRemove()`, 8510 `KSPSetPCSide()` 8511 @*/ 8512 PetscErrorCode MatSetNullSpace(Mat mat, MatNullSpace nullsp) { 8513 PetscFunctionBegin; 8514 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8515 if (nullsp) PetscValidHeaderSpecific(nullsp, MAT_NULLSPACE_CLASSID, 2); 8516 if (nullsp) PetscCall(PetscObjectReference((PetscObject)nullsp)); 8517 PetscCall(MatNullSpaceDestroy(&mat->nullsp)); 8518 mat->nullsp = nullsp; 8519 if (mat->symmetric == PETSC_BOOL3_TRUE) PetscCall(MatSetTransposeNullSpace(mat, nullsp)); 8520 PetscFunctionReturn(0); 8521 } 8522 8523 /*@ 8524 MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix. 8525 8526 Logically Collective on mat 8527 8528 Input Parameters: 8529 + mat - the matrix 8530 - nullsp - the null space object 8531 8532 Level: developer 8533 8534 .seealso: `MatNullSpace`, `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatSetTransposeNullSpace()`, `MatSetNullSpace()`, `MatGetNullSpace()` 8535 @*/ 8536 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp) { 8537 PetscFunctionBegin; 8538 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8539 PetscValidType(mat, 1); 8540 PetscValidPointer(nullsp, 2); 8541 *nullsp = (mat->symmetric == PETSC_BOOL3_TRUE && !mat->transnullsp) ? mat->nullsp : mat->transnullsp; 8542 PetscFunctionReturn(0); 8543 } 8544 8545 /*@ 8546 MatSetTransposeNullSpace - attaches the null space of a transpose of a matrix to the matrix 8547 8548 Logically Collective on mat 8549 8550 Input Parameters: 8551 + mat - the matrix 8552 - nullsp - the null space object 8553 8554 Level: advanced 8555 8556 Notes: 8557 This allows solving singular linear systems defined by the transpose of the matrix using `KSP` solvers with left preconditioning. 8558 8559 See `MatSetNullSpace()` 8560 8561 .seealso: `MatNullSpace`, `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatGetNullSpace()`, `MatSetNullSpace()`, `MatGetTransposeNullSpace()`, `MatNullSpaceRemove()`, `KSPSetPCSide()` 8562 @*/ 8563 PetscErrorCode MatSetTransposeNullSpace(Mat mat, MatNullSpace nullsp) { 8564 PetscFunctionBegin; 8565 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8566 if (nullsp) PetscValidHeaderSpecific(nullsp, MAT_NULLSPACE_CLASSID, 2); 8567 if (nullsp) PetscCall(PetscObjectReference((PetscObject)nullsp)); 8568 PetscCall(MatNullSpaceDestroy(&mat->transnullsp)); 8569 mat->transnullsp = nullsp; 8570 PetscFunctionReturn(0); 8571 } 8572 8573 /*@ 8574 MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions 8575 This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix. 8576 8577 Logically Collective on mat 8578 8579 Input Parameters: 8580 + mat - the matrix 8581 - nullsp - the null space object 8582 8583 Level: advanced 8584 8585 Notes: 8586 Overwrites any previous near null space that may have been attached 8587 8588 You can remove the null space by calling this routine with an nullsp of NULL 8589 8590 .seealso: `MatNullSpace`, `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNullSpace()`, `MatNullSpaceCreateRigidBody()`, `MatGetNearNullSpace()` 8591 @*/ 8592 PetscErrorCode MatSetNearNullSpace(Mat mat, MatNullSpace nullsp) { 8593 PetscFunctionBegin; 8594 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8595 PetscValidType(mat, 1); 8596 if (nullsp) PetscValidHeaderSpecific(nullsp, MAT_NULLSPACE_CLASSID, 2); 8597 MatCheckPreallocated(mat, 1); 8598 if (nullsp) PetscCall(PetscObjectReference((PetscObject)nullsp)); 8599 PetscCall(MatNullSpaceDestroy(&mat->nearnullsp)); 8600 mat->nearnullsp = nullsp; 8601 PetscFunctionReturn(0); 8602 } 8603 8604 /*@ 8605 MatGetNearNullSpace - Get null space attached with `MatSetNearNullSpace()` 8606 8607 Not Collective 8608 8609 Input Parameter: 8610 . mat - the matrix 8611 8612 Output Parameter: 8613 . nullsp - the null space object, NULL if not set 8614 8615 Level: advanced 8616 8617 .seealso: `MatNullSpace`, `MatSetNearNullSpace()`, `MatGetNullSpace()`, `MatNullSpaceCreate()` 8618 @*/ 8619 PetscErrorCode MatGetNearNullSpace(Mat mat, MatNullSpace *nullsp) { 8620 PetscFunctionBegin; 8621 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8622 PetscValidType(mat, 1); 8623 PetscValidPointer(nullsp, 2); 8624 MatCheckPreallocated(mat, 1); 8625 *nullsp = mat->nearnullsp; 8626 PetscFunctionReturn(0); 8627 } 8628 8629 /*@C 8630 MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix. 8631 8632 Collective on mat 8633 8634 Input Parameters: 8635 + mat - the matrix 8636 . row - row/column permutation 8637 . fill - expected fill factor >= 1.0 8638 - level - level of fill, for ICC(k) 8639 8640 Notes: 8641 Probably really in-place only when level of fill is zero, otherwise allocates 8642 new space to store factored matrix and deletes previous memory. 8643 8644 Most users should employ the `KSP` interface for linear solvers 8645 instead of working directly with matrix algebra routines such as this. 8646 See, e.g., `KSPCreate()`. 8647 8648 Level: developer 8649 8650 Developer Note: 8651 The Fortran interface is not autogenerated as the f90 8652 interface definition cannot be generated correctly [due to `MatFactorInfo`] 8653 8654 .seealso: `MatGetFactor()`, `MatICCFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()` 8655 @*/ 8656 PetscErrorCode MatICCFactor(Mat mat, IS row, const MatFactorInfo *info) { 8657 PetscFunctionBegin; 8658 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8659 PetscValidType(mat, 1); 8660 if (row) PetscValidHeaderSpecific(row, IS_CLASSID, 2); 8661 PetscValidPointer(info, 3); 8662 PetscCheck(mat->rmap->N == mat->cmap->N, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONG, "matrix must be square"); 8663 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 8664 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 8665 MatCheckPreallocated(mat, 1); 8666 PetscUseTypeMethod(mat, iccfactor, row, info); 8667 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 8668 PetscFunctionReturn(0); 8669 } 8670 8671 /*@ 8672 MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 8673 ghosted ones. 8674 8675 Not Collective 8676 8677 Input Parameters: 8678 + mat - the matrix 8679 - diag - the diagonal values, including ghost ones 8680 8681 Level: developer 8682 8683 Notes: 8684 Works only for `MATMPIAIJ` and `MATMPIBAIJ` matrices 8685 8686 This allows one to avoid during communication to perform the scaling that must be done with `MatDiagonalScale()` 8687 8688 .seealso: `MatDiagonalScale()` 8689 @*/ 8690 PetscErrorCode MatDiagonalScaleLocal(Mat mat, Vec diag) { 8691 PetscMPIInt size; 8692 8693 PetscFunctionBegin; 8694 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8695 PetscValidHeaderSpecific(diag, VEC_CLASSID, 2); 8696 PetscValidType(mat, 1); 8697 8698 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Matrix must be already assembled"); 8699 PetscCall(PetscLogEventBegin(MAT_Scale, mat, 0, 0, 0)); 8700 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size)); 8701 if (size == 1) { 8702 PetscInt n, m; 8703 PetscCall(VecGetSize(diag, &n)); 8704 PetscCall(MatGetSize(mat, NULL, &m)); 8705 if (m == n) { 8706 PetscCall(MatDiagonalScale(mat, NULL, diag)); 8707 } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Only supported for sequential matrices when no ghost points/periodic conditions"); 8708 } else { 8709 PetscUseMethod(mat, "MatDiagonalScaleLocal_C", (Mat, Vec), (mat, diag)); 8710 } 8711 PetscCall(PetscLogEventEnd(MAT_Scale, mat, 0, 0, 0)); 8712 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 8713 PetscFunctionReturn(0); 8714 } 8715 8716 /*@ 8717 MatGetInertia - Gets the inertia from a factored matrix 8718 8719 Collective on mat 8720 8721 Input Parameter: 8722 . mat - the matrix 8723 8724 Output Parameters: 8725 + nneg - number of negative eigenvalues 8726 . nzero - number of zero eigenvalues 8727 - npos - number of positive eigenvalues 8728 8729 Level: advanced 8730 8731 Note: 8732 Matrix must have been factored by `MatCholeskyFactor()` 8733 8734 .seealso: `MatGetFactor()`, `MatCholeskyFactor()` 8735 @*/ 8736 PetscErrorCode MatGetInertia(Mat mat, PetscInt *nneg, PetscInt *nzero, PetscInt *npos) { 8737 PetscFunctionBegin; 8738 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8739 PetscValidType(mat, 1); 8740 PetscCheck(mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Unfactored matrix"); 8741 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Numeric factor mat is not assembled"); 8742 PetscUseTypeMethod(mat, getinertia, nneg, nzero, npos); 8743 PetscFunctionReturn(0); 8744 } 8745 8746 /* ----------------------------------------------------------------*/ 8747 /*@C 8748 MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors 8749 8750 Neighbor-wise Collective on mat 8751 8752 Input Parameters: 8753 + mat - the factored matrix obtained with `MatGetFactor()` 8754 - b - the right-hand-side vectors 8755 8756 Output Parameter: 8757 . x - the result vectors 8758 8759 Note: 8760 The vectors b and x cannot be the same. I.e., one cannot 8761 call `MatSolves`(A,x,x). 8762 8763 Level: developer 8764 8765 .seealso: `Vecs`, `MatSolveAdd()`, `MatSolveTranspose()`, `MatSolveTransposeAdd()`, `MatSolve()` 8766 @*/ 8767 PetscErrorCode MatSolves(Mat mat, Vecs b, Vecs x) { 8768 PetscFunctionBegin; 8769 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8770 PetscValidType(mat, 1); 8771 PetscCheck(x != b, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_IDN, "x and b must be different vectors"); 8772 PetscCheck(mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Unfactored matrix"); 8773 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 8774 8775 MatCheckPreallocated(mat, 1); 8776 PetscCall(PetscLogEventBegin(MAT_Solves, mat, 0, 0, 0)); 8777 PetscUseTypeMethod(mat, solves, b, x); 8778 PetscCall(PetscLogEventEnd(MAT_Solves, mat, 0, 0, 0)); 8779 PetscFunctionReturn(0); 8780 } 8781 8782 /*@ 8783 MatIsSymmetric - Test whether a matrix is symmetric 8784 8785 Collective on mat 8786 8787 Input Parameters: 8788 + A - the matrix to test 8789 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose) 8790 8791 Output Parameters: 8792 . flg - the result 8793 8794 Notes: 8795 For real numbers `MatIsSymmetric()` and `MatIsHermitian()` return identical results 8796 8797 If the matrix does not yet know if it is symmetric or not this can be an expensive operation, also available `MatIsSymmetricKnown()` 8798 8799 One can declare that a matrix is symmetric with `MatSetOption`(mat,`MAT_SYMMETRIC`,`PETSC_TRUE`) and if it is known to remain symmetric 8800 after changes to the matrices values one can call `MatSetOption`(mat,`MAT_SYMMETRY_ETERNAL`,`PETSC_TRUE`) 8801 8802 Level: intermediate 8803 8804 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetricKnown()`, 8805 `MAT_SYMMETRIC`, `MAT_SYMMETRY_ETERNAL`, `MatSetOption()` 8806 @*/ 8807 PetscErrorCode MatIsSymmetric(Mat A, PetscReal tol, PetscBool *flg) { 8808 PetscFunctionBegin; 8809 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8810 PetscValidBoolPointer(flg, 3); 8811 8812 if (A->symmetric == PETSC_BOOL3_TRUE) *flg = PETSC_TRUE; 8813 else if (A->symmetric == PETSC_BOOL3_FALSE) *flg = PETSC_FALSE; 8814 else { 8815 if (!A->ops->issymmetric) { 8816 MatType mattype; 8817 PetscCall(MatGetType(A, &mattype)); 8818 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Matrix of type %s does not support checking for symmetric", mattype); 8819 } 8820 PetscUseTypeMethod(A, issymmetric, tol, flg); 8821 if (!tol) PetscCall(MatSetOption(A, MAT_SYMMETRIC, *flg)); 8822 } 8823 PetscFunctionReturn(0); 8824 } 8825 8826 /*@ 8827 MatIsHermitian - Test whether a matrix is Hermitian 8828 8829 Collective on Mat 8830 8831 Input Parameters: 8832 + A - the matrix to test 8833 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian) 8834 8835 Output Parameters: 8836 . flg - the result 8837 8838 Level: intermediate 8839 8840 Notes: 8841 For real numbers `MatIsSymmetric()` and `MatIsHermitian()` return identical results 8842 8843 If the matrix does not yet know if it is Hermitian or not this can be an expensive operation, also available `MatIsHermitianKnown()` 8844 8845 One can declare that a matrix is Hermitian with `MatSetOption`(mat,`MAT_HERMITIAN`,`PETSC_TRUE`) and if it is known to remain Hermitian 8846 after changes to the matrices values one can call `MatSetOption`(mat,`MAT_SYMEMTRY_ETERNAL`,`PETSC_TRUE`) 8847 8848 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitianKnown()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, 8849 `MatIsSymmetricKnown()`, `MatIsSymmetric()`, `MAT_HERMITIAN`, `MAT_SYMMETRY_ETERNAL`, `MatSetOption()` 8850 @*/ 8851 PetscErrorCode MatIsHermitian(Mat A, PetscReal tol, PetscBool *flg) { 8852 PetscFunctionBegin; 8853 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8854 PetscValidBoolPointer(flg, 3); 8855 8856 if (A->hermitian == PETSC_BOOL3_TRUE) *flg = PETSC_TRUE; 8857 else if (A->hermitian == PETSC_BOOL3_FALSE) *flg = PETSC_FALSE; 8858 else { 8859 if (!A->ops->ishermitian) { 8860 MatType mattype; 8861 PetscCall(MatGetType(A, &mattype)); 8862 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Matrix of type %s does not support checking for hermitian", mattype); 8863 } 8864 PetscUseTypeMethod(A, ishermitian, tol, flg); 8865 if (!tol) PetscCall(MatSetOption(A, MAT_HERMITIAN, *flg)); 8866 } 8867 PetscFunctionReturn(0); 8868 } 8869 8870 /*@ 8871 MatIsSymmetricKnown - Checks if a matrix knows if it is symmetric or not and its symmetric state 8872 8873 Not Collective 8874 8875 Input Parameter: 8876 . A - the matrix to check 8877 8878 Output Parameters: 8879 + set - `PETSC_TRUE` if the matrix knows its symmetry state (this tells you if the next flag is valid) 8880 - flg - the result (only valid if set is `PETSC_TRUE`) 8881 8882 Level: advanced 8883 8884 Notes: 8885 Does not check the matrix values directly, so this may return unknown (set = `PETSC_FALSE`). Use `MatIsSymmetric()` 8886 if you want it explicitly checked 8887 8888 One can declare that a matrix is symmetric with `MatSetOption`(mat,`MAT_SYMMETRIC`,`PETSC_TRUE`) and if it is known to remain symmetric 8889 after changes to the matrices values one can call `MatSetOption`(mat,`MAT_SYMMETRY_ETERNAL`,`PETSC_TRUE`) 8890 8891 .seealso: `MAT_SYMMETRY_ETERNAL`, `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitianKnown()` 8892 @*/ 8893 PetscErrorCode MatIsSymmetricKnown(Mat A, PetscBool *set, PetscBool *flg) { 8894 PetscFunctionBegin; 8895 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8896 PetscValidBoolPointer(set, 2); 8897 PetscValidBoolPointer(flg, 3); 8898 if (A->symmetric != PETSC_BOOL3_UNKNOWN) { 8899 *set = PETSC_TRUE; 8900 *flg = PetscBool3ToBool(A->symmetric); 8901 } else { 8902 *set = PETSC_FALSE; 8903 } 8904 PetscFunctionReturn(0); 8905 } 8906 8907 /*@ 8908 MatIsSPDKnown - Checks if a matrix knows if it is symmetric positive definite or not and its symmetric positive definite state 8909 8910 Not Collective 8911 8912 Input Parameter: 8913 . A - the matrix to check 8914 8915 Output Parameters: 8916 + set - `PETSC_TRUE` if the matrix knows its symmetric positive definite state (this tells you if the next flag is valid) 8917 - flg - the result (only valid if set is `PETSC_TRUE`) 8918 8919 Level: advanced 8920 8921 Notes: 8922 Does not check the matrix values directly, so this may return unknown (set = `PETSC_FALSE`). 8923 8924 One can declare that a matrix is SPD with `MatSetOption`(mat,`MAT_SPD`,`PETSC_TRUE`) and if it is known to remain SPD 8925 after changes to the matrices values one can call `MatSetOption`(mat,`MAT_SPD_ETERNAL`,`PETSC_TRUE`) 8926 8927 .seealso: `MAT_SPD_ETERNAL`, `MAT_SPD`, `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitianKnown()` 8928 @*/ 8929 PetscErrorCode MatIsSPDKnown(Mat A, PetscBool *set, PetscBool *flg) { 8930 PetscFunctionBegin; 8931 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8932 PetscValidBoolPointer(set, 2); 8933 PetscValidBoolPointer(flg, 3); 8934 if (A->spd != PETSC_BOOL3_UNKNOWN) { 8935 *set = PETSC_TRUE; 8936 *flg = PetscBool3ToBool(A->spd); 8937 } else { 8938 *set = PETSC_FALSE; 8939 } 8940 PetscFunctionReturn(0); 8941 } 8942 8943 /*@ 8944 MatIsHermitianKnown - Checks if a matrix knows if it is Hermitian or not and its Hermitian state 8945 8946 Not Collective 8947 8948 Input Parameter: 8949 . A - the matrix to check 8950 8951 Output Parameters: 8952 + set - `PETSC_TRUE` if the matrix knows its Hermitian state (this tells you if the next flag is valid) 8953 - flg - the result (only valid if set is `PETSC_TRUE`) 8954 8955 Level: advanced 8956 8957 Notes: 8958 Does not check the matrix values directly, so this may return unknown (set = `PETSC_FALSE`). Use `MatIsHermitian()` 8959 if you want it explicitly checked 8960 8961 One can declare that a matrix is Hermitian with `MatSetOption`(mat,`MAT_HERMITIAN`,`PETSC_TRUE`) and if it is known to remain Hermitian 8962 after changes to the matrices values one can call `MatSetOption`(mat,`MAT_SYMMETRY_ETERNAL`,`PETSC_TRUE`) 8963 8964 .seealso: `MAT_SYMMETRY_ETERNAL`, `MAT_HERMITIAN`, `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()` 8965 @*/ 8966 PetscErrorCode MatIsHermitianKnown(Mat A, PetscBool *set, PetscBool *flg) { 8967 PetscFunctionBegin; 8968 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8969 PetscValidBoolPointer(set, 2); 8970 PetscValidBoolPointer(flg, 3); 8971 if (A->hermitian != PETSC_BOOL3_UNKNOWN) { 8972 *set = PETSC_TRUE; 8973 *flg = PetscBool3ToBool(A->hermitian); 8974 } else { 8975 *set = PETSC_FALSE; 8976 } 8977 PetscFunctionReturn(0); 8978 } 8979 8980 /*@ 8981 MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric 8982 8983 Collective on Mat 8984 8985 Input Parameter: 8986 . A - the matrix to test 8987 8988 Output Parameters: 8989 . flg - the result 8990 8991 Notes: 8992 If the matrix does yet know it is structurally symmetric this can be an expensive operation, also available `MatIsStructurallySymmetricKnown()` 8993 8994 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 8995 symmetric after changes to the matrices values one can call `MatSetOption`(mat,`MAT_STRUCTURAL_SYMMETRY_ETERNAL`,`PETSC_TRUE`) 8996 8997 Level: intermediate 8998 8999 .seealso: `MAT_STRUCTURALLY_SYMMETRIC`, `MAT_STRUCTURAL_SYMMETRY_ETERNAL`, `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsSymmetric()`, `MatSetOption()`, `MatIsStructurallySymmetricKnown()` 9000 @*/ 9001 PetscErrorCode MatIsStructurallySymmetric(Mat A, PetscBool *flg) { 9002 PetscFunctionBegin; 9003 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 9004 PetscValidBoolPointer(flg, 2); 9005 if (A->structurally_symmetric != PETSC_BOOL3_UNKNOWN) { 9006 *flg = PetscBool3ToBool(A->structurally_symmetric); 9007 } else { 9008 PetscUseTypeMethod(A, isstructurallysymmetric, flg); 9009 PetscCall(MatSetOption(A, MAT_STRUCTURALLY_SYMMETRIC, *flg)); 9010 } 9011 PetscFunctionReturn(0); 9012 } 9013 9014 /*@ 9015 MatIsStructurallySymmetricKnown - Checks if a matrix knows if it is structurally symmetric or not and its structurally symmetric state 9016 9017 Not Collective 9018 9019 Input Parameter: 9020 . A - the matrix to check 9021 9022 Output Parameters: 9023 + set - PETSC_TRUE if the matrix knows its structurally symmetric state (this tells you if the next flag is valid) 9024 - flg - the result (only valid if set is PETSC_TRUE) 9025 9026 Level: advanced 9027 9028 Notes: 9029 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 9030 symmetric after changes to the matrices values one can call `MatSetOption`(mat,`MAT_STRUCTURAL_SYMMETRY_ETERNAL`,`PETSC_TRUE`) 9031 9032 Use `MatIsStructurallySymmetric()` to explicitly check if a matrix is structurally symmetric (this is an expensive operation) 9033 9034 .seealso: `MAT_STRUCTURALLY_SYMMETRIC`, `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitianKnown()` 9035 @*/ 9036 PetscErrorCode MatIsStructurallySymmetricKnown(Mat A, PetscBool *set, PetscBool *flg) { 9037 PetscFunctionBegin; 9038 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 9039 PetscValidBoolPointer(set, 2); 9040 PetscValidBoolPointer(flg, 3); 9041 if (A->structurally_symmetric != PETSC_BOOL3_UNKNOWN) { 9042 *set = PETSC_TRUE; 9043 *flg = PetscBool3ToBool(A->structurally_symmetric); 9044 } else { 9045 *set = PETSC_FALSE; 9046 } 9047 PetscFunctionReturn(0); 9048 } 9049 9050 /*@ 9051 MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need 9052 to be communicated to other processors during the `MatAssemblyBegin()`/`MatAssemblyEnd()` process 9053 9054 Not collective 9055 9056 Input Parameter: 9057 . mat - the matrix 9058 9059 Output Parameters: 9060 + nstash - the size of the stash 9061 . reallocs - the number of additional mallocs incurred. 9062 . bnstash - the size of the block stash 9063 - breallocs - the number of additional mallocs incurred.in the block stash 9064 9065 Level: advanced 9066 9067 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `Mat`, `MatStashSetInitialSize()` 9068 @*/ 9069 PetscErrorCode MatStashGetInfo(Mat mat, PetscInt *nstash, PetscInt *reallocs, PetscInt *bnstash, PetscInt *breallocs) { 9070 PetscFunctionBegin; 9071 PetscCall(MatStashGetInfo_Private(&mat->stash, nstash, reallocs)); 9072 PetscCall(MatStashGetInfo_Private(&mat->bstash, bnstash, breallocs)); 9073 PetscFunctionReturn(0); 9074 } 9075 9076 /*@C 9077 MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same 9078 parallel layout, `PetscLayout` for rows and columns 9079 9080 Collective on mat 9081 9082 Input Parameter: 9083 . mat - the matrix 9084 9085 Output Parameters: 9086 + right - (optional) vector that the matrix can be multiplied against 9087 - left - (optional) vector that the matrix vector product can be stored in 9088 9089 Notes: 9090 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()`. 9091 9092 These are new vectors which are not owned by the mat, they should be destroyed in `VecDestroy()` when no longer needed 9093 9094 Level: advanced 9095 9096 .seealso: `Mat`, `Vec`, `VecCreate()`, `VecDestroy()`, `DMCreateGlobalVector()` 9097 @*/ 9098 PetscErrorCode MatCreateVecs(Mat mat, Vec *right, Vec *left) { 9099 PetscFunctionBegin; 9100 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 9101 PetscValidType(mat, 1); 9102 if (mat->ops->getvecs) { 9103 PetscUseTypeMethod(mat, getvecs, right, left); 9104 } else { 9105 PetscInt rbs, cbs; 9106 PetscCall(MatGetBlockSizes(mat, &rbs, &cbs)); 9107 if (right) { 9108 PetscCheck(mat->cmap->n >= 0, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "PetscLayout for columns not yet setup"); 9109 PetscCall(VecCreate(PetscObjectComm((PetscObject)mat), right)); 9110 PetscCall(VecSetSizes(*right, mat->cmap->n, PETSC_DETERMINE)); 9111 PetscCall(VecSetBlockSize(*right, cbs)); 9112 PetscCall(VecSetType(*right, mat->defaultvectype)); 9113 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 9114 if (mat->boundtocpu && mat->bindingpropagates) { 9115 PetscCall(VecSetBindingPropagates(*right, PETSC_TRUE)); 9116 PetscCall(VecBindToCPU(*right, PETSC_TRUE)); 9117 } 9118 #endif 9119 PetscCall(PetscLayoutReference(mat->cmap, &(*right)->map)); 9120 } 9121 if (left) { 9122 PetscCheck(mat->rmap->n >= 0, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "PetscLayout for rows not yet setup"); 9123 PetscCall(VecCreate(PetscObjectComm((PetscObject)mat), left)); 9124 PetscCall(VecSetSizes(*left, mat->rmap->n, PETSC_DETERMINE)); 9125 PetscCall(VecSetBlockSize(*left, rbs)); 9126 PetscCall(VecSetType(*left, mat->defaultvectype)); 9127 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 9128 if (mat->boundtocpu && mat->bindingpropagates) { 9129 PetscCall(VecSetBindingPropagates(*left, PETSC_TRUE)); 9130 PetscCall(VecBindToCPU(*left, PETSC_TRUE)); 9131 } 9132 #endif 9133 PetscCall(PetscLayoutReference(mat->rmap, &(*left)->map)); 9134 } 9135 } 9136 PetscFunctionReturn(0); 9137 } 9138 9139 /*@C 9140 MatFactorInfoInitialize - Initializes a `MatFactorInfo` data structure 9141 with default values. 9142 9143 Not Collective 9144 9145 Input Parameters: 9146 . info - the `MatFactorInfo` data structure 9147 9148 Notes: 9149 The solvers are generally used through the `KSP` and `PC` objects, for example 9150 `PCLU`, `PCILU`, `PCCHOLESKY`, `PCICC` 9151 9152 Once the data structure is initialized one may change certain entries as desired for the particular factorization to be performed 9153 9154 Level: developer 9155 9156 Developer Note: 9157 The Fortran interface is not autogenerated as the f90 9158 interface definition cannot be generated correctly [due to `MatFactorInfo`] 9159 9160 .seealso: `MatGetFactor()`, `MatFactorInfo` 9161 @*/ 9162 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info) { 9163 PetscFunctionBegin; 9164 PetscCall(PetscMemzero(info, sizeof(MatFactorInfo))); 9165 PetscFunctionReturn(0); 9166 } 9167 9168 /*@ 9169 MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed 9170 9171 Collective on mat 9172 9173 Input Parameters: 9174 + mat - the factored matrix 9175 - is - the index set defining the Schur indices (0-based) 9176 9177 Notes: 9178 Call `MatFactorSolveSchurComplement()` or `MatFactorSolveSchurComplementTranspose()` after this call to solve a Schur complement system. 9179 9180 You can call `MatFactorGetSchurComplement()` or `MatFactorCreateSchurComplement()` after this call. 9181 9182 This functionality is only supported for `MATSOLVERMUMPS` and `MATSOLVERMKL_PARDISO` 9183 9184 Level: advanced 9185 9186 .seealso: `MatGetFactor()`, `MatFactorGetSchurComplement()`, `MatFactorRestoreSchurComplement()`, `MatFactorCreateSchurComplement()`, `MatFactorSolveSchurComplement()`, 9187 `MatFactorSolveSchurComplementTranspose()`, `MatFactorSolveSchurComplement()`, `MATSOLVERMUMPS`, `MATSOLVERMKL_PARDISO` 9188 9189 @*/ 9190 PetscErrorCode MatFactorSetSchurIS(Mat mat, IS is) { 9191 PetscErrorCode (*f)(Mat, IS); 9192 9193 PetscFunctionBegin; 9194 PetscValidType(mat, 1); 9195 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 9196 PetscValidType(is, 2); 9197 PetscValidHeaderSpecific(is, IS_CLASSID, 2); 9198 PetscCheckSameComm(mat, 1, is, 2); 9199 PetscCheck(mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Only for factored matrix"); 9200 PetscCall(PetscObjectQueryFunction((PetscObject)mat, "MatFactorSetSchurIS_C", &f)); 9201 PetscCheck(f, PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "The selected MatSolverType does not support Schur complement computation. You should use MATSOLVERMUMPS or MATSOLVERMKL_PARDISO"); 9202 PetscCall(MatDestroy(&mat->schur)); 9203 PetscCall((*f)(mat, is)); 9204 PetscCheck(mat->schur, PetscObjectComm((PetscObject)mat), PETSC_ERR_PLIB, "Schur complement has not been created"); 9205 PetscFunctionReturn(0); 9206 } 9207 9208 /*@ 9209 MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step 9210 9211 Logically Collective on mat 9212 9213 Input Parameters: 9214 + F - the factored matrix obtained by calling `MatGetFactor()` 9215 . S - location where to return the Schur complement, can be NULL 9216 - status - the status of the Schur complement matrix, can be NULL 9217 9218 Notes: 9219 You must call `MatFactorSetSchurIS()` before calling this routine. 9220 9221 This functionality is only supported for `MATSOLVERMUMPS` and `MATSOLVERMKL_PARDISO` 9222 9223 The routine provides a copy of the Schur matrix stored within the solver data structures. 9224 The caller must destroy the object when it is no longer needed. 9225 If `MatFactorInvertSchurComplement()` has been called, the routine gets back the inverse. 9226 9227 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) 9228 9229 See `MatCreateSchurComplement()` or `MatGetSchurComplement()` for ways to create virtual or approximate Schur complements. 9230 9231 Developer Note: 9232 The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc 9233 matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix. 9234 9235 Level: advanced 9236 9237 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorGetSchurComplement()`, `MatFactorSchurStatus`, `MATSOLVERMUMPS`, `MATSOLVERMKL_PARDISO` 9238 @*/ 9239 PetscErrorCode MatFactorCreateSchurComplement(Mat F, Mat *S, MatFactorSchurStatus *status) { 9240 PetscFunctionBegin; 9241 PetscValidHeaderSpecific(F, MAT_CLASSID, 1); 9242 if (S) PetscValidPointer(S, 2); 9243 if (status) PetscValidPointer(status, 3); 9244 if (S) { 9245 PetscErrorCode (*f)(Mat, Mat *); 9246 9247 PetscCall(PetscObjectQueryFunction((PetscObject)F, "MatFactorCreateSchurComplement_C", &f)); 9248 if (f) { 9249 PetscCall((*f)(F, S)); 9250 } else { 9251 PetscCall(MatDuplicate(F->schur, MAT_COPY_VALUES, S)); 9252 } 9253 } 9254 if (status) *status = F->schur_status; 9255 PetscFunctionReturn(0); 9256 } 9257 9258 /*@ 9259 MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix 9260 9261 Logically Collective on mat 9262 9263 Input Parameters: 9264 + F - the factored matrix obtained by calling `MatGetFactor()` 9265 . *S - location where to return the Schur complement, can be NULL 9266 - status - the status of the Schur complement matrix, can be NULL 9267 9268 Notes: 9269 You must call `MatFactorSetSchurIS()` before calling this routine. 9270 9271 Schur complement mode is currently implemented for sequential matrices with factor type of `MATSOLVERMUMPS` 9272 9273 The routine returns a the Schur Complement stored within the data strutures of the solver. 9274 9275 If `MatFactorInvertSchurComplement()` has previously been called, the returned matrix is actually the inverse of the Schur complement. 9276 9277 The returned matrix should not be destroyed; the caller should call `MatFactorRestoreSchurComplement()` when the object is no longer needed. 9278 9279 Use `MatFactorCreateSchurComplement()` to create a copy of the Schur complement matrix that is within a factored matrix 9280 9281 See `MatCreateSchurComplement()` or `MatGetSchurComplement()` for ways to create virtual or approximate Schur complements. 9282 9283 Level: advanced 9284 9285 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorRestoreSchurComplement()`, `MatFactorCreateSchurComplement()`, `MatFactorSchurStatus` 9286 @*/ 9287 PetscErrorCode MatFactorGetSchurComplement(Mat F, Mat *S, MatFactorSchurStatus *status) { 9288 PetscFunctionBegin; 9289 PetscValidHeaderSpecific(F, MAT_CLASSID, 1); 9290 if (S) PetscValidPointer(S, 2); 9291 if (status) PetscValidPointer(status, 3); 9292 if (S) *S = F->schur; 9293 if (status) *status = F->schur_status; 9294 PetscFunctionReturn(0); 9295 } 9296 9297 /*@ 9298 MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to `MatFactorGetSchurComplement()` 9299 9300 Logically Collective on mat 9301 9302 Input Parameters: 9303 + F - the factored matrix obtained by calling `MatGetFactor()` 9304 . *S - location where the Schur complement is stored 9305 - status - the status of the Schur complement matrix (see `MatFactorSchurStatus`) 9306 9307 Level: advanced 9308 9309 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorRestoreSchurComplement()`, `MatFactorCreateSchurComplement()`, `MatFactorSchurStatus` 9310 @*/ 9311 PetscErrorCode MatFactorRestoreSchurComplement(Mat F, Mat *S, MatFactorSchurStatus status) { 9312 PetscFunctionBegin; 9313 PetscValidHeaderSpecific(F, MAT_CLASSID, 1); 9314 if (S) { 9315 PetscValidHeaderSpecific(*S, MAT_CLASSID, 2); 9316 *S = NULL; 9317 } 9318 F->schur_status = status; 9319 PetscCall(MatFactorUpdateSchurStatus_Private(F)); 9320 PetscFunctionReturn(0); 9321 } 9322 9323 /*@ 9324 MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step 9325 9326 Logically Collective on mat 9327 9328 Input Parameters: 9329 + F - the factored matrix obtained by calling `MatGetFactor()` 9330 . rhs - location where the right hand side of the Schur complement system is stored 9331 - sol - location where the solution of the Schur complement system has to be returned 9332 9333 Notes: 9334 The sizes of the vectors should match the size of the Schur complement 9335 9336 Must be called after `MatFactorSetSchurIS()` 9337 9338 Level: advanced 9339 9340 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorSolveSchurComplement()` 9341 @*/ 9342 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol) { 9343 PetscFunctionBegin; 9344 PetscValidType(F, 1); 9345 PetscValidType(rhs, 2); 9346 PetscValidType(sol, 3); 9347 PetscValidHeaderSpecific(F, MAT_CLASSID, 1); 9348 PetscValidHeaderSpecific(rhs, VEC_CLASSID, 2); 9349 PetscValidHeaderSpecific(sol, VEC_CLASSID, 3); 9350 PetscCheckSameComm(F, 1, rhs, 2); 9351 PetscCheckSameComm(F, 1, sol, 3); 9352 PetscCall(MatFactorFactorizeSchurComplement(F)); 9353 switch (F->schur_status) { 9354 case MAT_FACTOR_SCHUR_FACTORED: PetscCall(MatSolveTranspose(F->schur, rhs, sol)); break; 9355 case MAT_FACTOR_SCHUR_INVERTED: PetscCall(MatMultTranspose(F->schur, rhs, sol)); break; 9356 default: SETERRQ(PetscObjectComm((PetscObject)F), PETSC_ERR_SUP, "Unhandled MatFactorSchurStatus %d", F->schur_status); 9357 } 9358 PetscFunctionReturn(0); 9359 } 9360 9361 /*@ 9362 MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step 9363 9364 Logically Collective on mat 9365 9366 Input Parameters: 9367 + F - the factored matrix obtained by calling `MatGetFactor()` 9368 . rhs - location where the right hand side of the Schur complement system is stored 9369 - sol - location where the solution of the Schur complement system has to be returned 9370 9371 Notes: 9372 The sizes of the vectors should match the size of the Schur complement 9373 9374 Must be called after `MatFactorSetSchurIS()` 9375 9376 Level: advanced 9377 9378 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorSolveSchurComplementTranspose()` 9379 @*/ 9380 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol) { 9381 PetscFunctionBegin; 9382 PetscValidType(F, 1); 9383 PetscValidType(rhs, 2); 9384 PetscValidType(sol, 3); 9385 PetscValidHeaderSpecific(F, MAT_CLASSID, 1); 9386 PetscValidHeaderSpecific(rhs, VEC_CLASSID, 2); 9387 PetscValidHeaderSpecific(sol, VEC_CLASSID, 3); 9388 PetscCheckSameComm(F, 1, rhs, 2); 9389 PetscCheckSameComm(F, 1, sol, 3); 9390 PetscCall(MatFactorFactorizeSchurComplement(F)); 9391 switch (F->schur_status) { 9392 case MAT_FACTOR_SCHUR_FACTORED: PetscCall(MatSolve(F->schur, rhs, sol)); break; 9393 case MAT_FACTOR_SCHUR_INVERTED: PetscCall(MatMult(F->schur, rhs, sol)); break; 9394 default: SETERRQ(PetscObjectComm((PetscObject)F), PETSC_ERR_SUP, "Unhandled MatFactorSchurStatus %d", F->schur_status); 9395 } 9396 PetscFunctionReturn(0); 9397 } 9398 9399 /*@ 9400 MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step 9401 9402 Logically Collective on F 9403 9404 Input Parameters: 9405 . F - the factored matrix obtained by calling `MatGetFactor()` 9406 9407 Notes: 9408 Must be called after `MatFactorSetSchurIS()`. 9409 9410 Call `MatFactorGetSchurComplement()` or `MatFactorCreateSchurComplement()` AFTER this call to actually compute the inverse and get access to it. 9411 9412 Level: advanced 9413 9414 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorGetSchurComplement()`, `MatFactorCreateSchurComplement()` 9415 @*/ 9416 PetscErrorCode MatFactorInvertSchurComplement(Mat F) { 9417 PetscFunctionBegin; 9418 PetscValidType(F, 1); 9419 PetscValidHeaderSpecific(F, MAT_CLASSID, 1); 9420 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0); 9421 PetscCall(MatFactorFactorizeSchurComplement(F)); 9422 PetscCall(MatFactorInvertSchurComplement_Private(F)); 9423 F->schur_status = MAT_FACTOR_SCHUR_INVERTED; 9424 PetscFunctionReturn(0); 9425 } 9426 9427 /*@ 9428 MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step 9429 9430 Logically Collective on mat 9431 9432 Input Parameters: 9433 . F - the factored matrix obtained by calling `MatGetFactor()` 9434 9435 Note: 9436 Must be called after `MatFactorSetSchurIS()` 9437 9438 Level: advanced 9439 9440 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorInvertSchurComplement()` 9441 @*/ 9442 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F) { 9443 PetscFunctionBegin; 9444 PetscValidType(F, 1); 9445 PetscValidHeaderSpecific(F, MAT_CLASSID, 1); 9446 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0); 9447 PetscCall(MatFactorFactorizeSchurComplement_Private(F)); 9448 F->schur_status = MAT_FACTOR_SCHUR_FACTORED; 9449 PetscFunctionReturn(0); 9450 } 9451 9452 /*@ 9453 MatPtAP - Creates the matrix product C = P^T * A * P 9454 9455 Neighbor-wise Collective on A 9456 9457 Input Parameters: 9458 + A - the matrix 9459 . P - the projection matrix 9460 . scall - either `MAT_INITIAL_MATRIX` or `MAT_REUSE_MATRIX` 9461 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use `PETSC_DEFAULT` if you do not have a good estimate 9462 if the result is a dense matrix this is irrelevant 9463 9464 Output Parameters: 9465 . C - the product matrix 9466 9467 Notes: 9468 C will be created and must be destroyed by the user with `MatDestroy()`. 9469 9470 An alternative approach to this function is to use `MatProductCreate()` and set the desired options before the computation is done 9471 9472 Developer Note: 9473 For matrix types without special implementation the function fallbacks to `MatMatMult()` followed by `MatTransposeMatMult()`. 9474 9475 Level: intermediate 9476 9477 .seealso: `MatProductCreate()`, `MatMatMult()`, `MatRARt()` 9478 @*/ 9479 PetscErrorCode MatPtAP(Mat A, Mat P, MatReuse scall, PetscReal fill, Mat *C) { 9480 PetscFunctionBegin; 9481 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*C, 5); 9482 PetscCheck(scall != MAT_INPLACE_MATRIX, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Inplace product not supported"); 9483 9484 if (scall == MAT_INITIAL_MATRIX) { 9485 PetscCall(MatProductCreate(A, P, NULL, C)); 9486 PetscCall(MatProductSetType(*C, MATPRODUCT_PtAP)); 9487 PetscCall(MatProductSetAlgorithm(*C, "default")); 9488 PetscCall(MatProductSetFill(*C, fill)); 9489 9490 (*C)->product->api_user = PETSC_TRUE; 9491 PetscCall(MatProductSetFromOptions(*C)); 9492 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); 9493 PetscCall(MatProductSymbolic(*C)); 9494 } else { /* scall == MAT_REUSE_MATRIX */ 9495 PetscCall(MatProductReplaceMats(A, P, NULL, *C)); 9496 } 9497 9498 PetscCall(MatProductNumeric(*C)); 9499 (*C)->symmetric = A->symmetric; 9500 (*C)->spd = A->spd; 9501 PetscFunctionReturn(0); 9502 } 9503 9504 /*@ 9505 MatRARt - Creates the matrix product C = R * A * R^T 9506 9507 Neighbor-wise Collective on A 9508 9509 Input Parameters: 9510 + A - the matrix 9511 . R - the projection matrix 9512 . scall - either `MAT_INITIAL_MATRIX` or `MAT_REUSE_MATRIX` 9513 - fill - expected fill as ratio of nnz(C)/nnz(A), use `PETSC_DEFAULT` if you do not have a good estimate 9514 if the result is a dense matrix this is irrelevant 9515 9516 Output Parameters: 9517 . C - the product matrix 9518 9519 Notes: 9520 C will be created and must be destroyed by the user with `MatDestroy()`. 9521 9522 An alternative approach to this function is to use `MatProductCreate()` and set the desired options before the computation is done 9523 9524 This routine is currently only implemented for pairs of `MATAIJ` matrices and classes 9525 which inherit from `MATAIJ`. Due to PETSc sparse matrix block row distribution among processes, 9526 parallel MatRARt is implemented via explicit transpose of R, which could be very expensive. 9527 We recommend using MatPtAP(). 9528 9529 Level: intermediate 9530 9531 .seealso: `MatProductCreate()`, `MatMatMult()`, `MatPtAP()` 9532 @*/ 9533 PetscErrorCode MatRARt(Mat A, Mat R, MatReuse scall, PetscReal fill, Mat *C) { 9534 PetscFunctionBegin; 9535 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*C, 5); 9536 PetscCheck(scall != MAT_INPLACE_MATRIX, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Inplace product not supported"); 9537 9538 if (scall == MAT_INITIAL_MATRIX) { 9539 PetscCall(MatProductCreate(A, R, NULL, C)); 9540 PetscCall(MatProductSetType(*C, MATPRODUCT_RARt)); 9541 PetscCall(MatProductSetAlgorithm(*C, "default")); 9542 PetscCall(MatProductSetFill(*C, fill)); 9543 9544 (*C)->product->api_user = PETSC_TRUE; 9545 PetscCall(MatProductSetFromOptions(*C)); 9546 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); 9547 PetscCall(MatProductSymbolic(*C)); 9548 } else { /* scall == MAT_REUSE_MATRIX */ 9549 PetscCall(MatProductReplaceMats(A, R, NULL, *C)); 9550 } 9551 9552 PetscCall(MatProductNumeric(*C)); 9553 if (A->symmetric == PETSC_BOOL3_TRUE) PetscCall(MatSetOption(*C, MAT_SYMMETRIC, PETSC_TRUE)); 9554 PetscFunctionReturn(0); 9555 } 9556 9557 static PetscErrorCode MatProduct_Private(Mat A, Mat B, MatReuse scall, PetscReal fill, MatProductType ptype, Mat *C) { 9558 PetscFunctionBegin; 9559 PetscCheck(scall != MAT_INPLACE_MATRIX, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Inplace product not supported"); 9560 9561 if (scall == MAT_INITIAL_MATRIX) { 9562 PetscCall(PetscInfo(A, "Calling MatProduct API with MAT_INITIAL_MATRIX and product type %s\n", MatProductTypes[ptype])); 9563 PetscCall(MatProductCreate(A, B, NULL, C)); 9564 PetscCall(MatProductSetType(*C, ptype)); 9565 PetscCall(MatProductSetAlgorithm(*C, MATPRODUCTALGORITHMDEFAULT)); 9566 PetscCall(MatProductSetFill(*C, fill)); 9567 9568 (*C)->product->api_user = PETSC_TRUE; 9569 PetscCall(MatProductSetFromOptions(*C)); 9570 PetscCall(MatProductSymbolic(*C)); 9571 } else { /* scall == MAT_REUSE_MATRIX */ 9572 Mat_Product *product = (*C)->product; 9573 PetscBool isdense; 9574 9575 PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)(*C), &isdense, MATSEQDENSE, MATMPIDENSE, "")); 9576 if (isdense && product && product->type != ptype) { 9577 PetscCall(MatProductClear(*C)); 9578 product = NULL; 9579 } 9580 PetscCall(PetscInfo(A, "Calling MatProduct API with MAT_REUSE_MATRIX %s product present and product type %s\n", product ? "with" : "without", MatProductTypes[ptype])); 9581 if (!product) { /* user provide the dense matrix *C without calling MatProductCreate() or reusing it from previous calls */ 9582 if (isdense) { 9583 PetscCall(MatProductCreate_Private(A, B, NULL, *C)); 9584 product = (*C)->product; 9585 product->fill = fill; 9586 product->api_user = PETSC_TRUE; 9587 product->clear = PETSC_TRUE; 9588 9589 PetscCall(MatProductSetType(*C, ptype)); 9590 PetscCall(MatProductSetFromOptions(*C)); 9591 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); 9592 PetscCall(MatProductSymbolic(*C)); 9593 } else SETERRQ(PetscObjectComm((PetscObject)(*C)), PETSC_ERR_SUP, "Call MatProductCreate() first"); 9594 } else { /* user may change input matrices A or B when REUSE */ 9595 PetscCall(MatProductReplaceMats(A, B, NULL, *C)); 9596 } 9597 } 9598 PetscCall(MatProductNumeric(*C)); 9599 PetscFunctionReturn(0); 9600 } 9601 9602 /*@ 9603 MatMatMult - Performs matrix-matrix multiplication C=A*B. 9604 9605 Neighbor-wise Collective on A 9606 9607 Input Parameters: 9608 + A - the left matrix 9609 . B - the right matrix 9610 . scall - either `MAT_INITIAL_MATRIX` or `MAT_REUSE_MATRIX` 9611 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use `PETSC_DEFAULT` if you do not have a good estimate 9612 if the result is a dense matrix this is irrelevant 9613 9614 Output Parameters: 9615 . C - the product matrix 9616 9617 Notes: 9618 Unless scall is `MAT_REUSE_MATRIX` C will be created. 9619 9620 `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 9621 call to this function with `MAT_INITIAL_MATRIX`. 9622 9623 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value actually needed. 9624 9625 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`, 9626 rather than first having `MatMatMult()` create it for you. You can NEVER do this if the matrix C is sparse. 9627 9628 Example of Usage: 9629 .vb 9630 MatProductCreate(A,B,NULL,&C); 9631 MatProductSetType(C,MATPRODUCT_AB); 9632 MatProductSymbolic(C); 9633 MatProductNumeric(C); // compute C=A * B 9634 MatProductReplaceMats(A1,B1,NULL,C); // compute C=A1 * B1 9635 MatProductNumeric(C); 9636 MatProductReplaceMats(A2,NULL,NULL,C); // compute C=A2 * B1 9637 MatProductNumeric(C); 9638 .ve 9639 9640 Level: intermediate 9641 9642 .seealso: `MatProductType`, `MATPRODUCT_AB`, `MatTransposeMatMult()`, `MatMatTransposeMult()`, `MatPtAP()`, `MatProductCreate()`, `MatProductSymbolic()`, `MatProductReplaceMats()`, `MatProductNumeric()` 9643 @*/ 9644 PetscErrorCode MatMatMult(Mat A, Mat B, MatReuse scall, PetscReal fill, Mat *C) { 9645 PetscFunctionBegin; 9646 PetscCall(MatProduct_Private(A, B, scall, fill, MATPRODUCT_AB, C)); 9647 PetscFunctionReturn(0); 9648 } 9649 9650 /*@ 9651 MatMatTransposeMult - Performs matrix-matrix multiplication C=A*B^T. 9652 9653 Neighbor-wise Collective on A 9654 9655 Input Parameters: 9656 + A - the left matrix 9657 . B - the right matrix 9658 . scall - either `MAT_INITIAL_MATRIX` or `MAT_REUSE_MATRIX` 9659 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use `PETSC_DEFAULT` if not known 9660 9661 Output Parameters: 9662 . C - the product matrix 9663 9664 Notes: 9665 C will be created if `MAT_INITIAL_MATRIX` and must be destroyed by the user with `MatDestroy()`. 9666 9667 `MAT_REUSE_MATRIX` can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9668 9669 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9670 actually needed. 9671 9672 This routine is currently only implemented for pairs of `MATSEQAIJ` matrices, for the `MATSEQDENSE` class, 9673 and for pairs of `MATMPIDENSE` matrices. 9674 9675 This routine is shorthand for using `MatProductCreate()` with the `MatProductType` of `MATPRODUCT_ABt` 9676 9677 Options Database Keys: 9678 . -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorithms for `MATMPIDENSE` matrices: the 9679 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity; 9680 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity. 9681 9682 Level: intermediate 9683 9684 .seealso: `MatProductCreate()`, `MATPRODUCT_ABt`, `MatMatMult()`, `MatTransposeMatMult()` `MatPtAP()`, `MatProductCreate()`, `MatProductAlgorithm`, `MatProductType`, `MATPRODUCT_ABt` 9685 @*/ 9686 PetscErrorCode MatMatTransposeMult(Mat A, Mat B, MatReuse scall, PetscReal fill, Mat *C) { 9687 PetscFunctionBegin; 9688 PetscCall(MatProduct_Private(A, B, scall, fill, MATPRODUCT_ABt, C)); 9689 if (A == B) PetscCall(MatSetOption(*C, MAT_SYMMETRIC, PETSC_TRUE)); 9690 PetscFunctionReturn(0); 9691 } 9692 9693 /*@ 9694 MatTransposeMatMult - Performs matrix-matrix multiplication C=A^T*B. 9695 9696 Neighbor-wise Collective on A 9697 9698 Input Parameters: 9699 + A - the left matrix 9700 . B - the right matrix 9701 . scall - either `MAT_INITIAL_MATRIX` or `MAT_REUSE_MATRIX` 9702 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use `PETSC_DEFAULT` if not known 9703 9704 Output Parameters: 9705 . C - the product matrix 9706 9707 Notes: 9708 C will be created if `MAT_INITIAL_MATRIX` and must be destroyed by the user with `MatDestroy()`. 9709 9710 `MAT_REUSE_MATRIX` can only be used if the matrices A and B have the same nonzero pattern as in the previous call. 9711 9712 This routine is shorthand for using `MatProductCreate()` with the `MatProductType` of `MATPRODUCT_AtB` 9713 9714 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9715 actually needed. 9716 9717 This routine is currently implemented for pairs of `MATAIJ` matrices and pairs of `MATSEQDENSE` matrices and classes 9718 which inherit from `MATSEQAIJ`. C will be of the same type as the input matrices. 9719 9720 Level: intermediate 9721 9722 .seealso: `MatProductCreate()`, `MATPRODUCT_AtB`, `MatMatMult()`, `MatMatTransposeMult()`, `MatPtAP()` 9723 @*/ 9724 PetscErrorCode MatTransposeMatMult(Mat A, Mat B, MatReuse scall, PetscReal fill, Mat *C) { 9725 PetscFunctionBegin; 9726 PetscCall(MatProduct_Private(A, B, scall, fill, MATPRODUCT_AtB, C)); 9727 PetscFunctionReturn(0); 9728 } 9729 9730 /*@ 9731 MatMatMatMult - Performs matrix-matrix-matrix multiplication D=A*B*C. 9732 9733 Neighbor-wise Collective on A 9734 9735 Input Parameters: 9736 + A - the left matrix 9737 . B - the middle matrix 9738 . C - the right matrix 9739 . scall - either `MAT_INITIAL_MATRIX` or `MAT_REUSE_MATRIX` 9740 - 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 9741 if the result is a dense matrix this is irrelevant 9742 9743 Output Parameters: 9744 . D - the product matrix 9745 9746 Notes: 9747 Unless scall is `MAT_REUSE_MATRIX` D will be created. 9748 9749 `MAT_REUSE_MATRIX` can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call 9750 9751 This routine is shorthand for using `MatProductCreate()` with the `MatProductType` of `MATPRODUCT_ABC` 9752 9753 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9754 actually needed. 9755 9756 If you have many matrices with the same non-zero structure to multiply, you 9757 should use `MAT_REUSE_MATRIX` in all calls but the first 9758 9759 Level: intermediate 9760 9761 .seealso: `MatProductCreate()`, `MATPRODUCT_ABC`, `MatMatMult`, `MatPtAP()`, `MatMatTransposeMult()`, `MatTransposeMatMult()` 9762 @*/ 9763 PetscErrorCode MatMatMatMult(Mat A, Mat B, Mat C, MatReuse scall, PetscReal fill, Mat *D) { 9764 PetscFunctionBegin; 9765 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*D, 6); 9766 PetscCheck(scall != MAT_INPLACE_MATRIX, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Inplace product not supported"); 9767 9768 if (scall == MAT_INITIAL_MATRIX) { 9769 PetscCall(MatProductCreate(A, B, C, D)); 9770 PetscCall(MatProductSetType(*D, MATPRODUCT_ABC)); 9771 PetscCall(MatProductSetAlgorithm(*D, "default")); 9772 PetscCall(MatProductSetFill(*D, fill)); 9773 9774 (*D)->product->api_user = PETSC_TRUE; 9775 PetscCall(MatProductSetFromOptions(*D)); 9776 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, 9777 ((PetscObject)C)->type_name); 9778 PetscCall(MatProductSymbolic(*D)); 9779 } else { /* user may change input matrices when REUSE */ 9780 PetscCall(MatProductReplaceMats(A, B, C, *D)); 9781 } 9782 PetscCall(MatProductNumeric(*D)); 9783 PetscFunctionReturn(0); 9784 } 9785 9786 /*@ 9787 MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators. 9788 9789 Collective on mat 9790 9791 Input Parameters: 9792 + mat - the matrix 9793 . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices) 9794 . subcomm - MPI communicator split from the communicator where mat resides in (or `MPI_COMM_NULL` if nsubcomm is used) 9795 - reuse - either `MAT_INITIAL_MATRIX` or `MAT_REUSE_MATRIX` 9796 9797 Output Parameter: 9798 . matredundant - redundant matrix 9799 9800 Notes: 9801 `MAT_REUSE_MATRIX` can only be used when the nonzero structure of the 9802 original matrix has not changed from that last call to MatCreateRedundantMatrix(). 9803 9804 This routine creates the duplicated matrices in the subcommunicators; you should NOT create them before 9805 calling it. 9806 9807 `PetscSubcommCreate()` can be used to manage the creation of the subcomm but need not be. 9808 9809 Level: advanced 9810 9811 .seealso: `MatDestroy()`, `PetscSubcommCreate()`, `PetscSubComm` 9812 @*/ 9813 PetscErrorCode MatCreateRedundantMatrix(Mat mat, PetscInt nsubcomm, MPI_Comm subcomm, MatReuse reuse, Mat *matredundant) { 9814 MPI_Comm comm; 9815 PetscMPIInt size; 9816 PetscInt mloc_sub, nloc_sub, rstart, rend, M = mat->rmap->N, N = mat->cmap->N, bs = mat->rmap->bs; 9817 Mat_Redundant *redund = NULL; 9818 PetscSubcomm psubcomm = NULL; 9819 MPI_Comm subcomm_in = subcomm; 9820 Mat *matseq; 9821 IS isrow, iscol; 9822 PetscBool newsubcomm = PETSC_FALSE; 9823 9824 PetscFunctionBegin; 9825 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 9826 if (nsubcomm && reuse == MAT_REUSE_MATRIX) { 9827 PetscValidPointer(*matredundant, 5); 9828 PetscValidHeaderSpecific(*matredundant, MAT_CLASSID, 5); 9829 } 9830 9831 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size)); 9832 if (size == 1 || nsubcomm == 1) { 9833 if (reuse == MAT_INITIAL_MATRIX) { 9834 PetscCall(MatDuplicate(mat, MAT_COPY_VALUES, matredundant)); 9835 } else { 9836 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"); 9837 PetscCall(MatCopy(mat, *matredundant, SAME_NONZERO_PATTERN)); 9838 } 9839 PetscFunctionReturn(0); 9840 } 9841 9842 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 9843 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 9844 MatCheckPreallocated(mat, 1); 9845 9846 PetscCall(PetscLogEventBegin(MAT_RedundantMat, mat, 0, 0, 0)); 9847 if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */ 9848 /* create psubcomm, then get subcomm */ 9849 PetscCall(PetscObjectGetComm((PetscObject)mat, &comm)); 9850 PetscCallMPI(MPI_Comm_size(comm, &size)); 9851 PetscCheck(nsubcomm >= 1 && nsubcomm <= size, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "nsubcomm must between 1 and %d", size); 9852 9853 PetscCall(PetscSubcommCreate(comm, &psubcomm)); 9854 PetscCall(PetscSubcommSetNumber(psubcomm, nsubcomm)); 9855 PetscCall(PetscSubcommSetType(psubcomm, PETSC_SUBCOMM_CONTIGUOUS)); 9856 PetscCall(PetscSubcommSetFromOptions(psubcomm)); 9857 PetscCall(PetscCommDuplicate(PetscSubcommChild(psubcomm), &subcomm, NULL)); 9858 newsubcomm = PETSC_TRUE; 9859 PetscCall(PetscSubcommDestroy(&psubcomm)); 9860 } 9861 9862 /* get isrow, iscol and a local sequential matrix matseq[0] */ 9863 if (reuse == MAT_INITIAL_MATRIX) { 9864 mloc_sub = PETSC_DECIDE; 9865 nloc_sub = PETSC_DECIDE; 9866 if (bs < 1) { 9867 PetscCall(PetscSplitOwnership(subcomm, &mloc_sub, &M)); 9868 PetscCall(PetscSplitOwnership(subcomm, &nloc_sub, &N)); 9869 } else { 9870 PetscCall(PetscSplitOwnershipBlock(subcomm, bs, &mloc_sub, &M)); 9871 PetscCall(PetscSplitOwnershipBlock(subcomm, bs, &nloc_sub, &N)); 9872 } 9873 PetscCallMPI(MPI_Scan(&mloc_sub, &rend, 1, MPIU_INT, MPI_SUM, subcomm)); 9874 rstart = rend - mloc_sub; 9875 PetscCall(ISCreateStride(PETSC_COMM_SELF, mloc_sub, rstart, 1, &isrow)); 9876 PetscCall(ISCreateStride(PETSC_COMM_SELF, N, 0, 1, &iscol)); 9877 } else { /* reuse == MAT_REUSE_MATRIX */ 9878 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"); 9879 /* retrieve subcomm */ 9880 PetscCall(PetscObjectGetComm((PetscObject)(*matredundant), &subcomm)); 9881 redund = (*matredundant)->redundant; 9882 isrow = redund->isrow; 9883 iscol = redund->iscol; 9884 matseq = redund->matseq; 9885 } 9886 PetscCall(MatCreateSubMatrices(mat, 1, &isrow, &iscol, reuse, &matseq)); 9887 9888 /* get matredundant over subcomm */ 9889 if (reuse == MAT_INITIAL_MATRIX) { 9890 PetscCall(MatCreateMPIMatConcatenateSeqMat(subcomm, matseq[0], nloc_sub, reuse, matredundant)); 9891 9892 /* create a supporting struct and attach it to C for reuse */ 9893 PetscCall(PetscNewLog(*matredundant, &redund)); 9894 (*matredundant)->redundant = redund; 9895 redund->isrow = isrow; 9896 redund->iscol = iscol; 9897 redund->matseq = matseq; 9898 if (newsubcomm) { 9899 redund->subcomm = subcomm; 9900 } else { 9901 redund->subcomm = MPI_COMM_NULL; 9902 } 9903 } else { 9904 PetscCall(MatCreateMPIMatConcatenateSeqMat(subcomm, matseq[0], PETSC_DECIDE, reuse, matredundant)); 9905 } 9906 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 9907 if (matseq[0]->boundtocpu && matseq[0]->bindingpropagates) { 9908 PetscCall(MatBindToCPU(*matredundant, PETSC_TRUE)); 9909 PetscCall(MatSetBindingPropagates(*matredundant, PETSC_TRUE)); 9910 } 9911 #endif 9912 PetscCall(PetscLogEventEnd(MAT_RedundantMat, mat, 0, 0, 0)); 9913 PetscFunctionReturn(0); 9914 } 9915 9916 /*@C 9917 MatGetMultiProcBlock - Create multiple 'parallel submatrices' from 9918 a given `Mat`. Each submatrix can span multiple procs. 9919 9920 Collective on mat 9921 9922 Input Parameters: 9923 + mat - the matrix 9924 . subcomm - the subcommunicator obtained by MPI_Com_split(comm) 9925 - scall - either `MAT_INITIAL_MATRIX` or `MAT_REUSE_MATRIX` 9926 9927 Output Parameter: 9928 . subMat - 'parallel submatrices each spans a given subcomm 9929 9930 Notes: 9931 The submatrix partition across processors is dictated by 'subComm' a 9932 communicator obtained by MPI_comm_split() or via `PetscSubcommCreate()`. The subComm 9933 is not restriced to be grouped with consecutive original ranks. 9934 9935 Due the MPI_Comm_split() usage, the parallel layout of the submatrices 9936 map directly to the layout of the original matrix [wrt the local 9937 row,col partitioning]. So the original 'DiagonalMat' naturally maps 9938 into the 'DiagonalMat' of the subMat, hence it is used directly from 9939 the subMat. However the offDiagMat looses some columns - and this is 9940 reconstructed with `MatSetValues()` 9941 9942 This is used by `PCBJACOBI` when a single block spans multiple MPI ranks 9943 9944 Level: advanced 9945 9946 .seealso: `MatCreateRedundantMatrix()`, `MatCreateSubMatrices()`, `PCBJACOBI` 9947 @*/ 9948 PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall, Mat *subMat) { 9949 PetscMPIInt commsize, subCommSize; 9950 9951 PetscFunctionBegin; 9952 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat), &commsize)); 9953 PetscCallMPI(MPI_Comm_size(subComm, &subCommSize)); 9954 PetscCheck(subCommSize <= commsize, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_OUTOFRANGE, "CommSize %d < SubCommZize %d", commsize, subCommSize); 9955 9956 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"); 9957 PetscCall(PetscLogEventBegin(MAT_GetMultiProcBlock, mat, 0, 0, 0)); 9958 PetscUseTypeMethod(mat, getmultiprocblock, subComm, scall, subMat); 9959 PetscCall(PetscLogEventEnd(MAT_GetMultiProcBlock, mat, 0, 0, 0)); 9960 PetscFunctionReturn(0); 9961 } 9962 9963 /*@ 9964 MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering 9965 9966 Not Collective 9967 9968 Input Parameters: 9969 + mat - matrix to extract local submatrix from 9970 . isrow - local row indices for submatrix 9971 - iscol - local column indices for submatrix 9972 9973 Output Parameter: 9974 . submat - the submatrix 9975 9976 Level: intermediate 9977 9978 Notes: 9979 The submat should be returned with `MatRestoreLocalSubMatrix()`. 9980 9981 Depending on the format of mat, the returned submat may not implement `MatMult()`. Its communicator may be 9982 the same as mat, it may be `PETSC_COMM_SELF`, or some other subcomm of mat's. 9983 9984 The submat always implements `MatSetValuesLocal()`. If isrow and iscol have the same block size, then 9985 `MatSetValuesBlockedLocal()` will also be implemented. 9986 9987 The mat must have had a `ISLocalToGlobalMapping` provided to it with `MatSetLocalToGlobalMapping()`. 9988 Matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided. 9989 9990 .seealso: `MatRestoreLocalSubMatrix()`, `MatCreateLocalRef()`, `MatSetLocalToGlobalMapping()` 9991 @*/ 9992 PetscErrorCode MatGetLocalSubMatrix(Mat mat, IS isrow, IS iscol, Mat *submat) { 9993 PetscFunctionBegin; 9994 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 9995 PetscValidHeaderSpecific(isrow, IS_CLASSID, 2); 9996 PetscValidHeaderSpecific(iscol, IS_CLASSID, 3); 9997 PetscCheckSameComm(isrow, 2, iscol, 3); 9998 PetscValidPointer(submat, 4); 9999 PetscCheck(mat->rmap->mapping, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Matrix must have local to global mapping provided before this call"); 10000 10001 if (mat->ops->getlocalsubmatrix) { 10002 PetscUseTypeMethod(mat, getlocalsubmatrix, isrow, iscol, submat); 10003 } else { 10004 PetscCall(MatCreateLocalRef(mat, isrow, iscol, submat)); 10005 } 10006 PetscFunctionReturn(0); 10007 } 10008 10009 /*@ 10010 MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering obtained with `MatGetLocalSubMatrix()` 10011 10012 Not Collective 10013 10014 Input Parameters: 10015 + mat - matrix to extract local submatrix from 10016 . isrow - local row indices for submatrix 10017 . iscol - local column indices for submatrix 10018 - submat - the submatrix 10019 10020 Level: intermediate 10021 10022 .seealso: `MatGetLocalSubMatrix()` 10023 @*/ 10024 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat, IS isrow, IS iscol, Mat *submat) { 10025 PetscFunctionBegin; 10026 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 10027 PetscValidHeaderSpecific(isrow, IS_CLASSID, 2); 10028 PetscValidHeaderSpecific(iscol, IS_CLASSID, 3); 10029 PetscCheckSameComm(isrow, 2, iscol, 3); 10030 PetscValidPointer(submat, 4); 10031 if (*submat) PetscValidHeaderSpecific(*submat, MAT_CLASSID, 4); 10032 10033 if (mat->ops->restorelocalsubmatrix) { 10034 PetscUseTypeMethod(mat, restorelocalsubmatrix, isrow, iscol, submat); 10035 } else { 10036 PetscCall(MatDestroy(submat)); 10037 } 10038 *submat = NULL; 10039 PetscFunctionReturn(0); 10040 } 10041 10042 /* --------------------------------------------------------*/ 10043 /*@ 10044 MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix 10045 10046 Collective on mat 10047 10048 Input Parameter: 10049 . mat - the matrix 10050 10051 Output Parameter: 10052 . is - if any rows have zero diagonals this contains the list of them 10053 10054 Level: developer 10055 10056 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 10057 @*/ 10058 PetscErrorCode MatFindZeroDiagonals(Mat mat, IS *is) { 10059 PetscFunctionBegin; 10060 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 10061 PetscValidType(mat, 1); 10062 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 10063 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 10064 10065 if (!mat->ops->findzerodiagonals) { 10066 Vec diag; 10067 const PetscScalar *a; 10068 PetscInt *rows; 10069 PetscInt rStart, rEnd, r, nrow = 0; 10070 10071 PetscCall(MatCreateVecs(mat, &diag, NULL)); 10072 PetscCall(MatGetDiagonal(mat, diag)); 10073 PetscCall(MatGetOwnershipRange(mat, &rStart, &rEnd)); 10074 PetscCall(VecGetArrayRead(diag, &a)); 10075 for (r = 0; r < rEnd - rStart; ++r) 10076 if (a[r] == 0.0) ++nrow; 10077 PetscCall(PetscMalloc1(nrow, &rows)); 10078 nrow = 0; 10079 for (r = 0; r < rEnd - rStart; ++r) 10080 if (a[r] == 0.0) rows[nrow++] = r + rStart; 10081 PetscCall(VecRestoreArrayRead(diag, &a)); 10082 PetscCall(VecDestroy(&diag)); 10083 PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)mat), nrow, rows, PETSC_OWN_POINTER, is)); 10084 } else { 10085 PetscUseTypeMethod(mat, findzerodiagonals, is); 10086 } 10087 PetscFunctionReturn(0); 10088 } 10089 10090 /*@ 10091 MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size) 10092 10093 Collective on mat 10094 10095 Input Parameter: 10096 . mat - the matrix 10097 10098 Output Parameter: 10099 . is - contains the list of rows with off block diagonal entries 10100 10101 Level: developer 10102 10103 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 10104 @*/ 10105 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat, IS *is) { 10106 PetscFunctionBegin; 10107 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 10108 PetscValidType(mat, 1); 10109 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 10110 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 10111 10112 PetscUseTypeMethod(mat, findoffblockdiagonalentries, is); 10113 PetscFunctionReturn(0); 10114 } 10115 10116 /*@C 10117 MatInvertBlockDiagonal - Inverts the block diagonal entries. 10118 10119 Collective on mat 10120 10121 Input Parameters: 10122 . mat - the matrix 10123 10124 Output Parameters: 10125 . values - the block inverses in column major order (FORTRAN-like) 10126 10127 Notes: 10128 The size of the blocks is determined by the block size of the matrix. 10129 10130 The blocks never overlap between two MPI ranks, use `MatInvertVariableBlockEnvelope()` for that case 10131 10132 The blocks all have the same size, use `MatInvertVariableBlockDiagonal()` for variable block size 10133 10134 Fortran Note: 10135 This routine is not available from Fortran. 10136 10137 Level: advanced 10138 10139 .seealso: `MatInvertVariableBlockEnvelope()`, `MatInvertBlockDiagonalMat()` 10140 @*/ 10141 PetscErrorCode MatInvertBlockDiagonal(Mat mat, const PetscScalar **values) { 10142 PetscFunctionBegin; 10143 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 10144 PetscCheck(mat->assembled, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 10145 PetscCheck(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 10146 PetscUseTypeMethod(mat, invertblockdiagonal, values); 10147 PetscFunctionReturn(0); 10148 } 10149 10150 /*@C 10151 MatInvertVariableBlockDiagonal - Inverts the point block diagonal entries. 10152 10153 Collective on mat 10154 10155 Input Parameters: 10156 + mat - the matrix 10157 . nblocks - the number of blocks on the process, set with `MatSetVariableBlockSizes()` 10158 - bsizes - the size of each block on the process, set with `MatSetVariableBlockSizes()` 10159 10160 Output Parameters: 10161 . values - the block inverses in column major order (FORTRAN-like) 10162 10163 Notes: 10164 Use `MatInvertBlockDiagonal()` if all blocks have the same size 10165 10166 The blocks never overlap between two MPI ranks, use `MatInvertVariableBlockEnvelope()` for that case 10167 10168 Fortran Note: 10169 This routine is not available from Fortran. 10170 10171 Level: advanced 10172 10173 .seealso: `MatInvertBlockDiagonal()`, `MatSetVariableBlockSizes()`, `MatInvertVariableBlockEnvelope()` 10174 @*/ 10175 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat, PetscInt nblocks, const PetscInt *bsizes, PetscScalar *values) { 10176 PetscFunctionBegin; 10177 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 10178 PetscCheck(mat->assembled, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 10179 PetscCheck(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 10180 PetscUseTypeMethod(mat, invertvariableblockdiagonal, nblocks, bsizes, values); 10181 PetscFunctionReturn(0); 10182 } 10183 10184 /*@ 10185 MatInvertBlockDiagonalMat - set the values of matrix C to be the inverted block diagonal of matrix A 10186 10187 Collective on Mat 10188 10189 Input Parameters: 10190 + A - the matrix 10191 - C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set. 10192 10193 Note: 10194 The blocksize of the matrix is used to determine the blocks on the diagonal of C 10195 10196 Level: advanced 10197 10198 .seealso: `MatInvertBlockDiagonal()` 10199 @*/ 10200 PetscErrorCode MatInvertBlockDiagonalMat(Mat A, Mat C) { 10201 const PetscScalar *vals; 10202 PetscInt *dnnz; 10203 PetscInt m, rstart, rend, bs, i, j; 10204 10205 PetscFunctionBegin; 10206 PetscCall(MatInvertBlockDiagonal(A, &vals)); 10207 PetscCall(MatGetBlockSize(A, &bs)); 10208 PetscCall(MatGetLocalSize(A, &m, NULL)); 10209 PetscCall(MatSetLayouts(C, A->rmap, A->cmap)); 10210 PetscCall(PetscMalloc1(m / bs, &dnnz)); 10211 for (j = 0; j < m / bs; j++) dnnz[j] = 1; 10212 PetscCall(MatXAIJSetPreallocation(C, bs, dnnz, NULL, NULL, NULL)); 10213 PetscCall(PetscFree(dnnz)); 10214 PetscCall(MatGetOwnershipRange(C, &rstart, &rend)); 10215 PetscCall(MatSetOption(C, MAT_ROW_ORIENTED, PETSC_FALSE)); 10216 for (i = rstart / bs; i < rend / bs; i++) PetscCall(MatSetValuesBlocked(C, 1, &i, 1, &i, &vals[(i - rstart / bs) * bs * bs], INSERT_VALUES)); 10217 PetscCall(MatAssemblyBegin(C, MAT_FINAL_ASSEMBLY)); 10218 PetscCall(MatAssemblyEnd(C, MAT_FINAL_ASSEMBLY)); 10219 PetscCall(MatSetOption(C, MAT_ROW_ORIENTED, PETSC_TRUE)); 10220 PetscFunctionReturn(0); 10221 } 10222 10223 /*@C 10224 MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created 10225 via `MatTransposeColoringCreate()`. 10226 10227 Collective on c 10228 10229 Input Parameter: 10230 . c - coloring context 10231 10232 Level: intermediate 10233 10234 .seealso: `MatTransposeColoringCreate()` 10235 @*/ 10236 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c) { 10237 MatTransposeColoring matcolor = *c; 10238 10239 PetscFunctionBegin; 10240 if (!matcolor) PetscFunctionReturn(0); 10241 if (--((PetscObject)matcolor)->refct > 0) { 10242 matcolor = NULL; 10243 PetscFunctionReturn(0); 10244 } 10245 10246 PetscCall(PetscFree3(matcolor->ncolumns, matcolor->nrows, matcolor->colorforrow)); 10247 PetscCall(PetscFree(matcolor->rows)); 10248 PetscCall(PetscFree(matcolor->den2sp)); 10249 PetscCall(PetscFree(matcolor->colorforcol)); 10250 PetscCall(PetscFree(matcolor->columns)); 10251 if (matcolor->brows > 0) PetscCall(PetscFree(matcolor->lstart)); 10252 PetscCall(PetscHeaderDestroy(c)); 10253 PetscFunctionReturn(0); 10254 } 10255 10256 /*@C 10257 MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which 10258 a `MatTransposeColoring` context has been created, computes a dense B^T by applying 10259 `MatTransposeColoring` to sparse B. 10260 10261 Collective on coloring 10262 10263 Input Parameters: 10264 + B - sparse matrix B 10265 . Btdense - symbolic dense matrix B^T 10266 - coloring - coloring context created with `MatTransposeColoringCreate()` 10267 10268 Output Parameter: 10269 . Btdense - dense matrix B^T 10270 10271 Level: developer 10272 10273 Note: 10274 These are used internally for some implementations of `MatRARt()` 10275 10276 .seealso: `MatTransposeColoringCreate()`, `MatTransposeColoringDestroy()`, `MatTransColoringApplyDenToSp()` 10277 10278 @*/ 10279 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring, Mat B, Mat Btdense) { 10280 PetscFunctionBegin; 10281 PetscValidHeaderSpecific(B, MAT_CLASSID, 2); 10282 PetscValidHeaderSpecific(Btdense, MAT_CLASSID, 3); 10283 PetscValidHeaderSpecific(coloring, MAT_TRANSPOSECOLORING_CLASSID, 1); 10284 10285 PetscCall((B->ops->transcoloringapplysptoden)(coloring, B, Btdense)); 10286 PetscFunctionReturn(0); 10287 } 10288 10289 /*@C 10290 MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which 10291 a `MatTransposeColoring` context has been created and a dense matrix Cden=A*Btdense 10292 in which Btdens is obtained from `MatTransColoringApplySpToDen()`, recover sparse matrix 10293 Csp from Cden. 10294 10295 Collective on matcoloring 10296 10297 Input Parameters: 10298 + coloring - coloring context created with `MatTransposeColoringCreate()` 10299 - Cden - matrix product of a sparse matrix and a dense matrix Btdense 10300 10301 Output Parameter: 10302 . Csp - sparse matrix 10303 10304 Level: developer 10305 10306 Note: 10307 These are used internally for some implementations of `MatRARt()` 10308 10309 .seealso: `MatTransposeColoringCreate()`, `MatTransposeColoringDestroy()`, `MatTransColoringApplySpToDen()` 10310 10311 @*/ 10312 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring, Mat Cden, Mat Csp) { 10313 PetscFunctionBegin; 10314 PetscValidHeaderSpecific(matcoloring, MAT_TRANSPOSECOLORING_CLASSID, 1); 10315 PetscValidHeaderSpecific(Cden, MAT_CLASSID, 2); 10316 PetscValidHeaderSpecific(Csp, MAT_CLASSID, 3); 10317 10318 PetscCall((Csp->ops->transcoloringapplydentosp)(matcoloring, Cden, Csp)); 10319 PetscCall(MatAssemblyBegin(Csp, MAT_FINAL_ASSEMBLY)); 10320 PetscCall(MatAssemblyEnd(Csp, MAT_FINAL_ASSEMBLY)); 10321 PetscFunctionReturn(0); 10322 } 10323 10324 /*@C 10325 MatTransposeColoringCreate - Creates a matrix coloring context for the matrix product C=A*B^T. 10326 10327 Collective on mat 10328 10329 Input Parameters: 10330 + mat - the matrix product C 10331 - iscoloring - the coloring of the matrix; usually obtained with `MatColoringCreate()` or `DMCreateColoring()` 10332 10333 Output Parameter: 10334 . color - the new coloring context 10335 10336 Level: intermediate 10337 10338 .seealso: `MatTransposeColoringDestroy()`, `MatTransColoringApplySpToDen()`, 10339 `MatTransColoringApplyDenToSp()` 10340 @*/ 10341 PetscErrorCode MatTransposeColoringCreate(Mat mat, ISColoring iscoloring, MatTransposeColoring *color) { 10342 MatTransposeColoring c; 10343 MPI_Comm comm; 10344 10345 PetscFunctionBegin; 10346 PetscCall(PetscLogEventBegin(MAT_TransposeColoringCreate, mat, 0, 0, 0)); 10347 PetscCall(PetscObjectGetComm((PetscObject)mat, &comm)); 10348 PetscCall(PetscHeaderCreate(c, MAT_TRANSPOSECOLORING_CLASSID, "MatTransposeColoring", "Matrix product C=A*B^T via coloring", "Mat", comm, MatTransposeColoringDestroy, NULL)); 10349 10350 c->ctype = iscoloring->ctype; 10351 if (mat->ops->transposecoloringcreate) { 10352 PetscUseTypeMethod(mat, transposecoloringcreate, iscoloring, c); 10353 } else SETERRQ(PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Code not yet written for matrix type %s", ((PetscObject)mat)->type_name); 10354 10355 *color = c; 10356 PetscCall(PetscLogEventEnd(MAT_TransposeColoringCreate, mat, 0, 0, 0)); 10357 PetscFunctionReturn(0); 10358 } 10359 10360 /*@ 10361 MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the 10362 matrix has had no new nonzero locations added to (or removed from) the matrix since the previous call then the value will be the 10363 same, otherwise it will be larger 10364 10365 Not Collective 10366 10367 Input Parameter: 10368 . A - the matrix 10369 10370 Output Parameter: 10371 . state - the current state 10372 10373 Notes: 10374 You can only compare states from two different calls to the SAME matrix, you cannot compare calls between 10375 different matrices 10376 10377 Use `PetscObjectStateGet()` to check for changes to the numerical values in a matrix 10378 10379 Use the result of `PetscObjectGetId()` to compare if a previously checked matrix is the same as the current matrix, do not compare object pointers. 10380 10381 Level: intermediate 10382 10383 .seealso: `PetscObjectStateGet()`, `PetscObjectGetId()` 10384 @*/ 10385 PetscErrorCode MatGetNonzeroState(Mat mat, PetscObjectState *state) { 10386 PetscFunctionBegin; 10387 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 10388 *state = mat->nonzerostate; 10389 PetscFunctionReturn(0); 10390 } 10391 10392 /*@ 10393 MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential 10394 matrices from each processor 10395 10396 Collective 10397 10398 Input Parameters: 10399 + comm - the communicators the parallel matrix will live on 10400 . seqmat - the input sequential matrices 10401 . n - number of local columns (or `PETSC_DECIDE`) 10402 - reuse - either `MAT_INITIAL_MATRIX` or `MAT_REUSE_MATRIX` 10403 10404 Output Parameter: 10405 . mpimat - the parallel matrix generated 10406 10407 Level: developer 10408 10409 Note: 10410 The number of columns of the matrix in EACH processor MUST be the same. 10411 10412 .seealso: `Mat` 10413 @*/ 10414 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm, Mat seqmat, PetscInt n, MatReuse reuse, Mat *mpimat) { 10415 PetscMPIInt size; 10416 10417 PetscFunctionBegin; 10418 PetscCallMPI(MPI_Comm_size(comm, &size)); 10419 if (size == 1) { 10420 if (reuse == MAT_INITIAL_MATRIX) { 10421 PetscCall(MatDuplicate(seqmat, MAT_COPY_VALUES, mpimat)); 10422 } else { 10423 PetscCall(MatCopy(seqmat, *mpimat, SAME_NONZERO_PATTERN)); 10424 } 10425 PetscFunctionReturn(0); 10426 } 10427 10428 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"); 10429 10430 PetscCall(PetscLogEventBegin(MAT_Merge, seqmat, 0, 0, 0)); 10431 PetscCall((*seqmat->ops->creatempimatconcatenateseqmat)(comm, seqmat, n, reuse, mpimat)); 10432 PetscCall(PetscLogEventEnd(MAT_Merge, seqmat, 0, 0, 0)); 10433 PetscFunctionReturn(0); 10434 } 10435 10436 /*@ 10437 MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent ranks' ownership ranges. 10438 10439 Collective on A 10440 10441 Input Parameters: 10442 + A - the matrix to create subdomains from 10443 - N - requested number of subdomains 10444 10445 Output Parameters: 10446 + n - number of subdomains resulting on this rank 10447 - iss - `IS` list with indices of subdomains on this rank 10448 10449 Level: advanced 10450 10451 Note: 10452 The number of subdomains must be smaller than the communicator size 10453 10454 .seealso: `Mat`, `IS` 10455 @*/ 10456 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A, PetscInt N, PetscInt *n, IS *iss[]) { 10457 MPI_Comm comm, subcomm; 10458 PetscMPIInt size, rank, color; 10459 PetscInt rstart, rend, k; 10460 10461 PetscFunctionBegin; 10462 PetscCall(PetscObjectGetComm((PetscObject)A, &comm)); 10463 PetscCallMPI(MPI_Comm_size(comm, &size)); 10464 PetscCallMPI(MPI_Comm_rank(comm, &rank)); 10465 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); 10466 *n = 1; 10467 k = ((PetscInt)size) / N + ((PetscInt)size % N > 0); /* There are up to k ranks to a color */ 10468 color = rank / k; 10469 PetscCallMPI(MPI_Comm_split(comm, color, rank, &subcomm)); 10470 PetscCall(PetscMalloc1(1, iss)); 10471 PetscCall(MatGetOwnershipRange(A, &rstart, &rend)); 10472 PetscCall(ISCreateStride(subcomm, rend - rstart, rstart, 1, iss[0])); 10473 PetscCallMPI(MPI_Comm_free(&subcomm)); 10474 PetscFunctionReturn(0); 10475 } 10476 10477 /*@ 10478 MatGalerkin - Constructs the coarse grid problem matrix via Galerkin projection. 10479 10480 If the interpolation and restriction operators are the same, uses `MatPtAP()`. 10481 If they are not the same, uses `MatMatMatMult()`. 10482 10483 Once the coarse grid problem is constructed, correct for interpolation operators 10484 that are not of full rank, which can legitimately happen in the case of non-nested 10485 geometric multigrid. 10486 10487 Input Parameters: 10488 + restrct - restriction operator 10489 . dA - fine grid matrix 10490 . interpolate - interpolation operator 10491 . reuse - either `MAT_INITIAL_MATRIX` or `MAT_REUSE_MATRIX` 10492 - fill - expected fill, use `PETSC_DEFAULT` if you do not have a good estimate 10493 10494 Output Parameters: 10495 . A - the Galerkin coarse matrix 10496 10497 Options Database Key: 10498 . -pc_mg_galerkin <both,pmat,mat,none> - for what matrices the Galerkin process should be used 10499 10500 Level: developer 10501 10502 .seealso: `MatPtAP()`, `MatMatMatMult()` 10503 @*/ 10504 PetscErrorCode MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A) { 10505 IS zerorows; 10506 Vec diag; 10507 10508 PetscFunctionBegin; 10509 PetscCheck(reuse != MAT_INPLACE_MATRIX, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Inplace product not supported"); 10510 /* Construct the coarse grid matrix */ 10511 if (interpolate == restrct) { 10512 PetscCall(MatPtAP(dA, interpolate, reuse, fill, A)); 10513 } else { 10514 PetscCall(MatMatMatMult(restrct, dA, interpolate, reuse, fill, A)); 10515 } 10516 10517 /* If the interpolation matrix is not of full rank, A will have zero rows. 10518 This can legitimately happen in the case of non-nested geometric multigrid. 10519 In that event, we set the rows of the matrix to the rows of the identity, 10520 ignoring the equations (as the RHS will also be zero). */ 10521 10522 PetscCall(MatFindZeroRows(*A, &zerorows)); 10523 10524 if (zerorows != NULL) { /* if there are any zero rows */ 10525 PetscCall(MatCreateVecs(*A, &diag, NULL)); 10526 PetscCall(MatGetDiagonal(*A, diag)); 10527 PetscCall(VecISSet(diag, zerorows, 1.0)); 10528 PetscCall(MatDiagonalSet(*A, diag, INSERT_VALUES)); 10529 PetscCall(VecDestroy(&diag)); 10530 PetscCall(ISDestroy(&zerorows)); 10531 } 10532 PetscFunctionReturn(0); 10533 } 10534 10535 /*@C 10536 MatSetOperation - Allows user to set a matrix operation for any matrix type 10537 10538 Logically Collective on mat 10539 10540 Input Parameters: 10541 + mat - the matrix 10542 . op - the name of the operation 10543 - f - the function that provides the operation 10544 10545 Level: developer 10546 10547 Usage: 10548 $ extern PetscErrorCode usermult(Mat,Vec,Vec); 10549 $ PetscCall(MatCreateXXX(comm,...&A); 10550 $ PetscCall(MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult); 10551 10552 Notes: 10553 See the file include/petscmat.h for a complete list of matrix 10554 operations, which all have the form MATOP_<OPERATION>, where 10555 <OPERATION> is the name (in all capital letters) of the 10556 user interface routine (e.g., MatMult() -> MATOP_MULT). 10557 10558 All user-provided functions (except for `MATOP_DESTROY`) should have the same calling 10559 sequence as the usual matrix interface routines, since they 10560 are intended to be accessed via the usual matrix interface 10561 routines, e.g., 10562 $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 10563 10564 In particular each function MUST return an error code of 0 on success and 10565 nonzero on failure. 10566 10567 This routine is distinct from `MatShellSetOperation()` in that it can be called on any matrix type. 10568 10569 .seealso: `MatGetOperation()`, `MatCreateShell()`, `MatShellSetContext()`, `MatShellSetOperation()` 10570 @*/ 10571 PetscErrorCode MatSetOperation(Mat mat, MatOperation op, void (*f)(void)) { 10572 PetscFunctionBegin; 10573 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 10574 if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) mat->ops->viewnative = mat->ops->view; 10575 (((void (**)(void))mat->ops)[op]) = f; 10576 PetscFunctionReturn(0); 10577 } 10578 10579 /*@C 10580 MatGetOperation - Gets a matrix operation for any matrix type. 10581 10582 Not Collective 10583 10584 Input Parameters: 10585 + mat - the matrix 10586 - op - the name of the operation 10587 10588 Output Parameter: 10589 . f - the function that provides the operation 10590 10591 Level: developer 10592 10593 Usage: 10594 $ PetscErrorCode (*usermult)(Mat,Vec,Vec); 10595 $ MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult); 10596 10597 Notes: 10598 See the file include/petscmat.h for a complete list of matrix 10599 operations, which all have the form MATOP_<OPERATION>, where 10600 <OPERATION> is the name (in all capital letters) of the 10601 user interface routine (e.g., `MatMult()` -> `MATOP_MULT`). 10602 10603 This routine is distinct from `MatShellGetOperation()` in that it can be called on any matrix type. 10604 10605 .seealso: `MatSetOperation()`, `MatCreateShell()`, `MatShellGetContext()`, `MatShellGetOperation()` 10606 @*/ 10607 PetscErrorCode MatGetOperation(Mat mat, MatOperation op, void (**f)(void)) { 10608 PetscFunctionBegin; 10609 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 10610 *f = (((void (**)(void))mat->ops)[op]); 10611 PetscFunctionReturn(0); 10612 } 10613 10614 /*@ 10615 MatHasOperation - Determines whether the given matrix supports the particular operation. 10616 10617 Not Collective 10618 10619 Input Parameters: 10620 + mat - the matrix 10621 - op - the operation, for example, `MATOP_GET_DIAGONAL` 10622 10623 Output Parameter: 10624 . has - either `PETSC_TRUE` or `PETSC_FALSE` 10625 10626 Level: advanced 10627 10628 Note: 10629 See the file include/petscmat.h for a complete list of matrix 10630 operations, which all have the form MATOP_<OPERATION>, where 10631 <OPERATION> is the name (in all capital letters) of the 10632 user-level routine. E.g., `MatNorm()` -> `MATOP_NORM`. 10633 10634 .seealso: `MatCreateShell()`, `MatGetOperation()`, `MatSetOperation()` 10635 @*/ 10636 PetscErrorCode MatHasOperation(Mat mat, MatOperation op, PetscBool *has) { 10637 PetscFunctionBegin; 10638 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 10639 PetscValidBoolPointer(has, 3); 10640 if (mat->ops->hasoperation) { 10641 PetscUseTypeMethod(mat, hasoperation, op, has); 10642 } else { 10643 if (((void **)mat->ops)[op]) *has = PETSC_TRUE; 10644 else { 10645 *has = PETSC_FALSE; 10646 if (op == MATOP_CREATE_SUBMATRIX) { 10647 PetscMPIInt size; 10648 10649 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size)); 10650 if (size == 1) PetscCall(MatHasOperation(mat, MATOP_CREATE_SUBMATRICES, has)); 10651 } 10652 } 10653 } 10654 PetscFunctionReturn(0); 10655 } 10656 10657 /*@ 10658 MatHasCongruentLayouts - Determines whether the rows and columns layouts of the matrix are congruent 10659 10660 Collective on mat 10661 10662 Input Parameters: 10663 . mat - the matrix 10664 10665 Output Parameter: 10666 . cong - either `PETSC_TRUE` or `PETSC_FALSE` 10667 10668 Level: beginner 10669 10670 .seealso: `MatCreate()`, `MatSetSizes()`, `PetscLayout` 10671 @*/ 10672 PetscErrorCode MatHasCongruentLayouts(Mat mat, PetscBool *cong) { 10673 PetscFunctionBegin; 10674 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 10675 PetscValidType(mat, 1); 10676 PetscValidBoolPointer(cong, 2); 10677 if (!mat->rmap || !mat->cmap) { 10678 *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE; 10679 PetscFunctionReturn(0); 10680 } 10681 if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */ 10682 PetscCall(PetscLayoutSetUp(mat->rmap)); 10683 PetscCall(PetscLayoutSetUp(mat->cmap)); 10684 PetscCall(PetscLayoutCompare(mat->rmap, mat->cmap, cong)); 10685 if (*cong) mat->congruentlayouts = 1; 10686 else mat->congruentlayouts = 0; 10687 } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE; 10688 PetscFunctionReturn(0); 10689 } 10690 10691 PetscErrorCode MatSetInf(Mat A) { 10692 PetscFunctionBegin; 10693 PetscUseTypeMethod(A, setinf); 10694 PetscFunctionReturn(0); 10695 } 10696 10697 /*C 10698 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 10699 10700 Collective on mat 10701 10702 Input Parameters: 10703 + A - the matrix 10704 - sym - `PETSC_TRUE` indicates that the graph will be symmetrized 10705 . scale - `PETSC_TRUE` indicates that the graph will be scaled with the diagonal 10706 10707 Output Parameter: 10708 . graph - the resulting graph 10709 10710 Level: advanced 10711 10712 .seealso: `MatCreate()`, `MatFilter()` 10713 */ 10714 PETSC_EXTERN PetscErrorCode MatCreateGraph(Mat A, PetscBool sym, PetscBool scale, Mat *graph) { 10715 PetscFunctionBegin; 10716 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 10717 PetscValidType(A, 1); 10718 PetscValidPointer(graph, 3); 10719 PetscUseTypeMethod(A, creategraph, sym, scale, graph); 10720 PetscFunctionReturn(0); 10721 } 10722 10723 /*C 10724 MatFilter - filters a matrices values with an absolut value equal to or below a give threshold 10725 10726 Collective on mat 10727 10728 Input Parameter: 10729 . value - filter value - < 0: does nothing; == 0: removes only 0.0 entries; otherwise: removes entries <= value 10730 10731 Input/Output Parameter: 10732 . A - the `Mat` to filter in place 10733 10734 Level: developer 10735 10736 Note: 10737 This is called before graph coarsers are called in `PCGAMG` 10738 10739 .seealso: `MatCreate()`, `MatCreateGraph()` 10740 */ 10741 PETSC_EXTERN PetscErrorCode MatFilter(Mat G, PetscReal value, Mat *F) { 10742 PetscFunctionBegin; 10743 PetscValidHeaderSpecific(G, MAT_CLASSID, 1); 10744 PetscValidType(G, 1); 10745 PetscValidPointer(F, 3); 10746 if (value >= 0.0) PetscCall((G->ops->filter)(G, value, F)); 10747 PetscFunctionReturn(0); 10748 } 10749