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(PetscRandomSetFromOptions(randObj)); 86 rctx = randObj; 87 } 88 PetscCall(PetscLogEventBegin(MAT_SetRandom, x, rctx, 0, 0)); 89 PetscUseTypeMethod(x, setrandom, rctx); 90 PetscCall(PetscLogEventEnd(MAT_SetRandom, x, rctx, 0, 0)); 91 92 PetscCall(MatAssemblyBegin(x, MAT_FINAL_ASSEMBLY)); 93 PetscCall(MatAssemblyEnd(x, MAT_FINAL_ASSEMBLY)); 94 PetscCall(PetscRandomDestroy(&randObj)); 95 PetscFunctionReturn(0); 96 } 97 98 /*@ 99 MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in 100 101 Logically Collective on mat 102 103 Input Parameter: 104 . mat - the factored matrix 105 106 Output Parameters: 107 + pivot - the pivot value computed 108 - row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes 109 the share the matrix 110 111 Level: advanced 112 113 Notes: 114 This routine does not work for factorizations done with external packages. 115 116 This routine should only be called if `MatGetFactorError()` returns a value of `MAT_FACTOR_NUMERIC_ZEROPIVOT` 117 118 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 119 120 .seealso: `MatZeroEntries()`, `MatFactor()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()`, `MatFactorClearError()`, `MatFactorGetErrorZeroPivot()`, 121 `MAT_FACTOR_NUMERIC_ZEROPIVOT` 122 @*/ 123 PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat, PetscReal *pivot, PetscInt *row) { 124 PetscFunctionBegin; 125 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 126 PetscValidRealPointer(pivot, 2); 127 PetscValidIntPointer(row, 3); 128 *pivot = mat->factorerror_zeropivot_value; 129 *row = mat->factorerror_zeropivot_row; 130 PetscFunctionReturn(0); 131 } 132 133 /*@ 134 MatFactorGetError - gets the error code from a factorization 135 136 Logically Collective on mat 137 138 Input Parameters: 139 . mat - the factored matrix 140 141 Output Parameter: 142 . err - the error code 143 144 Level: advanced 145 146 Note: 147 This can also be called on non-factored matrices that come from, for example, matrices used in SOR. 148 149 .seealso: `MatZeroEntries()`, `MatFactor()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()`, `MatFactorClearError()`, `MatFactorGetErrorZeroPivot()`, 150 `MatFactorError` 151 @*/ 152 PetscErrorCode MatFactorGetError(Mat mat, MatFactorError *err) { 153 PetscFunctionBegin; 154 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 155 PetscValidPointer(err, 2); 156 *err = mat->factorerrortype; 157 PetscFunctionReturn(0); 158 } 159 160 /*@ 161 MatFactorClearError - clears the error code in a factorization 162 163 Logically Collective on mat 164 165 Input Parameter: 166 . mat - the factored matrix 167 168 Level: developer 169 170 Note: 171 This can also be called on non-factored matrices that come from, for example, matrices used in SOR. 172 173 .seealso: `MatZeroEntries()`, `MatFactor()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()`, `MatFactorGetError()`, `MatFactorGetErrorZeroPivot()`, 174 `MatGetErrorCode()`, `MatFactorError` 175 @*/ 176 PetscErrorCode MatFactorClearError(Mat mat) { 177 PetscFunctionBegin; 178 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 179 mat->factorerrortype = MAT_FACTOR_NOERROR; 180 mat->factorerror_zeropivot_value = 0.0; 181 mat->factorerror_zeropivot_row = 0; 182 PetscFunctionReturn(0); 183 } 184 185 PETSC_INTERN PetscErrorCode MatFindNonzeroRowsOrCols_Basic(Mat mat, PetscBool cols, PetscReal tol, IS *nonzero) { 186 Vec r, l; 187 const PetscScalar *al; 188 PetscInt i, nz, gnz, N, n; 189 190 PetscFunctionBegin; 191 PetscCall(MatCreateVecs(mat, &r, &l)); 192 if (!cols) { /* nonzero rows */ 193 PetscCall(MatGetSize(mat, &N, NULL)); 194 PetscCall(MatGetLocalSize(mat, &n, NULL)); 195 PetscCall(VecSet(l, 0.0)); 196 PetscCall(VecSetRandom(r, NULL)); 197 PetscCall(MatMult(mat, r, l)); 198 PetscCall(VecGetArrayRead(l, &al)); 199 } else { /* nonzero columns */ 200 PetscCall(MatGetSize(mat, NULL, &N)); 201 PetscCall(MatGetLocalSize(mat, NULL, &n)); 202 PetscCall(VecSet(r, 0.0)); 203 PetscCall(VecSetRandom(l, NULL)); 204 PetscCall(MatMultTranspose(mat, l, r)); 205 PetscCall(VecGetArrayRead(r, &al)); 206 } 207 if (tol <= 0.0) { 208 for (i = 0, nz = 0; i < n; i++) 209 if (al[i] != 0.0) nz++; 210 } else { 211 for (i = 0, nz = 0; i < n; i++) 212 if (PetscAbsScalar(al[i]) > tol) nz++; 213 } 214 PetscCall(MPIU_Allreduce(&nz, &gnz, 1, MPIU_INT, MPI_SUM, PetscObjectComm((PetscObject)mat))); 215 if (gnz != N) { 216 PetscInt *nzr; 217 PetscCall(PetscMalloc1(nz, &nzr)); 218 if (nz) { 219 if (tol < 0) { 220 for (i = 0, nz = 0; i < n; i++) 221 if (al[i] != 0.0) nzr[nz++] = i; 222 } else { 223 for (i = 0, nz = 0; i < n; i++) 224 if (PetscAbsScalar(al[i]) > tol) nzr[nz++] = i; 225 } 226 } 227 PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)mat), nz, nzr, PETSC_OWN_POINTER, nonzero)); 228 } else *nonzero = NULL; 229 if (!cols) { /* nonzero rows */ 230 PetscCall(VecRestoreArrayRead(l, &al)); 231 } else { 232 PetscCall(VecRestoreArrayRead(r, &al)); 233 } 234 PetscCall(VecDestroy(&l)); 235 PetscCall(VecDestroy(&r)); 236 PetscFunctionReturn(0); 237 } 238 239 /*@ 240 MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix 241 242 Input Parameter: 243 . A - the matrix 244 245 Output Parameter: 246 . keptrows - the rows that are not completely zero 247 248 Note: 249 keptrows is set to NULL if all rows are nonzero. 250 251 Level: intermediate 252 253 .seealso: `Mat`, `MatFindZeroRows()` 254 @*/ 255 PetscErrorCode MatFindNonzeroRows(Mat mat, IS *keptrows) { 256 PetscFunctionBegin; 257 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 258 PetscValidType(mat, 1); 259 PetscValidPointer(keptrows, 2); 260 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 261 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 262 if (mat->ops->findnonzerorows) PetscUseTypeMethod(mat, findnonzerorows, keptrows); 263 else PetscCall(MatFindNonzeroRowsOrCols_Basic(mat, PETSC_FALSE, 0.0, keptrows)); 264 PetscFunctionReturn(0); 265 } 266 267 /*@ 268 MatFindZeroRows - Locate all rows that are completely zero in the matrix 269 270 Input Parameter: 271 . A - the matrix 272 273 Output Parameter: 274 . zerorows - the rows that are completely zero 275 276 Note: 277 zerorows is set to NULL if no rows are zero. 278 279 Level: intermediate 280 281 .seealso: `Mat`, `MatFindNonzeroRows()` 282 @*/ 283 PetscErrorCode MatFindZeroRows(Mat mat, IS *zerorows) { 284 IS keptrows; 285 PetscInt m, n; 286 287 PetscFunctionBegin; 288 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 289 PetscValidType(mat, 1); 290 PetscValidPointer(zerorows, 2); 291 PetscCall(MatFindNonzeroRows(mat, &keptrows)); 292 /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows. 293 In keeping with this convention, we set zerorows to NULL if there are no zero 294 rows. */ 295 if (keptrows == NULL) { 296 *zerorows = NULL; 297 } else { 298 PetscCall(MatGetOwnershipRange(mat, &m, &n)); 299 PetscCall(ISComplement(keptrows, m, n, zerorows)); 300 PetscCall(ISDestroy(&keptrows)); 301 } 302 PetscFunctionReturn(0); 303 } 304 305 /*@ 306 MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling 307 308 Not Collective 309 310 Input Parameters: 311 . A - the matrix 312 313 Output Parameters: 314 . a - the diagonal part (which is a SEQUENTIAL matrix) 315 316 Notes: 317 See the manual page for `MatCreateAIJ()` for more information on the "diagonal part" of the matrix. 318 319 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. 320 321 Level: advanced 322 323 .seelaso: `MatCreateAIJ()`, `MATAIJ`, `MATBAIJ`, `MATSBAIJ` 324 @*/ 325 PetscErrorCode MatGetDiagonalBlock(Mat A, Mat *a) { 326 PetscFunctionBegin; 327 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 328 PetscValidType(A, 1); 329 PetscValidPointer(a, 2); 330 PetscCheck(!A->factortype, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 331 if (A->ops->getdiagonalblock) PetscUseTypeMethod(A, getdiagonalblock, a); 332 else { 333 PetscMPIInt size; 334 335 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)A), &size)); 336 PetscCheck(size == 1, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Not for parallel matrix type %s", ((PetscObject)A)->type_name); 337 *a = A; 338 } 339 PetscFunctionReturn(0); 340 } 341 342 /*@ 343 MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries. 344 345 Collective on mat 346 347 Input Parameters: 348 . mat - the matrix 349 350 Output Parameter: 351 . trace - the sum of the diagonal entries 352 353 Level: advanced 354 355 .seealso: `Mat` 356 @*/ 357 PetscErrorCode MatGetTrace(Mat mat, PetscScalar *trace) { 358 Vec diag; 359 360 PetscFunctionBegin; 361 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 362 PetscValidScalarPointer(trace, 2); 363 PetscCall(MatCreateVecs(mat, &diag, NULL)); 364 PetscCall(MatGetDiagonal(mat, diag)); 365 PetscCall(VecSum(diag, trace)); 366 PetscCall(VecDestroy(&diag)); 367 PetscFunctionReturn(0); 368 } 369 370 /*@ 371 MatRealPart - Zeros out the imaginary part of the matrix 372 373 Logically Collective on mat 374 375 Input Parameters: 376 . mat - the matrix 377 378 Level: advanced 379 380 .seealso: `MatImaginaryPart()` 381 @*/ 382 PetscErrorCode MatRealPart(Mat mat) { 383 PetscFunctionBegin; 384 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 385 PetscValidType(mat, 1); 386 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 387 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 388 MatCheckPreallocated(mat, 1); 389 PetscUseTypeMethod(mat, realpart); 390 PetscFunctionReturn(0); 391 } 392 393 /*@C 394 MatGetGhosts - Get the global indices of all ghost nodes defined by the sparse matrix 395 396 Collective on mat 397 398 Input Parameter: 399 . mat - the matrix 400 401 Output Parameters: 402 + nghosts - number of ghosts (note for `MATBAIJ` and `MATSBAIJ` matrices there is one ghost for each block) 403 - ghosts - the global indices of the ghost points 404 405 Note: 406 the nghosts and ghosts are suitable to pass into `VecCreateGhost()` 407 408 Level: advanced 409 410 .seealso: `Mat`, `VecCreateGhost()` 411 @*/ 412 PetscErrorCode MatGetGhosts(Mat mat, PetscInt *nghosts, const PetscInt *ghosts[]) { 413 PetscFunctionBegin; 414 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 415 PetscValidType(mat, 1); 416 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 417 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 418 if (mat->ops->getghosts) PetscUseTypeMethod(mat, getghosts, nghosts, ghosts); 419 else { 420 if (nghosts) *nghosts = 0; 421 if (ghosts) *ghosts = NULL; 422 } 423 PetscFunctionReturn(0); 424 } 425 426 /*@ 427 MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part 428 429 Logically Collective on mat 430 431 Input Parameters: 432 . mat - the matrix 433 434 Level: advanced 435 436 .seealso: `MatRealPart()` 437 @*/ 438 PetscErrorCode MatImaginaryPart(Mat mat) { 439 PetscFunctionBegin; 440 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 441 PetscValidType(mat, 1); 442 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 443 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 444 MatCheckPreallocated(mat, 1); 445 PetscUseTypeMethod(mat, imaginarypart); 446 PetscFunctionReturn(0); 447 } 448 449 /*@ 450 MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for `MATBAIJ` and `MATSBAIJ` matrices) 451 452 Not Collective 453 454 Input Parameter: 455 . mat - the matrix 456 457 Output Parameters: 458 + missing - is any diagonal missing 459 - dd - first diagonal entry that is missing (optional) on this process 460 461 Level: advanced 462 463 .seealso: `Mat` 464 @*/ 465 PetscErrorCode MatMissingDiagonal(Mat mat, PetscBool *missing, PetscInt *dd) { 466 PetscFunctionBegin; 467 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 468 PetscValidType(mat, 1); 469 PetscValidBoolPointer(missing, 2); 470 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix %s", ((PetscObject)mat)->type_name); 471 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 472 PetscUseTypeMethod(mat, missingdiagonal, missing, dd); 473 PetscFunctionReturn(0); 474 } 475 476 /*@C 477 MatGetRow - Gets a row of a matrix. You MUST call `MatRestoreRow()` 478 for each row that you get to ensure that your application does 479 not bleed memory. 480 481 Not Collective 482 483 Input Parameters: 484 + mat - the matrix 485 - row - the row to get 486 487 Output Parameters: 488 + ncols - if not NULL, the number of nonzeros in the row 489 . cols - if not NULL, the column numbers 490 - vals - if not NULL, the values 491 492 Notes: 493 This routine is provided for people who need to have direct access 494 to the structure of a matrix. We hope that we provide enough 495 high-level matrix routines that few users will need it. 496 497 `MatGetRow()` always returns 0-based column indices, regardless of 498 whether the internal representation is 0-based (default) or 1-based. 499 500 For better efficiency, set cols and/or vals to NULL if you do 501 not wish to extract these quantities. 502 503 The user can only examine the values extracted with `MatGetRow()`; 504 the values cannot be altered. To change the matrix entries, one 505 must use `MatSetValues()`. 506 507 You can only have one call to `MatGetRow()` outstanding for a particular 508 matrix at a time, per processor. `MatGetRow()` can only obtain rows 509 associated with the given processor, it cannot get rows from the 510 other processors; for that we suggest using `MatCreateSubMatrices()`, then 511 MatGetRow() on the submatrix. The row index passed to `MatGetRow()` 512 is in the global number of rows. 513 514 Use `MatGetRowIJ()` and `MatRestoreRowIJ()` to access all the local indices of the sparse matrix. 515 516 Use `MatSeqAIJGetArray()` and similar functions to access the numerical values for certain matrix types directly. 517 518 Fortran Note: 519 The calling sequence from Fortran is 520 .vb 521 MatGetRow(matrix,row,ncols,cols,values,ierr) 522 Mat matrix (input) 523 integer row (input) 524 integer ncols (output) 525 integer cols(maxcols) (output) 526 double precision (or double complex) values(maxcols) output 527 .ve 528 where maxcols >= maximum nonzeros in any row of the matrix. 529 530 Caution: 531 Do not try to change the contents of the output arrays (cols and vals). 532 In some cases, this may corrupt the matrix. 533 534 Level: advanced 535 536 .seealso: `MatRestoreRow()`, `MatSetValues()`, `MatGetValues()`, `MatCreateSubMatrices()`, `MatGetDiagonal()`, `MatGetRowIJ()`, `MatRestoreRowIJ()` 537 @*/ 538 PetscErrorCode MatGetRow(Mat mat, PetscInt row, PetscInt *ncols, const PetscInt *cols[], const PetscScalar *vals[]) { 539 PetscInt incols; 540 541 PetscFunctionBegin; 542 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 543 PetscValidType(mat, 1); 544 PetscCheck(mat->assembled, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 545 PetscCheck(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 546 MatCheckPreallocated(mat, 1); 547 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); 548 PetscCall(PetscLogEventBegin(MAT_GetRow, mat, 0, 0, 0)); 549 PetscCall((*mat->ops->getrow)(mat, row, &incols, (PetscInt **)cols, (PetscScalar **)vals)); 550 if (ncols) *ncols = incols; 551 PetscCall(PetscLogEventEnd(MAT_GetRow, mat, 0, 0, 0)); 552 PetscFunctionReturn(0); 553 } 554 555 /*@ 556 MatConjugate - replaces the matrix values with their complex conjugates 557 558 Logically Collective on mat 559 560 Input Parameters: 561 . mat - the matrix 562 563 Level: advanced 564 565 .seealso: `MatRealPart()`, `MatImaginaryPart()`, `VecConjugate()`, `MatTranspose()` 566 @*/ 567 PetscErrorCode MatConjugate(Mat mat) { 568 PetscFunctionBegin; 569 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 570 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 571 if (PetscDefined(USE_COMPLEX) && mat->hermitian != PETSC_BOOL3_TRUE) { 572 PetscUseTypeMethod(mat, conjugate); 573 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 574 } 575 PetscFunctionReturn(0); 576 } 577 578 /*@C 579 MatRestoreRow - Frees any temporary space allocated by `MatGetRow()`. 580 581 Not Collective 582 583 Input Parameters: 584 + mat - the matrix 585 . row - the row to get 586 . ncols, cols - the number of nonzeros and their columns 587 - vals - if nonzero the column values 588 589 Notes: 590 This routine should be called after you have finished examining the entries. 591 592 This routine zeros out ncols, cols, and vals. This is to prevent accidental 593 us of the array after it has been restored. If you pass NULL, it will 594 not zero the pointers. Use of cols or vals after `MatRestoreRow()` is invalid. 595 596 Fortran Notes: 597 The calling sequence from Fortran is 598 .vb 599 MatRestoreRow(matrix,row,ncols,cols,values,ierr) 600 Mat matrix (input) 601 integer row (input) 602 integer ncols (output) 603 integer cols(maxcols) (output) 604 double precision (or double complex) values(maxcols) output 605 .ve 606 Where maxcols >= maximum nonzeros in any row of the matrix. 607 608 In Fortran `MatRestoreRow()` MUST be called after `MatGetRow()` 609 before another call to `MatGetRow()` can be made. 610 611 Level: advanced 612 613 .seealso: `MatGetRow()` 614 @*/ 615 PetscErrorCode MatRestoreRow(Mat mat, PetscInt row, PetscInt *ncols, const PetscInt *cols[], const PetscScalar *vals[]) { 616 PetscFunctionBegin; 617 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 618 if (ncols) PetscValidIntPointer(ncols, 3); 619 PetscCheck(mat->assembled, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 620 if (!mat->ops->restorerow) PetscFunctionReturn(0); 621 PetscCall((*mat->ops->restorerow)(mat, row, ncols, (PetscInt **)cols, (PetscScalar **)vals)); 622 if (ncols) *ncols = 0; 623 if (cols) *cols = NULL; 624 if (vals) *vals = NULL; 625 PetscFunctionReturn(0); 626 } 627 628 /*@ 629 MatGetRowUpperTriangular - Sets a flag to enable calls to `MatGetRow()` for matrix in `MATSBAIJ` format. 630 You should call `MatRestoreRowUpperTriangular()` after calling` MatGetRow()` and `MatRestoreRow()` to disable the flag. 631 632 Not Collective 633 634 Input Parameters: 635 . mat - the matrix 636 637 Note: 638 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. 639 640 Level: advanced 641 642 .seealso: `MATSBAIJ`, `MatRestoreRowUpperTriangular()` 643 @*/ 644 PetscErrorCode MatGetRowUpperTriangular(Mat mat) { 645 PetscFunctionBegin; 646 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 647 PetscValidType(mat, 1); 648 PetscCheck(mat->assembled, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 649 PetscCheck(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 650 MatCheckPreallocated(mat, 1); 651 if (!mat->ops->getrowuppertriangular) PetscFunctionReturn(0); 652 PetscUseTypeMethod(mat, getrowuppertriangular); 653 PetscFunctionReturn(0); 654 } 655 656 /*@ 657 MatRestoreRowUpperTriangular - Disable calls to `MatGetRow()` for matrix in `MATSBAIJ` format. 658 659 Not Collective 660 661 Input Parameters: 662 . mat - the matrix 663 664 Note: 665 This routine should be called after you have finished calls to `MatGetRow()` and `MatRestoreRow()`. 666 667 Level: advanced 668 669 .seealso: `MATSBAIJ`, `MatGetRowUpperTriangular()` 670 @*/ 671 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat) { 672 PetscFunctionBegin; 673 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 674 PetscValidType(mat, 1); 675 PetscCheck(mat->assembled, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 676 PetscCheck(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 677 MatCheckPreallocated(mat, 1); 678 if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0); 679 PetscUseTypeMethod(mat, restorerowuppertriangular); 680 PetscFunctionReturn(0); 681 } 682 683 /*@C 684 MatSetOptionsPrefix - Sets the prefix used for searching for all 685 `Mat` options in the database. 686 687 Logically Collective on A 688 689 Input Parameters: 690 + A - the matrix 691 - prefix - the prefix to prepend to all option names 692 693 Notes: 694 A hyphen (-) must NOT be given at the beginning of the prefix name. 695 The first character of all runtime options is AUTOMATICALLY the hyphen. 696 697 This is NOT used for options for the factorization of the matrix. Normally the 698 prefix is automatically passed in from the PC calling the factorization. To set 699 it directly use `MatSetOptionsPrefixFactor()` 700 701 Level: advanced 702 703 .seealso: `MatSetFromOptions()`, `MatSetOptionsPrefixFactor()` 704 @*/ 705 PetscErrorCode MatSetOptionsPrefix(Mat A, const char prefix[]) { 706 PetscFunctionBegin; 707 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 708 PetscCall(PetscObjectSetOptionsPrefix((PetscObject)A, prefix)); 709 PetscFunctionReturn(0); 710 } 711 712 /*@C 713 MatSetOptionsPrefixFactor - Sets the prefix used for searching for all matrix factor options in the database for 714 for matrices created with `MatGetFactor()` 715 716 Logically Collective on A 717 718 Input Parameters: 719 + A - the matrix 720 - prefix - the prefix to prepend to all option names for the factored matrix 721 722 Notes: 723 A hyphen (-) must NOT be given at the beginning of the prefix name. 724 The first character of all runtime options is AUTOMATICALLY the hyphen. 725 726 Normally the prefix is automatically passed in from the `PC` calling the factorization. To set 727 it directly when not using `KSP`/`PC` use `MatSetOptionsPrefixFactor()` 728 729 Level: developer 730 731 .seealso: `MatSetFromOptions()`, `MatSetOptionsPrefix()`, `MatAppendOptionsPrefixFactor()` 732 @*/ 733 PetscErrorCode MatSetOptionsPrefixFactor(Mat A, const char prefix[]) { 734 PetscFunctionBegin; 735 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 736 if (prefix) { 737 PetscValidCharPointer(prefix, 2); 738 PetscCheck(prefix[0] != '-', PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Options prefix should not begin with a hyphen"); 739 if (prefix != A->factorprefix) { 740 PetscCall(PetscFree(A->factorprefix)); 741 PetscCall(PetscStrallocpy(prefix, &A->factorprefix)); 742 } 743 } else PetscCall(PetscFree(A->factorprefix)); 744 PetscFunctionReturn(0); 745 } 746 747 /*@C 748 MatAppendOptionsPrefixFactor - Appends to the prefix used for searching for all matrix factor options in the database for 749 for matrices created with `MatGetFactor()` 750 751 Logically Collective on A 752 753 Input Parameters: 754 + A - the matrix 755 - prefix - the prefix to prepend to all option names for the factored matrix 756 757 Notes: 758 A hyphen (-) must NOT be given at the beginning of the prefix name. 759 The first character of all runtime options is AUTOMATICALLY the hyphen. 760 761 Normally the prefix is automatically passed in from the `PC` calling the factorization. To set 762 it directly when not using `KSP`/`PC` use `MatAppendOptionsPrefixFactor()` 763 764 Level: developer 765 766 .seealso: `PetscOptionsCreate()`, `PetscOptionsDestroy()`, `PetscObjectSetOptionsPrefix()`, `PetscObjectPrependOptionsPrefix()`, 767 `PetscObjectGetOptionsPrefix()`, `TSAppendOptionsPrefix()`, `SNESAppendOptionsPrefix()`, `KSPAppendOptionsPrefix()`, `MatSetOptionsPrefixFactor()`, 768 `MatSetOptionsPrefix()` 769 @*/ 770 PetscErrorCode MatAppendOptionsPrefixFactor(Mat A, const char prefix[]) { 771 char *buf = A->factorprefix; 772 size_t len1, len2; 773 774 PetscFunctionBegin; 775 PetscValidHeader(A, 1); 776 if (!prefix) PetscFunctionReturn(0); 777 if (!buf) { 778 PetscCall(MatSetOptionsPrefixFactor(A, prefix)); 779 PetscFunctionReturn(0); 780 } 781 PetscCheck(prefix[0] != '-', PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Options prefix should not begin with a hyphen"); 782 783 PetscCall(PetscStrlen(prefix, &len1)); 784 PetscCall(PetscStrlen(buf, &len2)); 785 PetscCall(PetscMalloc1(1 + len1 + len2, &A->factorprefix)); 786 PetscCall(PetscStrcpy(A->factorprefix, buf)); 787 PetscCall(PetscStrcat(A->factorprefix, prefix)); 788 PetscCall(PetscFree(buf)); 789 PetscFunctionReturn(0); 790 } 791 792 /*@C 793 MatAppendOptionsPrefix - Appends to the prefix used for searching for all 794 matrix options in the database. 795 796 Logically Collective on A 797 798 Input Parameters: 799 + A - the matrix 800 - prefix - the prefix to prepend to all option names 801 802 Note: 803 A hyphen (-) must NOT be given at the beginning of the prefix name. 804 The first character of all runtime options is AUTOMATICALLY the hyphen. 805 806 Level: advanced 807 808 .seealso: `Mat`, `MatGetOptionsPrefix()`, `MatAppendOptionsPrefixFactor()`, `MatSetOptionsPrefix()` 809 @*/ 810 PetscErrorCode MatAppendOptionsPrefix(Mat A, const char prefix[]) { 811 PetscFunctionBegin; 812 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 813 PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)A, prefix)); 814 PetscFunctionReturn(0); 815 } 816 817 /*@C 818 MatGetOptionsPrefix - Gets the prefix used for searching for all 819 matrix options in the database. 820 821 Not Collective 822 823 Input Parameter: 824 . A - the matrix 825 826 Output Parameter: 827 . prefix - pointer to the prefix string used 828 829 Fortran Note: 830 On the fortran side, the user should pass in a string 'prefix' of 831 sufficient length to hold the prefix. 832 833 Level: advanced 834 835 .seealso: `MatAppendOptionsPrefix()`, `MatSetOptionsPrefix()`, `MatAppendOptionsPrefixFactor()`, `MatSetOptionsPrefixFactor()` 836 @*/ 837 PetscErrorCode MatGetOptionsPrefix(Mat A, const char *prefix[]) { 838 PetscFunctionBegin; 839 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 840 PetscValidPointer(prefix, 2); 841 PetscCall(PetscObjectGetOptionsPrefix((PetscObject)A, prefix)); 842 PetscFunctionReturn(0); 843 } 844 845 /*@ 846 MatResetPreallocation - Reset matrix to use the original nonzero pattern provided by users. 847 848 Collective on A 849 850 Input Parameters: 851 . A - the matrix 852 853 Notes: 854 The allocated memory will be shrunk after calling `MatAssemblyBegin()` and `MatAssemblyEnd()` with `MAT_FINAL_ASSEMBLY`. 855 856 Users can reset the preallocation to access the original memory. 857 858 Currently only supported for `MATMPIAIJ` and `MATSEQAIJ` matrices. 859 860 Level: beginner 861 862 .seealso: `MatSeqAIJSetPreallocation()`, `MatMPIAIJSetPreallocation()`, `MatXAIJSetPreallocation()` 863 @*/ 864 PetscErrorCode MatResetPreallocation(Mat A) { 865 PetscFunctionBegin; 866 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 867 PetscValidType(A, 1); 868 PetscUseMethod(A, "MatResetPreallocation_C", (Mat), (A)); 869 PetscFunctionReturn(0); 870 } 871 872 /*@ 873 MatSetUp - Sets up the internal matrix data structures for later use. 874 875 Collective on A 876 877 Input Parameters: 878 . A - the matrix 879 880 Notes: 881 If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used. 882 883 If a suitable preallocation routine is used, this function does not need to be called. 884 885 See the Performance chapter of the PETSc users manual for how to preallocate matrices 886 887 This routine is called internally by other matrix functions when needed so rarely needs to be called by users 888 889 Level: intermediate 890 891 .seealso: `Mat`, `MatMult()`, `MatCreate()`, `MatDestroy()` 892 @*/ 893 PetscErrorCode MatSetUp(Mat A) { 894 PetscFunctionBegin; 895 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 896 if (!((PetscObject)A)->type_name) { 897 PetscMPIInt size; 898 899 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)A), &size)); 900 PetscCall(MatSetType(A, size == 1 ? MATSEQAIJ : MATMPIAIJ)); 901 } 902 if (!A->preallocated && A->ops->setup) { 903 PetscCall(PetscInfo(A, "Warning not preallocating matrix storage\n")); 904 PetscUseTypeMethod(A, setup); 905 } 906 PetscCall(PetscLayoutSetUp(A->rmap)); 907 PetscCall(PetscLayoutSetUp(A->cmap)); 908 A->preallocated = PETSC_TRUE; 909 PetscFunctionReturn(0); 910 } 911 912 #if defined(PETSC_HAVE_SAWS) 913 #include <petscviewersaws.h> 914 #endif 915 916 /*@C 917 MatViewFromOptions - View properties of the matrix from the options database 918 919 Collective on A 920 921 Input Parameters: 922 + A - the matrix 923 . obj - optional additional object that provides the options prefix to use 924 - name - command line option 925 926 Options Database: 927 . -mat_view [viewertype]:... - the viewer and its options 928 929 Notes: 930 .vb 931 If no value is provided ascii:stdout is used 932 ascii[:[filename][:[format][:append]]] defaults to stdout - format can be one of ascii_info, ascii_info_detail, or ascii_matlab, 933 for example ascii::ascii_info prints just the information about the object not all details 934 unless :append is given filename opens in write mode, overwriting what was already there 935 binary[:[filename][:[format][:append]]] defaults to the file binaryoutput 936 draw[:drawtype[:filename]] for example, draw:tikz, draw:tikz:figure.tex or draw:x 937 socket[:port] defaults to the standard output port 938 saws[:communicatorname] publishes object to the Scientific Application Webserver (SAWs) 939 .ve 940 941 Level: intermediate 942 943 .seealso: `Mat`, `MatView()`, `PetscObjectViewFromOptions()`, `MatCreate()` 944 @*/ 945 PetscErrorCode MatViewFromOptions(Mat A, PetscObject obj, const char name[]) { 946 PetscFunctionBegin; 947 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 948 PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name)); 949 PetscFunctionReturn(0); 950 } 951 952 /*@C 953 MatView - display information about a matrix in a variety ways 954 955 Collective on mat 956 957 Input Parameters: 958 + mat - the matrix 959 - viewer - visualization context 960 961 Notes: 962 The available visualization contexts include 963 + `PETSC_VIEWER_STDOUT_SELF` - for sequential matrices 964 . `PETSC_VIEWER_STDOUT_WORLD` - for parallel matrices created on `PETSC_COMM_WORLD` 965 . `PETSC_VIEWER_STDOUT_`(comm) - for matrices created on MPI communicator comm 966 - `PETSC_VIEWER_DRAW_WORLD` - graphical display of nonzero structure 967 968 The user can open alternative visualization contexts with 969 + `PetscViewerASCIIOpen()` - Outputs matrix to a specified file 970 . `PetscViewerBinaryOpen()` - Outputs matrix in binary to a 971 specified file; corresponding input uses MatLoad() 972 . `PetscViewerDrawOpen()` - Outputs nonzero matrix structure to 973 an X window display 974 - `PetscViewerSocketOpen()` - Outputs matrix to Socket viewer. 975 Currently only the sequential dense and AIJ 976 matrix types support the Socket viewer. 977 978 The user can call `PetscViewerPushFormat()` to specify the output 979 format of ASCII printed objects (when using `PETSC_VIEWER_STDOUT_SELF`, 980 `PETSC_VIEWER_STDOUT_WORLD` and `PetscViewerASCIIOpen()`). Available formats include 981 + `PETSC_VIEWER_DEFAULT` - default, prints matrix contents 982 . `PETSC_VIEWER_ASCII_MATLAB` - prints matrix contents in Matlab format 983 . `PETSC_VIEWER_ASCII_DENSE` - prints entire matrix including zeros 984 . `PETSC_VIEWER_ASCII_COMMON` - prints matrix contents, using a sparse 985 format common among all matrix types 986 . `PETSC_VIEWER_ASCII_IMPL` - prints matrix contents, using an implementation-specific 987 format (which is in many cases the same as the default) 988 . `PETSC_VIEWER_ASCII_INFO` - prints basic information about the matrix 989 size and structure (not the matrix entries) 990 - `PETSC_VIEWER_ASCII_INFO_DETAIL` - prints more detailed information about 991 the matrix structure 992 993 Options Database Keys: 994 + -mat_view ::ascii_info - Prints info on matrix at conclusion of `MatAssemblyEnd()` 995 . -mat_view ::ascii_info_detail - Prints more detailed info 996 . -mat_view - Prints matrix in ASCII format 997 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 998 . -mat_view draw - PetscDraws nonzero structure of matrix, using `MatView()` and `PetscDrawOpenX()`. 999 . -display <name> - Sets display name (default is host) 1000 . -draw_pause <sec> - Sets number of seconds to pause after display 1001 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details) 1002 . -viewer_socket_machine <machine> - 1003 . -viewer_socket_port <port> - 1004 . -mat_view binary - save matrix to file in binary format 1005 - -viewer_binary_filename <name> - 1006 1007 Level: beginner 1008 1009 Notes: 1010 The ASCII viewers are only recommended for small matrices on at most a moderate number of processes, 1011 the program will seemingly hang and take hours for larger matrices, for larger matrices one should use the binary format. 1012 1013 In the debugger you can do "call MatView(mat,0)" to display the matrix. (The same holds for any PETSc object viewer). 1014 1015 See the manual page for `MatLoad()` for the exact format of the binary file when the binary 1016 viewer is used. 1017 1018 See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary 1019 viewer is used and lib/petsc/bin/PetscBinaryIO.py for loading them into Python. 1020 1021 One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure, 1022 and then use the following mouse functions. 1023 .vb 1024 left mouse: zoom in 1025 middle mouse: zoom out 1026 right mouse: continue with the simulation 1027 .ve 1028 1029 .seealso: `PetscViewerPushFormat()`, `PetscViewerASCIIOpen()`, `PetscViewerDrawOpen()`, `PetscViewer`, `Mat`, 1030 `PetscViewerSocketOpen()`, `PetscViewerBinaryOpen()`, `MatLoad()`, `MatViewFromOptions()` 1031 @*/ 1032 PetscErrorCode MatView(Mat mat, PetscViewer viewer) { 1033 PetscInt rows, cols, rbs, cbs; 1034 PetscBool isascii, isstring, issaws; 1035 PetscViewerFormat format; 1036 PetscMPIInt size; 1037 1038 PetscFunctionBegin; 1039 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 1040 PetscValidType(mat, 1); 1041 if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat), &viewer)); 1042 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1043 PetscCheckSameComm(mat, 1, viewer, 2); 1044 MatCheckPreallocated(mat, 1); 1045 1046 PetscCall(PetscViewerGetFormat(viewer, &format)); 1047 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size)); 1048 if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0); 1049 1050 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring)); 1051 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii)); 1052 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSAWS, &issaws)); 1053 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"); 1054 1055 PetscCall(PetscLogEventBegin(MAT_View, mat, viewer, 0, 0)); 1056 if (isascii) { 1057 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ORDER, "Must call MatAssemblyBegin/End() before viewing matrix"); 1058 PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)mat, viewer)); 1059 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1060 MatNullSpace nullsp, transnullsp; 1061 1062 PetscCall(PetscViewerASCIIPushTab(viewer)); 1063 PetscCall(MatGetSize(mat, &rows, &cols)); 1064 PetscCall(MatGetBlockSizes(mat, &rbs, &cbs)); 1065 if (rbs != 1 || cbs != 1) { 1066 if (rbs != cbs) PetscCall(PetscViewerASCIIPrintf(viewer, "rows=%" PetscInt_FMT ", cols=%" PetscInt_FMT ", rbs=%" PetscInt_FMT ", cbs=%" PetscInt_FMT "\n", rows, cols, rbs, cbs)); 1067 else PetscCall(PetscViewerASCIIPrintf(viewer, "rows=%" PetscInt_FMT ", cols=%" PetscInt_FMT ", bs=%" PetscInt_FMT "\n", rows, cols, rbs)); 1068 } else PetscCall(PetscViewerASCIIPrintf(viewer, "rows=%" PetscInt_FMT ", cols=%" PetscInt_FMT "\n", rows, cols)); 1069 if (mat->factortype) { 1070 MatSolverType solver; 1071 PetscCall(MatFactorGetSolverType(mat, &solver)); 1072 PetscCall(PetscViewerASCIIPrintf(viewer, "package used to perform factorization: %s\n", solver)); 1073 } 1074 if (mat->ops->getinfo) { 1075 MatInfo info; 1076 PetscCall(MatGetInfo(mat, MAT_GLOBAL_SUM, &info)); 1077 PetscCall(PetscViewerASCIIPrintf(viewer, "total: nonzeros=%.f, allocated nonzeros=%.f\n", info.nz_used, info.nz_allocated)); 1078 if (!mat->factortype) PetscCall(PetscViewerASCIIPrintf(viewer, "total number of mallocs used during MatSetValues calls=%" PetscInt_FMT "\n", (PetscInt)info.mallocs)); 1079 } 1080 PetscCall(MatGetNullSpace(mat, &nullsp)); 1081 PetscCall(MatGetTransposeNullSpace(mat, &transnullsp)); 1082 if (nullsp) PetscCall(PetscViewerASCIIPrintf(viewer, " has attached null space\n")); 1083 if (transnullsp && transnullsp != nullsp) PetscCall(PetscViewerASCIIPrintf(viewer, " has attached transposed null space\n")); 1084 PetscCall(MatGetNearNullSpace(mat, &nullsp)); 1085 if (nullsp) PetscCall(PetscViewerASCIIPrintf(viewer, " has attached near null space\n")); 1086 PetscCall(PetscViewerASCIIPushTab(viewer)); 1087 PetscCall(MatProductView(mat, viewer)); 1088 PetscCall(PetscViewerASCIIPopTab(viewer)); 1089 } 1090 } else if (issaws) { 1091 #if defined(PETSC_HAVE_SAWS) 1092 PetscMPIInt rank; 1093 1094 PetscCall(PetscObjectName((PetscObject)mat)); 1095 PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank)); 1096 if (!((PetscObject)mat)->amsmem && rank == 0) PetscCall(PetscObjectViewSAWs((PetscObject)mat, viewer)); 1097 #endif 1098 } else if (isstring) { 1099 const char *type; 1100 PetscCall(MatGetType(mat, &type)); 1101 PetscCall(PetscViewerStringSPrintf(viewer, " MatType: %-7.7s", type)); 1102 PetscTryTypeMethod(mat, view, viewer); 1103 } 1104 if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) { 1105 PetscCall(PetscViewerASCIIPushTab(viewer)); 1106 PetscUseTypeMethod(mat, viewnative, viewer); 1107 PetscCall(PetscViewerASCIIPopTab(viewer)); 1108 } else if (mat->ops->view) { 1109 PetscCall(PetscViewerASCIIPushTab(viewer)); 1110 PetscUseTypeMethod(mat, view, viewer); 1111 PetscCall(PetscViewerASCIIPopTab(viewer)); 1112 } 1113 if (isascii) { 1114 PetscCall(PetscViewerGetFormat(viewer, &format)); 1115 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) PetscCall(PetscViewerASCIIPopTab(viewer)); 1116 } 1117 PetscCall(PetscLogEventEnd(MAT_View, mat, viewer, 0, 0)); 1118 PetscFunctionReturn(0); 1119 } 1120 1121 #if defined(PETSC_USE_DEBUG) 1122 #include <../src/sys/totalview/tv_data_display.h> 1123 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat) { 1124 TV_add_row("Local rows", "int", &mat->rmap->n); 1125 TV_add_row("Local columns", "int", &mat->cmap->n); 1126 TV_add_row("Global rows", "int", &mat->rmap->N); 1127 TV_add_row("Global columns", "int", &mat->cmap->N); 1128 TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name); 1129 return TV_format_OK; 1130 } 1131 #endif 1132 1133 /*@C 1134 MatLoad - Loads a matrix that has been stored in binary/HDF5 format 1135 with `MatView()`. The matrix format is determined from the options database. 1136 Generates a parallel MPI matrix if the communicator has more than one 1137 processor. The default matrix type is `MATAIJ`. 1138 1139 Collective on mat 1140 1141 Input Parameters: 1142 + mat - the newly loaded matrix, this needs to have been created with `MatCreate()` 1143 or some related function before a call to `MatLoad()` 1144 - viewer - binary/HDF5 file viewer 1145 1146 Options Database Keys: 1147 Used with block matrix formats (`MATSEQBAIJ`, ...) to specify 1148 block size 1149 . -matload_block_size <bs> - set block size 1150 1151 Level: beginner 1152 1153 Notes: 1154 If the `Mat` type has not yet been given then `MATAIJ` is used, call `MatSetFromOptions()` on the 1155 `Mat` before calling this routine if you wish to set it from the options database. 1156 1157 `MatLoad()` automatically loads into the options database any options 1158 given in the file filename.info where filename is the name of the file 1159 that was passed to the `PetscViewerBinaryOpen()`. The options in the info 1160 file will be ignored if you use the -viewer_binary_skip_info option. 1161 1162 If the type or size of mat is not set before a call to `MatLoad()`, PETSc 1163 sets the default matrix type AIJ and sets the local and global sizes. 1164 If type and/or size is already set, then the same are used. 1165 1166 In parallel, each processor can load a subset of rows (or the 1167 entire matrix). This routine is especially useful when a large 1168 matrix is stored on disk and only part of it is desired on each 1169 processor. For example, a parallel solver may access only some of 1170 the rows from each processor. The algorithm used here reads 1171 relatively small blocks of data rather than reading the entire 1172 matrix and then subsetting it. 1173 1174 Viewer's `PetscViewerType` must be either `PETSCVIEWERBINARY` or `PETSCVIEWERHDF5`. 1175 Such viewer can be created using `PetscViewerBinaryOpen()` or `PetscViewerHDF5Open()`, 1176 or the sequence like 1177 .vb 1178 `PetscViewer` v; 1179 `PetscViewerCreate`(`PETSC_COMM_WORLD`,&v); 1180 `PetscViewerSetType`(v,`PETSCVIEWERBINARY`); 1181 `PetscViewerSetFromOptions`(v); 1182 `PetscViewerFileSetMode`(v,`FILE_MODE_READ`); 1183 `PetscViewerFileSetName`(v,"datafile"); 1184 .ve 1185 The optional `PetscViewerSetFromOptions()` call allows overriding `PetscViewerSetType()` using the option 1186 $ -viewer_type {binary,hdf5} 1187 1188 See the example src/ksp/ksp/tutorials/ex27.c with the first approach, 1189 and src/mat/tutorials/ex10.c with the second approach. 1190 1191 Notes about the PETSc binary format: 1192 In case of `PETSCVIEWERBINARY`, a native PETSc binary format is used. Each of the blocks 1193 is read onto rank 0 and then shipped to its destination rank, one after another. 1194 Multiple objects, both matrices and vectors, can be stored within the same file. 1195 Their PetscObject name is ignored; they are loaded in the order of their storage. 1196 1197 Most users should not need to know the details of the binary storage 1198 format, since `MatLoad()` and `MatView()` completely hide these details. 1199 But for anyone who's interested, the standard binary matrix storage 1200 format is 1201 1202 $ PetscInt MAT_FILE_CLASSID 1203 $ PetscInt number of rows 1204 $ PetscInt number of columns 1205 $ PetscInt total number of nonzeros 1206 $ PetscInt *number nonzeros in each row 1207 $ PetscInt *column indices of all nonzeros (starting index is zero) 1208 $ PetscScalar *values of all nonzeros 1209 1210 PETSc automatically does the byte swapping for 1211 machines that store the bytes reversed, e.g. DEC alpha, freebsd, 1212 Linux, Microsoft Windows and the Intel Paragon; thus if you write your own binary 1213 read/write routines you have to swap the bytes; see `PetscBinaryRead()` 1214 and `PetscBinaryWrite()` to see how this may be done. 1215 1216 Notes about the HDF5 (MATLAB MAT-File Version 7.3) format: 1217 In case of `PETSCVIEWERHDF5`, a parallel HDF5 reader is used. 1218 Each processor's chunk is loaded independently by its owning rank. 1219 Multiple objects, both matrices and vectors, can be stored within the same file. 1220 They are looked up by their PetscObject name. 1221 1222 As the MATLAB MAT-File Version 7.3 format is also a HDF5 flavor, we decided to use 1223 by default the same structure and naming of the AIJ arrays and column count 1224 within the HDF5 file. This means that a MAT file saved with -v7.3 flag, e.g. 1225 $ save example.mat A b -v7.3 1226 can be directly read by this routine (see Reference 1 for details). 1227 Note that depending on your MATLAB version, this format might be a default, 1228 otherwise you can set it as default in Preferences. 1229 1230 Unless -nocompression flag is used to save the file in MATLAB, 1231 PETSc must be configured with ZLIB package. 1232 1233 See also examples src/mat/tutorials/ex10.c and src/ksp/ksp/tutorials/ex27.c 1234 1235 Current HDF5 (MAT-File) limitations: 1236 This reader currently supports only real `MATSEQAIJ`, `MATMPIAIJ`, `MATSEQDENSE` and `MATMPIDENSE` matrices. 1237 1238 Corresponding `MatView()` is not yet implemented. 1239 1240 The loaded matrix is actually a transpose of the original one in MATLAB, 1241 unless you push `PETSC_VIEWER_HDF5_MAT` format (see examples above). 1242 With this format, matrix is automatically transposed by PETSc, 1243 unless the matrix is marked as SPD or symmetric 1244 (see `MatSetOption()`, `MAT_SPD`, `MAT_SYMMETRIC`). 1245 1246 References: 1247 . * - MATLAB(R) Documentation, manual page of save(), https://www.mathworks.com/help/matlab/ref/save.html#btox10b-1-version 1248 1249 .seealso: `PetscViewerBinaryOpen()`, `PetscViewerSetType()`, `MatView()`, `VecLoad()` 1250 @*/ 1251 PetscErrorCode MatLoad(Mat mat, PetscViewer viewer) { 1252 PetscBool flg; 1253 1254 PetscFunctionBegin; 1255 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 1256 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1257 1258 if (!((PetscObject)mat)->type_name) PetscCall(MatSetType(mat, MATAIJ)); 1259 1260 flg = PETSC_FALSE; 1261 PetscCall(PetscOptionsGetBool(((PetscObject)mat)->options, ((PetscObject)mat)->prefix, "-matload_symmetric", &flg, NULL)); 1262 if (flg) { 1263 PetscCall(MatSetOption(mat, MAT_SYMMETRIC, PETSC_TRUE)); 1264 PetscCall(MatSetOption(mat, MAT_SYMMETRY_ETERNAL, PETSC_TRUE)); 1265 } 1266 flg = PETSC_FALSE; 1267 PetscCall(PetscOptionsGetBool(((PetscObject)mat)->options, ((PetscObject)mat)->prefix, "-matload_spd", &flg, NULL)); 1268 if (flg) PetscCall(MatSetOption(mat, MAT_SPD, PETSC_TRUE)); 1269 1270 PetscCall(PetscLogEventBegin(MAT_Load, mat, viewer, 0, 0)); 1271 PetscUseTypeMethod(mat, load, viewer); 1272 PetscCall(PetscLogEventEnd(MAT_Load, mat, viewer, 0, 0)); 1273 PetscFunctionReturn(0); 1274 } 1275 1276 static PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant) { 1277 Mat_Redundant *redund = *redundant; 1278 1279 PetscFunctionBegin; 1280 if (redund) { 1281 if (redund->matseq) { /* via MatCreateSubMatrices() */ 1282 PetscCall(ISDestroy(&redund->isrow)); 1283 PetscCall(ISDestroy(&redund->iscol)); 1284 PetscCall(MatDestroySubMatrices(1, &redund->matseq)); 1285 } else { 1286 PetscCall(PetscFree2(redund->send_rank, redund->recv_rank)); 1287 PetscCall(PetscFree(redund->sbuf_j)); 1288 PetscCall(PetscFree(redund->sbuf_a)); 1289 for (PetscInt i = 0; i < redund->nrecvs; i++) { 1290 PetscCall(PetscFree(redund->rbuf_j[i])); 1291 PetscCall(PetscFree(redund->rbuf_a[i])); 1292 } 1293 PetscCall(PetscFree4(redund->sbuf_nz, redund->rbuf_nz, redund->rbuf_j, redund->rbuf_a)); 1294 } 1295 1296 if (redund->subcomm) PetscCall(PetscCommDestroy(&redund->subcomm)); 1297 PetscCall(PetscFree(redund)); 1298 } 1299 PetscFunctionReturn(0); 1300 } 1301 1302 /*@C 1303 MatDestroy - Frees space taken by a matrix. 1304 1305 Collective on A 1306 1307 Input Parameter: 1308 . A - the matrix 1309 1310 Level: beginner 1311 1312 Developer Note: 1313 Some special arrays of matrices are not destroyed in this routine but instead by the routines called by 1314 `MatDestroySubMatrices()`. Thus one must be sure that any changes here must also be made in those routines. 1315 `MatHeaderMerge()` and `MatHeaderReplace()` also manipulate the data in the `Mat` object and likely need changes 1316 if changes are needed here. 1317 1318 .seealso: `Mat`, `MatCreate()` 1319 @*/ 1320 PetscErrorCode MatDestroy(Mat *A) { 1321 PetscFunctionBegin; 1322 if (!*A) PetscFunctionReturn(0); 1323 PetscValidHeaderSpecific(*A, MAT_CLASSID, 1); 1324 if (--((PetscObject)(*A))->refct > 0) { 1325 *A = NULL; 1326 PetscFunctionReturn(0); 1327 } 1328 1329 /* if memory was published with SAWs then destroy it */ 1330 PetscCall(PetscObjectSAWsViewOff((PetscObject)*A)); 1331 PetscTryTypeMethod((*A), destroy); 1332 1333 PetscCall(PetscFree((*A)->factorprefix)); 1334 PetscCall(PetscFree((*A)->defaultvectype)); 1335 PetscCall(PetscFree((*A)->bsizes)); 1336 PetscCall(PetscFree((*A)->solvertype)); 1337 for (PetscInt i = 0; i < MAT_FACTOR_NUM_TYPES; i++) PetscCall(PetscFree((*A)->preferredordering[i])); 1338 if ((*A)->redundant && (*A)->redundant->matseq[0] == *A) (*A)->redundant->matseq[0] = NULL; 1339 PetscCall(MatDestroy_Redundant(&(*A)->redundant)); 1340 PetscCall(MatProductClear(*A)); 1341 PetscCall(MatNullSpaceDestroy(&(*A)->nullsp)); 1342 PetscCall(MatNullSpaceDestroy(&(*A)->transnullsp)); 1343 PetscCall(MatNullSpaceDestroy(&(*A)->nearnullsp)); 1344 PetscCall(MatDestroy(&(*A)->schur)); 1345 PetscCall(PetscLayoutDestroy(&(*A)->rmap)); 1346 PetscCall(PetscLayoutDestroy(&(*A)->cmap)); 1347 PetscCall(PetscHeaderDestroy(A)); 1348 PetscFunctionReturn(0); 1349 } 1350 1351 /*@C 1352 MatSetValues - Inserts or adds a block of values into a matrix. 1353 These values may be cached, so `MatAssemblyBegin()` and `MatAssemblyEnd()` 1354 MUST be called after all calls to `MatSetValues()` have been completed. 1355 1356 Not Collective 1357 1358 Input Parameters: 1359 + mat - the matrix 1360 . v - a logically two-dimensional array of values 1361 . m, idxm - the number of rows and their global indices 1362 . n, idxn - the number of columns and their global indices 1363 - addv - either `ADD_VALUES` to add values to any existing entries, or `INSERT_VALUES` to replace existing entries with new values 1364 1365 Notes: 1366 If you create the matrix yourself (that is not with a call to `DMCreateMatrix()`) then you MUST call MatXXXXSetPreallocation() or 1367 `MatSetUp()` before using this routine 1368 1369 By default the values, v, are row-oriented. See `MatSetOption()` for other options. 1370 1371 Calls to `MatSetValues()` with the `INSERT_VALUES` and `ADD_VALUES` 1372 options cannot be mixed without intervening calls to the assembly 1373 routines. 1374 1375 `MatSetValues()` uses 0-based row and column numbers in Fortran 1376 as well as in C. 1377 1378 Negative indices may be passed in idxm and idxn, these rows and columns are 1379 simply ignored. This allows easily inserting element stiffness matrices 1380 with homogeneous Dirchlet boundary conditions that you don't want represented 1381 in the matrix. 1382 1383 Efficiency Alert: 1384 The routine `MatSetValuesBlocked()` may offer much better efficiency 1385 for users of block sparse formats (`MATSEQBAIJ` and `MATMPIBAIJ`). 1386 1387 Level: beginner 1388 1389 Developer Note: 1390 This is labeled with C so does not automatically generate Fortran stubs and interfaces 1391 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 1392 1393 .seealso: `Mat`, `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 1394 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES` 1395 @*/ 1396 PetscErrorCode MatSetValues(Mat mat, PetscInt m, const PetscInt idxm[], PetscInt n, const PetscInt idxn[], const PetscScalar v[], InsertMode addv) { 1397 PetscFunctionBeginHot; 1398 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 1399 PetscValidType(mat, 1); 1400 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1401 PetscValidIntPointer(idxm, 3); 1402 PetscValidIntPointer(idxn, 5); 1403 MatCheckPreallocated(mat, 1); 1404 1405 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 1406 else PetscCheck(mat->insertmode == addv, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cannot mix add values and insert values"); 1407 1408 if (PetscDefined(USE_DEBUG)) { 1409 PetscInt i, j; 1410 1411 PetscCheck(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 1412 for (i = 0; i < m; i++) { 1413 for (j = 0; j < n; j++) { 1414 if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i * n + j])) 1415 #if defined(PETSC_USE_COMPLEX) 1416 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]); 1417 #else 1418 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]); 1419 #endif 1420 } 1421 } 1422 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); 1423 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); 1424 } 1425 1426 if (mat->assembled) { 1427 mat->was_assembled = PETSC_TRUE; 1428 mat->assembled = PETSC_FALSE; 1429 } 1430 PetscCall(PetscLogEventBegin(MAT_SetValues, mat, 0, 0, 0)); 1431 PetscUseTypeMethod(mat, setvalues, m, idxm, n, idxn, v, addv); 1432 PetscCall(PetscLogEventEnd(MAT_SetValues, mat, 0, 0, 0)); 1433 PetscFunctionReturn(0); 1434 } 1435 1436 /*@C 1437 MatSetValuesIS - Inserts or adds a block of values into a matrix using an `IS` to indicate the rows and columns 1438 These values may be cached, so `MatAssemblyBegin()` and `MatAssemblyEnd()` 1439 MUST be called after all calls to `MatSetValues()` have been completed. 1440 1441 Not Collective 1442 1443 Input Parameters: 1444 + mat - the matrix 1445 . v - a logically two-dimensional array of values 1446 . ism - the rows to provide 1447 . isn - the columns to provide 1448 - addv - either `ADD_VALUES` to add values to any existing entries, or `INSERT_VALUES` to replace existing entries with new values 1449 1450 Notes: 1451 If you create the matrix yourself (that is not with a call to `DMCreateMatrix()`) then you MUST call MatXXXXSetPreallocation() or 1452 `MatSetUp()` before using this routine 1453 1454 By default the values, v, are row-oriented. See `MatSetOption()` for other options. 1455 1456 Calls to `MatSetValues()` with the `INSERT_VALUES` and `ADD_VALUES` 1457 options cannot be mixed without intervening calls to the assembly 1458 routines. 1459 1460 MatSetValues() uses 0-based row and column numbers in Fortran 1461 as well as in C. 1462 1463 Negative indices may be passed in ism and isn, these rows and columns are 1464 simply ignored. This allows easily inserting element stiffness matrices 1465 with homogeneous Dirchlet boundary conditions that you don't want represented 1466 in the matrix. 1467 1468 Efficiency Alert: 1469 The routine `MatSetValuesBlocked()` may offer much better efficiency 1470 for users of block sparse formats (`MATSEQBAIJ` and `MATMPIBAIJ`). 1471 1472 Level: beginner 1473 1474 Developer Notes: 1475 This is labeled with C so does not automatically generate Fortran stubs and interfaces 1476 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 1477 1478 This is currently not optimized for any particular `ISType` 1479 1480 .seealso: `MatSetOption()`, `MatSetValues()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 1481 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()` 1482 @*/ 1483 PetscErrorCode MatSetValuesIS(Mat mat, IS ism, IS isn, const PetscScalar v[], InsertMode addv) { 1484 PetscInt m, n; 1485 const PetscInt *rows, *cols; 1486 1487 PetscFunctionBeginHot; 1488 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 1489 PetscCall(ISGetIndices(ism, &rows)); 1490 PetscCall(ISGetIndices(isn, &cols)); 1491 PetscCall(ISGetLocalSize(ism, &m)); 1492 PetscCall(ISGetLocalSize(isn, &n)); 1493 PetscCall(MatSetValues(mat, m, rows, n, cols, v, addv)); 1494 PetscCall(ISRestoreIndices(ism, &rows)); 1495 PetscCall(ISRestoreIndices(isn, &cols)); 1496 PetscFunctionReturn(0); 1497 } 1498 1499 /*@ 1500 MatSetValuesRowLocal - Inserts a row (block row for `MATBAIJ` matrices) of nonzero 1501 values into a matrix 1502 1503 Not Collective 1504 1505 Input Parameters: 1506 + mat - the matrix 1507 . row - the (block) row to set 1508 - v - a logically two-dimensional array of values 1509 1510 Notes: 1511 By the values, v, are column-oriented (for the block version) and sorted 1512 1513 All the nonzeros in the row must be provided 1514 1515 The matrix must have previously had its column indices set 1516 1517 The row must belong to this process 1518 1519 Level: intermediate 1520 1521 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 1522 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()`, `MatSetValuesRow()`, `MatSetLocalToGlobalMapping()` 1523 @*/ 1524 PetscErrorCode MatSetValuesRowLocal(Mat mat, PetscInt row, const PetscScalar v[]) { 1525 PetscInt globalrow; 1526 1527 PetscFunctionBegin; 1528 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 1529 PetscValidType(mat, 1); 1530 PetscValidScalarPointer(v, 3); 1531 PetscCall(ISLocalToGlobalMappingApply(mat->rmap->mapping, 1, &row, &globalrow)); 1532 PetscCall(MatSetValuesRow(mat, globalrow, v)); 1533 PetscFunctionReturn(0); 1534 } 1535 1536 /*@ 1537 MatSetValuesRow - Inserts a row (block row for `MATBAIJ` matrices) of nonzero 1538 values into a matrix 1539 1540 Not Collective 1541 1542 Input Parameters: 1543 + mat - the matrix 1544 . row - the (block) row to set 1545 - 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 1546 1547 Notes: 1548 The values, v, are column-oriented for the block version. 1549 1550 All the nonzeros in the row must be provided 1551 1552 THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually `MatSetValues()` is used. 1553 1554 The row must belong to this process 1555 1556 Level: advanced 1557 1558 .seealso: `MatSetValues()`, `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 1559 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()` 1560 @*/ 1561 PetscErrorCode MatSetValuesRow(Mat mat, PetscInt row, const PetscScalar v[]) { 1562 PetscFunctionBeginHot; 1563 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 1564 PetscValidType(mat, 1); 1565 MatCheckPreallocated(mat, 1); 1566 PetscValidScalarPointer(v, 3); 1567 PetscCheck(mat->insertmode != ADD_VALUES, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cannot mix add and insert values"); 1568 PetscCheck(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 1569 mat->insertmode = INSERT_VALUES; 1570 1571 if (mat->assembled) { 1572 mat->was_assembled = PETSC_TRUE; 1573 mat->assembled = PETSC_FALSE; 1574 } 1575 PetscCall(PetscLogEventBegin(MAT_SetValues, mat, 0, 0, 0)); 1576 PetscUseTypeMethod(mat, setvaluesrow, row, v); 1577 PetscCall(PetscLogEventEnd(MAT_SetValues, mat, 0, 0, 0)); 1578 PetscFunctionReturn(0); 1579 } 1580 1581 /*@ 1582 MatSetValuesStencil - Inserts or adds a block of values into a matrix. 1583 Using structured grid indexing 1584 1585 Not Collective 1586 1587 Input Parameters: 1588 + mat - the matrix 1589 . m - number of rows being entered 1590 . idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered 1591 . n - number of columns being entered 1592 . idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered 1593 . v - a logically two-dimensional array of values 1594 - addv - either `ADD_VALUES` to add to existing entries at that location or `INSERT_VALUES` to replace existing entries with new values 1595 1596 Notes: 1597 By default the values, v, are row-oriented. See `MatSetOption()` for other options. 1598 1599 Calls to `MatSetValuesStencil()` with the `INSERT_VALUES` and `ADD_VALUES` 1600 options cannot be mixed without intervening calls to the assembly 1601 routines. 1602 1603 The grid coordinates are across the entire grid, not just the local portion 1604 1605 `MatSetValuesStencil()` uses 0-based row and column numbers in Fortran 1606 as well as in C. 1607 1608 For setting/accessing vector values via array coordinates you can use the `DMDAVecGetArray()` routine 1609 1610 In order to use this routine you must either obtain the matrix with `DMCreateMatrix()` 1611 or call `MatSetLocalToGlobalMapping()` and `MatSetStencil()` first. 1612 1613 The columns and rows in the stencil passed in MUST be contained within the 1614 ghost region of the given process as set with DMDACreateXXX() or `MatSetStencil()`. For example, 1615 if you create a `DMDA` with an overlap of one grid level and on a particular process its first 1616 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1617 first i index you can use in your column and row indices in `MatSetStencil()` is 5. 1618 1619 In Fortran idxm and idxn should be declared as 1620 $ MatStencil idxm(4,m),idxn(4,n) 1621 and the values inserted using 1622 $ idxm(MatStencil_i,1) = i 1623 $ idxm(MatStencil_j,1) = j 1624 $ idxm(MatStencil_k,1) = k 1625 $ idxm(MatStencil_c,1) = c 1626 etc 1627 1628 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 1629 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 1630 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 1631 `DM_BOUNDARY_PERIODIC` boundary type. 1632 1633 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 1634 a single value per point) you can skip filling those indices. 1635 1636 Inspired by the structured grid interface to the HYPRE package 1637 (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods) 1638 1639 Efficiency Alert: 1640 The routine `MatSetValuesBlockedStencil()` may offer much better efficiency 1641 for users of block sparse formats (`MATSEQBAIJ` and `MATMPIBAIJ`). 1642 1643 Level: beginner 1644 1645 .seealso: `Mat`, `DMDA`, `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()` 1646 `MatSetValues()`, `MatSetValuesBlockedStencil()`, `MatSetStencil()`, `DMCreateMatrix()`, `DMDAVecGetArray()`, `MatStencil` 1647 @*/ 1648 PetscErrorCode MatSetValuesStencil(Mat mat, PetscInt m, const MatStencil idxm[], PetscInt n, const MatStencil idxn[], const PetscScalar v[], InsertMode addv) { 1649 PetscInt buf[8192], *bufm = NULL, *bufn = NULL, *jdxm, *jdxn; 1650 PetscInt j, i, dim = mat->stencil.dim, *dims = mat->stencil.dims + 1, tmp; 1651 PetscInt *starts = mat->stencil.starts, *dxm = (PetscInt *)idxm, *dxn = (PetscInt *)idxn, sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1652 1653 PetscFunctionBegin; 1654 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1655 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 1656 PetscValidType(mat, 1); 1657 PetscValidPointer(idxm, 3); 1658 PetscValidPointer(idxn, 5); 1659 1660 if ((m + n) <= (PetscInt)(sizeof(buf) / sizeof(PetscInt))) { 1661 jdxm = buf; 1662 jdxn = buf + m; 1663 } else { 1664 PetscCall(PetscMalloc2(m, &bufm, n, &bufn)); 1665 jdxm = bufm; 1666 jdxn = bufn; 1667 } 1668 for (i = 0; i < m; i++) { 1669 for (j = 0; j < 3 - sdim; j++) dxm++; 1670 tmp = *dxm++ - starts[0]; 1671 for (j = 0; j < dim - 1; j++) { 1672 if ((*dxm++ - starts[j + 1]) < 0 || tmp < 0) tmp = -1; 1673 else tmp = tmp * dims[j] + *(dxm - 1) - starts[j + 1]; 1674 } 1675 if (mat->stencil.noc) dxm++; 1676 jdxm[i] = tmp; 1677 } 1678 for (i = 0; i < n; i++) { 1679 for (j = 0; j < 3 - sdim; j++) dxn++; 1680 tmp = *dxn++ - starts[0]; 1681 for (j = 0; j < dim - 1; j++) { 1682 if ((*dxn++ - starts[j + 1]) < 0 || tmp < 0) tmp = -1; 1683 else tmp = tmp * dims[j] + *(dxn - 1) - starts[j + 1]; 1684 } 1685 if (mat->stencil.noc) dxn++; 1686 jdxn[i] = tmp; 1687 } 1688 PetscCall(MatSetValuesLocal(mat, m, jdxm, n, jdxn, v, addv)); 1689 PetscCall(PetscFree2(bufm, bufn)); 1690 PetscFunctionReturn(0); 1691 } 1692 1693 /*@ 1694 MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix. 1695 Using structured grid indexing 1696 1697 Not Collective 1698 1699 Input Parameters: 1700 + mat - the matrix 1701 . m - number of rows being entered 1702 . idxm - grid coordinates for matrix rows being entered 1703 . n - number of columns being entered 1704 . idxn - grid coordinates for matrix columns being entered 1705 . v - a logically two-dimensional array of values 1706 - addv - either `ADD_VALUES` to add to existing entries or `INSERT_VALUES` to replace existing entries with new values 1707 1708 Notes: 1709 By default the values, v, are row-oriented and unsorted. 1710 See `MatSetOption()` for other options. 1711 1712 Calls to `MatSetValuesBlockedStencil()` with the `INSERT_VALUES` and `ADD_VALUES` 1713 options cannot be mixed without intervening calls to the assembly 1714 routines. 1715 1716 The grid coordinates are across the entire grid, not just the local portion 1717 1718 `MatSetValuesBlockedStencil()` uses 0-based row and column numbers in Fortran 1719 as well as in C. 1720 1721 For setting/accessing vector values via array coordinates you can use the `DMDAVecGetArray()` routine 1722 1723 In order to use this routine you must either obtain the matrix with `DMCreateMatrix()` 1724 or call `MatSetBlockSize()`, `MatSetLocalToGlobalMapping()` and `MatSetStencil()` first. 1725 1726 The columns and rows in the stencil passed in MUST be contained within the 1727 ghost region of the given process as set with DMDACreateXXX() or `MatSetStencil()`. For example, 1728 if you create a `DMDA` with an overlap of one grid level and on a particular process its first 1729 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1730 first i index you can use in your column and row indices in `MatSetStencil()` is 5. 1731 1732 In Fortran idxm and idxn should be declared as 1733 $ MatStencil idxm(4,m),idxn(4,n) 1734 and the values inserted using 1735 $ idxm(MatStencil_i,1) = i 1736 $ idxm(MatStencil_j,1) = j 1737 $ idxm(MatStencil_k,1) = k 1738 etc 1739 1740 Negative indices may be passed in idxm and idxn, these rows and columns are 1741 simply ignored. This allows easily inserting element stiffness matrices 1742 with homogeneous Dirchlet boundary conditions that you don't want represented 1743 in the matrix. 1744 1745 Inspired by the structured grid interface to the HYPRE package 1746 (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods) 1747 1748 Level: beginner 1749 1750 .seealso: `Mat`, `DMDA`, `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()` 1751 `MatSetValues()`, `MatSetValuesStencil()`, `MatSetStencil()`, `DMCreateMatrix()`, `DMDAVecGetArray()`, `MatStencil`, 1752 `MatSetBlockSize()`, `MatSetLocalToGlobalMapping()` 1753 @*/ 1754 PetscErrorCode MatSetValuesBlockedStencil(Mat mat, PetscInt m, const MatStencil idxm[], PetscInt n, const MatStencil idxn[], const PetscScalar v[], InsertMode addv) { 1755 PetscInt buf[8192], *bufm = NULL, *bufn = NULL, *jdxm, *jdxn; 1756 PetscInt j, i, dim = mat->stencil.dim, *dims = mat->stencil.dims + 1, tmp; 1757 PetscInt *starts = mat->stencil.starts, *dxm = (PetscInt *)idxm, *dxn = (PetscInt *)idxn, sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1758 1759 PetscFunctionBegin; 1760 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1761 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 1762 PetscValidType(mat, 1); 1763 PetscValidPointer(idxm, 3); 1764 PetscValidPointer(idxn, 5); 1765 PetscValidScalarPointer(v, 6); 1766 1767 if ((m + n) <= (PetscInt)(sizeof(buf) / sizeof(PetscInt))) { 1768 jdxm = buf; 1769 jdxn = buf + m; 1770 } else { 1771 PetscCall(PetscMalloc2(m, &bufm, n, &bufn)); 1772 jdxm = bufm; 1773 jdxn = bufn; 1774 } 1775 for (i = 0; i < m; i++) { 1776 for (j = 0; j < 3 - sdim; j++) dxm++; 1777 tmp = *dxm++ - starts[0]; 1778 for (j = 0; j < sdim - 1; j++) { 1779 if ((*dxm++ - starts[j + 1]) < 0 || tmp < 0) tmp = -1; 1780 else tmp = tmp * dims[j] + *(dxm - 1) - starts[j + 1]; 1781 } 1782 dxm++; 1783 jdxm[i] = tmp; 1784 } 1785 for (i = 0; i < n; i++) { 1786 for (j = 0; j < 3 - sdim; j++) dxn++; 1787 tmp = *dxn++ - starts[0]; 1788 for (j = 0; j < sdim - 1; j++) { 1789 if ((*dxn++ - starts[j + 1]) < 0 || tmp < 0) tmp = -1; 1790 else tmp = tmp * dims[j] + *(dxn - 1) - starts[j + 1]; 1791 } 1792 dxn++; 1793 jdxn[i] = tmp; 1794 } 1795 PetscCall(MatSetValuesBlockedLocal(mat, m, jdxm, n, jdxn, v, addv)); 1796 PetscCall(PetscFree2(bufm, bufn)); 1797 PetscFunctionReturn(0); 1798 } 1799 1800 /*@ 1801 MatSetStencil - Sets the grid information for setting values into a matrix via 1802 `MatSetValuesStencil()` 1803 1804 Not Collective 1805 1806 Input Parameters: 1807 + mat - the matrix 1808 . dim - dimension of the grid 1, 2, or 3 1809 . dims - number of grid points in x, y, and z direction, including ghost points on your processor 1810 . starts - starting point of ghost nodes on your processor in x, y, and z direction 1811 - dof - number of degrees of freedom per node 1812 1813 Notes: 1814 Inspired by the structured grid interface to the HYPRE package 1815 (www.llnl.gov/CASC/hyper) 1816 1817 For matrices generated with `DMCreateMatrix()` this routine is automatically called and so not needed by the 1818 user. 1819 1820 Level: beginner 1821 1822 .seealso: `Mat`, `MatStencil`, `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()` 1823 `MatSetValues()`, `MatSetValuesBlockedStencil()`, `MatSetValuesStencil()` 1824 @*/ 1825 PetscErrorCode MatSetStencil(Mat mat, PetscInt dim, const PetscInt dims[], const PetscInt starts[], PetscInt dof) { 1826 PetscFunctionBegin; 1827 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 1828 PetscValidIntPointer(dims, 3); 1829 PetscValidIntPointer(starts, 4); 1830 1831 mat->stencil.dim = dim + (dof > 1); 1832 for (PetscInt i = 0; i < dim; i++) { 1833 mat->stencil.dims[i] = dims[dim - i - 1]; /* copy the values in backwards */ 1834 mat->stencil.starts[i] = starts[dim - i - 1]; 1835 } 1836 mat->stencil.dims[dim] = dof; 1837 mat->stencil.starts[dim] = 0; 1838 mat->stencil.noc = (PetscBool)(dof == 1); 1839 PetscFunctionReturn(0); 1840 } 1841 1842 /*@C 1843 MatSetValuesBlocked - Inserts or adds a block of values into a matrix. 1844 1845 Not Collective 1846 1847 Input Parameters: 1848 + mat - the matrix 1849 . v - a logically two-dimensional array of values 1850 . m, idxm - the number of block rows and their global block indices 1851 . n, idxn - the number of block columns and their global block indices 1852 - addv - either `ADD_VALUES` to add values to any existing entries, or `INSERT_VALUES` replaces existing entries with new values 1853 1854 Notes: 1855 If you create the matrix yourself (that is not with a call to `DMCreateMatrix()`) then you MUST call 1856 MatXXXXSetPreallocation() or `MatSetUp()` before using this routine. 1857 1858 The m and n count the NUMBER of blocks in the row direction and column direction, 1859 NOT the total number of rows/columns; for example, if the block size is 2 and 1860 you are passing in values for rows 2,3,4,5 then m would be 2 (not 4). 1861 The values in idxm would be 1 2; that is the first index for each block divided by 1862 the block size. 1863 1864 Note that you must call `MatSetBlockSize()` when constructing this matrix (before 1865 preallocating it). 1866 1867 By default the values, v, are row-oriented, so the layout of 1868 v is the same as for `MatSetValues()`. See `MatSetOption()` for other options. 1869 1870 Calls to `MatSetValuesBlocked()` with the `INSERT_VALUES` and `ADD_VALUES` 1871 options cannot be mixed without intervening calls to the assembly 1872 routines. 1873 1874 `MatSetValuesBlocked()` uses 0-based row and column numbers in Fortran 1875 as well as in C. 1876 1877 Negative indices may be passed in idxm and idxn, these rows and columns are 1878 simply ignored. This allows easily inserting element stiffness matrices 1879 with homogeneous Dirchlet boundary conditions that you don't want represented 1880 in the matrix. 1881 1882 Each time an entry is set within a sparse matrix via `MatSetValues()`, 1883 internal searching must be done to determine where to place the 1884 data in the matrix storage space. By instead inserting blocks of 1885 entries via `MatSetValuesBlocked()`, the overhead of matrix assembly is 1886 reduced. 1887 1888 Example: 1889 $ Suppose m=n=2 and block size(bs) = 2 The array is 1890 $ 1891 $ 1 2 | 3 4 1892 $ 5 6 | 7 8 1893 $ - - - | - - - 1894 $ 9 10 | 11 12 1895 $ 13 14 | 15 16 1896 $ 1897 $ v[] should be passed in like 1898 $ v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] 1899 $ 1900 $ If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then 1901 $ v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16] 1902 1903 Level: intermediate 1904 1905 .seealso: `Mat`, `MatSetBlockSize()`, `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetValuesBlockedLocal()` 1906 @*/ 1907 PetscErrorCode MatSetValuesBlocked(Mat mat, PetscInt m, const PetscInt idxm[], PetscInt n, const PetscInt idxn[], const PetscScalar v[], InsertMode addv) { 1908 PetscFunctionBeginHot; 1909 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 1910 PetscValidType(mat, 1); 1911 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1912 PetscValidIntPointer(idxm, 3); 1913 PetscValidIntPointer(idxn, 5); 1914 MatCheckPreallocated(mat, 1); 1915 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 1916 else PetscCheck(mat->insertmode == addv, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cannot mix add values and insert values"); 1917 if (PetscDefined(USE_DEBUG)) { 1918 PetscCheck(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 1919 PetscCheck(mat->ops->setvaluesblocked || mat->ops->setvalues, PETSC_COMM_SELF, PETSC_ERR_SUP, "Mat type %s", ((PetscObject)mat)->type_name); 1920 } 1921 if (PetscDefined(USE_DEBUG)) { 1922 PetscInt rbs, cbs, M, N, i; 1923 PetscCall(MatGetBlockSizes(mat, &rbs, &cbs)); 1924 PetscCall(MatGetSize(mat, &M, &N)); 1925 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); 1926 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); 1927 } 1928 if (mat->assembled) { 1929 mat->was_assembled = PETSC_TRUE; 1930 mat->assembled = PETSC_FALSE; 1931 } 1932 PetscCall(PetscLogEventBegin(MAT_SetValues, mat, 0, 0, 0)); 1933 if (mat->ops->setvaluesblocked) { 1934 PetscUseTypeMethod(mat, setvaluesblocked, m, idxm, n, idxn, v, addv); 1935 } else { 1936 PetscInt buf[8192], *bufr = NULL, *bufc = NULL, *iidxm, *iidxn; 1937 PetscInt i, j, bs, cbs; 1938 1939 PetscCall(MatGetBlockSizes(mat, &bs, &cbs)); 1940 if (m * bs + n * cbs <= (PetscInt)(sizeof(buf) / sizeof(PetscInt))) { 1941 iidxm = buf; 1942 iidxn = buf + m * bs; 1943 } else { 1944 PetscCall(PetscMalloc2(m * bs, &bufr, n * cbs, &bufc)); 1945 iidxm = bufr; 1946 iidxn = bufc; 1947 } 1948 for (i = 0; i < m; i++) { 1949 for (j = 0; j < bs; j++) iidxm[i * bs + j] = bs * idxm[i] + j; 1950 } 1951 if (m != n || bs != cbs || idxm != idxn) { 1952 for (i = 0; i < n; i++) { 1953 for (j = 0; j < cbs; j++) iidxn[i * cbs + j] = cbs * idxn[i] + j; 1954 } 1955 } else iidxn = iidxm; 1956 PetscCall(MatSetValues(mat, m * bs, iidxm, n * cbs, iidxn, v, addv)); 1957 PetscCall(PetscFree2(bufr, bufc)); 1958 } 1959 PetscCall(PetscLogEventEnd(MAT_SetValues, mat, 0, 0, 0)); 1960 PetscFunctionReturn(0); 1961 } 1962 1963 /*@C 1964 MatGetValues - Gets a block of local values from a matrix. 1965 1966 Not Collective; can only return values that are owned by the give process 1967 1968 Input Parameters: 1969 + mat - the matrix 1970 . v - a logically two-dimensional array for storing the values 1971 . m, idxm - the number of rows and their global indices 1972 - n, idxn - the number of columns and their global indices 1973 1974 Notes: 1975 The user must allocate space (m*n `PetscScalar`s) for the values, v. 1976 The values, v, are then returned in a row-oriented format, 1977 analogous to that used by default in `MatSetValues()`. 1978 1979 `MatGetValues()` uses 0-based row and column numbers in 1980 Fortran as well as in C. 1981 1982 `MatGetValues()` requires that the matrix has been assembled 1983 with `MatAssemblyBegin()`/`MatAssemblyEnd()`. Thus, calls to 1984 `MatSetValues()` and `MatGetValues()` CANNOT be made in succession 1985 without intermediate matrix assembly. 1986 1987 Negative row or column indices will be ignored and those locations in v[] will be 1988 left unchanged. 1989 1990 For the standard row-based matrix formats, idxm[] can only contain rows owned by the requesting MPI rank. 1991 That is, rows with global index greater than or equal to rstart and less than rend where rstart and rend are obtainable 1992 from `MatGetOwnershipRange`(mat,&rstart,&rend). 1993 1994 Level: advanced 1995 1996 .seealso: `Mat`, `MatGetRow()`, `MatCreateSubMatrices()`, `MatSetValues()`, `MatGetOwnershipRange()`, `MatGetValuesLocal()`, `MatGetValue()` 1997 @*/ 1998 PetscErrorCode MatGetValues(Mat mat, PetscInt m, const PetscInt idxm[], PetscInt n, const PetscInt idxn[], PetscScalar v[]) { 1999 PetscFunctionBegin; 2000 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2001 PetscValidType(mat, 1); 2002 if (!m || !n) PetscFunctionReturn(0); 2003 PetscValidIntPointer(idxm, 3); 2004 PetscValidIntPointer(idxn, 5); 2005 PetscValidScalarPointer(v, 6); 2006 PetscCheck(mat->assembled, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 2007 PetscCheck(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 2008 MatCheckPreallocated(mat, 1); 2009 2010 PetscCall(PetscLogEventBegin(MAT_GetValues, mat, 0, 0, 0)); 2011 PetscUseTypeMethod(mat, getvalues, m, idxm, n, idxn, v); 2012 PetscCall(PetscLogEventEnd(MAT_GetValues, mat, 0, 0, 0)); 2013 PetscFunctionReturn(0); 2014 } 2015 2016 /*@C 2017 MatGetValuesLocal - retrieves values from certain locations in a matrix using the local numbering of the indices 2018 defined previously by `MatSetLocalToGlobalMapping()` 2019 2020 Not Collective 2021 2022 Input Parameters: 2023 + mat - the matrix 2024 . nrow, irow - number of rows and their local indices 2025 - ncol, icol - number of columns and their local indices 2026 2027 Output Parameter: 2028 . y - a logically two-dimensional array of values 2029 2030 Notes: 2031 If you create the matrix yourself (that is not with a call to `DMCreateMatrix()`) then you MUST call `MatSetLocalToGlobalMapping()` before using this routine. 2032 2033 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, 2034 are greater than or equal to rstart and less than rend where rstart and rend are obtainable from `MatGetOwnershipRange`(mat,&rstart,&rend). One can 2035 determine if the resulting global row associated with the local row r is owned by the requesting MPI rank by applying the `ISLocalToGlobalMapping` set 2036 with `MatSetLocalToGlobalMapping()`. 2037 2038 Developer Note: 2039 This is labelled with C so does not automatically generate Fortran stubs and interfaces 2040 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2041 2042 Level: advanced 2043 2044 .seealso: `Mat`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetLocalToGlobalMapping()`, 2045 `MatSetValuesLocal()`, `MatGetValues()` 2046 @*/ 2047 PetscErrorCode MatGetValuesLocal(Mat mat, PetscInt nrow, const PetscInt irow[], PetscInt ncol, const PetscInt icol[], PetscScalar y[]) { 2048 PetscFunctionBeginHot; 2049 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2050 PetscValidType(mat, 1); 2051 MatCheckPreallocated(mat, 1); 2052 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to retrieve */ 2053 PetscValidIntPointer(irow, 3); 2054 PetscValidIntPointer(icol, 5); 2055 if (PetscDefined(USE_DEBUG)) { 2056 PetscCheck(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 2057 PetscCheck(mat->ops->getvalueslocal || mat->ops->getvalues, PETSC_COMM_SELF, PETSC_ERR_SUP, "Mat type %s", ((PetscObject)mat)->type_name); 2058 } 2059 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 2060 PetscCall(PetscLogEventBegin(MAT_GetValues, mat, 0, 0, 0)); 2061 if (mat->ops->getvalueslocal) PetscUseTypeMethod(mat, getvalueslocal, nrow, irow, ncol, icol, y); 2062 else { 2063 PetscInt buf[8192], *bufr = NULL, *bufc = NULL, *irowm, *icolm; 2064 if ((nrow + ncol) <= (PetscInt)(sizeof(buf) / sizeof(PetscInt))) { 2065 irowm = buf; 2066 icolm = buf + nrow; 2067 } else { 2068 PetscCall(PetscMalloc2(nrow, &bufr, ncol, &bufc)); 2069 irowm = bufr; 2070 icolm = bufc; 2071 } 2072 PetscCheck(mat->rmap->mapping, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "MatGetValuesLocal() cannot proceed without local-to-global row mapping (See MatSetLocalToGlobalMapping())."); 2073 PetscCheck(mat->cmap->mapping, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "MatGetValuesLocal() cannot proceed without local-to-global column mapping (See MatSetLocalToGlobalMapping())."); 2074 PetscCall(ISLocalToGlobalMappingApply(mat->rmap->mapping, nrow, irow, irowm)); 2075 PetscCall(ISLocalToGlobalMappingApply(mat->cmap->mapping, ncol, icol, icolm)); 2076 PetscCall(MatGetValues(mat, nrow, irowm, ncol, icolm, y)); 2077 PetscCall(PetscFree2(bufr, bufc)); 2078 } 2079 PetscCall(PetscLogEventEnd(MAT_GetValues, mat, 0, 0, 0)); 2080 PetscFunctionReturn(0); 2081 } 2082 2083 /*@ 2084 MatSetValuesBatch - Adds (`ADD_VALUES`) many blocks of values into a matrix at once. The blocks must all be square and 2085 the same size. Currently, this can only be called once and creates the given matrix. 2086 2087 Not Collective 2088 2089 Input Parameters: 2090 + mat - the matrix 2091 . nb - the number of blocks 2092 . bs - the number of rows (and columns) in each block 2093 . rows - a concatenation of the rows for each block 2094 - v - a concatenation of logically two-dimensional arrays of values 2095 2096 Note: 2097 `MatSetPreallocationCOO()` and `MatSetValuesCOO()` may be a better way to provide the values 2098 2099 In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix. 2100 2101 Level: advanced 2102 2103 .seealso: `Mat`, `Mat`MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 2104 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()`, `MatSetPreallocationCOO()`, `MatSetValuesCOO()` 2105 @*/ 2106 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[]) { 2107 PetscFunctionBegin; 2108 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2109 PetscValidType(mat, 1); 2110 PetscValidIntPointer(rows, 4); 2111 PetscValidScalarPointer(v, 5); 2112 PetscAssert(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 2113 2114 PetscCall(PetscLogEventBegin(MAT_SetValuesBatch, mat, 0, 0, 0)); 2115 if (mat->ops->setvaluesbatch) PetscUseTypeMethod(mat, setvaluesbatch, nb, bs, rows, v); 2116 else { 2117 for (PetscInt b = 0; b < nb; ++b) PetscCall(MatSetValues(mat, bs, &rows[b * bs], bs, &rows[b * bs], &v[b * bs * bs], ADD_VALUES)); 2118 } 2119 PetscCall(PetscLogEventEnd(MAT_SetValuesBatch, mat, 0, 0, 0)); 2120 PetscFunctionReturn(0); 2121 } 2122 2123 /*@ 2124 MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by 2125 the routine `MatSetValuesLocal()` to allow users to insert matrix entries 2126 using a local (per-processor) numbering. 2127 2128 Not Collective 2129 2130 Input Parameters: 2131 + x - the matrix 2132 . rmapping - row mapping created with `ISLocalToGlobalMappingCreate()` or `ISLocalToGlobalMappingCreateIS()` 2133 - cmapping - column mapping 2134 2135 Level: intermediate 2136 2137 Note: 2138 If the matrix is obtained with `DMCreateMatrix()` then this may already have been called on the matrix 2139 2140 .seealso: `Mat`, `DM`, `DMCreateMatrix()`, `MatGetLocalToGlobalMapping()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetValuesLocal()`, `MatGetValuesLocal()` 2141 @*/ 2142 PetscErrorCode MatSetLocalToGlobalMapping(Mat x, ISLocalToGlobalMapping rmapping, ISLocalToGlobalMapping cmapping) { 2143 PetscFunctionBegin; 2144 PetscValidHeaderSpecific(x, MAT_CLASSID, 1); 2145 PetscValidType(x, 1); 2146 if (rmapping) PetscValidHeaderSpecific(rmapping, IS_LTOGM_CLASSID, 2); 2147 if (cmapping) PetscValidHeaderSpecific(cmapping, IS_LTOGM_CLASSID, 3); 2148 if (x->ops->setlocaltoglobalmapping) PetscUseTypeMethod(x, setlocaltoglobalmapping, rmapping, cmapping); 2149 else { 2150 PetscCall(PetscLayoutSetISLocalToGlobalMapping(x->rmap, rmapping)); 2151 PetscCall(PetscLayoutSetISLocalToGlobalMapping(x->cmap, cmapping)); 2152 } 2153 PetscFunctionReturn(0); 2154 } 2155 2156 /*@ 2157 MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by `MatSetLocalToGlobalMapping()` 2158 2159 Not Collective 2160 2161 Input Parameter: 2162 . A - the matrix 2163 2164 Output Parameters: 2165 + rmapping - row mapping 2166 - cmapping - column mapping 2167 2168 Level: advanced 2169 2170 .seealso: `Mat`, `MatSetLocalToGlobalMapping()`, `MatSetValuesLocal()` 2171 @*/ 2172 PetscErrorCode MatGetLocalToGlobalMapping(Mat A, ISLocalToGlobalMapping *rmapping, ISLocalToGlobalMapping *cmapping) { 2173 PetscFunctionBegin; 2174 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2175 PetscValidType(A, 1); 2176 if (rmapping) { 2177 PetscValidPointer(rmapping, 2); 2178 *rmapping = A->rmap->mapping; 2179 } 2180 if (cmapping) { 2181 PetscValidPointer(cmapping, 3); 2182 *cmapping = A->cmap->mapping; 2183 } 2184 PetscFunctionReturn(0); 2185 } 2186 2187 /*@ 2188 MatSetLayouts - Sets the `PetscLayout` objects for rows and columns of a matrix 2189 2190 Logically Collective on A 2191 2192 Input Parameters: 2193 + A - the matrix 2194 . rmap - row layout 2195 - cmap - column layout 2196 2197 Level: advanced 2198 2199 Note: 2200 The `PetscLayout` objects are usually created automatically for the matrix so this routine rarely needs to be called. 2201 2202 .seealso: `PetscLayout`, `MatCreateVecs()`, `MatGetLocalToGlobalMapping()`, `MatGetLayouts()` 2203 @*/ 2204 PetscErrorCode MatSetLayouts(Mat A, PetscLayout rmap, PetscLayout cmap) { 2205 PetscFunctionBegin; 2206 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2207 PetscCall(PetscLayoutReference(rmap, &A->rmap)); 2208 PetscCall(PetscLayoutReference(cmap, &A->cmap)); 2209 PetscFunctionReturn(0); 2210 } 2211 2212 /*@ 2213 MatGetLayouts - Gets the `PetscLayout` objects for rows and columns 2214 2215 Not Collective 2216 2217 Input Parameter: 2218 . A - the matrix 2219 2220 Output Parameters: 2221 + rmap - row layout 2222 - cmap - column layout 2223 2224 Level: advanced 2225 2226 .seealso: `PetscLayout`, `MatCreateVecs()`, `MatGetLocalToGlobalMapping()`, `MatSetLayouts()` 2227 @*/ 2228 PetscErrorCode MatGetLayouts(Mat A, PetscLayout *rmap, PetscLayout *cmap) { 2229 PetscFunctionBegin; 2230 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2231 PetscValidType(A, 1); 2232 if (rmap) { 2233 PetscValidPointer(rmap, 2); 2234 *rmap = A->rmap; 2235 } 2236 if (cmap) { 2237 PetscValidPointer(cmap, 3); 2238 *cmap = A->cmap; 2239 } 2240 PetscFunctionReturn(0); 2241 } 2242 2243 /*@C 2244 MatSetValuesLocal - Inserts or adds values into certain locations of a matrix, 2245 using a local numbering of the nodes. 2246 2247 Not Collective 2248 2249 Input Parameters: 2250 + mat - the matrix 2251 . nrow, irow - number of rows and their local indices 2252 . ncol, icol - number of columns and their local indices 2253 . y - a logically two-dimensional array of values 2254 - addv - either `INSERT_VALUES` to add values to any existing entries, or `INSERT_VALUES` to replace existing entries with new values 2255 2256 Notes: 2257 If you create the matrix yourself (that is not with a call to `DMCreateMatrix()`) then you MUST call MatXXXXSetPreallocation() or 2258 `MatSetUp()` before using this routine 2259 2260 If you create the matrix yourself (that is not with a call to `DMCreateMatrix()`) then you MUST call `MatSetLocalToGlobalMapping()` before using this routine 2261 2262 Calls to `MatSetValuesLocal()` with the `INSERT_VALUES` and `ADD_VALUES` 2263 options cannot be mixed without intervening calls to the assembly 2264 routines. 2265 2266 These values may be cached, so `MatAssemblyBegin()` and `MatAssemblyEnd()` 2267 MUST be called after all calls to `MatSetValuesLocal()` have been completed. 2268 2269 Level: intermediate 2270 2271 Developer Note: 2272 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2273 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2274 2275 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetLocalToGlobalMapping()`, 2276 `MatGetValuesLocal()` 2277 @*/ 2278 PetscErrorCode MatSetValuesLocal(Mat mat, PetscInt nrow, const PetscInt irow[], PetscInt ncol, const PetscInt icol[], const PetscScalar y[], InsertMode addv) { 2279 PetscFunctionBeginHot; 2280 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2281 PetscValidType(mat, 1); 2282 MatCheckPreallocated(mat, 1); 2283 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2284 PetscValidIntPointer(irow, 3); 2285 PetscValidIntPointer(icol, 5); 2286 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 2287 else PetscCheck(mat->insertmode == addv, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cannot mix add values and insert values"); 2288 if (PetscDefined(USE_DEBUG)) { 2289 PetscCheck(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 2290 PetscCheck(mat->ops->setvalueslocal || mat->ops->setvalues, PETSC_COMM_SELF, PETSC_ERR_SUP, "Mat type %s", ((PetscObject)mat)->type_name); 2291 } 2292 2293 if (mat->assembled) { 2294 mat->was_assembled = PETSC_TRUE; 2295 mat->assembled = PETSC_FALSE; 2296 } 2297 PetscCall(PetscLogEventBegin(MAT_SetValues, mat, 0, 0, 0)); 2298 if (mat->ops->setvalueslocal) PetscUseTypeMethod(mat, setvalueslocal, nrow, irow, ncol, icol, y, addv); 2299 else { 2300 PetscInt buf[8192], *bufr = NULL, *bufc = NULL; 2301 const PetscInt *irowm, *icolm; 2302 2303 if ((!mat->rmap->mapping && !mat->cmap->mapping) || (nrow + ncol) <= (PetscInt)(sizeof(buf) / sizeof(PetscInt))) { 2304 bufr = buf; 2305 bufc = buf + nrow; 2306 irowm = bufr; 2307 icolm = bufc; 2308 } else { 2309 PetscCall(PetscMalloc2(nrow, &bufr, ncol, &bufc)); 2310 irowm = bufr; 2311 icolm = bufc; 2312 } 2313 if (mat->rmap->mapping) PetscCall(ISLocalToGlobalMappingApply(mat->rmap->mapping, nrow, irow, bufr)); 2314 else irowm = irow; 2315 if (mat->cmap->mapping) { 2316 if (mat->cmap->mapping != mat->rmap->mapping || ncol != nrow || icol != irow) { 2317 PetscCall(ISLocalToGlobalMappingApply(mat->cmap->mapping, ncol, icol, bufc)); 2318 } else icolm = irowm; 2319 } else icolm = icol; 2320 PetscCall(MatSetValues(mat, nrow, irowm, ncol, icolm, y, addv)); 2321 if (bufr != buf) PetscCall(PetscFree2(bufr, bufc)); 2322 } 2323 PetscCall(PetscLogEventEnd(MAT_SetValues, mat, 0, 0, 0)); 2324 PetscFunctionReturn(0); 2325 } 2326 2327 /*@C 2328 MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix, 2329 using a local ordering of the nodes a block at a time. 2330 2331 Not Collective 2332 2333 Input Parameters: 2334 + x - the matrix 2335 . nrow, irow - number of rows and their local indices 2336 . ncol, icol - number of columns and their local indices 2337 . y - a logically two-dimensional array of values 2338 - addv - either `ADD_VALUES` to add values to any existing entries, or `INSERT_VALUES` to replace existing entries with new values 2339 2340 Notes: 2341 If you create the matrix yourself (that is not with a call to `DMCreateMatrix()`) then you MUST call MatXXXXSetPreallocation() or 2342 `MatSetUp()` before using this routine 2343 2344 If you create the matrix yourself (that is not with a call to `DMCreateMatrix()`) then you MUST call `MatSetBlockSize()` and `MatSetLocalToGlobalMapping()` 2345 before using this routineBefore calling `MatSetValuesLocal()`, the user must first set the 2346 2347 Calls to `MatSetValuesBlockedLocal()` with the `INSERT_VALUES` and `ADD_VALUES` 2348 options cannot be mixed without intervening calls to the assembly 2349 routines. 2350 2351 These values may be cached, so `MatAssemblyBegin()` and `MatAssemblyEnd()` 2352 MUST be called after all calls to `MatSetValuesBlockedLocal()` have been completed. 2353 2354 Level: intermediate 2355 2356 Developer Note: 2357 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2358 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2359 2360 .seealso: `Mat`, `MatSetBlockSize()`, `MatSetLocalToGlobalMapping()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, 2361 `MatSetValuesLocal()`, `MatSetValuesBlocked()` 2362 @*/ 2363 PetscErrorCode MatSetValuesBlockedLocal(Mat mat, PetscInt nrow, const PetscInt irow[], PetscInt ncol, const PetscInt icol[], const PetscScalar y[], InsertMode addv) { 2364 PetscFunctionBeginHot; 2365 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2366 PetscValidType(mat, 1); 2367 MatCheckPreallocated(mat, 1); 2368 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2369 PetscValidIntPointer(irow, 3); 2370 PetscValidIntPointer(icol, 5); 2371 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 2372 else PetscCheck(mat->insertmode == addv, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cannot mix add values and insert values"); 2373 if (PetscDefined(USE_DEBUG)) { 2374 PetscCheck(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 2375 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); 2376 } 2377 2378 if (mat->assembled) { 2379 mat->was_assembled = PETSC_TRUE; 2380 mat->assembled = PETSC_FALSE; 2381 } 2382 if (PetscUnlikelyDebug(mat->rmap->mapping)) { /* Condition on the mapping existing, because MatSetValuesBlockedLocal_IS does not require it to be set. */ 2383 PetscInt irbs, rbs; 2384 PetscCall(MatGetBlockSizes(mat, &rbs, NULL)); 2385 PetscCall(ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping, &irbs)); 2386 PetscCheck(rbs == irbs, PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Different row block sizes! mat %" PetscInt_FMT ", row l2g map %" PetscInt_FMT, rbs, irbs); 2387 } 2388 if (PetscUnlikelyDebug(mat->cmap->mapping)) { 2389 PetscInt icbs, cbs; 2390 PetscCall(MatGetBlockSizes(mat, NULL, &cbs)); 2391 PetscCall(ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping, &icbs)); 2392 PetscCheck(cbs == icbs, PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Different col block sizes! mat %" PetscInt_FMT ", col l2g map %" PetscInt_FMT, cbs, icbs); 2393 } 2394 PetscCall(PetscLogEventBegin(MAT_SetValues, mat, 0, 0, 0)); 2395 if (mat->ops->setvaluesblockedlocal) PetscUseTypeMethod(mat, setvaluesblockedlocal, nrow, irow, ncol, icol, y, addv); 2396 else { 2397 PetscInt buf[8192], *bufr = NULL, *bufc = NULL; 2398 const PetscInt *irowm, *icolm; 2399 2400 if ((!mat->rmap->mapping && !mat->cmap->mapping) || (nrow + ncol) <= (PetscInt)(sizeof(buf) / sizeof(PetscInt))) { 2401 bufr = buf; 2402 bufc = buf + nrow; 2403 irowm = bufr; 2404 icolm = bufc; 2405 } else { 2406 PetscCall(PetscMalloc2(nrow, &bufr, ncol, &bufc)); 2407 irowm = bufr; 2408 icolm = bufc; 2409 } 2410 if (mat->rmap->mapping) PetscCall(ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping, nrow, irow, bufr)); 2411 else irowm = irow; 2412 if (mat->cmap->mapping) { 2413 if (mat->cmap->mapping != mat->rmap->mapping || ncol != nrow || icol != irow) { 2414 PetscCall(ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping, ncol, icol, bufc)); 2415 } else icolm = irowm; 2416 } else icolm = icol; 2417 PetscCall(MatSetValuesBlocked(mat, nrow, irowm, ncol, icolm, y, addv)); 2418 if (bufr != buf) PetscCall(PetscFree2(bufr, bufc)); 2419 } 2420 PetscCall(PetscLogEventEnd(MAT_SetValues, mat, 0, 0, 0)); 2421 PetscFunctionReturn(0); 2422 } 2423 2424 /*@ 2425 MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal 2426 2427 Collective on mat 2428 2429 Input Parameters: 2430 + mat - the matrix 2431 - x - the vector to be multiplied 2432 2433 Output Parameters: 2434 . y - the result 2435 2436 Note: 2437 The vectors x and y cannot be the same. I.e., one cannot 2438 call `MatMultDiagonalBlock`(A,y,y). 2439 2440 Level: developer 2441 2442 .seealso: `Mat`, `MatMult()`, `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 2443 @*/ 2444 PetscErrorCode MatMultDiagonalBlock(Mat mat, Vec x, Vec y) { 2445 PetscFunctionBegin; 2446 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2447 PetscValidType(mat, 1); 2448 PetscValidHeaderSpecific(x, VEC_CLASSID, 2); 2449 PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 2450 2451 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 2452 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 2453 PetscCheck(x != y, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "x and y must be different vectors"); 2454 MatCheckPreallocated(mat, 1); 2455 2456 PetscUseTypeMethod(mat, multdiagonalblock, x, y); 2457 PetscCall(PetscObjectStateIncrease((PetscObject)y)); 2458 PetscFunctionReturn(0); 2459 } 2460 2461 /* --------------------------------------------------------*/ 2462 /*@ 2463 MatMult - Computes the matrix-vector product, y = Ax. 2464 2465 Neighbor-wise Collective on mat 2466 2467 Input Parameters: 2468 + mat - the matrix 2469 - x - the vector to be multiplied 2470 2471 Output Parameters: 2472 . y - the result 2473 2474 Note: 2475 The vectors x and y cannot be the same. I.e., one cannot 2476 call `MatMult`(A,y,y). 2477 2478 Level: beginner 2479 2480 .seealso: `Mat`, `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 2481 @*/ 2482 PetscErrorCode MatMult(Mat mat, Vec x, Vec y) { 2483 PetscFunctionBegin; 2484 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2485 PetscValidType(mat, 1); 2486 PetscValidHeaderSpecific(x, VEC_CLASSID, 2); 2487 PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 2488 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 2489 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 2490 PetscCheck(x != y, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "x and y must be different vectors"); 2491 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); 2492 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); 2493 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); 2494 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); 2495 PetscCall(VecSetErrorIfLocked(y, 3)); 2496 if (mat->erroriffailure) PetscCall(VecValidValues(x, 2, PETSC_TRUE)); 2497 MatCheckPreallocated(mat, 1); 2498 2499 PetscCall(VecLockReadPush(x)); 2500 PetscCall(PetscLogEventBegin(MAT_Mult, mat, x, y, 0)); 2501 PetscUseTypeMethod(mat, mult, x, y); 2502 PetscCall(PetscLogEventEnd(MAT_Mult, mat, x, y, 0)); 2503 if (mat->erroriffailure) PetscCall(VecValidValues(y, 3, PETSC_FALSE)); 2504 PetscCall(VecLockReadPop(x)); 2505 PetscFunctionReturn(0); 2506 } 2507 2508 /*@ 2509 MatMultTranspose - Computes matrix transpose times a vector y = A^T * x. 2510 2511 Neighbor-wise Collective on mat 2512 2513 Input Parameters: 2514 + mat - the matrix 2515 - x - the vector to be multiplied 2516 2517 Output Parameters: 2518 . y - the result 2519 2520 Notes: 2521 The vectors x and y cannot be the same. I.e., one cannot 2522 call `MatMultTranspose`(A,y,y). 2523 2524 For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple, 2525 use `MatMultHermitianTranspose()` 2526 2527 Level: beginner 2528 2529 .seealso: `Mat`, `MatMult()`, `MatMultAdd()`, `MatMultTransposeAdd()`, `MatMultHermitianTranspose()`, `MatTranspose()` 2530 @*/ 2531 PetscErrorCode MatMultTranspose(Mat mat, Vec x, Vec y) { 2532 PetscErrorCode (*op)(Mat, Vec, Vec) = NULL; 2533 2534 PetscFunctionBegin; 2535 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2536 PetscValidType(mat, 1); 2537 PetscValidHeaderSpecific(x, VEC_CLASSID, 2); 2538 PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 2539 2540 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 2541 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 2542 PetscCheck(x != y, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "x and y must be different vectors"); 2543 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); 2544 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); 2545 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); 2546 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); 2547 if (mat->erroriffailure) PetscCall(VecValidValues(x, 2, PETSC_TRUE)); 2548 MatCheckPreallocated(mat, 1); 2549 2550 if (!mat->ops->multtranspose) { 2551 if (mat->symmetric == PETSC_BOOL3_TRUE && mat->ops->mult) op = mat->ops->mult; 2552 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); 2553 } else op = mat->ops->multtranspose; 2554 PetscCall(PetscLogEventBegin(MAT_MultTranspose, mat, x, y, 0)); 2555 PetscCall(VecLockReadPush(x)); 2556 PetscCall((*op)(mat, x, y)); 2557 PetscCall(VecLockReadPop(x)); 2558 PetscCall(PetscLogEventEnd(MAT_MultTranspose, mat, x, y, 0)); 2559 PetscCall(PetscObjectStateIncrease((PetscObject)y)); 2560 if (mat->erroriffailure) PetscCall(VecValidValues(y, 3, PETSC_FALSE)); 2561 PetscFunctionReturn(0); 2562 } 2563 2564 /*@ 2565 MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector. 2566 2567 Neighbor-wise Collective on mat 2568 2569 Input Parameters: 2570 + mat - the matrix 2571 - x - the vector to be multilplied 2572 2573 Output Parameters: 2574 . y - the result 2575 2576 Notes: 2577 The vectors x and y cannot be the same. I.e., one cannot 2578 call `MatMultHermitianTranspose`(A,y,y). 2579 2580 Also called the conjugate transpose, complex conjugate transpose, or adjoint. 2581 2582 For real numbers `MatMultTranspose()` and `MatMultHermitianTranspose()` are identical. 2583 2584 Level: beginner 2585 2586 .seealso: `Mat`, `MatMult()`, `MatMultAdd()`, `MatMultHermitianTransposeAdd()`, `MatMultTranspose()` 2587 @*/ 2588 PetscErrorCode MatMultHermitianTranspose(Mat mat, Vec x, Vec y) { 2589 PetscFunctionBegin; 2590 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2591 PetscValidType(mat, 1); 2592 PetscValidHeaderSpecific(x, VEC_CLASSID, 2); 2593 PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 2594 2595 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 2596 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 2597 PetscCheck(x != y, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "x and y must be different vectors"); 2598 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); 2599 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); 2600 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); 2601 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); 2602 MatCheckPreallocated(mat, 1); 2603 2604 PetscCall(PetscLogEventBegin(MAT_MultHermitianTranspose, mat, x, y, 0)); 2605 #if defined(PETSC_USE_COMPLEX) 2606 if (mat->ops->multhermitiantranspose || (mat->hermitian == PETSC_BOOL3_TRUE && mat->ops->mult)) { 2607 PetscCall(VecLockReadPush(x)); 2608 if (mat->ops->multhermitiantranspose) PetscUseTypeMethod(mat, multhermitiantranspose, x, y); 2609 else PetscUseTypeMethod(mat, mult, x, y); 2610 PetscCall(VecLockReadPop(x)); 2611 } else { 2612 Vec w; 2613 PetscCall(VecDuplicate(x, &w)); 2614 PetscCall(VecCopy(x, w)); 2615 PetscCall(VecConjugate(w)); 2616 PetscCall(MatMultTranspose(mat, w, y)); 2617 PetscCall(VecDestroy(&w)); 2618 PetscCall(VecConjugate(y)); 2619 } 2620 PetscCall(PetscObjectStateIncrease((PetscObject)y)); 2621 #else 2622 PetscCall(MatMultTranspose(mat, x, y)); 2623 #endif 2624 PetscCall(PetscLogEventEnd(MAT_MultHermitianTranspose, mat, x, y, 0)); 2625 PetscFunctionReturn(0); 2626 } 2627 2628 /*@ 2629 MatMultAdd - Computes v3 = v2 + A * v1. 2630 2631 Neighbor-wise Collective on mat 2632 2633 Input Parameters: 2634 + mat - the matrix 2635 - v1, v2 - the vectors 2636 2637 Output Parameters: 2638 . v3 - the result 2639 2640 Note: 2641 The vectors v1 and v3 cannot be the same. I.e., one cannot 2642 call `MatMultAdd`(A,v1,v2,v1). 2643 2644 Level: beginner 2645 2646 .seealso: `Mat`, `MatMultTranspose()`, `MatMult()`, `MatMultTransposeAdd()` 2647 @*/ 2648 PetscErrorCode MatMultAdd(Mat mat, Vec v1, Vec v2, Vec v3) { 2649 PetscFunctionBegin; 2650 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2651 PetscValidType(mat, 1); 2652 PetscValidHeaderSpecific(v1, VEC_CLASSID, 2); 2653 PetscValidHeaderSpecific(v2, VEC_CLASSID, 3); 2654 PetscValidHeaderSpecific(v3, VEC_CLASSID, 4); 2655 2656 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 2657 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 2658 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); 2659 /* 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); 2660 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); */ 2661 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); 2662 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); 2663 PetscCheck(v1 != v3, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_IDN, "v1 and v3 must be different vectors"); 2664 MatCheckPreallocated(mat, 1); 2665 2666 PetscCall(PetscLogEventBegin(MAT_MultAdd, mat, v1, v2, v3)); 2667 PetscCall(VecLockReadPush(v1)); 2668 PetscUseTypeMethod(mat, multadd, v1, v2, v3); 2669 PetscCall(VecLockReadPop(v1)); 2670 PetscCall(PetscLogEventEnd(MAT_MultAdd, mat, v1, v2, v3)); 2671 PetscCall(PetscObjectStateIncrease((PetscObject)v3)); 2672 PetscFunctionReturn(0); 2673 } 2674 2675 /*@ 2676 MatMultTransposeAdd - Computes v3 = v2 + A' * v1. 2677 2678 Neighbor-wise Collective on mat 2679 2680 Input Parameters: 2681 + mat - the matrix 2682 - v1, v2 - the vectors 2683 2684 Output Parameters: 2685 . v3 - the result 2686 2687 Note: 2688 The vectors v1 and v3 cannot be the same. I.e., one cannot 2689 call `MatMultTransposeAdd`(A,v1,v2,v1). 2690 2691 Level: beginner 2692 2693 .seealso: `Mat`, `MatMultTranspose()`, `MatMultAdd()`, `MatMult()` 2694 @*/ 2695 PetscErrorCode MatMultTransposeAdd(Mat mat, Vec v1, Vec v2, Vec v3) { 2696 PetscErrorCode (*op)(Mat, Vec, Vec, Vec) = (!mat->ops->multtransposeadd && mat->symmetric) ? mat->ops->multadd : mat->ops->multtransposeadd; 2697 2698 PetscFunctionBegin; 2699 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2700 PetscValidType(mat, 1); 2701 PetscValidHeaderSpecific(v1, VEC_CLASSID, 2); 2702 PetscValidHeaderSpecific(v2, VEC_CLASSID, 3); 2703 PetscValidHeaderSpecific(v3, VEC_CLASSID, 4); 2704 2705 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 2706 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 2707 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); 2708 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); 2709 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); 2710 PetscCheck(v1 != v3, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_IDN, "v1 and v3 must be different vectors"); 2711 PetscCheck(op, PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Mat type %s", ((PetscObject)mat)->type_name); 2712 MatCheckPreallocated(mat, 1); 2713 2714 PetscCall(PetscLogEventBegin(MAT_MultTransposeAdd, mat, v1, v2, v3)); 2715 PetscCall(VecLockReadPush(v1)); 2716 PetscCall((*op)(mat, v1, v2, v3)); 2717 PetscCall(VecLockReadPop(v1)); 2718 PetscCall(PetscLogEventEnd(MAT_MultTransposeAdd, mat, v1, v2, v3)); 2719 PetscCall(PetscObjectStateIncrease((PetscObject)v3)); 2720 PetscFunctionReturn(0); 2721 } 2722 2723 /*@ 2724 MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1. 2725 2726 Neighbor-wise Collective on mat 2727 2728 Input Parameters: 2729 + mat - the matrix 2730 - v1, v2 - the vectors 2731 2732 Output Parameters: 2733 . v3 - the result 2734 2735 Note: 2736 The vectors v1 and v3 cannot be the same. I.e., one cannot 2737 call `MatMultHermitianTransposeAdd`(A,v1,v2,v1). 2738 2739 Level: beginner 2740 2741 .seealso: `Mat`, `MatMultHermitianTranspose()`, `MatMultTranspose()`, `MatMultAdd()`, `MatMult()` 2742 @*/ 2743 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat, Vec v1, Vec v2, Vec v3) { 2744 PetscFunctionBegin; 2745 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2746 PetscValidType(mat, 1); 2747 PetscValidHeaderSpecific(v1, VEC_CLASSID, 2); 2748 PetscValidHeaderSpecific(v2, VEC_CLASSID, 3); 2749 PetscValidHeaderSpecific(v3, VEC_CLASSID, 4); 2750 2751 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 2752 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 2753 PetscCheck(v1 != v3, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_IDN, "v1 and v3 must be different vectors"); 2754 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); 2755 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); 2756 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); 2757 MatCheckPreallocated(mat, 1); 2758 2759 PetscCall(PetscLogEventBegin(MAT_MultHermitianTransposeAdd, mat, v1, v2, v3)); 2760 PetscCall(VecLockReadPush(v1)); 2761 if (mat->ops->multhermitiantransposeadd) PetscUseTypeMethod(mat, multhermitiantransposeadd, v1, v2, v3); 2762 else { 2763 Vec w, z; 2764 PetscCall(VecDuplicate(v1, &w)); 2765 PetscCall(VecCopy(v1, w)); 2766 PetscCall(VecConjugate(w)); 2767 PetscCall(VecDuplicate(v3, &z)); 2768 PetscCall(MatMultTranspose(mat, w, z)); 2769 PetscCall(VecDestroy(&w)); 2770 PetscCall(VecConjugate(z)); 2771 if (v2 != v3) { 2772 PetscCall(VecWAXPY(v3, 1.0, v2, z)); 2773 } else { 2774 PetscCall(VecAXPY(v3, 1.0, z)); 2775 } 2776 PetscCall(VecDestroy(&z)); 2777 } 2778 PetscCall(VecLockReadPop(v1)); 2779 PetscCall(PetscLogEventEnd(MAT_MultHermitianTransposeAdd, mat, v1, v2, v3)); 2780 PetscCall(PetscObjectStateIncrease((PetscObject)v3)); 2781 PetscFunctionReturn(0); 2782 } 2783 2784 /*@C 2785 MatGetFactorType - gets the type of factorization it is 2786 2787 Not Collective 2788 2789 Input Parameters: 2790 . mat - the matrix 2791 2792 Output Parameters: 2793 . 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` 2794 2795 Level: intermediate 2796 2797 .seealso: `MatFactorType`, `MatGetFactor()`, `MatSetFactorType()`, `MAT_FACTOR_NONE`, `MAT_FACTOR_LU`, `MAT_FACTOR_CHOLESKY`, `MAT_FACTOR_ILU`, 2798 `MAT_FACTOR_ICC,MAT_FACTOR_ILUDT`, `MAT_FACTOR_QR` 2799 @*/ 2800 PetscErrorCode MatGetFactorType(Mat mat, MatFactorType *t) { 2801 PetscFunctionBegin; 2802 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2803 PetscValidType(mat, 1); 2804 PetscValidPointer(t, 2); 2805 *t = mat->factortype; 2806 PetscFunctionReturn(0); 2807 } 2808 2809 /*@C 2810 MatSetFactorType - sets the type of factorization it is 2811 2812 Logically Collective on mat 2813 2814 Input Parameters: 2815 + mat - the matrix 2816 - 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` 2817 2818 Level: intermediate 2819 2820 .seealso: `MatFactorType`, `MatGetFactor()`, `MatGetFactorType()`, `MAT_FACTOR_NONE`, `MAT_FACTOR_LU`, `MAT_FACTOR_CHOLESKY`, `MAT_FACTOR_ILU`, 2821 `MAT_FACTOR_ICC,MAT_FACTOR_ILUDT`, `MAT_FACTOR_QR` 2822 @*/ 2823 PetscErrorCode MatSetFactorType(Mat mat, MatFactorType t) { 2824 PetscFunctionBegin; 2825 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2826 PetscValidType(mat, 1); 2827 mat->factortype = t; 2828 PetscFunctionReturn(0); 2829 } 2830 2831 /* ------------------------------------------------------------*/ 2832 /*@C 2833 MatGetInfo - Returns information about matrix storage (number of 2834 nonzeros, memory, etc.). 2835 2836 Collective on mat if `MAT_GLOBAL_MAX` or `MAT_GLOBAL_SUM` is used as the flag 2837 2838 Input Parameter: 2839 . mat - the matrix 2840 2841 Output Parameters: 2842 + flag - flag indicating the type of parameters to be returned 2843 (`MAT_LOCAL` - local matrix, `MAT_GLOBAL_MAX` - maximum over all processors, 2844 MAT_GLOBAL_SUM - sum over all processors) 2845 - info - matrix information context 2846 2847 Notes: 2848 The `MatInfo` context contains a variety of matrix data, including 2849 number of nonzeros allocated and used, number of mallocs during 2850 matrix assembly, etc. Additional information for factored matrices 2851 is provided (such as the fill ratio, number of mallocs during 2852 factorization, etc.). Much of this info is printed to `PETSC_STDOUT` 2853 when using the runtime options 2854 $ -info -mat_view ::ascii_info 2855 2856 Example for C/C++ Users: 2857 See the file ${PETSC_DIR}/include/petscmat.h for a complete list of 2858 data within the MatInfo context. For example, 2859 .vb 2860 MatInfo info; 2861 Mat A; 2862 double mal, nz_a, nz_u; 2863 2864 MatGetInfo(A,MAT_LOCAL,&info); 2865 mal = info.mallocs; 2866 nz_a = info.nz_allocated; 2867 .ve 2868 2869 Example for Fortran Users: 2870 Fortran users should declare info as a double precision 2871 array of dimension `MAT_INFO_SIZE`, and then extract the parameters 2872 of interest. See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h 2873 a complete list of parameter names. 2874 .vb 2875 double precision info(MAT_INFO_SIZE) 2876 double precision mal, nz_a 2877 Mat A 2878 integer ierr 2879 2880 call MatGetInfo(A,MAT_LOCAL,info,ierr) 2881 mal = info(MAT_INFO_MALLOCS) 2882 nz_a = info(MAT_INFO_NZ_ALLOCATED) 2883 .ve 2884 2885 Level: intermediate 2886 2887 Developer Note: fortran interface is not autogenerated as the f90 2888 interface definition cannot be generated correctly [due to MatInfo] 2889 2890 .seealso: `MatInfo`, `MatStashGetInfo()` 2891 @*/ 2892 PetscErrorCode MatGetInfo(Mat mat, MatInfoType flag, MatInfo *info) { 2893 PetscFunctionBegin; 2894 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2895 PetscValidType(mat, 1); 2896 PetscValidPointer(info, 3); 2897 MatCheckPreallocated(mat, 1); 2898 PetscUseTypeMethod(mat, getinfo, flag, info); 2899 PetscFunctionReturn(0); 2900 } 2901 2902 /* 2903 This is used by external packages where it is not easy to get the info from the actual 2904 matrix factorization. 2905 */ 2906 PetscErrorCode MatGetInfo_External(Mat A, MatInfoType flag, MatInfo *info) { 2907 PetscFunctionBegin; 2908 PetscCall(PetscMemzero(info, sizeof(MatInfo))); 2909 PetscFunctionReturn(0); 2910 } 2911 2912 /* ----------------------------------------------------------*/ 2913 2914 /*@C 2915 MatLUFactor - Performs in-place LU factorization of matrix. 2916 2917 Collective on mat 2918 2919 Input Parameters: 2920 + mat - the matrix 2921 . row - row permutation 2922 . col - column permutation 2923 - info - options for factorization, includes 2924 $ fill - expected fill as ratio of original fill. 2925 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 2926 $ Run with the option -info to determine an optimal value to use 2927 2928 Notes: 2929 Most users should employ the `KSP` interface for linear solvers 2930 instead of working directly with matrix algebra routines such as this. 2931 See, e.g., `KSPCreate()`. 2932 2933 This changes the state of the matrix to a factored matrix; it cannot be used 2934 for example with `MatSetValues()` unless one first calls `MatSetUnfactored()`. 2935 2936 This is really in-place only for dense matrices, the prefered approach is to use `MatGetFactor()`, `MatLUFactorSymbolic()`, and `MatLUFactorNumeric()` 2937 when not using `KSP`. 2938 2939 Level: developer 2940 2941 Developer Note: 2942 The Fortran interface is not autogenerated as the f90 2943 interface definition cannot be generated correctly [due to `MatFactorInfo`] 2944 2945 .seealso: `Mat`, `MatFactorType`, `MatLUFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()`, 2946 `MatGetOrdering()`, `MatSetUnfactored()`, `MatFactorInfo`, `MatGetFactor()` 2947 @*/ 2948 PetscErrorCode MatLUFactor(Mat mat, IS row, IS col, const MatFactorInfo *info) { 2949 MatFactorInfo tinfo; 2950 2951 PetscFunctionBegin; 2952 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2953 if (row) PetscValidHeaderSpecific(row, IS_CLASSID, 2); 2954 if (col) PetscValidHeaderSpecific(col, IS_CLASSID, 3); 2955 if (info) PetscValidPointer(info, 4); 2956 PetscValidType(mat, 1); 2957 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 2958 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 2959 MatCheckPreallocated(mat, 1); 2960 if (!info) { 2961 PetscCall(MatFactorInfoInitialize(&tinfo)); 2962 info = &tinfo; 2963 } 2964 2965 PetscCall(PetscLogEventBegin(MAT_LUFactor, mat, row, col, 0)); 2966 PetscUseTypeMethod(mat, lufactor, row, col, info); 2967 PetscCall(PetscLogEventEnd(MAT_LUFactor, mat, row, col, 0)); 2968 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 2969 PetscFunctionReturn(0); 2970 } 2971 2972 /*@C 2973 MatILUFactor - Performs in-place ILU factorization of matrix. 2974 2975 Collective on mat 2976 2977 Input Parameters: 2978 + mat - the matrix 2979 . row - row permutation 2980 . col - column permutation 2981 - info - structure containing 2982 $ levels - number of levels of fill. 2983 $ expected fill - as ratio of original fill. 2984 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 2985 missing diagonal entries) 2986 2987 Notes: 2988 Most users should employ the `KSP` interface for linear solvers 2989 instead of working directly with matrix algebra routines such as this. 2990 See, e.g., `KSPCreate()`. 2991 2992 Probably really in-place only when level of fill is zero, otherwise allocates 2993 new space to store factored matrix and deletes previous memory. The prefered approach is to use `MatGetFactor()`, `MatILUFactorSymbolic()`, and `MatILUFactorNumeric()` 2994 when not using `KSP`. 2995 2996 Level: developer 2997 2998 Developer Note: 2999 The Fortran interface is not autogenerated as the f90 3000 interface definition cannot be generated correctly [due to MatFactorInfo] 3001 3002 .seealso: `MatILUFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()`, `MatFactorInfo` 3003 @*/ 3004 PetscErrorCode MatILUFactor(Mat mat, IS row, IS col, const MatFactorInfo *info) { 3005 PetscFunctionBegin; 3006 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 3007 if (row) PetscValidHeaderSpecific(row, IS_CLASSID, 2); 3008 if (col) PetscValidHeaderSpecific(col, IS_CLASSID, 3); 3009 PetscValidPointer(info, 4); 3010 PetscValidType(mat, 1); 3011 PetscCheck(mat->rmap->N == mat->cmap->N, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONG, "matrix must be square"); 3012 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 3013 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 3014 MatCheckPreallocated(mat, 1); 3015 3016 PetscCall(PetscLogEventBegin(MAT_ILUFactor, mat, row, col, 0)); 3017 PetscUseTypeMethod(mat, ilufactor, row, col, info); 3018 PetscCall(PetscLogEventEnd(MAT_ILUFactor, mat, row, col, 0)); 3019 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 3020 PetscFunctionReturn(0); 3021 } 3022 3023 /*@C 3024 MatLUFactorSymbolic - Performs symbolic LU factorization of matrix. 3025 Call this routine before calling `MatLUFactorNumeric()` and after `MatGetFactor()`. 3026 3027 Collective on fact 3028 3029 Input Parameters: 3030 + fact - the factor matrix obtained with `MatGetFactor()` 3031 . mat - the matrix 3032 . row, col - row and column permutations 3033 - info - options for factorization, includes 3034 $ fill - expected fill as ratio of original fill. 3035 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3036 $ Run with the option -info to determine an optimal value to use 3037 3038 Notes: 3039 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 3040 3041 Most users should employ the simplified `KSP` interface for linear solvers 3042 instead of working directly with matrix algebra routines such as this. 3043 See, e.g., `KSPCreate()`. 3044 3045 Level: developer 3046 3047 Developer Note: 3048 The Fortran interface is not autogenerated as the f90 3049 interface definition cannot be generated correctly [due to `MatFactorInfo`] 3050 3051 .seealso: `MatGetFactor()`, `MatLUFactor()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()`, `MatFactorInfo`, `MatFactorInfoInitialize()` 3052 @*/ 3053 PetscErrorCode MatLUFactorSymbolic(Mat fact, Mat mat, IS row, IS col, const MatFactorInfo *info) { 3054 MatFactorInfo tinfo; 3055 3056 PetscFunctionBegin; 3057 PetscValidHeaderSpecific(mat, MAT_CLASSID, 2); 3058 if (row) PetscValidHeaderSpecific(row, IS_CLASSID, 3); 3059 if (col) PetscValidHeaderSpecific(col, IS_CLASSID, 4); 3060 if (info) PetscValidPointer(info, 5); 3061 PetscValidType(mat, 2); 3062 PetscValidPointer(fact, 1); 3063 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 3064 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 3065 if (!(fact)->ops->lufactorsymbolic) { 3066 MatSolverType stype; 3067 PetscCall(MatFactorGetSolverType(fact, &stype)); 3068 SETERRQ(PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Matrix type %s symbolic LU using solver package %s", ((PetscObject)mat)->type_name, stype); 3069 } 3070 MatCheckPreallocated(mat, 2); 3071 if (!info) { 3072 PetscCall(MatFactorInfoInitialize(&tinfo)); 3073 info = &tinfo; 3074 } 3075 3076 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_LUFactorSymbolic, mat, row, col, 0)); 3077 PetscCall((fact->ops->lufactorsymbolic)(fact, mat, row, col, info)); 3078 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_LUFactorSymbolic, mat, row, col, 0)); 3079 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3080 PetscFunctionReturn(0); 3081 } 3082 3083 /*@C 3084 MatLUFactorNumeric - Performs numeric LU factorization of a matrix. 3085 Call this routine after first calling `MatLUFactorSymbolic()` and `MatGetFactor()`. 3086 3087 Collective on fact 3088 3089 Input Parameters: 3090 + fact - the factor matrix obtained with `MatGetFactor()` 3091 . mat - the matrix 3092 - info - options for factorization 3093 3094 Notes: 3095 See `MatLUFactor()` for in-place factorization. See 3096 `MatCholeskyFactorNumeric()` for the symmetric, positive definite case. 3097 3098 Most users should employ the `KSP` interface for linear solvers 3099 instead of working directly with matrix algebra routines such as this. 3100 See, e.g., `KSPCreate()`. 3101 3102 Level: developer 3103 3104 Developer Note: 3105 The Fortran interface is not autogenerated as the f90 3106 interface definition cannot be generated correctly [due to `MatFactorInfo`] 3107 3108 .seealso: `MatGetFactor()`, `MatFactorInfo`, `MatLUFactorSymbolic()`, `MatLUFactor()`, `MatCholeskyFactor()` 3109 @*/ 3110 PetscErrorCode MatLUFactorNumeric(Mat fact, Mat mat, const MatFactorInfo *info) { 3111 MatFactorInfo tinfo; 3112 3113 PetscFunctionBegin; 3114 PetscValidHeaderSpecific(mat, MAT_CLASSID, 2); 3115 PetscValidType(mat, 2); 3116 PetscValidPointer(fact, 1); 3117 PetscValidHeaderSpecific(fact, MAT_CLASSID, 1); 3118 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 3119 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, 3120 mat->rmap->N, (fact)->rmap->N, mat->cmap->N, (fact)->cmap->N); 3121 3122 PetscCheck((fact)->ops->lufactornumeric, PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Mat type %s numeric LU", ((PetscObject)mat)->type_name); 3123 MatCheckPreallocated(mat, 2); 3124 if (!info) { 3125 PetscCall(MatFactorInfoInitialize(&tinfo)); 3126 info = &tinfo; 3127 } 3128 3129 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_LUFactorNumeric, mat, fact, 0, 0)); 3130 else PetscCall(PetscLogEventBegin(MAT_LUFactor, mat, fact, 0, 0)); 3131 PetscCall((fact->ops->lufactornumeric)(fact, mat, info)); 3132 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_LUFactorNumeric, mat, fact, 0, 0)); 3133 else PetscCall(PetscLogEventEnd(MAT_LUFactor, mat, fact, 0, 0)); 3134 PetscCall(MatViewFromOptions(fact, NULL, "-mat_factor_view")); 3135 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3136 PetscFunctionReturn(0); 3137 } 3138 3139 /*@C 3140 MatCholeskyFactor - Performs in-place Cholesky factorization of a 3141 symmetric matrix. 3142 3143 Collective on mat 3144 3145 Input Parameters: 3146 + mat - the matrix 3147 . perm - row and column permutations 3148 - f - expected fill as ratio of original fill 3149 3150 Notes: 3151 See `MatLUFactor()` for the nonsymmetric case. See also `MatGetFactor()`, 3152 `MatCholeskyFactorSymbolic()`, and `MatCholeskyFactorNumeric()`. 3153 3154 Most users should employ the `KSP` interface for linear solvers 3155 instead of working directly with matrix algebra routines such as this. 3156 See, e.g., `KSPCreate()`. 3157 3158 Level: developer 3159 3160 Developer Note: 3161 The Fortran interface is not autogenerated as the f90 3162 interface definition cannot be generated correctly [due to `MatFactorInfo`] 3163 3164 .seealso: `MatGetFactor()`, `MatFactorInfo`, `MatLUFactor()`, `MatCholeskyFactorSymbolic()`, `MatCholeskyFactorNumeric()` 3165 `MatGetOrdering()` 3166 @*/ 3167 PetscErrorCode MatCholeskyFactor(Mat mat, IS perm, const MatFactorInfo *info) { 3168 MatFactorInfo tinfo; 3169 3170 PetscFunctionBegin; 3171 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 3172 PetscValidType(mat, 1); 3173 if (perm) PetscValidHeaderSpecific(perm, IS_CLASSID, 2); 3174 if (info) PetscValidPointer(info, 3); 3175 PetscCheck(mat->rmap->N == mat->cmap->N, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONG, "Matrix must be square"); 3176 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 3177 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 3178 MatCheckPreallocated(mat, 1); 3179 if (!info) { 3180 PetscCall(MatFactorInfoInitialize(&tinfo)); 3181 info = &tinfo; 3182 } 3183 3184 PetscCall(PetscLogEventBegin(MAT_CholeskyFactor, mat, perm, 0, 0)); 3185 PetscUseTypeMethod(mat, choleskyfactor, perm, info); 3186 PetscCall(PetscLogEventEnd(MAT_CholeskyFactor, mat, perm, 0, 0)); 3187 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 3188 PetscFunctionReturn(0); 3189 } 3190 3191 /*@C 3192 MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization 3193 of a symmetric matrix. 3194 3195 Collective on fact 3196 3197 Input Parameters: 3198 + fact - the factor matrix obtained with `MatGetFactor()` 3199 . mat - the matrix 3200 . perm - row and column permutations 3201 - info - options for factorization, includes 3202 $ fill - expected fill as ratio of original fill. 3203 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3204 $ Run with the option -info to determine an optimal value to use 3205 3206 Notes: 3207 See `MatLUFactorSymbolic()` for the nonsymmetric case. See also 3208 `MatCholeskyFactor()` and `MatCholeskyFactorNumeric()`. 3209 3210 Most users should employ the `KSP` interface for linear solvers 3211 instead of working directly with matrix algebra routines such as this. 3212 See, e.g., `KSPCreate()`. 3213 3214 Level: developer 3215 3216 Developer Note: 3217 The Fortran interface is not autogenerated as the f90 3218 interface definition cannot be generated correctly [due to `MatFactorInfo`] 3219 3220 .seealso: `MatFactorInfo`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactor()`, `MatCholeskyFactorNumeric()` 3221 `MatGetOrdering()` 3222 @*/ 3223 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact, Mat mat, IS perm, const MatFactorInfo *info) { 3224 MatFactorInfo tinfo; 3225 3226 PetscFunctionBegin; 3227 PetscValidHeaderSpecific(mat, MAT_CLASSID, 2); 3228 PetscValidType(mat, 2); 3229 if (perm) PetscValidHeaderSpecific(perm, IS_CLASSID, 3); 3230 if (info) PetscValidPointer(info, 4); 3231 PetscValidPointer(fact, 1); 3232 PetscCheck(mat->rmap->N == mat->cmap->N, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONG, "Matrix must be square"); 3233 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 3234 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 3235 if (!(fact)->ops->choleskyfactorsymbolic) { 3236 MatSolverType stype; 3237 PetscCall(MatFactorGetSolverType(fact, &stype)); 3238 SETERRQ(PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Mat type %s symbolic factor Cholesky using solver package %s", ((PetscObject)mat)->type_name, stype); 3239 } 3240 MatCheckPreallocated(mat, 2); 3241 if (!info) { 3242 PetscCall(MatFactorInfoInitialize(&tinfo)); 3243 info = &tinfo; 3244 } 3245 3246 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_CholeskyFactorSymbolic, mat, perm, 0, 0)); 3247 PetscCall((fact->ops->choleskyfactorsymbolic)(fact, mat, perm, info)); 3248 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_CholeskyFactorSymbolic, mat, perm, 0, 0)); 3249 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3250 PetscFunctionReturn(0); 3251 } 3252 3253 /*@C 3254 MatCholeskyFactorNumeric - Performs numeric Cholesky factorization 3255 of a symmetric matrix. Call this routine after first calling `MatGetFactor()` and 3256 `MatCholeskyFactorSymbolic()`. 3257 3258 Collective on fact 3259 3260 Input Parameters: 3261 + fact - the factor matrix obtained with `MatGetFactor()` 3262 . mat - the initial matrix 3263 . info - options for factorization 3264 - fact - the symbolic factor of mat 3265 3266 Note: 3267 Most users should employ the `KSP` interface for linear solvers 3268 instead of working directly with matrix algebra routines such as this. 3269 See, e.g., `KSPCreate()`. 3270 3271 Level: developer 3272 3273 Developer Note: 3274 The Fortran interface is not autogenerated as the f90 3275 interface definition cannot be generated correctly [due to `MatFactorInfo`] 3276 3277 .seealso: `MatFactorInfo`, `MatGetFactor()`, `MatCholeskyFactorSymbolic()`, `MatCholeskyFactor()`, `MatLUFactorNumeric()` 3278 @*/ 3279 PetscErrorCode MatCholeskyFactorNumeric(Mat fact, Mat mat, const MatFactorInfo *info) { 3280 MatFactorInfo tinfo; 3281 3282 PetscFunctionBegin; 3283 PetscValidHeaderSpecific(mat, MAT_CLASSID, 2); 3284 PetscValidType(mat, 2); 3285 PetscValidPointer(fact, 1); 3286 PetscValidHeaderSpecific(fact, MAT_CLASSID, 1); 3287 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 3288 PetscCheck((fact)->ops->choleskyfactornumeric, PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Mat type %s numeric factor Cholesky", ((PetscObject)mat)->type_name); 3289 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, 3290 mat->rmap->N, (fact)->rmap->N, mat->cmap->N, (fact)->cmap->N); 3291 MatCheckPreallocated(mat, 2); 3292 if (!info) { 3293 PetscCall(MatFactorInfoInitialize(&tinfo)); 3294 info = &tinfo; 3295 } 3296 3297 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_CholeskyFactorNumeric, mat, fact, 0, 0)); 3298 else PetscCall(PetscLogEventBegin(MAT_CholeskyFactor, mat, fact, 0, 0)); 3299 PetscCall((fact->ops->choleskyfactornumeric)(fact, mat, info)); 3300 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_CholeskyFactorNumeric, mat, fact, 0, 0)); 3301 else PetscCall(PetscLogEventEnd(MAT_CholeskyFactor, mat, fact, 0, 0)); 3302 PetscCall(MatViewFromOptions(fact, NULL, "-mat_factor_view")); 3303 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3304 PetscFunctionReturn(0); 3305 } 3306 3307 /*@ 3308 MatQRFactor - Performs in-place QR factorization of matrix. 3309 3310 Collective on mat 3311 3312 Input Parameters: 3313 + mat - the matrix 3314 . col - column permutation 3315 - info - options for factorization, includes 3316 $ fill - expected fill as ratio of original fill. 3317 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3318 $ Run with the option -info to determine an optimal value to use 3319 3320 Notes: 3321 Most users should employ the `KSP` interface for linear solvers 3322 instead of working directly with matrix algebra routines such as this. 3323 See, e.g., `KSPCreate()`. 3324 3325 This changes the state of the matrix to a factored matrix; it cannot be used 3326 for example with `MatSetValues()` unless one first calls `MatSetUnfactored()`. 3327 3328 Level: developer 3329 3330 Developer Note: 3331 The Fortran interface is not autogenerated as the f90 3332 interface definition cannot be generated correctly [due to MatFactorInfo] 3333 3334 .seealso: `MatFactorInfo`, `MatGetFactor()`, `MatQRFactorSymbolic()`, `MatQRFactorNumeric()`, `MatLUFactor()`, 3335 `MatSetUnfactored()`, `MatFactorInfo`, `MatGetFactor()` 3336 @*/ 3337 PetscErrorCode MatQRFactor(Mat mat, IS col, const MatFactorInfo *info) { 3338 PetscFunctionBegin; 3339 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 3340 if (col) PetscValidHeaderSpecific(col, IS_CLASSID, 2); 3341 if (info) PetscValidPointer(info, 3); 3342 PetscValidType(mat, 1); 3343 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 3344 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 3345 MatCheckPreallocated(mat, 1); 3346 PetscCall(PetscLogEventBegin(MAT_QRFactor, mat, col, 0, 0)); 3347 PetscUseMethod(mat, "MatQRFactor_C", (Mat, IS, const MatFactorInfo *), (mat, col, info)); 3348 PetscCall(PetscLogEventEnd(MAT_QRFactor, mat, col, 0, 0)); 3349 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 3350 PetscFunctionReturn(0); 3351 } 3352 3353 /*@ 3354 MatQRFactorSymbolic - Performs symbolic QR factorization of matrix. 3355 Call this routine after `MatGetFactor()` but before calling `MatQRFactorNumeric()`. 3356 3357 Collective on fact 3358 3359 Input Parameters: 3360 + fact - the factor matrix obtained with `MatGetFactor()` 3361 . mat - the matrix 3362 . col - column permutation 3363 - info - options for factorization, includes 3364 $ fill - expected fill as ratio of original fill. 3365 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3366 $ Run with the option -info to determine an optimal value to use 3367 3368 Most users should employ the `KSP` interface for linear solvers 3369 instead of working directly with matrix algebra routines such as this. 3370 See, e.g., `KSPCreate()`. 3371 3372 Level: developer 3373 3374 Developer Note: 3375 The Fortran interface is not autogenerated as the f90 3376 interface definition cannot be generated correctly [due to `MatFactorInfo`] 3377 3378 .seealso: `MatGetFactor()`, `MatFactorInfo`, `MatQRFactor()`, `MatQRFactorNumeric()`, `MatLUFactor()`, `MatFactorInfo`, `MatFactorInfoInitialize()` 3379 @*/ 3380 PetscErrorCode MatQRFactorSymbolic(Mat fact, Mat mat, IS col, const MatFactorInfo *info) { 3381 MatFactorInfo tinfo; 3382 3383 PetscFunctionBegin; 3384 PetscValidHeaderSpecific(mat, MAT_CLASSID, 2); 3385 if (col) PetscValidHeaderSpecific(col, IS_CLASSID, 3); 3386 if (info) PetscValidPointer(info, 4); 3387 PetscValidType(mat, 2); 3388 PetscValidPointer(fact, 1); 3389 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 3390 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 3391 MatCheckPreallocated(mat, 2); 3392 if (!info) { 3393 PetscCall(MatFactorInfoInitialize(&tinfo)); 3394 info = &tinfo; 3395 } 3396 3397 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_QRFactorSymbolic, fact, mat, col, 0)); 3398 PetscUseMethod(fact, "MatQRFactorSymbolic_C", (Mat, Mat, IS, const MatFactorInfo *), (fact, mat, col, info)); 3399 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_QRFactorSymbolic, fact, mat, col, 0)); 3400 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3401 PetscFunctionReturn(0); 3402 } 3403 3404 /*@ 3405 MatQRFactorNumeric - Performs numeric QR factorization of a matrix. 3406 Call this routine after first calling `MatGetFactor()`, and `MatQRFactorSymbolic()`. 3407 3408 Collective on fact 3409 3410 Input Parameters: 3411 + fact - the factor matrix obtained with `MatGetFactor()` 3412 . mat - the matrix 3413 - info - options for factorization 3414 3415 Notes: 3416 See `MatQRFactor()` for in-place factorization. 3417 3418 Most users should employ the `KSP` interface for linear solvers 3419 instead of working directly with matrix algebra routines such as this. 3420 See, e.g., `KSPCreate()`. 3421 3422 Level: developer 3423 3424 Developer Note: 3425 The Fortran interface is not autogenerated as the f90 3426 interface definition cannot be generated correctly [due to `MatFactorInfo`] 3427 3428 .seealso: `MatFactorInfo`, `MatGetFactor()`, `MatQRFactor()`, `MatQRFactorSymbolic()`, `MatLUFactor()` 3429 @*/ 3430 PetscErrorCode MatQRFactorNumeric(Mat fact, Mat mat, const MatFactorInfo *info) { 3431 MatFactorInfo tinfo; 3432 3433 PetscFunctionBegin; 3434 PetscValidHeaderSpecific(mat, MAT_CLASSID, 2); 3435 PetscValidType(mat, 2); 3436 PetscValidPointer(fact, 1); 3437 PetscValidHeaderSpecific(fact, MAT_CLASSID, 1); 3438 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 3439 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, 3440 mat->rmap->N, (fact)->rmap->N, mat->cmap->N, (fact)->cmap->N); 3441 3442 MatCheckPreallocated(mat, 2); 3443 if (!info) { 3444 PetscCall(MatFactorInfoInitialize(&tinfo)); 3445 info = &tinfo; 3446 } 3447 3448 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_QRFactorNumeric, mat, fact, 0, 0)); 3449 else PetscCall(PetscLogEventBegin(MAT_QRFactor, mat, fact, 0, 0)); 3450 PetscUseMethod(fact, "MatQRFactorNumeric_C", (Mat, Mat, const MatFactorInfo *), (fact, mat, info)); 3451 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_QRFactorNumeric, mat, fact, 0, 0)); 3452 else PetscCall(PetscLogEventEnd(MAT_QRFactor, mat, fact, 0, 0)); 3453 PetscCall(MatViewFromOptions(fact, NULL, "-mat_factor_view")); 3454 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3455 PetscFunctionReturn(0); 3456 } 3457 3458 /* ----------------------------------------------------------------*/ 3459 /*@ 3460 MatSolve - Solves A x = b, given a factored matrix. 3461 3462 Neighbor-wise Collective on mat 3463 3464 Input Parameters: 3465 + mat - the factored matrix 3466 - b - the right-hand-side vector 3467 3468 Output Parameter: 3469 . x - the result vector 3470 3471 Notes: 3472 The vectors b and x cannot be the same. I.e., one cannot 3473 call `MatSolve`(A,x,x). 3474 3475 Most users should employ the `KSP` interface for linear solvers 3476 instead of working directly with matrix algebra routines such as this. 3477 See, e.g., `KSPCreate()`. 3478 3479 Level: developer 3480 3481 .seealso: `MatGetFactor()`, `MatLUFactor()`, `MatSolveAdd()`, `MatSolveTranspose()`, `MatSolveTransposeAdd()` 3482 @*/ 3483 PetscErrorCode MatSolve(Mat mat, Vec b, Vec x) { 3484 PetscFunctionBegin; 3485 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 3486 PetscValidType(mat, 1); 3487 PetscValidHeaderSpecific(b, VEC_CLASSID, 2); 3488 PetscValidHeaderSpecific(x, VEC_CLASSID, 3); 3489 PetscCheckSameComm(mat, 1, b, 2); 3490 PetscCheckSameComm(mat, 1, x, 3); 3491 PetscCheck(x != b, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_IDN, "x and b must be different vectors"); 3492 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); 3493 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); 3494 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); 3495 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3496 MatCheckPreallocated(mat, 1); 3497 3498 PetscCall(PetscLogEventBegin(MAT_Solve, mat, b, x, 0)); 3499 if (mat->factorerrortype) { 3500 PetscCall(PetscInfo(mat, "MatFactorError %d\n", mat->factorerrortype)); 3501 PetscCall(VecSetInf(x)); 3502 } else PetscUseTypeMethod(mat, solve, b, x); 3503 PetscCall(PetscLogEventEnd(MAT_Solve, mat, b, x, 0)); 3504 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3505 PetscFunctionReturn(0); 3506 } 3507 3508 static PetscErrorCode MatMatSolve_Basic(Mat A, Mat B, Mat X, PetscBool trans) { 3509 Vec b, x; 3510 PetscInt N, i; 3511 PetscErrorCode (*f)(Mat, Vec, Vec); 3512 PetscBool Abound, Bneedconv = PETSC_FALSE, Xneedconv = PETSC_FALSE; 3513 3514 PetscFunctionBegin; 3515 if (A->factorerrortype) { 3516 PetscCall(PetscInfo(A, "MatFactorError %d\n", A->factorerrortype)); 3517 PetscCall(MatSetInf(X)); 3518 PetscFunctionReturn(0); 3519 } 3520 f = (!trans || (!A->ops->solvetranspose && A->symmetric)) ? A->ops->solve : A->ops->solvetranspose; 3521 PetscCheck(f, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Mat type %s", ((PetscObject)A)->type_name); 3522 PetscCall(MatBoundToCPU(A, &Abound)); 3523 if (!Abound) { 3524 PetscCall(PetscObjectTypeCompareAny((PetscObject)B, &Bneedconv, MATSEQDENSE, MATMPIDENSE, "")); 3525 PetscCall(PetscObjectTypeCompareAny((PetscObject)X, &Xneedconv, MATSEQDENSE, MATMPIDENSE, "")); 3526 } 3527 if (Bneedconv) PetscCall(MatConvert(B, MATDENSECUDA, MAT_INPLACE_MATRIX, &B)); 3528 if (Xneedconv) PetscCall(MatConvert(X, MATDENSECUDA, MAT_INPLACE_MATRIX, &X)); 3529 PetscCall(MatGetSize(B, NULL, &N)); 3530 for (i = 0; i < N; i++) { 3531 PetscCall(MatDenseGetColumnVecRead(B, i, &b)); 3532 PetscCall(MatDenseGetColumnVecWrite(X, i, &x)); 3533 PetscCall((*f)(A, b, x)); 3534 PetscCall(MatDenseRestoreColumnVecWrite(X, i, &x)); 3535 PetscCall(MatDenseRestoreColumnVecRead(B, i, &b)); 3536 } 3537 if (Bneedconv) PetscCall(MatConvert(B, MATDENSE, MAT_INPLACE_MATRIX, &B)); 3538 if (Xneedconv) PetscCall(MatConvert(X, MATDENSE, MAT_INPLACE_MATRIX, &X)); 3539 PetscFunctionReturn(0); 3540 } 3541 3542 /*@ 3543 MatMatSolve - Solves A X = B, given a factored matrix. 3544 3545 Neighbor-wise Collective on A 3546 3547 Input Parameters: 3548 + A - the factored matrix 3549 - B - the right-hand-side matrix `MATDENSE` (or sparse `MATAIJ`-- when using MUMPS) 3550 3551 Output Parameter: 3552 . X - the result matrix (dense matrix) 3553 3554 Note: 3555 If B is a `MATDENSE` matrix then one can call `MatMatSolve`(A,B,B) except with MKL_CPARDISO; 3556 otherwise, B and X cannot be the same. 3557 3558 Level: developer 3559 3560 .seealso: `MatGetFactor()`, `MatSolve()`, `MatMatSolveTranspose()`, `MatLUFactor()`, `MatCholeskyFactor()` 3561 @*/ 3562 PetscErrorCode MatMatSolve(Mat A, Mat B, Mat X) { 3563 PetscFunctionBegin; 3564 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 3565 PetscValidType(A, 1); 3566 PetscValidHeaderSpecific(B, MAT_CLASSID, 2); 3567 PetscValidHeaderSpecific(X, MAT_CLASSID, 3); 3568 PetscCheckSameComm(A, 1, B, 2); 3569 PetscCheckSameComm(A, 1, X, 3); 3570 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); 3571 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); 3572 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"); 3573 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3574 PetscCheck(A->factortype, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Unfactored matrix"); 3575 MatCheckPreallocated(A, 1); 3576 3577 PetscCall(PetscLogEventBegin(MAT_MatSolve, A, B, X, 0)); 3578 if (!A->ops->matsolve) { 3579 PetscCall(PetscInfo(A, "Mat type %s using basic MatMatSolve\n", ((PetscObject)A)->type_name)); 3580 PetscCall(MatMatSolve_Basic(A, B, X, PETSC_FALSE)); 3581 } else PetscUseTypeMethod(A, matsolve, B, X); 3582 PetscCall(PetscLogEventEnd(MAT_MatSolve, A, B, X, 0)); 3583 PetscCall(PetscObjectStateIncrease((PetscObject)X)); 3584 PetscFunctionReturn(0); 3585 } 3586 3587 /*@ 3588 MatMatSolveTranspose - Solves A^T X = B, given a factored matrix. 3589 3590 Neighbor-wise Collective on A 3591 3592 Input Parameters: 3593 + A - the factored matrix 3594 - B - the right-hand-side matrix (`MATDENSE` matrix) 3595 3596 Output Parameter: 3597 . X - the result matrix (dense matrix) 3598 3599 Note: 3600 The matrices B and X cannot be the same. I.e., one cannot 3601 call `MatMatSolveTranspose`(A,X,X). 3602 3603 Level: developer 3604 3605 .seealso: `MatGetFactor()`, `MatSolveTranspose()`, `MatMatSolve()`, `MatLUFactor()`, `MatCholeskyFactor()` 3606 @*/ 3607 PetscErrorCode MatMatSolveTranspose(Mat A, Mat B, Mat X) { 3608 PetscFunctionBegin; 3609 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 3610 PetscValidType(A, 1); 3611 PetscValidHeaderSpecific(B, MAT_CLASSID, 2); 3612 PetscValidHeaderSpecific(X, MAT_CLASSID, 3); 3613 PetscCheckSameComm(A, 1, B, 2); 3614 PetscCheckSameComm(A, 1, X, 3); 3615 PetscCheck(X != B, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_IDN, "X and B must be different matrices"); 3616 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); 3617 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); 3618 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); 3619 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"); 3620 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3621 PetscCheck(A->factortype, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Unfactored matrix"); 3622 MatCheckPreallocated(A, 1); 3623 3624 PetscCall(PetscLogEventBegin(MAT_MatSolve, A, B, X, 0)); 3625 if (!A->ops->matsolvetranspose) { 3626 PetscCall(PetscInfo(A, "Mat type %s using basic MatMatSolveTranspose\n", ((PetscObject)A)->type_name)); 3627 PetscCall(MatMatSolve_Basic(A, B, X, PETSC_TRUE)); 3628 } else PetscUseTypeMethod(A, matsolvetranspose, B, X); 3629 PetscCall(PetscLogEventEnd(MAT_MatSolve, A, B, X, 0)); 3630 PetscCall(PetscObjectStateIncrease((PetscObject)X)); 3631 PetscFunctionReturn(0); 3632 } 3633 3634 /*@ 3635 MatMatTransposeSolve - Solves A X = B^T, given a factored matrix. 3636 3637 Neighbor-wise Collective on A 3638 3639 Input Parameters: 3640 + A - the factored matrix 3641 - Bt - the transpose of right-hand-side matrix as a `MATDENSE` 3642 3643 Output Parameter: 3644 . X - the result matrix (dense matrix) 3645 3646 Note: 3647 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 3648 format on the host processor and call `MatMatTransposeSolve()` to implement MUMPS' `MatMatSolve()`. 3649 3650 Level: developer 3651 3652 .seealso: `MatMatSolve()`, `MatMatSolveTranspose()`, `MatLUFactor()`, `MatCholeskyFactor()` 3653 @*/ 3654 PetscErrorCode MatMatTransposeSolve(Mat A, Mat Bt, Mat X) { 3655 PetscFunctionBegin; 3656 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 3657 PetscValidType(A, 1); 3658 PetscValidHeaderSpecific(Bt, MAT_CLASSID, 2); 3659 PetscValidHeaderSpecific(X, MAT_CLASSID, 3); 3660 PetscCheckSameComm(A, 1, Bt, 2); 3661 PetscCheckSameComm(A, 1, X, 3); 3662 3663 PetscCheck(X != Bt, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_IDN, "X and B must be different matrices"); 3664 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); 3665 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); 3666 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"); 3667 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3668 PetscCheck(A->factortype, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Unfactored matrix"); 3669 MatCheckPreallocated(A, 1); 3670 3671 PetscCall(PetscLogEventBegin(MAT_MatTrSolve, A, Bt, X, 0)); 3672 PetscUseTypeMethod(A, mattransposesolve, Bt, X); 3673 PetscCall(PetscLogEventEnd(MAT_MatTrSolve, A, Bt, X, 0)); 3674 PetscCall(PetscObjectStateIncrease((PetscObject)X)); 3675 PetscFunctionReturn(0); 3676 } 3677 3678 /*@ 3679 MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or 3680 U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U, 3681 3682 Neighbor-wise Collective on mat 3683 3684 Input Parameters: 3685 + mat - the factored matrix 3686 - b - the right-hand-side vector 3687 3688 Output Parameter: 3689 . x - the result vector 3690 3691 Notes: 3692 `MatSolve()` should be used for most applications, as it performs 3693 a forward solve followed by a backward solve. 3694 3695 The vectors b and x cannot be the same, i.e., one cannot 3696 call `MatForwardSolve`(A,x,x). 3697 3698 For matrix in `MATSEQBAIJ` format with block size larger than 1, 3699 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3700 `MatForwardSolve()` solves U^T*D y = b, and 3701 `MatBackwardSolve()` solves U x = y. 3702 Thus they do not provide a symmetric preconditioner. 3703 3704 Level: developer 3705 3706 .seealso: `MatBackwardSolve()`, `MatGetFactor()`, `MatSolve()`, `MatBackwardSolve()` 3707 @*/ 3708 PetscErrorCode MatForwardSolve(Mat mat, Vec b, Vec x) { 3709 PetscFunctionBegin; 3710 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 3711 PetscValidType(mat, 1); 3712 PetscValidHeaderSpecific(b, VEC_CLASSID, 2); 3713 PetscValidHeaderSpecific(x, VEC_CLASSID, 3); 3714 PetscCheckSameComm(mat, 1, b, 2); 3715 PetscCheckSameComm(mat, 1, x, 3); 3716 PetscCheck(x != b, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_IDN, "x and b must be different vectors"); 3717 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); 3718 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); 3719 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); 3720 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3721 MatCheckPreallocated(mat, 1); 3722 3723 PetscCall(PetscLogEventBegin(MAT_ForwardSolve, mat, b, x, 0)); 3724 PetscUseTypeMethod(mat, forwardsolve, b, x); 3725 PetscCall(PetscLogEventEnd(MAT_ForwardSolve, mat, b, x, 0)); 3726 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3727 PetscFunctionReturn(0); 3728 } 3729 3730 /*@ 3731 MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU. 3732 D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U, 3733 3734 Neighbor-wise Collective on mat 3735 3736 Input Parameters: 3737 + mat - the factored matrix 3738 - b - the right-hand-side vector 3739 3740 Output Parameter: 3741 . x - the result vector 3742 3743 Notes: 3744 `MatSolve()` should be used for most applications, as it performs 3745 a forward solve followed by a backward solve. 3746 3747 The vectors b and x cannot be the same. I.e., one cannot 3748 call `MatBackwardSolve`(A,x,x). 3749 3750 For matrix in `MATSEQBAIJ` format with block size larger than 1, 3751 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3752 `MatForwardSolve()` solves U^T*D y = b, and 3753 `MatBackwardSolve()` solves U x = y. 3754 Thus they do not provide a symmetric preconditioner. 3755 3756 Level: developer 3757 3758 .seealso: `MatForwardSolve()`, `MatGetFactor()`, `MatSolve()`, `MatForwardSolve()` 3759 @*/ 3760 PetscErrorCode MatBackwardSolve(Mat mat, Vec b, Vec x) { 3761 PetscFunctionBegin; 3762 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 3763 PetscValidType(mat, 1); 3764 PetscValidHeaderSpecific(b, VEC_CLASSID, 2); 3765 PetscValidHeaderSpecific(x, VEC_CLASSID, 3); 3766 PetscCheckSameComm(mat, 1, b, 2); 3767 PetscCheckSameComm(mat, 1, x, 3); 3768 PetscCheck(x != b, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_IDN, "x and b must be different vectors"); 3769 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); 3770 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); 3771 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); 3772 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3773 MatCheckPreallocated(mat, 1); 3774 3775 PetscCall(PetscLogEventBegin(MAT_BackwardSolve, mat, b, x, 0)); 3776 PetscUseTypeMethod(mat, backwardsolve, b, x); 3777 PetscCall(PetscLogEventEnd(MAT_BackwardSolve, mat, b, x, 0)); 3778 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3779 PetscFunctionReturn(0); 3780 } 3781 3782 /*@ 3783 MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix. 3784 3785 Neighbor-wise Collective on mat 3786 3787 Input Parameters: 3788 + mat - the factored matrix 3789 . b - the right-hand-side vector 3790 - y - the vector to be added to 3791 3792 Output Parameter: 3793 . x - the result vector 3794 3795 Note: 3796 The vectors b and x cannot be the same. I.e., one cannot 3797 call `MatSolveAdd`(A,x,y,x). 3798 3799 Level: developer 3800 3801 .seealso: `MatSolve()`, `MatGetFactor()`, `MatSolveTranspose()`, `MatSolveTransposeAdd()` 3802 @*/ 3803 PetscErrorCode MatSolveAdd(Mat mat, Vec b, Vec y, Vec x) { 3804 PetscScalar one = 1.0; 3805 Vec tmp; 3806 3807 PetscFunctionBegin; 3808 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 3809 PetscValidType(mat, 1); 3810 PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 3811 PetscValidHeaderSpecific(b, VEC_CLASSID, 2); 3812 PetscValidHeaderSpecific(x, VEC_CLASSID, 4); 3813 PetscCheckSameComm(mat, 1, b, 2); 3814 PetscCheckSameComm(mat, 1, y, 3); 3815 PetscCheckSameComm(mat, 1, x, 4); 3816 PetscCheck(x != b, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_IDN, "x and b must be different vectors"); 3817 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); 3818 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); 3819 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); 3820 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); 3821 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); 3822 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3823 MatCheckPreallocated(mat, 1); 3824 3825 PetscCall(PetscLogEventBegin(MAT_SolveAdd, mat, b, x, y)); 3826 if (mat->factorerrortype) { 3827 PetscCall(PetscInfo(mat, "MatFactorError %d\n", mat->factorerrortype)); 3828 PetscCall(VecSetInf(x)); 3829 } else if (mat->ops->solveadd) { 3830 PetscUseTypeMethod(mat, solveadd, b, y, x); 3831 } else { 3832 /* do the solve then the add manually */ 3833 if (x != y) { 3834 PetscCall(MatSolve(mat, b, x)); 3835 PetscCall(VecAXPY(x, one, y)); 3836 } else { 3837 PetscCall(VecDuplicate(x, &tmp)); 3838 PetscCall(PetscLogObjectParent((PetscObject)mat, (PetscObject)tmp)); 3839 PetscCall(VecCopy(x, tmp)); 3840 PetscCall(MatSolve(mat, b, x)); 3841 PetscCall(VecAXPY(x, one, tmp)); 3842 PetscCall(VecDestroy(&tmp)); 3843 } 3844 } 3845 PetscCall(PetscLogEventEnd(MAT_SolveAdd, mat, b, x, y)); 3846 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3847 PetscFunctionReturn(0); 3848 } 3849 3850 /*@ 3851 MatSolveTranspose - Solves A' x = b, given a factored matrix. 3852 3853 Neighbor-wise Collective on mat 3854 3855 Input Parameters: 3856 + mat - the factored matrix 3857 - b - the right-hand-side vector 3858 3859 Output Parameter: 3860 . x - the result vector 3861 3862 Notes: 3863 The vectors b and x cannot be the same. I.e., one cannot 3864 call `MatSolveTranspose`(A,x,x). 3865 3866 Most users should employ the `KSP` interface for linear solvers 3867 instead of working directly with matrix algebra routines such as this. 3868 See, e.g., `KSPCreate()`. 3869 3870 Level: developer 3871 3872 .seealso: `MatGetFactor()`, `KSP`, `MatSolve()`, `MatSolveAdd()`, `MatSolveTransposeAdd()` 3873 @*/ 3874 PetscErrorCode MatSolveTranspose(Mat mat, Vec b, Vec x) { 3875 PetscErrorCode (*f)(Mat, Vec, Vec) = (!mat->ops->solvetranspose && mat->symmetric) ? mat->ops->solve : mat->ops->solvetranspose; 3876 3877 PetscFunctionBegin; 3878 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 3879 PetscValidType(mat, 1); 3880 PetscValidHeaderSpecific(b, VEC_CLASSID, 2); 3881 PetscValidHeaderSpecific(x, VEC_CLASSID, 3); 3882 PetscCheckSameComm(mat, 1, b, 2); 3883 PetscCheckSameComm(mat, 1, x, 3); 3884 PetscCheck(x != b, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_IDN, "x and b must be different vectors"); 3885 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); 3886 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); 3887 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3888 MatCheckPreallocated(mat, 1); 3889 PetscCall(PetscLogEventBegin(MAT_SolveTranspose, mat, b, x, 0)); 3890 if (mat->factorerrortype) { 3891 PetscCall(PetscInfo(mat, "MatFactorError %d\n", mat->factorerrortype)); 3892 PetscCall(VecSetInf(x)); 3893 } else { 3894 PetscCheck(f, PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Matrix type %s", ((PetscObject)mat)->type_name); 3895 PetscCall((*f)(mat, b, x)); 3896 } 3897 PetscCall(PetscLogEventEnd(MAT_SolveTranspose, mat, b, x, 0)); 3898 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3899 PetscFunctionReturn(0); 3900 } 3901 3902 /*@ 3903 MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a 3904 factored matrix. 3905 3906 Neighbor-wise Collective on mat 3907 3908 Input Parameters: 3909 + mat - the factored matrix 3910 . b - the right-hand-side vector 3911 - y - the vector to be added to 3912 3913 Output Parameter: 3914 . x - the result vector 3915 3916 Note: 3917 The vectors b and x cannot be the same. I.e., one cannot 3918 call `MatSolveTransposeAdd`(A,x,y,x). 3919 3920 Level: developer 3921 3922 .seealso: `MatGetFactor()`, `MatSolve()`, `MatSolveAdd()`, `MatSolveTranspose()` 3923 @*/ 3924 PetscErrorCode MatSolveTransposeAdd(Mat mat, Vec b, Vec y, Vec x) { 3925 PetscScalar one = 1.0; 3926 Vec tmp; 3927 PetscErrorCode (*f)(Mat, Vec, Vec, Vec) = (!mat->ops->solvetransposeadd && mat->symmetric) ? mat->ops->solveadd : mat->ops->solvetransposeadd; 3928 3929 PetscFunctionBegin; 3930 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 3931 PetscValidType(mat, 1); 3932 PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 3933 PetscValidHeaderSpecific(b, VEC_CLASSID, 2); 3934 PetscValidHeaderSpecific(x, VEC_CLASSID, 4); 3935 PetscCheckSameComm(mat, 1, b, 2); 3936 PetscCheckSameComm(mat, 1, y, 3); 3937 PetscCheckSameComm(mat, 1, x, 4); 3938 PetscCheck(x != b, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_IDN, "x and b must be different vectors"); 3939 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); 3940 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); 3941 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); 3942 PetscCheck(x->map->n == y->map->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Vec x,Vec y: local dim %" PetscInt_FMT " %" PetscInt_FMT, x->map->n, y->map->n); 3943 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3944 MatCheckPreallocated(mat, 1); 3945 3946 PetscCall(PetscLogEventBegin(MAT_SolveTransposeAdd, mat, b, x, y)); 3947 if (mat->factorerrortype) { 3948 PetscCall(PetscInfo(mat, "MatFactorError %d\n", mat->factorerrortype)); 3949 PetscCall(VecSetInf(x)); 3950 } else if (f) { 3951 PetscCall((*f)(mat, b, y, x)); 3952 } else { 3953 /* do the solve then the add manually */ 3954 if (x != y) { 3955 PetscCall(MatSolveTranspose(mat, b, x)); 3956 PetscCall(VecAXPY(x, one, y)); 3957 } else { 3958 PetscCall(VecDuplicate(x, &tmp)); 3959 PetscCall(PetscLogObjectParent((PetscObject)mat, (PetscObject)tmp)); 3960 PetscCall(VecCopy(x, tmp)); 3961 PetscCall(MatSolveTranspose(mat, b, x)); 3962 PetscCall(VecAXPY(x, one, tmp)); 3963 PetscCall(VecDestroy(&tmp)); 3964 } 3965 } 3966 PetscCall(PetscLogEventEnd(MAT_SolveTransposeAdd, mat, b, x, y)); 3967 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3968 PetscFunctionReturn(0); 3969 } 3970 /* ----------------------------------------------------------------*/ 3971 3972 /*@ 3973 MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps. 3974 3975 Neighbor-wise Collective on mat 3976 3977 Input Parameters: 3978 + mat - the matrix 3979 . b - the right hand side 3980 . omega - the relaxation factor 3981 . flag - flag indicating the type of SOR (see below) 3982 . shift - diagonal shift 3983 . its - the number of iterations 3984 - lits - the number of local iterations 3985 3986 Output Parameter: 3987 . x - the solution (can contain an initial guess, use option `SOR_ZERO_INITIAL_GUESS` to indicate no guess) 3988 3989 SOR Flags: 3990 + `SOR_FORWARD_SWEEP` - forward SOR 3991 . `SOR_BACKWARD_SWEEP` - backward SOR 3992 . `SOR_SYMMETRIC_SWEEP` - SSOR (symmetric SOR) 3993 . `SOR_LOCAL_FORWARD_SWEEP` - local forward SOR 3994 . `SOR_LOCAL_BACKWARD_SWEEP` - local forward SOR 3995 . `SOR_LOCAL_SYMMETRIC_SWEEP` - local SSOR 3996 . `SOR_APPLY_UPPER`, `SOR_APPLY_LOWER` - applies 3997 upper/lower triangular part of matrix to 3998 vector (with omega) 3999 - `SOR_ZERO_INITIAL_GUESS` - zero initial guess 4000 4001 Notes: 4002 `SOR_LOCAL_FORWARD_SWEEP`, `SOR_LOCAL_BACKWARD_SWEEP`, and 4003 `SOR_LOCAL_SYMMETRIC_SWEEP` perform separate independent smoothings 4004 on each processor. 4005 4006 Application programmers will not generally use `MatSOR()` directly, 4007 but instead will employ the `KSP`/`PC` interface. 4008 4009 For `MATBAIJ`, `MATSBAIJ`, and `MATAIJ` matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing 4010 4011 Most users should employ the `KSP` interface for linear solvers 4012 instead of working directly with matrix algebra routines such as this. 4013 See, e.g., `KSPCreate()`. 4014 4015 Vectors x and b CANNOT be the same 4016 4017 Notes for Advanced Users: 4018 The flags are implemented as bitwise inclusive or operations. 4019 For example, use (`SOR_ZERO_INITIAL_GUESS` | `SOR_SYMMETRIC_SWEEP`) 4020 to specify a zero initial guess for SSOR. 4021 4022 Developer Note: 4023 We should add block SOR support for `MATAIJ` matrices with block size set to great than one and no inodes 4024 4025 Level: developer 4026 4027 .seealso: `Mat`, `MatMult()`, `KSP`, `PC`, `MatGetFactor()` 4028 @*/ 4029 PetscErrorCode MatSOR(Mat mat, Vec b, PetscReal omega, MatSORType flag, PetscReal shift, PetscInt its, PetscInt lits, Vec x) { 4030 PetscFunctionBegin; 4031 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4032 PetscValidType(mat, 1); 4033 PetscValidHeaderSpecific(b, VEC_CLASSID, 2); 4034 PetscValidHeaderSpecific(x, VEC_CLASSID, 8); 4035 PetscCheckSameComm(mat, 1, b, 2); 4036 PetscCheckSameComm(mat, 1, x, 8); 4037 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 4038 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 4039 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); 4040 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); 4041 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); 4042 PetscCheck(its > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Relaxation requires global its %" PetscInt_FMT " positive", its); 4043 PetscCheck(lits > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Relaxation requires local its %" PetscInt_FMT " positive", lits); 4044 PetscCheck(b != x, PETSC_COMM_SELF, PETSC_ERR_ARG_IDN, "b and x vector cannot be the same"); 4045 4046 MatCheckPreallocated(mat, 1); 4047 PetscCall(PetscLogEventBegin(MAT_SOR, mat, b, x, 0)); 4048 PetscUseTypeMethod(mat, sor, b, omega, flag, shift, its, lits, x); 4049 PetscCall(PetscLogEventEnd(MAT_SOR, mat, b, x, 0)); 4050 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 4051 PetscFunctionReturn(0); 4052 } 4053 4054 /* 4055 Default matrix copy routine. 4056 */ 4057 PetscErrorCode MatCopy_Basic(Mat A, Mat B, MatStructure str) { 4058 PetscInt i, rstart = 0, rend = 0, nz; 4059 const PetscInt *cwork; 4060 const PetscScalar *vwork; 4061 4062 PetscFunctionBegin; 4063 if (B->assembled) PetscCall(MatZeroEntries(B)); 4064 if (str == SAME_NONZERO_PATTERN) { 4065 PetscCall(MatGetOwnershipRange(A, &rstart, &rend)); 4066 for (i = rstart; i < rend; i++) { 4067 PetscCall(MatGetRow(A, i, &nz, &cwork, &vwork)); 4068 PetscCall(MatSetValues(B, 1, &i, nz, cwork, vwork, INSERT_VALUES)); 4069 PetscCall(MatRestoreRow(A, i, &nz, &cwork, &vwork)); 4070 } 4071 } else { 4072 PetscCall(MatAYPX(B, 0.0, A, str)); 4073 } 4074 PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 4075 PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 4076 PetscFunctionReturn(0); 4077 } 4078 4079 /*@ 4080 MatCopy - Copies a matrix to another matrix. 4081 4082 Collective on A 4083 4084 Input Parameters: 4085 + A - the matrix 4086 - str - `SAME_NONZERO_PATTERN` or `DIFFERENT_NONZERO_PATTERN` 4087 4088 Output Parameter: 4089 . B - where the copy is put 4090 4091 Notes: 4092 If you use `SAME_NONZERO_PATTERN `then the two matrices must have the same nonzero pattern or the routine will crash. 4093 4094 `MatCopy()` copies the matrix entries of a matrix to another existing 4095 matrix (after first zeroing the second matrix). A related routine is 4096 `MatConvert()`, which first creates a new matrix and then copies the data. 4097 4098 Level: intermediate 4099 4100 .seealso: `Mat`, `MatConvert()`, `MatDuplicate()` 4101 @*/ 4102 PetscErrorCode MatCopy(Mat A, Mat B, MatStructure str) { 4103 PetscInt i; 4104 4105 PetscFunctionBegin; 4106 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 4107 PetscValidHeaderSpecific(B, MAT_CLASSID, 2); 4108 PetscValidType(A, 1); 4109 PetscValidType(B, 2); 4110 PetscCheckSameComm(A, 1, B, 2); 4111 MatCheckPreallocated(B, 2); 4112 PetscCheck(A->assembled, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 4113 PetscCheck(!A->factortype, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 4114 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, 4115 A->cmap->N, B->cmap->N); 4116 MatCheckPreallocated(A, 1); 4117 if (A == B) PetscFunctionReturn(0); 4118 4119 PetscCall(PetscLogEventBegin(MAT_Copy, A, B, 0, 0)); 4120 if (A->ops->copy) PetscUseTypeMethod(A, copy, B, str); 4121 else PetscCall(MatCopy_Basic(A, B, str)); 4122 4123 B->stencil.dim = A->stencil.dim; 4124 B->stencil.noc = A->stencil.noc; 4125 for (i = 0; i <= A->stencil.dim; i++) { 4126 B->stencil.dims[i] = A->stencil.dims[i]; 4127 B->stencil.starts[i] = A->stencil.starts[i]; 4128 } 4129 4130 PetscCall(PetscLogEventEnd(MAT_Copy, A, B, 0, 0)); 4131 PetscCall(PetscObjectStateIncrease((PetscObject)B)); 4132 PetscFunctionReturn(0); 4133 } 4134 4135 /*@C 4136 MatConvert - Converts a matrix to another matrix, either of the same 4137 or different type. 4138 4139 Collective on mat 4140 4141 Input Parameters: 4142 + mat - the matrix 4143 . newtype - new matrix type. Use `MATSAME` to create a new matrix of the 4144 same type as the original matrix. 4145 - reuse - denotes if the destination matrix is to be created or reused. 4146 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 4147 `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). 4148 4149 Output Parameter: 4150 . M - pointer to place new matrix 4151 4152 Notes: 4153 `MatConvert()` first creates a new matrix and then copies the data from 4154 the first matrix. A related routine is `MatCopy()`, which copies the matrix 4155 entries of one matrix to another already existing matrix context. 4156 4157 Cannot be used to convert a sequential matrix to parallel or parallel to sequential, 4158 the MPI communicator of the generated matrix is always the same as the communicator 4159 of the input matrix. 4160 4161 Level: intermediate 4162 4163 .seealso: `Mat`, `MatCopy()`, `MatDuplicate()`, `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, `MAT_INPLACE_MATRIX` 4164 @*/ 4165 PetscErrorCode MatConvert(Mat mat, MatType newtype, MatReuse reuse, Mat *M) { 4166 PetscBool sametype, issame, flg; 4167 PetscBool3 issymmetric, ishermitian; 4168 char convname[256], mtype[256]; 4169 Mat B; 4170 4171 PetscFunctionBegin; 4172 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4173 PetscValidType(mat, 1); 4174 PetscValidPointer(M, 4); 4175 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 4176 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 4177 MatCheckPreallocated(mat, 1); 4178 4179 PetscCall(PetscOptionsGetString(((PetscObject)mat)->options, ((PetscObject)mat)->prefix, "-matconvert_type", mtype, sizeof(mtype), &flg)); 4180 if (flg) newtype = mtype; 4181 4182 PetscCall(PetscObjectTypeCompare((PetscObject)mat, newtype, &sametype)); 4183 PetscCall(PetscStrcmp(newtype, "same", &issame)); 4184 PetscCheck(!(reuse == MAT_INPLACE_MATRIX) || !(mat != *M), PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "MAT_INPLACE_MATRIX requires same input and output matrix"); 4185 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"); 4186 4187 if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) { 4188 PetscCall(PetscInfo(mat, "Early return for inplace %s %d %d\n", ((PetscObject)mat)->type_name, sametype, issame)); 4189 PetscFunctionReturn(0); 4190 } 4191 4192 /* Cache Mat options because some converters use MatHeaderReplace */ 4193 issymmetric = mat->symmetric; 4194 ishermitian = mat->hermitian; 4195 4196 if ((sametype || issame) && (reuse == MAT_INITIAL_MATRIX) && mat->ops->duplicate) { 4197 PetscCall(PetscInfo(mat, "Calling duplicate for initial matrix %s %d %d\n", ((PetscObject)mat)->type_name, sametype, issame)); 4198 PetscUseTypeMethod(mat, duplicate, MAT_COPY_VALUES, M); 4199 } else { 4200 PetscErrorCode (*conv)(Mat, MatType, MatReuse, Mat *) = NULL; 4201 const char *prefix[3] = {"seq", "mpi", ""}; 4202 PetscInt i; 4203 /* 4204 Order of precedence: 4205 0) See if newtype is a superclass of the current matrix. 4206 1) See if a specialized converter is known to the current matrix. 4207 2) See if a specialized converter is known to the desired matrix class. 4208 3) See if a good general converter is registered for the desired class 4209 (as of 6/27/03 only MATMPIADJ falls into this category). 4210 4) See if a good general converter is known for the current matrix. 4211 5) Use a really basic converter. 4212 */ 4213 4214 /* 0) See if newtype is a superclass of the current matrix. 4215 i.e mat is mpiaij and newtype is aij */ 4216 for (i = 0; i < 2; i++) { 4217 PetscCall(PetscStrncpy(convname, prefix[i], sizeof(convname))); 4218 PetscCall(PetscStrlcat(convname, newtype, sizeof(convname))); 4219 PetscCall(PetscStrcmp(convname, ((PetscObject)mat)->type_name, &flg)); 4220 PetscCall(PetscInfo(mat, "Check superclass %s %s -> %d\n", convname, ((PetscObject)mat)->type_name, flg)); 4221 if (flg) { 4222 if (reuse == MAT_INPLACE_MATRIX) { 4223 PetscCall(PetscInfo(mat, "Early return\n")); 4224 PetscFunctionReturn(0); 4225 } else if (reuse == MAT_INITIAL_MATRIX && mat->ops->duplicate) { 4226 PetscCall(PetscInfo(mat, "Calling MatDuplicate\n")); 4227 PetscUseTypeMethod(mat, duplicate, MAT_COPY_VALUES, M); 4228 PetscFunctionReturn(0); 4229 } else if (reuse == MAT_REUSE_MATRIX && mat->ops->copy) { 4230 PetscCall(PetscInfo(mat, "Calling MatCopy\n")); 4231 PetscCall(MatCopy(mat, *M, SAME_NONZERO_PATTERN)); 4232 PetscFunctionReturn(0); 4233 } 4234 } 4235 } 4236 /* 1) See if a specialized converter is known to the current matrix and the desired class */ 4237 for (i = 0; i < 3; i++) { 4238 PetscCall(PetscStrncpy(convname, "MatConvert_", sizeof(convname))); 4239 PetscCall(PetscStrlcat(convname, ((PetscObject)mat)->type_name, sizeof(convname))); 4240 PetscCall(PetscStrlcat(convname, "_", sizeof(convname))); 4241 PetscCall(PetscStrlcat(convname, prefix[i], sizeof(convname))); 4242 PetscCall(PetscStrlcat(convname, issame ? ((PetscObject)mat)->type_name : newtype, sizeof(convname))); 4243 PetscCall(PetscStrlcat(convname, "_C", sizeof(convname))); 4244 PetscCall(PetscObjectQueryFunction((PetscObject)mat, convname, &conv)); 4245 PetscCall(PetscInfo(mat, "Check specialized (1) %s (%s) -> %d\n", convname, ((PetscObject)mat)->type_name, !!conv)); 4246 if (conv) goto foundconv; 4247 } 4248 4249 /* 2) See if a specialized converter is known to the desired matrix class. */ 4250 PetscCall(MatCreate(PetscObjectComm((PetscObject)mat), &B)); 4251 PetscCall(MatSetSizes(B, mat->rmap->n, mat->cmap->n, mat->rmap->N, mat->cmap->N)); 4252 PetscCall(MatSetType(B, newtype)); 4253 for (i = 0; i < 3; i++) { 4254 PetscCall(PetscStrncpy(convname, "MatConvert_", sizeof(convname))); 4255 PetscCall(PetscStrlcat(convname, ((PetscObject)mat)->type_name, sizeof(convname))); 4256 PetscCall(PetscStrlcat(convname, "_", sizeof(convname))); 4257 PetscCall(PetscStrlcat(convname, prefix[i], sizeof(convname))); 4258 PetscCall(PetscStrlcat(convname, newtype, sizeof(convname))); 4259 PetscCall(PetscStrlcat(convname, "_C", sizeof(convname))); 4260 PetscCall(PetscObjectQueryFunction((PetscObject)B, convname, &conv)); 4261 PetscCall(PetscInfo(mat, "Check specialized (2) %s (%s) -> %d\n", convname, ((PetscObject)B)->type_name, !!conv)); 4262 if (conv) { 4263 PetscCall(MatDestroy(&B)); 4264 goto foundconv; 4265 } 4266 } 4267 4268 /* 3) See if a good general converter is registered for the desired class */ 4269 conv = B->ops->convertfrom; 4270 PetscCall(PetscInfo(mat, "Check convertfrom (%s) -> %d\n", ((PetscObject)B)->type_name, !!conv)); 4271 PetscCall(MatDestroy(&B)); 4272 if (conv) goto foundconv; 4273 4274 /* 4) See if a good general converter is known for the current matrix */ 4275 if (mat->ops->convert) conv = mat->ops->convert; 4276 PetscCall(PetscInfo(mat, "Check general convert (%s) -> %d\n", ((PetscObject)mat)->type_name, !!conv)); 4277 if (conv) goto foundconv; 4278 4279 /* 5) Use a really basic converter. */ 4280 PetscCall(PetscInfo(mat, "Using MatConvert_Basic\n")); 4281 conv = MatConvert_Basic; 4282 4283 foundconv: 4284 PetscCall(PetscLogEventBegin(MAT_Convert, mat, 0, 0, 0)); 4285 PetscCall((*conv)(mat, newtype, reuse, M)); 4286 if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) { 4287 /* the block sizes must be same if the mappings are copied over */ 4288 (*M)->rmap->bs = mat->rmap->bs; 4289 (*M)->cmap->bs = mat->cmap->bs; 4290 PetscCall(PetscObjectReference((PetscObject)mat->rmap->mapping)); 4291 PetscCall(PetscObjectReference((PetscObject)mat->cmap->mapping)); 4292 (*M)->rmap->mapping = mat->rmap->mapping; 4293 (*M)->cmap->mapping = mat->cmap->mapping; 4294 } 4295 (*M)->stencil.dim = mat->stencil.dim; 4296 (*M)->stencil.noc = mat->stencil.noc; 4297 for (i = 0; i <= mat->stencil.dim; i++) { 4298 (*M)->stencil.dims[i] = mat->stencil.dims[i]; 4299 (*M)->stencil.starts[i] = mat->stencil.starts[i]; 4300 } 4301 PetscCall(PetscLogEventEnd(MAT_Convert, mat, 0, 0, 0)); 4302 } 4303 PetscCall(PetscObjectStateIncrease((PetscObject)*M)); 4304 4305 /* Copy Mat options */ 4306 if (issymmetric == PETSC_BOOL3_TRUE) PetscCall(MatSetOption(*M, MAT_SYMMETRIC, PETSC_TRUE)); 4307 else if (issymmetric == PETSC_BOOL3_FALSE) PetscCall(MatSetOption(*M, MAT_SYMMETRIC, PETSC_FALSE)); 4308 if (ishermitian == PETSC_BOOL3_TRUE) PetscCall(MatSetOption(*M, MAT_HERMITIAN, PETSC_TRUE)); 4309 else if (ishermitian == PETSC_BOOL3_FALSE) PetscCall(MatSetOption(*M, MAT_HERMITIAN, PETSC_FALSE)); 4310 PetscFunctionReturn(0); 4311 } 4312 4313 /*@C 4314 MatFactorGetSolverType - Returns name of the package providing the factorization routines 4315 4316 Not Collective 4317 4318 Input Parameter: 4319 . mat - the matrix, must be a factored matrix 4320 4321 Output Parameter: 4322 . type - the string name of the package (do not free this string) 4323 4324 Note: 4325 In Fortran you pass in a empty string and the package name will be copied into it. 4326 (Make sure the string is long enough) 4327 4328 Level: intermediate 4329 4330 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()` 4331 @*/ 4332 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type) { 4333 PetscErrorCode (*conv)(Mat, MatSolverType *); 4334 4335 PetscFunctionBegin; 4336 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4337 PetscValidType(mat, 1); 4338 PetscValidPointer(type, 2); 4339 PetscCheck(mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Only for factored matrix"); 4340 PetscCall(PetscObjectQueryFunction((PetscObject)mat, "MatFactorGetSolverType_C", &conv)); 4341 if (conv) PetscCall((*conv)(mat, type)); 4342 else *type = MATSOLVERPETSC; 4343 PetscFunctionReturn(0); 4344 } 4345 4346 typedef struct _MatSolverTypeForSpecifcType *MatSolverTypeForSpecifcType; 4347 struct _MatSolverTypeForSpecifcType { 4348 MatType mtype; 4349 /* no entry for MAT_FACTOR_NONE */ 4350 PetscErrorCode (*createfactor[MAT_FACTOR_NUM_TYPES - 1])(Mat, MatFactorType, Mat *); 4351 MatSolverTypeForSpecifcType next; 4352 }; 4353 4354 typedef struct _MatSolverTypeHolder *MatSolverTypeHolder; 4355 struct _MatSolverTypeHolder { 4356 char *name; 4357 MatSolverTypeForSpecifcType handlers; 4358 MatSolverTypeHolder next; 4359 }; 4360 4361 static MatSolverTypeHolder MatSolverTypeHolders = NULL; 4362 4363 /*@C 4364 MatSolverTypeRegister - Registers a `MatSolverType` that works for a particular matrix type 4365 4366 Input Parameters: 4367 + package - name of the package, for example petsc or superlu 4368 . mtype - the matrix type that works with this package 4369 . ftype - the type of factorization supported by the package 4370 - createfactor - routine that will create the factored matrix ready to be used 4371 4372 Level: developer 4373 4374 .seealso: `MatFactorGetSolverType()`, `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()` 4375 @*/ 4376 PetscErrorCode MatSolverTypeRegister(MatSolverType package, MatType mtype, MatFactorType ftype, PetscErrorCode (*createfactor)(Mat, MatFactorType, Mat *)) { 4377 MatSolverTypeHolder next = MatSolverTypeHolders, prev = NULL; 4378 PetscBool flg; 4379 MatSolverTypeForSpecifcType inext, iprev = NULL; 4380 4381 PetscFunctionBegin; 4382 PetscCall(MatInitializePackage()); 4383 if (!next) { 4384 PetscCall(PetscNew(&MatSolverTypeHolders)); 4385 PetscCall(PetscStrallocpy(package, &MatSolverTypeHolders->name)); 4386 PetscCall(PetscNew(&MatSolverTypeHolders->handlers)); 4387 PetscCall(PetscStrallocpy(mtype, (char **)&MatSolverTypeHolders->handlers->mtype)); 4388 MatSolverTypeHolders->handlers->createfactor[(int)ftype - 1] = createfactor; 4389 PetscFunctionReturn(0); 4390 } 4391 while (next) { 4392 PetscCall(PetscStrcasecmp(package, next->name, &flg)); 4393 if (flg) { 4394 PetscCheck(next->handlers, PETSC_COMM_SELF, PETSC_ERR_PLIB, "MatSolverTypeHolder is missing handlers"); 4395 inext = next->handlers; 4396 while (inext) { 4397 PetscCall(PetscStrcasecmp(mtype, inext->mtype, &flg)); 4398 if (flg) { 4399 inext->createfactor[(int)ftype - 1] = createfactor; 4400 PetscFunctionReturn(0); 4401 } 4402 iprev = inext; 4403 inext = inext->next; 4404 } 4405 PetscCall(PetscNew(&iprev->next)); 4406 PetscCall(PetscStrallocpy(mtype, (char **)&iprev->next->mtype)); 4407 iprev->next->createfactor[(int)ftype - 1] = createfactor; 4408 PetscFunctionReturn(0); 4409 } 4410 prev = next; 4411 next = next->next; 4412 } 4413 PetscCall(PetscNew(&prev->next)); 4414 PetscCall(PetscStrallocpy(package, &prev->next->name)); 4415 PetscCall(PetscNew(&prev->next->handlers)); 4416 PetscCall(PetscStrallocpy(mtype, (char **)&prev->next->handlers->mtype)); 4417 prev->next->handlers->createfactor[(int)ftype - 1] = createfactor; 4418 PetscFunctionReturn(0); 4419 } 4420 4421 /*@C 4422 MatSolverTypeGet - Gets the function that creates the factor matrix if it exist 4423 4424 Input Parameters: 4425 + type - name of the package, for example petsc or superlu 4426 . ftype - the type of factorization supported by the type 4427 - mtype - the matrix type that works with this type 4428 4429 Output Parameters: 4430 + foundtype - `PETSC_TRUE` if the type was registered 4431 . foundmtype - `PETSC_TRUE` if the type supports the requested mtype 4432 - createfactor - routine that will create the factored matrix ready to be used or NULL if not found 4433 4434 Level: developer 4435 4436 .seealso: `MatFactorType`, `MatType`, `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatSolverTypeRegister()`, `MatGetFactor()` 4437 @*/ 4438 PetscErrorCode MatSolverTypeGet(MatSolverType type, MatType mtype, MatFactorType ftype, PetscBool *foundtype, PetscBool *foundmtype, PetscErrorCode (**createfactor)(Mat, MatFactorType, Mat *)) { 4439 MatSolverTypeHolder next = MatSolverTypeHolders; 4440 PetscBool flg; 4441 MatSolverTypeForSpecifcType inext; 4442 4443 PetscFunctionBegin; 4444 if (foundtype) *foundtype = PETSC_FALSE; 4445 if (foundmtype) *foundmtype = PETSC_FALSE; 4446 if (createfactor) *createfactor = NULL; 4447 4448 if (type) { 4449 while (next) { 4450 PetscCall(PetscStrcasecmp(type, next->name, &flg)); 4451 if (flg) { 4452 if (foundtype) *foundtype = PETSC_TRUE; 4453 inext = next->handlers; 4454 while (inext) { 4455 PetscCall(PetscStrbeginswith(mtype, inext->mtype, &flg)); 4456 if (flg) { 4457 if (foundmtype) *foundmtype = PETSC_TRUE; 4458 if (createfactor) *createfactor = inext->createfactor[(int)ftype - 1]; 4459 PetscFunctionReturn(0); 4460 } 4461 inext = inext->next; 4462 } 4463 } 4464 next = next->next; 4465 } 4466 } else { 4467 while (next) { 4468 inext = next->handlers; 4469 while (inext) { 4470 PetscCall(PetscStrcmp(mtype, inext->mtype, &flg)); 4471 if (flg && inext->createfactor[(int)ftype - 1]) { 4472 if (foundtype) *foundtype = PETSC_TRUE; 4473 if (foundmtype) *foundmtype = PETSC_TRUE; 4474 if (createfactor) *createfactor = inext->createfactor[(int)ftype - 1]; 4475 PetscFunctionReturn(0); 4476 } 4477 inext = inext->next; 4478 } 4479 next = next->next; 4480 } 4481 /* try with base classes inext->mtype */ 4482 next = MatSolverTypeHolders; 4483 while (next) { 4484 inext = next->handlers; 4485 while (inext) { 4486 PetscCall(PetscStrbeginswith(mtype, inext->mtype, &flg)); 4487 if (flg && inext->createfactor[(int)ftype - 1]) { 4488 if (foundtype) *foundtype = PETSC_TRUE; 4489 if (foundmtype) *foundmtype = PETSC_TRUE; 4490 if (createfactor) *createfactor = inext->createfactor[(int)ftype - 1]; 4491 PetscFunctionReturn(0); 4492 } 4493 inext = inext->next; 4494 } 4495 next = next->next; 4496 } 4497 } 4498 PetscFunctionReturn(0); 4499 } 4500 4501 PetscErrorCode MatSolverTypeDestroy(void) { 4502 MatSolverTypeHolder next = MatSolverTypeHolders, prev; 4503 MatSolverTypeForSpecifcType inext, iprev; 4504 4505 PetscFunctionBegin; 4506 while (next) { 4507 PetscCall(PetscFree(next->name)); 4508 inext = next->handlers; 4509 while (inext) { 4510 PetscCall(PetscFree(inext->mtype)); 4511 iprev = inext; 4512 inext = inext->next; 4513 PetscCall(PetscFree(iprev)); 4514 } 4515 prev = next; 4516 next = next->next; 4517 PetscCall(PetscFree(prev)); 4518 } 4519 MatSolverTypeHolders = NULL; 4520 PetscFunctionReturn(0); 4521 } 4522 4523 /*@C 4524 MatFactorGetCanUseOrdering - Indicates if the factorization can use the ordering provided in `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()` 4525 4526 Logically Collective on mat 4527 4528 Input Parameters: 4529 . mat - the matrix 4530 4531 Output Parameters: 4532 . flg - `PETSC_TRUE` if uses the ordering 4533 4534 Note: 4535 Most internal PETSc factorizations use the ordering passed to the factorization routine but external 4536 packages do not, thus we want to skip generating the ordering when it is not needed or used. 4537 4538 Level: developer 4539 4540 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()` 4541 @*/ 4542 PetscErrorCode MatFactorGetCanUseOrdering(Mat mat, PetscBool *flg) { 4543 PetscFunctionBegin; 4544 *flg = mat->canuseordering; 4545 PetscFunctionReturn(0); 4546 } 4547 4548 /*@C 4549 MatFactorGetPreferredOrdering - The preferred ordering for a particular matrix factor object 4550 4551 Logically Collective on mat 4552 4553 Input Parameters: 4554 . mat - the matrix obtained with `MatGetFactor()` 4555 4556 Output Parameters: 4557 . otype - the preferred type 4558 4559 Level: developer 4560 4561 .seealso: `MatFactorType`, `MatOrderingType`, `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()` 4562 @*/ 4563 PetscErrorCode MatFactorGetPreferredOrdering(Mat mat, MatFactorType ftype, MatOrderingType *otype) { 4564 PetscFunctionBegin; 4565 *otype = mat->preferredordering[ftype]; 4566 PetscCheck(*otype, PETSC_COMM_SELF, PETSC_ERR_PLIB, "MatFactor did not have a preferred ordering"); 4567 PetscFunctionReturn(0); 4568 } 4569 4570 /*@C 4571 MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic() 4572 4573 Collective on mat 4574 4575 Input Parameters: 4576 + mat - the matrix 4577 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4578 - ftype - factor type, `MAT_FACTOR_LU`, `MAT_FACTOR_CHOLESKY`, `MAT_FACTOR_ICC`, `MAT_FACTOR_ILU`, `MAT_FACTOR_QR` 4579 4580 Output Parameters: 4581 . f - the factor matrix used with MatXXFactorSymbolic() calls 4582 4583 Options Database Key: 4584 . -mat_factor_bind_factorization <host, device> - Where to do matrix factorization? Default is device (might consume more device memory. 4585 One can choose host to save device memory). Currently only supported with `MATSEQAIJCUSPARSE` matrices. 4586 4587 Notes: 4588 Users usually access the factorization solvers via `KSP` 4589 4590 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4591 such as pastix, superlu, mumps etc. 4592 4593 PETSc must have been ./configure to use the external solver, using the option --download-package 4594 4595 Some of the packages have options for controlling the factorization, these are in the form -prefix_mat_packagename_packageoption 4596 where prefix is normally obtained from the calling `KSP`/`PC`. If `MatGetFactor()` is called directly one can set 4597 call `MatSetOptionsPrefixFactor()` on the originating matrix or `MatSetOptionsPrefix()` on the resulting factor matrix. 4598 4599 Developer Note: 4600 This should actually be called `MatCreateFactor()` since it creates a new factor object 4601 4602 Level: intermediate 4603 4604 .seealso: `KSP`, `MatSolverType`, `MatFactorType`, `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatFactorGetCanUseOrdering()`, `MatSolverTypeRegister()`, 4605 `MAT_FACTOR_LU`, `MAT_FACTOR_CHOLESKY`, `MAT_FACTOR_ICC`, `MAT_FACTOR_ILU`, `MAT_FACTOR_QR` 4606 @*/ 4607 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type, MatFactorType ftype, Mat *f) { 4608 PetscBool foundtype, foundmtype; 4609 PetscErrorCode (*conv)(Mat, MatFactorType, Mat *); 4610 4611 PetscFunctionBegin; 4612 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4613 PetscValidType(mat, 1); 4614 4615 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 4616 MatCheckPreallocated(mat, 1); 4617 4618 PetscCall(MatSolverTypeGet(type, ((PetscObject)mat)->type_name, ftype, &foundtype, &foundmtype, &conv)); 4619 if (!foundtype) { 4620 if (type) { 4621 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], 4622 ((PetscObject)mat)->type_name, type); 4623 } else { 4624 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); 4625 } 4626 } 4627 PetscCheck(foundmtype, PetscObjectComm((PetscObject)mat), PETSC_ERR_MISSING_FACTOR, "MatSolverType %s does not support matrix type %s", type, ((PetscObject)mat)->type_name); 4628 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); 4629 4630 PetscCall((*conv)(mat, ftype, f)); 4631 if (mat->factorprefix) PetscCall(MatSetOptionsPrefix(*f, mat->factorprefix)); 4632 PetscFunctionReturn(0); 4633 } 4634 4635 /*@C 4636 MatGetFactorAvailable - Returns a a flag if matrix supports particular type and factor type 4637 4638 Not Collective 4639 4640 Input Parameters: 4641 + mat - the matrix 4642 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4643 - ftype - factor type, `MAT_FACTOR_LU`, `MAT_FACTOR_CHOLESKY`, `MAT_FACTOR_ICC`, `MAT_FACTOR_ILU`, `MAT_FACTOR_QR` 4644 4645 Output Parameter: 4646 . flg - PETSC_TRUE if the factorization is available 4647 4648 Notes: 4649 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4650 such as pastix, superlu, mumps etc. 4651 4652 PETSc must have been ./configure to use the external solver, using the option --download-package 4653 4654 Developer Note: 4655 This should actually be called MatCreateFactorAvailable() since MatGetFactor() creates a new factor object 4656 4657 Level: intermediate 4658 4659 .seealso: `MatSolverType`, `MatFactorType`, `MatGetFactor()`, `MatCopy()`, `MatDuplicate()`, `MatGetFactor()`, `MatSolverTypeRegister()`, 4660 `MAT_FACTOR_LU`, `MAT_FACTOR_CHOLESKY`, `MAT_FACTOR_ICC`, `MAT_FACTOR_ILU`, `MAT_FACTOR_QR` 4661 @*/ 4662 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type, MatFactorType ftype, PetscBool *flg) { 4663 PetscErrorCode (*gconv)(Mat, MatFactorType, Mat *); 4664 4665 PetscFunctionBegin; 4666 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4667 PetscValidType(mat, 1); 4668 PetscValidBoolPointer(flg, 4); 4669 4670 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 4671 MatCheckPreallocated(mat, 1); 4672 4673 PetscCall(MatSolverTypeGet(type, ((PetscObject)mat)->type_name, ftype, NULL, NULL, &gconv)); 4674 *flg = gconv ? PETSC_TRUE : PETSC_FALSE; 4675 PetscFunctionReturn(0); 4676 } 4677 4678 /*@ 4679 MatDuplicate - Duplicates a matrix including the non-zero structure. 4680 4681 Collective on mat 4682 4683 Input Parameters: 4684 + mat - the matrix 4685 - op - One of `MAT_DO_NOT_COPY_VALUES`, `MAT_COPY_VALUES`, or `MAT_SHARE_NONZERO_PATTERN`. 4686 See the manual page for `MatDuplicateOption()` for an explanation of these options. 4687 4688 Output Parameter: 4689 . M - pointer to place new matrix 4690 4691 Level: intermediate 4692 4693 Notes: 4694 You cannot change the nonzero pattern for the parent or child matrix if you use `MAT_SHARE_NONZERO_PATTERN`. 4695 4696 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. 4697 4698 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 4699 is duplicated and the internal data structures created for the reuse of previous matrix operations are not duplicated. 4700 User should not use `MatDuplicate()` to create new matrix M if M is intended to be reused as the product of matrix operation. 4701 4702 .seealso: `MatCopy()`, `MatConvert()`, `MatDuplicateOption` 4703 @*/ 4704 PetscErrorCode MatDuplicate(Mat mat, MatDuplicateOption op, Mat *M) { 4705 Mat B; 4706 VecType vtype; 4707 PetscInt i; 4708 PetscObject dm; 4709 void (*viewf)(void); 4710 4711 PetscFunctionBegin; 4712 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4713 PetscValidType(mat, 1); 4714 PetscValidPointer(M, 3); 4715 PetscCheck(op != MAT_COPY_VALUES || mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "MAT_COPY_VALUES not allowed for unassembled matrix"); 4716 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 4717 MatCheckPreallocated(mat, 1); 4718 4719 *M = NULL; 4720 PetscCall(PetscLogEventBegin(MAT_Convert, mat, 0, 0, 0)); 4721 PetscUseTypeMethod(mat, duplicate, op, M); 4722 PetscCall(PetscLogEventEnd(MAT_Convert, mat, 0, 0, 0)); 4723 B = *M; 4724 4725 PetscCall(MatGetOperation(mat, MATOP_VIEW, &viewf)); 4726 if (viewf) PetscCall(MatSetOperation(B, MATOP_VIEW, viewf)); 4727 PetscCall(MatGetVecType(mat, &vtype)); 4728 PetscCall(MatSetVecType(B, vtype)); 4729 4730 B->stencil.dim = mat->stencil.dim; 4731 B->stencil.noc = mat->stencil.noc; 4732 for (i = 0; i <= mat->stencil.dim; i++) { 4733 B->stencil.dims[i] = mat->stencil.dims[i]; 4734 B->stencil.starts[i] = mat->stencil.starts[i]; 4735 } 4736 4737 B->nooffproczerorows = mat->nooffproczerorows; 4738 B->nooffprocentries = mat->nooffprocentries; 4739 4740 PetscCall(PetscObjectQuery((PetscObject)mat, "__PETSc_dm", &dm)); 4741 if (dm) PetscCall(PetscObjectCompose((PetscObject)B, "__PETSc_dm", dm)); 4742 PetscCall(PetscObjectStateIncrease((PetscObject)B)); 4743 PetscFunctionReturn(0); 4744 } 4745 4746 /*@ 4747 MatGetDiagonal - Gets the diagonal of a matrix as a `Vec` 4748 4749 Logically Collective on mat 4750 4751 Input Parameters: 4752 + mat - the matrix 4753 - v - the vector for storing the diagonal 4754 4755 Output Parameter: 4756 . v - the diagonal of the matrix 4757 4758 Level: intermediate 4759 4760 Note: 4761 Currently only correct in parallel for square matrices. 4762 4763 .seealso: `Mat`, `Vec`, `MatGetRow()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMaxAbs()` 4764 @*/ 4765 PetscErrorCode MatGetDiagonal(Mat mat, Vec v) { 4766 PetscFunctionBegin; 4767 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4768 PetscValidType(mat, 1); 4769 PetscValidHeaderSpecific(v, VEC_CLASSID, 2); 4770 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 4771 MatCheckPreallocated(mat, 1); 4772 4773 PetscUseTypeMethod(mat, getdiagonal, v); 4774 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 4775 PetscFunctionReturn(0); 4776 } 4777 4778 /*@C 4779 MatGetRowMin - Gets the minimum value (of the real part) of each 4780 row of the matrix 4781 4782 Logically Collective on mat 4783 4784 Input Parameter: 4785 . mat - the matrix 4786 4787 Output Parameters: 4788 + v - the vector for storing the maximums 4789 - idx - the indices of the column found for each row (optional) 4790 4791 Level: intermediate 4792 4793 Note: 4794 The result of this call are the same as if one converted the matrix to dense format 4795 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4796 4797 This code is only implemented for a couple of matrix formats. 4798 4799 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMaxAbs()`, `MatGetRowMinAbs()`, 4800 `MatGetRowMax()` 4801 @*/ 4802 PetscErrorCode MatGetRowMin(Mat mat, Vec v, PetscInt idx[]) { 4803 PetscFunctionBegin; 4804 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4805 PetscValidType(mat, 1); 4806 PetscValidHeaderSpecific(v, VEC_CLASSID, 2); 4807 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 4808 4809 if (!mat->cmap->N) { 4810 PetscCall(VecSet(v, PETSC_MAX_REAL)); 4811 if (idx) { 4812 PetscInt i, m = mat->rmap->n; 4813 for (i = 0; i < m; i++) idx[i] = -1; 4814 } 4815 } else { 4816 MatCheckPreallocated(mat, 1); 4817 } 4818 PetscUseTypeMethod(mat, getrowmin, v, idx); 4819 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 4820 PetscFunctionReturn(0); 4821 } 4822 4823 /*@C 4824 MatGetRowMinAbs - Gets the minimum value (in absolute value) of each 4825 row of the matrix 4826 4827 Logically Collective on mat 4828 4829 Input Parameter: 4830 . mat - the matrix 4831 4832 Output Parameters: 4833 + v - the vector for storing the minimums 4834 - idx - the indices of the column found for each row (or NULL if not needed) 4835 4836 Level: intermediate 4837 4838 Notes: 4839 if a row is completely empty or has only 0.0 values then the idx[] value for that 4840 row is 0 (the first column). 4841 4842 This code is only implemented for a couple of matrix formats. 4843 4844 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMax()`, `MatGetRowMaxAbs()`, `MatGetRowMin()` 4845 @*/ 4846 PetscErrorCode MatGetRowMinAbs(Mat mat, Vec v, PetscInt idx[]) { 4847 PetscFunctionBegin; 4848 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4849 PetscValidType(mat, 1); 4850 PetscValidHeaderSpecific(v, VEC_CLASSID, 2); 4851 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 4852 PetscCheck(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 4853 4854 if (!mat->cmap->N) { 4855 PetscCall(VecSet(v, 0.0)); 4856 if (idx) { 4857 PetscInt i, m = mat->rmap->n; 4858 for (i = 0; i < m; i++) idx[i] = -1; 4859 } 4860 } else { 4861 MatCheckPreallocated(mat, 1); 4862 if (idx) PetscCall(PetscArrayzero(idx, mat->rmap->n)); 4863 PetscUseTypeMethod(mat, getrowminabs, v, idx); 4864 } 4865 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 4866 PetscFunctionReturn(0); 4867 } 4868 4869 /*@C 4870 MatGetRowMax - Gets the maximum value (of the real part) of each 4871 row of the matrix 4872 4873 Logically Collective on mat 4874 4875 Input Parameter: 4876 . mat - the matrix 4877 4878 Output Parameters: 4879 + v - the vector for storing the maximums 4880 - idx - the indices of the column found for each row (optional) 4881 4882 Level: intermediate 4883 4884 Notes: 4885 The result of this call are the same as if one converted the matrix to dense format 4886 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4887 4888 This code is only implemented for a couple of matrix formats. 4889 4890 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMaxAbs()`, `MatGetRowMin()`, `MatGetRowMinAbs()` 4891 @*/ 4892 PetscErrorCode MatGetRowMax(Mat mat, Vec v, PetscInt idx[]) { 4893 PetscFunctionBegin; 4894 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4895 PetscValidType(mat, 1); 4896 PetscValidHeaderSpecific(v, VEC_CLASSID, 2); 4897 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 4898 4899 if (!mat->cmap->N) { 4900 PetscCall(VecSet(v, PETSC_MIN_REAL)); 4901 if (idx) { 4902 PetscInt i, m = mat->rmap->n; 4903 for (i = 0; i < m; i++) idx[i] = -1; 4904 } 4905 } else { 4906 MatCheckPreallocated(mat, 1); 4907 PetscUseTypeMethod(mat, getrowmax, v, idx); 4908 } 4909 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 4910 PetscFunctionReturn(0); 4911 } 4912 4913 /*@C 4914 MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each 4915 row of the matrix 4916 4917 Logically Collective on mat 4918 4919 Input Parameter: 4920 . mat - the matrix 4921 4922 Output Parameters: 4923 + v - the vector for storing the maximums 4924 - idx - the indices of the column found for each row (or NULL if not needed) 4925 4926 Level: intermediate 4927 4928 Notes: 4929 if a row is completely empty or has only 0.0 values then the idx[] value for that 4930 row is 0 (the first column). 4931 4932 This code is only implemented for a couple of matrix formats. 4933 4934 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMax()`, `MatGetRowMin()`, `MatGetRowMinAbs()` 4935 @*/ 4936 PetscErrorCode MatGetRowMaxAbs(Mat mat, Vec v, PetscInt idx[]) { 4937 PetscFunctionBegin; 4938 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4939 PetscValidType(mat, 1); 4940 PetscValidHeaderSpecific(v, VEC_CLASSID, 2); 4941 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 4942 4943 if (!mat->cmap->N) { 4944 PetscCall(VecSet(v, 0.0)); 4945 if (idx) { 4946 PetscInt i, m = mat->rmap->n; 4947 for (i = 0; i < m; i++) idx[i] = -1; 4948 } 4949 } else { 4950 MatCheckPreallocated(mat, 1); 4951 if (idx) PetscCall(PetscArrayzero(idx, mat->rmap->n)); 4952 PetscUseTypeMethod(mat, getrowmaxabs, v, idx); 4953 } 4954 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 4955 PetscFunctionReturn(0); 4956 } 4957 4958 /*@ 4959 MatGetRowSum - Gets the sum of each row of the matrix 4960 4961 Logically or Neighborhood Collective on mat 4962 4963 Input Parameters: 4964 . mat - the matrix 4965 4966 Output Parameter: 4967 . v - the vector for storing the sum of rows 4968 4969 Level: intermediate 4970 4971 Notes: 4972 This code is slow since it is not currently specialized for different formats 4973 4974 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMax()`, `MatGetRowMin()`, `MatGetRowMaxAbs()`, `MatGetRowMinAbs()` 4975 @*/ 4976 PetscErrorCode MatGetRowSum(Mat mat, Vec v) { 4977 Vec ones; 4978 4979 PetscFunctionBegin; 4980 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4981 PetscValidType(mat, 1); 4982 PetscValidHeaderSpecific(v, VEC_CLASSID, 2); 4983 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 4984 MatCheckPreallocated(mat, 1); 4985 PetscCall(MatCreateVecs(mat, &ones, NULL)); 4986 PetscCall(VecSet(ones, 1.)); 4987 PetscCall(MatMult(mat, ones, v)); 4988 PetscCall(VecDestroy(&ones)); 4989 PetscFunctionReturn(0); 4990 } 4991 4992 /*@ 4993 MatTransposeSetPrecursor - Set the matrix from which the second matrix will receive numerical transpose data with a call to `MatTranspose`(A,`MAT_REUSE_MATRIX`,&B) 4994 when B was not obtained with `MatTranspose`(A,`MAT_INITIAL_MATRIX`,&B) 4995 4996 Collective on mat 4997 4998 Input Parameter: 4999 . mat - the matrix to provide the transpose 5000 5001 Output Parameter: 5002 . 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 5003 5004 Level: advanced 5005 5006 Note: 5007 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 5008 routine allows bypassing that call. 5009 5010 .seealso: `MatTransposeSymbolic()`, `MatTranspose()`, `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse`, `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, `MAT_INPLACE_MATRIX` 5011 @*/ 5012 PetscErrorCode MatTransposeSetPrecursor(Mat mat, Mat B) { 5013 PetscContainer rB = NULL; 5014 MatParentState *rb = NULL; 5015 5016 PetscFunctionBegin; 5017 PetscCall(PetscNew(&rb)); 5018 rb->id = ((PetscObject)mat)->id; 5019 rb->state = 0; 5020 PetscCall(MatGetNonzeroState(mat, &rb->nonzerostate)); 5021 PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)B), &rB)); 5022 PetscCall(PetscContainerSetPointer(rB, rb)); 5023 PetscCall(PetscContainerSetUserDestroy(rB, PetscContainerUserDestroyDefault)); 5024 PetscCall(PetscObjectCompose((PetscObject)B, "MatTransposeParent", (PetscObject)rB)); 5025 PetscCall(PetscObjectDereference((PetscObject)rB)); 5026 PetscFunctionReturn(0); 5027 } 5028 5029 /*@ 5030 MatTranspose - Computes an in-place or out-of-place transpose of a matrix. 5031 5032 Collective on mat 5033 5034 Input Parameters: 5035 + mat - the matrix to transpose 5036 - reuse - either `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, or `MAT_INPLACE_MATRIX` 5037 5038 Output Parameter: 5039 . B - the transpose 5040 5041 Notes: 5042 If you use `MAT_INPLACE_MATRIX` then you must pass in &mat for B 5043 5044 `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 5045 transpose, call `MatTransposeSetPrecursor`(mat,B) before calling this routine. 5046 5047 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. 5048 5049 Consider using `MatCreateTranspose()` instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed. 5050 5051 If mat is unchanged from the last call this function returns immediately without recomputing the result 5052 5053 If you only need the symbolic transpose, and not the numerical values, use `MatTransposeSymbolic()` 5054 5055 Level: intermediate 5056 5057 .seealso: `MatTransposeSetPrecursor()`, `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse`, `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, `MAT_INPLACE_MATRIX`, 5058 `MatTransposeSymbolic()` 5059 @*/ 5060 PetscErrorCode MatTranspose(Mat mat, MatReuse reuse, Mat *B) { 5061 PetscContainer rB = NULL; 5062 MatParentState *rb = NULL; 5063 5064 PetscFunctionBegin; 5065 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5066 PetscValidType(mat, 1); 5067 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 5068 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 5069 PetscCheck(reuse != MAT_INPLACE_MATRIX || mat == *B, PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "MAT_INPLACE_MATRIX requires last matrix to match first"); 5070 PetscCheck(reuse != MAT_REUSE_MATRIX || mat != *B, PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Perhaps you mean MAT_INPLACE_MATRIX"); 5071 MatCheckPreallocated(mat, 1); 5072 if (reuse == MAT_REUSE_MATRIX) { 5073 PetscCall(PetscObjectQuery((PetscObject)*B, "MatTransposeParent", (PetscObject *)&rB)); 5074 PetscCheck(rB, PetscObjectComm((PetscObject)*B), PETSC_ERR_ARG_WRONG, "Reuse matrix used was not generated from call to MatTranspose(). Suggest MatTransposeSetPrecursor()."); 5075 PetscCall(PetscContainerGetPointer(rB, (void **)&rb)); 5076 PetscCheck(rb->id == ((PetscObject)mat)->id, PetscObjectComm((PetscObject)*B), PETSC_ERR_ARG_WRONG, "Reuse matrix used was not generated from input matrix"); 5077 if (rb->state == ((PetscObject)mat)->state) PetscFunctionReturn(0); 5078 } 5079 5080 PetscCall(PetscLogEventBegin(MAT_Transpose, mat, 0, 0, 0)); 5081 if (reuse != MAT_INPLACE_MATRIX || mat->symmetric != PETSC_BOOL3_TRUE) { 5082 PetscUseTypeMethod(mat, transpose, reuse, B); 5083 PetscCall(PetscObjectStateIncrease((PetscObject)*B)); 5084 } 5085 PetscCall(PetscLogEventEnd(MAT_Transpose, mat, 0, 0, 0)); 5086 5087 if (reuse == MAT_INITIAL_MATRIX) PetscCall(MatTransposeSetPrecursor(mat, *B)); 5088 if (reuse != MAT_INPLACE_MATRIX) { 5089 PetscCall(PetscObjectQuery((PetscObject)*B, "MatTransposeParent", (PetscObject *)&rB)); 5090 PetscCall(PetscContainerGetPointer(rB, (void **)&rb)); 5091 rb->state = ((PetscObject)mat)->state; 5092 rb->nonzerostate = mat->nonzerostate; 5093 } 5094 PetscFunctionReturn(0); 5095 } 5096 5097 /*@ 5098 MatTransposeSymbolic - Computes the symbolic part of the transpose of a matrix. 5099 5100 Collective on A 5101 5102 Input Parameters: 5103 . A - the matrix to transpose 5104 5105 Output Parameter: 5106 . 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 5107 numerical portion. 5108 5109 Level: intermediate 5110 5111 Note: 5112 This is not supported for many matrix types, use `MatTranspose()` in those cases 5113 5114 .seealso: `MatTransposeSetPrecursor()`, `MatTranspose()`, `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse`, `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, `MAT_INPLACE_MATRIX` 5115 @*/ 5116 PetscErrorCode MatTransposeSymbolic(Mat A, Mat *B) { 5117 PetscFunctionBegin; 5118 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 5119 PetscValidType(A, 1); 5120 PetscCheck(A->assembled, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 5121 PetscCheck(!A->factortype, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 5122 PetscCheck(A->ops->transposesymbolic, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Mat type %s", ((PetscObject)A)->type_name); 5123 PetscCall(PetscLogEventBegin(MAT_Transpose, A, 0, 0, 0)); 5124 PetscCall((*A->ops->transposesymbolic)(A, B)); 5125 PetscCall(PetscLogEventEnd(MAT_Transpose, A, 0, 0, 0)); 5126 5127 PetscCall(MatTransposeSetPrecursor(A, *B)); 5128 PetscFunctionReturn(0); 5129 } 5130 5131 PetscErrorCode MatTransposeCheckNonzeroState_Private(Mat A, Mat B) { 5132 PetscContainer rB; 5133 MatParentState *rb; 5134 5135 PetscFunctionBegin; 5136 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 5137 PetscValidType(A, 1); 5138 PetscCheck(A->assembled, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 5139 PetscCheck(!A->factortype, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 5140 PetscCall(PetscObjectQuery((PetscObject)B, "MatTransposeParent", (PetscObject *)&rB)); 5141 PetscCheck(rB, PetscObjectComm((PetscObject)B), PETSC_ERR_ARG_WRONG, "Reuse matrix used was not generated from call to MatTranspose()"); 5142 PetscCall(PetscContainerGetPointer(rB, (void **)&rb)); 5143 PetscCheck(rb->id == ((PetscObject)A)->id, PetscObjectComm((PetscObject)B), PETSC_ERR_ARG_WRONG, "Reuse matrix used was not generated from input matrix"); 5144 PetscCheck(rb->nonzerostate == A->nonzerostate, PetscObjectComm((PetscObject)B), PETSC_ERR_ARG_WRONGSTATE, "Reuse matrix has changed nonzero structure"); 5145 PetscFunctionReturn(0); 5146 } 5147 5148 /*@ 5149 MatIsTranspose - Test whether a matrix is another one's transpose, 5150 or its own, in which case it tests symmetry. 5151 5152 Collective on A 5153 5154 Input Parameters: 5155 + A - the matrix to test 5156 - B - the matrix to test against, this can equal the first parameter 5157 5158 Output Parameters: 5159 . flg - the result 5160 5161 Notes: 5162 Only available for `MATAIJ` matrices. 5163 5164 The sequential algorithm has a running time of the order of the number of nonzeros; the parallel 5165 test involves parallel copies of the block-offdiagonal parts of the matrix. 5166 5167 Level: intermediate 5168 5169 .seealso: `MatTranspose()`, `MatIsSymmetric()`, `MatIsHermitian()` 5170 @*/ 5171 PetscErrorCode MatIsTranspose(Mat A, Mat B, PetscReal tol, PetscBool *flg) { 5172 PetscErrorCode (*f)(Mat, Mat, PetscReal, PetscBool *), (*g)(Mat, Mat, PetscReal, PetscBool *); 5173 5174 PetscFunctionBegin; 5175 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 5176 PetscValidHeaderSpecific(B, MAT_CLASSID, 2); 5177 PetscValidBoolPointer(flg, 4); 5178 PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatIsTranspose_C", &f)); 5179 PetscCall(PetscObjectQueryFunction((PetscObject)B, "MatIsTranspose_C", &g)); 5180 *flg = PETSC_FALSE; 5181 if (f && g) { 5182 PetscCheck(f == g, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_NOTSAMETYPE, "Matrices do not have the same comparator for symmetry test"); 5183 PetscCall((*f)(A, B, tol, flg)); 5184 } else { 5185 MatType mattype; 5186 5187 PetscCall(MatGetType(f ? B : A, &mattype)); 5188 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Matrix of type %s does not support checking for transpose", mattype); 5189 } 5190 PetscFunctionReturn(0); 5191 } 5192 5193 /*@ 5194 MatHermitianTranspose - Computes an in-place or out-of-place Hermitian transpose of a matrix in complex conjugate. 5195 5196 Collective on mat 5197 5198 Input Parameters: 5199 + mat - the matrix to transpose and complex conjugate 5200 - reuse - either `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, or `MAT_INPLACE_MATRIX` 5201 5202 Output Parameter: 5203 . B - the Hermitian transpose 5204 5205 Level: intermediate 5206 5207 .seealso: `MatTranspose()`, `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse` 5208 @*/ 5209 PetscErrorCode MatHermitianTranspose(Mat mat, MatReuse reuse, Mat *B) { 5210 PetscFunctionBegin; 5211 PetscCall(MatTranspose(mat, reuse, B)); 5212 #if defined(PETSC_USE_COMPLEX) 5213 PetscCall(MatConjugate(*B)); 5214 #endif 5215 PetscFunctionReturn(0); 5216 } 5217 5218 /*@ 5219 MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose, 5220 5221 Collective on A 5222 5223 Input Parameters: 5224 + A - the matrix to test 5225 - B - the matrix to test against, this can equal the first parameter 5226 5227 Output Parameters: 5228 . flg - the result 5229 5230 Notes: 5231 Only available for `MATAIJ` matrices. 5232 5233 The sequential algorithm 5234 has a running time of the order of the number of nonzeros; the parallel 5235 test involves parallel copies of the block-offdiagonal parts of the matrix. 5236 5237 Level: intermediate 5238 5239 .seealso: `MatTranspose()`, `MatIsSymmetric()`, `MatIsHermitian()`, `MatIsTranspose()` 5240 @*/ 5241 PetscErrorCode MatIsHermitianTranspose(Mat A, Mat B, PetscReal tol, PetscBool *flg) { 5242 PetscErrorCode (*f)(Mat, Mat, PetscReal, PetscBool *), (*g)(Mat, Mat, PetscReal, PetscBool *); 5243 5244 PetscFunctionBegin; 5245 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 5246 PetscValidHeaderSpecific(B, MAT_CLASSID, 2); 5247 PetscValidBoolPointer(flg, 4); 5248 PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatIsHermitianTranspose_C", &f)); 5249 PetscCall(PetscObjectQueryFunction((PetscObject)B, "MatIsHermitianTranspose_C", &g)); 5250 if (f && g) { 5251 PetscCheck(f != g, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_NOTSAMETYPE, "Matrices do not have the same comparator for Hermitian test"); 5252 PetscCall((*f)(A, B, tol, flg)); 5253 } 5254 PetscFunctionReturn(0); 5255 } 5256 5257 /*@ 5258 MatPermute - Creates a new matrix with rows and columns permuted from the 5259 original. 5260 5261 Collective on mat 5262 5263 Input Parameters: 5264 + mat - the matrix to permute 5265 . row - row permutation, each processor supplies only the permutation for its rows 5266 - col - column permutation, each processor supplies only the permutation for its columns 5267 5268 Output Parameters: 5269 . B - the permuted matrix 5270 5271 Level: advanced 5272 5273 Note: 5274 The index sets map from row/col of permuted matrix to row/col of original matrix. 5275 The index sets should be on the same communicator as mat and have the same local sizes. 5276 5277 Developer Note: 5278 If you want to implement `MatPermute()` for a matrix type, and your approach doesn't 5279 exploit the fact that row and col are permutations, consider implementing the 5280 more general `MatCreateSubMatrix()` instead. 5281 5282 .seealso: `MatGetOrdering()`, `ISAllGather()`, `MatCreateSubMatrix()` 5283 @*/ 5284 PetscErrorCode MatPermute(Mat mat, IS row, IS col, Mat *B) { 5285 PetscFunctionBegin; 5286 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5287 PetscValidType(mat, 1); 5288 PetscValidHeaderSpecific(row, IS_CLASSID, 2); 5289 PetscValidHeaderSpecific(col, IS_CLASSID, 3); 5290 PetscValidPointer(B, 4); 5291 PetscCheckSameComm(mat, 1, row, 2); 5292 if (row != col) PetscCheckSameComm(row, 2, col, 3); 5293 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 5294 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 5295 PetscCheck(mat->ops->permute || mat->ops->createsubmatrix, PETSC_COMM_SELF, PETSC_ERR_SUP, "MatPermute not available for Mat type %s", ((PetscObject)mat)->type_name); 5296 MatCheckPreallocated(mat, 1); 5297 5298 if (mat->ops->permute) { 5299 PetscUseTypeMethod(mat, permute, row, col, B); 5300 PetscCall(PetscObjectStateIncrease((PetscObject)*B)); 5301 } else { 5302 PetscCall(MatCreateSubMatrix(mat, row, col, MAT_INITIAL_MATRIX, B)); 5303 } 5304 PetscFunctionReturn(0); 5305 } 5306 5307 /*@ 5308 MatEqual - Compares two matrices. 5309 5310 Collective on A 5311 5312 Input Parameters: 5313 + A - the first matrix 5314 - B - the second matrix 5315 5316 Output Parameter: 5317 . flg - `PETSC_TRUE` if the matrices are equal; `PETSC_FALSE` otherwise. 5318 5319 Level: intermediate 5320 5321 .seealso: `Mat` 5322 @*/ 5323 PetscErrorCode MatEqual(Mat A, Mat B, PetscBool *flg) { 5324 PetscFunctionBegin; 5325 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 5326 PetscValidHeaderSpecific(B, MAT_CLASSID, 2); 5327 PetscValidType(A, 1); 5328 PetscValidType(B, 2); 5329 PetscValidBoolPointer(flg, 3); 5330 PetscCheckSameComm(A, 1, B, 2); 5331 MatCheckPreallocated(A, 1); 5332 MatCheckPreallocated(B, 2); 5333 PetscCheck(A->assembled, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 5334 PetscCheck(B->assembled, PetscObjectComm((PetscObject)B), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 5335 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, 5336 B->cmap->N); 5337 if (A->ops->equal && A->ops->equal == B->ops->equal) { 5338 PetscUseTypeMethod(A, equal, B, flg); 5339 } else { 5340 PetscCall(MatMultEqual(A, B, 10, flg)); 5341 } 5342 PetscFunctionReturn(0); 5343 } 5344 5345 /*@ 5346 MatDiagonalScale - Scales a matrix on the left and right by diagonal 5347 matrices that are stored as vectors. Either of the two scaling 5348 matrices can be NULL. 5349 5350 Collective on mat 5351 5352 Input Parameters: 5353 + mat - the matrix to be scaled 5354 . l - the left scaling vector (or NULL) 5355 - r - the right scaling vector (or NULL) 5356 5357 Note: 5358 `MatDiagonalScale()` computes A = LAR, where 5359 L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector) 5360 The L scales the rows of the matrix, the R scales the columns of the matrix. 5361 5362 Level: intermediate 5363 5364 .seealso: `Mat`, `MatScale()`, `MatShift()`, `MatDiagonalSet()` 5365 @*/ 5366 PetscErrorCode MatDiagonalScale(Mat mat, Vec l, Vec r) { 5367 PetscFunctionBegin; 5368 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5369 PetscValidType(mat, 1); 5370 if (l) { 5371 PetscValidHeaderSpecific(l, VEC_CLASSID, 2); 5372 PetscCheckSameComm(mat, 1, l, 2); 5373 } 5374 if (r) { 5375 PetscValidHeaderSpecific(r, VEC_CLASSID, 3); 5376 PetscCheckSameComm(mat, 1, r, 3); 5377 } 5378 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 5379 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 5380 MatCheckPreallocated(mat, 1); 5381 if (!l && !r) PetscFunctionReturn(0); 5382 5383 PetscCall(PetscLogEventBegin(MAT_Scale, mat, 0, 0, 0)); 5384 PetscUseTypeMethod(mat, diagonalscale, l, r); 5385 PetscCall(PetscLogEventEnd(MAT_Scale, mat, 0, 0, 0)); 5386 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5387 if (l != r) mat->symmetric = PETSC_BOOL3_FALSE; 5388 PetscFunctionReturn(0); 5389 } 5390 5391 /*@ 5392 MatScale - Scales all elements of a matrix by a given number. 5393 5394 Logically Collective on mat 5395 5396 Input Parameters: 5397 + mat - the matrix to be scaled 5398 - a - the scaling value 5399 5400 Output Parameter: 5401 . mat - the scaled matrix 5402 5403 Level: intermediate 5404 5405 .seealso: `Mat`, `MatDiagonalScale()` 5406 @*/ 5407 PetscErrorCode MatScale(Mat mat, PetscScalar a) { 5408 PetscFunctionBegin; 5409 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5410 PetscValidType(mat, 1); 5411 PetscCheck(a == (PetscScalar)1.0 || mat->ops->scale, PETSC_COMM_SELF, PETSC_ERR_SUP, "Mat type %s", ((PetscObject)mat)->type_name); 5412 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 5413 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 5414 PetscValidLogicalCollectiveScalar(mat, a, 2); 5415 MatCheckPreallocated(mat, 1); 5416 5417 PetscCall(PetscLogEventBegin(MAT_Scale, mat, 0, 0, 0)); 5418 if (a != (PetscScalar)1.0) { 5419 PetscUseTypeMethod(mat, scale, a); 5420 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5421 } 5422 PetscCall(PetscLogEventEnd(MAT_Scale, mat, 0, 0, 0)); 5423 PetscFunctionReturn(0); 5424 } 5425 5426 /*@ 5427 MatNorm - Calculates various norms of a matrix. 5428 5429 Collective on mat 5430 5431 Input Parameters: 5432 + mat - the matrix 5433 - type - the type of norm, `NORM_1`, `NORM_FROBENIUS`, `NORM_INFINITY` 5434 5435 Output Parameter: 5436 . nrm - the resulting norm 5437 5438 Level: intermediate 5439 5440 .seealso: `Mat` 5441 @*/ 5442 PetscErrorCode MatNorm(Mat mat, NormType type, PetscReal *nrm) { 5443 PetscFunctionBegin; 5444 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5445 PetscValidType(mat, 1); 5446 PetscValidRealPointer(nrm, 3); 5447 5448 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 5449 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 5450 MatCheckPreallocated(mat, 1); 5451 5452 PetscUseTypeMethod(mat, norm, type, nrm); 5453 PetscFunctionReturn(0); 5454 } 5455 5456 /* 5457 This variable is used to prevent counting of MatAssemblyBegin() that 5458 are called from within a MatAssemblyEnd(). 5459 */ 5460 static PetscInt MatAssemblyEnd_InUse = 0; 5461 /*@ 5462 MatAssemblyBegin - Begins assembling the matrix. This routine should 5463 be called after completing all calls to `MatSetValues()`. 5464 5465 Collective on mat 5466 5467 Input Parameters: 5468 + mat - the matrix 5469 - type - type of assembly, either `MAT_FLUSH_ASSEMBLY` or `MAT_FINAL_ASSEMBLY` 5470 5471 Notes: 5472 `MatSetValues()` generally caches the values that belong to other MPI ranks. The matrix is ready to 5473 use only after `MatAssemblyBegin()` and `MatAssemblyEnd()` have been called. 5474 5475 Use `MAT_FLUSH_ASSEMBLY` when switching between `ADD_VALUES` and `INSERT_VALUES` 5476 in `MatSetValues()`; use `MAT_FINAL_ASSEMBLY` for the final assembly before 5477 using the matrix. 5478 5479 ALL processes that share a matrix MUST call `MatAssemblyBegin()` and `MatAssemblyEnd()` the SAME NUMBER of times, and each time with the 5480 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 5481 a global collective operation requring all processes that share the matrix. 5482 5483 Space for preallocated nonzeros that is not filled by a call to `MatSetValues()` or a related routine are compressed 5484 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5485 before `MAT_FINAL_ASSEMBLY` so the space is not compressed out. 5486 5487 Level: beginner 5488 5489 .seealso: `Mat`, `MatAssemblyEnd()`, `MatSetValues()`, `MatAssembled()` 5490 @*/ 5491 PetscErrorCode MatAssemblyBegin(Mat mat, MatAssemblyType type) { 5492 PetscFunctionBegin; 5493 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5494 PetscValidType(mat, 1); 5495 MatCheckPreallocated(mat, 1); 5496 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix.\nDid you forget to call MatSetUnfactored()?"); 5497 if (mat->assembled) { 5498 mat->was_assembled = PETSC_TRUE; 5499 mat->assembled = PETSC_FALSE; 5500 } 5501 5502 if (!MatAssemblyEnd_InUse) { 5503 PetscCall(PetscLogEventBegin(MAT_AssemblyBegin, mat, 0, 0, 0)); 5504 PetscTryTypeMethod(mat, assemblybegin, type); 5505 PetscCall(PetscLogEventEnd(MAT_AssemblyBegin, mat, 0, 0, 0)); 5506 } else PetscTryTypeMethod(mat, assemblybegin, type); 5507 PetscFunctionReturn(0); 5508 } 5509 5510 /*@ 5511 MatAssembled - Indicates if a matrix has been assembled and is ready for 5512 use; for example, in matrix-vector product. 5513 5514 Not Collective 5515 5516 Input Parameter: 5517 . mat - the matrix 5518 5519 Output Parameter: 5520 . assembled - `PETSC_TRUE` or `PETSC_FALSE` 5521 5522 Level: advanced 5523 5524 .seealso: `Mat`, `MatAssemblyEnd()`, `MatSetValues()`, `MatAssemblyBegin()` 5525 @*/ 5526 PetscErrorCode MatAssembled(Mat mat, PetscBool *assembled) { 5527 PetscFunctionBegin; 5528 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5529 PetscValidBoolPointer(assembled, 2); 5530 *assembled = mat->assembled; 5531 PetscFunctionReturn(0); 5532 } 5533 5534 /*@ 5535 MatAssemblyEnd - Completes assembling the matrix. This routine should 5536 be called after `MatAssemblyBegin()`. 5537 5538 Collective on Mat 5539 5540 Input Parameters: 5541 + mat - the matrix 5542 - type - type of assembly, either `MAT_FLUSH_ASSEMBLY` or `MAT_FINAL_ASSEMBLY` 5543 5544 Options Database Keys: 5545 + -mat_view ::ascii_info - Prints info on matrix at conclusion of `MatEndAssembly()` 5546 . -mat_view ::ascii_info_detail - Prints more detailed info 5547 . -mat_view - Prints matrix in ASCII format 5548 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 5549 . -mat_view draw - draws nonzero structure of matrix, using `MatView()` and `PetscDrawOpenX()`. 5550 . -display <name> - Sets display name (default is host) 5551 . -draw_pause <sec> - Sets number of seconds to pause after display 5552 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab) 5553 . -viewer_socket_machine <machine> - Machine to use for socket 5554 . -viewer_socket_port <port> - Port number to use for socket 5555 - -mat_view binary:filename[:append] - Save matrix to file in binary format 5556 5557 Level: beginner 5558 5559 .seealso: `Mat`, `MatAssemblyBegin()`, `MatSetValues()`, `PetscDrawOpenX()`, `PetscDrawCreate()`, `MatView()`, `MatAssembled()`, `PetscViewerSocketOpen()` 5560 @*/ 5561 PetscErrorCode MatAssemblyEnd(Mat mat, MatAssemblyType type) { 5562 static PetscInt inassm = 0; 5563 PetscBool flg = PETSC_FALSE; 5564 5565 PetscFunctionBegin; 5566 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5567 PetscValidType(mat, 1); 5568 5569 inassm++; 5570 MatAssemblyEnd_InUse++; 5571 if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */ 5572 PetscCall(PetscLogEventBegin(MAT_AssemblyEnd, mat, 0, 0, 0)); 5573 PetscTryTypeMethod(mat, assemblyend, type); 5574 PetscCall(PetscLogEventEnd(MAT_AssemblyEnd, mat, 0, 0, 0)); 5575 } else PetscTryTypeMethod(mat, assemblyend, type); 5576 5577 /* Flush assembly is not a true assembly */ 5578 if (type != MAT_FLUSH_ASSEMBLY) { 5579 if (mat->num_ass) { 5580 if (!mat->symmetry_eternal) { 5581 mat->symmetric = PETSC_BOOL3_UNKNOWN; 5582 mat->hermitian = PETSC_BOOL3_UNKNOWN; 5583 } 5584 if (!mat->structural_symmetry_eternal && mat->ass_nonzerostate != mat->nonzerostate) mat->structurally_symmetric = PETSC_BOOL3_UNKNOWN; 5585 if (!mat->spd_eternal) mat->spd = PETSC_BOOL3_UNKNOWN; 5586 } 5587 mat->num_ass++; 5588 mat->assembled = PETSC_TRUE; 5589 mat->ass_nonzerostate = mat->nonzerostate; 5590 } 5591 5592 mat->insertmode = NOT_SET_VALUES; 5593 MatAssemblyEnd_InUse--; 5594 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5595 if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) { 5596 PetscCall(MatViewFromOptions(mat, NULL, "-mat_view")); 5597 5598 if (mat->checksymmetryonassembly) { 5599 PetscCall(MatIsSymmetric(mat, mat->checksymmetrytol, &flg)); 5600 if (flg) { 5601 PetscCall(PetscPrintf(PetscObjectComm((PetscObject)mat), "Matrix is symmetric (tolerance %g)\n", (double)mat->checksymmetrytol)); 5602 } else { 5603 PetscCall(PetscPrintf(PetscObjectComm((PetscObject)mat), "Matrix is not symmetric (tolerance %g)\n", (double)mat->checksymmetrytol)); 5604 } 5605 } 5606 if (mat->nullsp && mat->checknullspaceonassembly) PetscCall(MatNullSpaceTest(mat->nullsp, mat, NULL)); 5607 } 5608 inassm--; 5609 PetscFunctionReturn(0); 5610 } 5611 5612 /*@ 5613 MatSetOption - Sets a parameter option for a matrix. Some options 5614 may be specific to certain storage formats. Some options 5615 determine how values will be inserted (or added). Sorted, 5616 row-oriented input will generally assemble the fastest. The default 5617 is row-oriented. 5618 5619 Logically Collective on mat for certain operations, such as `MAT_SPD`, not collective for `MAT_ROW_ORIENTED`, see `MatOption` 5620 5621 Input Parameters: 5622 + mat - the matrix 5623 . option - the option, one of those listed below (and possibly others), 5624 - flg - turn the option on (`PETSC_TRUE`) or off (`PETSC_FALSE`) 5625 5626 Options Describing Matrix Structure: 5627 + `MAT_SPD` - symmetric positive definite 5628 . `MAT_SYMMETRIC` - symmetric in terms of both structure and value 5629 . `MAT_HERMITIAN` - transpose is the complex conjugation 5630 . `MAT_STRUCTURALLY_SYMMETRIC` - symmetric nonzero structure 5631 . `MAT_SYMMETRY_ETERNAL` - indicates the symmetry (or Hermitian structure) or its absence will persist through any changes to the matrix 5632 . `MAT_STRUCTURAL_SYMMETRY_ETERNAL` - indicates the structural symmetry or its absence will persist through any changes to the matrix 5633 - `MAT_SPD_ETERNAL` - indicates the value of `MAT_SPD` (true or false) will persist through any changes to the matrix 5634 5635 These are not really options of the matrix, they are knowledge about the structure of the matrix that users may provide so that they 5636 do not need to be computed (usually at a high cost) 5637 5638 Options For Use with `MatSetValues()`: 5639 Insert a logically dense subblock, which can be 5640 . `MAT_ROW_ORIENTED` - row-oriented (default) 5641 5642 Note these options reflect the data you pass in with `MatSetValues()`; it has 5643 nothing to do with how the data is stored internally in the matrix 5644 data structure. 5645 5646 When (re)assembling a matrix, we can restrict the input for 5647 efficiency/debugging purposes. These options include 5648 + `MAT_NEW_NONZERO_LOCATIONS` - additional insertions will be allowed if they generate a new nonzero (slow) 5649 . `MAT_FORCE_DIAGONAL_ENTRIES` - forces diagonal entries to be allocated 5650 . `MAT_IGNORE_OFF_PROC_ENTRIES` - drops off-processor entries 5651 . `MAT_NEW_NONZERO_LOCATION_ERR` - generates an error for new matrix entry 5652 . `MAT_USE_HASH_TABLE` - uses a hash table to speed up matrix assembly 5653 . `MAT_NO_OFF_PROC_ENTRIES` - you know each process will only set values for its own rows, will generate an error if 5654 any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves 5655 performance for very large process counts. 5656 - `MAT_SUBSET_OFF_PROC_ENTRIES` - you know that the first assembly after setting this flag will set a superset 5657 of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly 5658 functions, instead sending only neighbor messages. 5659 5660 Notes: 5661 Except for `MAT_UNUSED_NONZERO_LOCATION_ERR` and `MAT_ROW_ORIENTED` all processes that share the matrix must pass the same value in flg! 5662 5663 Some options are relevant only for particular matrix types and 5664 are thus ignored by others. Other options are not supported by 5665 certain matrix types and will generate an error message if set. 5666 5667 If using a Fortran 77 module to compute a matrix, one may need to 5668 use the column-oriented option (or convert to the row-oriented 5669 format). 5670 5671 `MAT_NEW_NONZERO_LOCATIONS` set to `PETSC_FALSE` indicates that any add or insertion 5672 that would generate a new entry in the nonzero structure is instead 5673 ignored. Thus, if memory has not alredy been allocated for this particular 5674 data, then the insertion is ignored. For dense matrices, in which 5675 the entire array is allocated, no entries are ever ignored. 5676 Set after the first `MatAssemblyEnd()`. If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5677 5678 `MAT_NEW_NONZERO_LOCATION_ERR` set to PETSC_TRUE indicates that any add or insertion 5679 that would generate a new entry in the nonzero structure instead produces 5680 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 5681 5682 `MAT_NEW_NONZERO_ALLOCATION_ERR` set to `PETSC_TRUE` indicates that any add or insertion 5683 that would generate a new entry that has not been preallocated will 5684 instead produce an error. (Currently supported for `MATAIJ` and `MATBAIJ` formats 5685 only.) This is a useful flag when debugging matrix memory preallocation. 5686 If this option is set then the `MatAssemblyBegin()`/`MatAssemblyEnd()` processes has one less global reduction 5687 5688 `MAT_IGNORE_OFF_PROC_ENTRIES` set to `PETSC_TRUE` indicates entries destined for 5689 other processors should be dropped, rather than stashed. 5690 This is useful if you know that the "owning" processor is also 5691 always generating the correct matrix entries, so that PETSc need 5692 not transfer duplicate entries generated on another processor. 5693 5694 `MAT_USE_HASH_TABLE` indicates that a hash table be used to improve the 5695 searches during matrix assembly. When this flag is set, the hash table 5696 is created during the first matrix assembly. This hash table is 5697 used the next time through, during `MatSetVaules()`/`MatSetVaulesBlocked()` 5698 to improve the searching of indices. `MAT_NEW_NONZERO_LOCATIONS` flag 5699 should be used with `MAT_USE_HASH_TABLE` flag. This option is currently 5700 supported by` MATMPIBAIJ` format only. 5701 5702 `MAT_KEEP_NONZERO_PATTERN` indicates when `MatZeroRows()` is called the zeroed entries 5703 are kept in the nonzero structure 5704 5705 `MAT_IGNORE_ZERO_ENTRIES` - for `MATAIJ` and `MATIS` matrices this will stop zero values from creating 5706 a zero location in the matrix 5707 5708 `MAT_USE_INODES` - indicates using inode version of the code - works with `MATAIJ` matrix types 5709 5710 `MAT_NO_OFF_PROC_ZERO_ROWS` - you know each process will only zero its own rows. This avoids all reductions in the 5711 zero row routines and thus improves performance for very large process counts. 5712 5713 `MAT_IGNORE_LOWER_TRIANGULAR` - For `MATSBAIJ` matrices will ignore any insertions you make in the lower triangular 5714 part of the matrix (since they should match the upper triangular part). 5715 5716 `MAT_SORTED_FULL` - each process provides exactly its local rows; all column indices for a given row are passed in a 5717 single call to `MatSetValues()`, preallocation is perfect, row oriented, `INSERT_VALUES` is used. Common 5718 with finite difference schemes with non-periodic boundary conditions. 5719 5720 Developer Note: 5721 `MAT_SYMMETRY_ETERNAL`, `MAT_STRUCTURAL_SYMMETRY_ETERNAL`, and `MAT_SPD_ETERNAL` are used by `MatAssemblyEnd()` and in other 5722 places where otherwise the value of `MAT_SYMMETRIC`, `MAT_STRUCTURAL_SYMMETRIC` or `MAT_SPD` would need to be changed back 5723 to `PETSC_BOOL3_UNKNOWN` because the matrix values had changed so the code cannot be certain that the related property had 5724 not changed. 5725 5726 Level: intermediate 5727 5728 .seealso: `MatOption`, `Mat`, `MatGetOption()` 5729 @*/ 5730 PetscErrorCode MatSetOption(Mat mat, MatOption op, PetscBool flg) { 5731 PetscFunctionBegin; 5732 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5733 if (op > 0) { 5734 PetscValidLogicalCollectiveEnum(mat, op, 2); 5735 PetscValidLogicalCollectiveBool(mat, flg, 3); 5736 } 5737 5738 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); 5739 5740 switch (op) { 5741 case MAT_FORCE_DIAGONAL_ENTRIES: mat->force_diagonals = flg; PetscFunctionReturn(0); 5742 case MAT_NO_OFF_PROC_ENTRIES: mat->nooffprocentries = flg; PetscFunctionReturn(0); 5743 case MAT_SUBSET_OFF_PROC_ENTRIES: 5744 mat->assembly_subset = flg; 5745 if (!mat->assembly_subset) { /* See the same logic in VecAssembly wrt VEC_SUBSET_OFF_PROC_ENTRIES */ 5746 #if !defined(PETSC_HAVE_MPIUNI) 5747 PetscCall(MatStashScatterDestroy_BTS(&mat->stash)); 5748 #endif 5749 mat->stash.first_assembly_done = PETSC_FALSE; 5750 } 5751 PetscFunctionReturn(0); 5752 case MAT_NO_OFF_PROC_ZERO_ROWS: mat->nooffproczerorows = flg; PetscFunctionReturn(0); 5753 case MAT_SPD: 5754 if (flg) { 5755 mat->spd = PETSC_BOOL3_TRUE; 5756 mat->symmetric = PETSC_BOOL3_TRUE; 5757 mat->structurally_symmetric = PETSC_BOOL3_TRUE; 5758 } else { 5759 mat->spd = PETSC_BOOL3_FALSE; 5760 } 5761 break; 5762 case MAT_SYMMETRIC: 5763 mat->symmetric = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5764 if (flg) mat->structurally_symmetric = PETSC_BOOL3_TRUE; 5765 #if !defined(PETSC_USE_COMPLEX) 5766 mat->hermitian = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5767 #endif 5768 break; 5769 case MAT_HERMITIAN: 5770 mat->hermitian = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5771 if (flg) mat->structurally_symmetric = PETSC_BOOL3_TRUE; 5772 #if !defined(PETSC_USE_COMPLEX) 5773 mat->symmetric = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5774 #endif 5775 break; 5776 case MAT_STRUCTURALLY_SYMMETRIC: mat->structurally_symmetric = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; break; 5777 case MAT_SYMMETRY_ETERNAL: 5778 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"); 5779 mat->symmetry_eternal = flg; 5780 if (flg) mat->structural_symmetry_eternal = PETSC_TRUE; 5781 break; 5782 case MAT_STRUCTURAL_SYMMETRY_ETERNAL: 5783 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"); 5784 mat->structural_symmetry_eternal = flg; 5785 break; 5786 case MAT_SPD_ETERNAL: 5787 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"); 5788 mat->spd_eternal = flg; 5789 if (flg) { 5790 mat->structural_symmetry_eternal = PETSC_TRUE; 5791 mat->symmetry_eternal = PETSC_TRUE; 5792 } 5793 break; 5794 case MAT_STRUCTURE_ONLY: mat->structure_only = flg; break; 5795 case MAT_SORTED_FULL: mat->sortedfull = flg; break; 5796 default: break; 5797 } 5798 PetscTryTypeMethod(mat, setoption, op, flg); 5799 PetscFunctionReturn(0); 5800 } 5801 5802 /*@ 5803 MatGetOption - Gets a parameter option that has been set for a matrix. 5804 5805 Logically Collective on mat 5806 5807 Input Parameters: 5808 + mat - the matrix 5809 - option - the option, this only responds to certain options, check the code for which ones 5810 5811 Output Parameter: 5812 . flg - turn the option on (`PETSC_TRUE`) or off (`PETSC_FALSE`) 5813 5814 Notes: 5815 Can only be called after `MatSetSizes()` and `MatSetType()` have been set. 5816 5817 Certain option values may be unknown, for those use the routines `MatIsSymmetric()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, or 5818 `MatIsSymmetricKnown()`, `MatIsHermitianKnown()`, `MatIsStructurallySymmetricKnown()` 5819 5820 Level: intermediate 5821 5822 .seealso: `MatOption`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, 5823 `MatIsSymmetricKnown()`, `MatIsHermitianKnown()`, `MatIsStructurallySymmetricKnown()` 5824 @*/ 5825 PetscErrorCode MatGetOption(Mat mat, MatOption op, PetscBool *flg) { 5826 PetscFunctionBegin; 5827 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5828 PetscValidType(mat, 1); 5829 5830 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); 5831 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()"); 5832 5833 switch (op) { 5834 case MAT_NO_OFF_PROC_ENTRIES: *flg = mat->nooffprocentries; break; 5835 case MAT_NO_OFF_PROC_ZERO_ROWS: *flg = mat->nooffproczerorows; break; 5836 case MAT_SYMMETRIC: SETERRQ(PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Use MatIsSymmetric() or MatIsSymmetricKnown()"); break; 5837 case MAT_HERMITIAN: SETERRQ(PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Use MatIsHermitian() or MatIsHermitianKnown()"); break; 5838 case MAT_STRUCTURALLY_SYMMETRIC: SETERRQ(PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Use MatIsStructurallySymmetric() or MatIsStructurallySymmetricKnown()"); break; 5839 case MAT_SPD: SETERRQ(PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Use MatIsSPDKnown()"); break; 5840 case MAT_SYMMETRY_ETERNAL: *flg = mat->symmetry_eternal; break; 5841 case MAT_STRUCTURAL_SYMMETRY_ETERNAL: *flg = mat->symmetry_eternal; break; 5842 default: break; 5843 } 5844 PetscFunctionReturn(0); 5845 } 5846 5847 /*@ 5848 MatZeroEntries - Zeros all entries of a matrix. For sparse matrices 5849 this routine retains the old nonzero structure. 5850 5851 Logically Collective on mat 5852 5853 Input Parameters: 5854 . mat - the matrix 5855 5856 Level: intermediate 5857 5858 Note: 5859 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. 5860 See the Performance chapter of the users manual for information on preallocating matrices. 5861 5862 .seealso: `Mat`, `MatZeroRows()`, `MatZeroRowsColumns()` 5863 @*/ 5864 PetscErrorCode MatZeroEntries(Mat mat) { 5865 PetscFunctionBegin; 5866 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5867 PetscValidType(mat, 1); 5868 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 5869 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"); 5870 MatCheckPreallocated(mat, 1); 5871 5872 PetscCall(PetscLogEventBegin(MAT_ZeroEntries, mat, 0, 0, 0)); 5873 PetscUseTypeMethod(mat, zeroentries); 5874 PetscCall(PetscLogEventEnd(MAT_ZeroEntries, mat, 0, 0, 0)); 5875 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5876 PetscFunctionReturn(0); 5877 } 5878 5879 /*@ 5880 MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal) 5881 of a set of rows and columns of a matrix. 5882 5883 Collective on mat 5884 5885 Input Parameters: 5886 + mat - the matrix 5887 . numRows - the number of rows to remove 5888 . rows - the global row indices 5889 . diag - value put in the diagonal of the eliminated rows 5890 . x - optional vector of solutions for zeroed rows (other entries in vector are not used), these must be set before this call 5891 - b - optional vector of right hand side, that will be adjusted by provided solution 5892 5893 Notes: 5894 This routine, along with `MatZeroRows()`, is typically used to eliminate known Dirichlet boundary conditions from a linear system. 5895 5896 For each zeroed row, the value of the corresponding b is set to diag times the value of the corresponding x. 5897 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 5898 5899 If the resulting linear system is to be solved with `KSP` then one can (but does not have to) call `KSPSetInitialGuessNonzero()` to allow the 5900 Krylov method to take advantage of the known solution on the zeroed rows. 5901 5902 For the parallel case, all processes that share the matrix (i.e., 5903 those in the communicator used for matrix creation) MUST call this 5904 routine, regardless of whether any rows being zeroed are owned by 5905 them. 5906 5907 Unlike `MatZeroRows()` this does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5908 5909 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5910 list only rows local to itself). 5911 5912 The option `MAT_NO_OFF_PROC_ZERO_ROWS` does not apply to this routine. 5913 5914 Level: intermediate 5915 5916 .seealso: `MatZeroRowsIS()`, `MatZeroRows()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 5917 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 5918 @*/ 5919 PetscErrorCode MatZeroRowsColumns(Mat mat, PetscInt numRows, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) { 5920 PetscFunctionBegin; 5921 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5922 PetscValidType(mat, 1); 5923 if (numRows) PetscValidIntPointer(rows, 3); 5924 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 5925 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 5926 MatCheckPreallocated(mat, 1); 5927 5928 PetscUseTypeMethod(mat, zerorowscolumns, numRows, rows, diag, x, b); 5929 PetscCall(MatViewFromOptions(mat, NULL, "-mat_view")); 5930 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5931 PetscFunctionReturn(0); 5932 } 5933 5934 /*@ 5935 MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal) 5936 of a set of rows and columns of a matrix. 5937 5938 Collective on mat 5939 5940 Input Parameters: 5941 + mat - the matrix 5942 . is - the rows to zero 5943 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5944 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5945 - b - optional vector of right hand side, that will be adjusted by provided solution 5946 5947 Note: 5948 See `MatZeroRowsColumns()` for details on how this routine operates. 5949 5950 Level: intermediate 5951 5952 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 5953 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRows()`, `MatZeroRowsColumnsStencil()` 5954 @*/ 5955 PetscErrorCode MatZeroRowsColumnsIS(Mat mat, IS is, PetscScalar diag, Vec x, Vec b) { 5956 PetscInt numRows; 5957 const PetscInt *rows; 5958 5959 PetscFunctionBegin; 5960 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5961 PetscValidHeaderSpecific(is, IS_CLASSID, 2); 5962 PetscValidType(mat, 1); 5963 PetscValidType(is, 2); 5964 PetscCall(ISGetLocalSize(is, &numRows)); 5965 PetscCall(ISGetIndices(is, &rows)); 5966 PetscCall(MatZeroRowsColumns(mat, numRows, rows, diag, x, b)); 5967 PetscCall(ISRestoreIndices(is, &rows)); 5968 PetscFunctionReturn(0); 5969 } 5970 5971 /*@ 5972 MatZeroRows - Zeros all entries (except possibly the main diagonal) 5973 of a set of rows of a matrix. 5974 5975 Collective on mat 5976 5977 Input Parameters: 5978 + mat - the matrix 5979 . numRows - the number of rows to remove 5980 . rows - the global row indices 5981 . diag - value put in the diagonal of the eliminated rows 5982 . x - optional vector of solutions for zeroed rows (other entries in vector are not used), these must be set before this call 5983 - b - optional vector of right hand side, that will be adjusted by provided solution 5984 5985 Notes: 5986 This routine, along with `MatZeroRowsColumns()`, is typically used to eliminate known Dirichlet boundary conditions from a linear system. 5987 5988 For each zeroed row, the value of the corresponding b is set to diag times the value of the corresponding x. 5989 5990 If the resulting linear system is to be solved with `KSP` then one can (but does not have to) call `KSPSetInitialGuessNonzero()` to allow the 5991 Krylov method to take advantage of the known solution on the zeroed rows. 5992 5993 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) 5994 from the matrix. 5995 5996 Unlike `MatZeroRowsColumns()` for the `MATAIJ` and `MATBAIJ` matrix formats this removes the old nonzero structure, from the eliminated rows of the matrix 5997 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 5998 formats this does not alter the nonzero structure. 5999 6000 If the option `MatSetOption`(mat,`MAT_KEEP_NONZERO_PATTERN`,`PETSC_TRUE`) the nonzero structure 6001 of the matrix is not changed the values are 6002 merely zeroed. 6003 6004 The user can set a value in the diagonal entry (or for the `MATAIJ` format 6005 formats can optionally remove the main diagonal entry from the 6006 nonzero structure as well, by passing 0.0 as the final argument). 6007 6008 For the parallel case, all processes that share the matrix (i.e., 6009 those in the communicator used for matrix creation) MUST call this 6010 routine, regardless of whether any rows being zeroed are owned by 6011 them. 6012 6013 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6014 list only rows local to itself). 6015 6016 You can call `MatSetOption`(mat,`MAT_NO_OFF_PROC_ZERO_ROWS`,`PETSC_TRUE`) if each process indicates only rows it 6017 owns that are to be zeroed. This saves a global synchronization in the implementation. 6018 6019 Level: intermediate 6020 6021 .seealso: `Mat`, `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6022 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()`, `PCREDISTRIBUTE` 6023 @*/ 6024 PetscErrorCode MatZeroRows(Mat mat, PetscInt numRows, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) { 6025 PetscFunctionBegin; 6026 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6027 PetscValidType(mat, 1); 6028 if (numRows) PetscValidIntPointer(rows, 3); 6029 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 6030 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 6031 MatCheckPreallocated(mat, 1); 6032 6033 PetscUseTypeMethod(mat, zerorows, numRows, rows, diag, x, b); 6034 PetscCall(MatViewFromOptions(mat, NULL, "-mat_view")); 6035 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6036 PetscFunctionReturn(0); 6037 } 6038 6039 /*@ 6040 MatZeroRowsIS - Zeros all entries (except possibly the main diagonal) 6041 of a set of rows of a matrix. 6042 6043 Collective on Mat 6044 6045 Input Parameters: 6046 + mat - the matrix 6047 . is - index set of rows to remove (if NULL then no row is removed) 6048 . diag - value put in all diagonals of eliminated rows 6049 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6050 - b - optional vector of right hand side, that will be adjusted by provided solution 6051 6052 Note: 6053 See `MatZeroRows()` for details on how this routine operates. 6054 6055 Level: intermediate 6056 6057 .seealso: `MatZeroRows()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6058 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6059 @*/ 6060 PetscErrorCode MatZeroRowsIS(Mat mat, IS is, PetscScalar diag, Vec x, Vec b) { 6061 PetscInt numRows = 0; 6062 const PetscInt *rows = NULL; 6063 6064 PetscFunctionBegin; 6065 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6066 PetscValidType(mat, 1); 6067 if (is) { 6068 PetscValidHeaderSpecific(is, IS_CLASSID, 2); 6069 PetscCall(ISGetLocalSize(is, &numRows)); 6070 PetscCall(ISGetIndices(is, &rows)); 6071 } 6072 PetscCall(MatZeroRows(mat, numRows, rows, diag, x, b)); 6073 if (is) PetscCall(ISRestoreIndices(is, &rows)); 6074 PetscFunctionReturn(0); 6075 } 6076 6077 /*@ 6078 MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal) 6079 of a set of rows of a matrix. These rows must be local to the process. 6080 6081 Collective on mat 6082 6083 Input Parameters: 6084 + mat - the matrix 6085 . numRows - the number of rows to remove 6086 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 6087 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6088 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6089 - b - optional vector of right hand side, that will be adjusted by provided solution 6090 6091 Notes: 6092 See `MatZeroRows()` for details on how this routine operates. 6093 6094 The grid coordinates are across the entire grid, not just the local portion 6095 6096 In Fortran idxm and idxn should be declared as 6097 $ MatStencil idxm(4,m) 6098 and the values inserted using 6099 $ idxm(MatStencil_i,1) = i 6100 $ idxm(MatStencil_j,1) = j 6101 $ idxm(MatStencil_k,1) = k 6102 $ idxm(MatStencil_c,1) = c 6103 etc 6104 6105 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6106 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6107 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6108 `DM_BOUNDARY_PERIODIC` boundary type. 6109 6110 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 6111 a single value per point) you can skip filling those indices. 6112 6113 Level: intermediate 6114 6115 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsl()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6116 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6117 @*/ 6118 PetscErrorCode MatZeroRowsStencil(Mat mat, PetscInt numRows, const MatStencil rows[], PetscScalar diag, Vec x, Vec b) { 6119 PetscInt dim = mat->stencil.dim; 6120 PetscInt sdim = dim - (1 - (PetscInt)mat->stencil.noc); 6121 PetscInt *dims = mat->stencil.dims + 1; 6122 PetscInt *starts = mat->stencil.starts; 6123 PetscInt *dxm = (PetscInt *)rows; 6124 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6125 6126 PetscFunctionBegin; 6127 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6128 PetscValidType(mat, 1); 6129 if (numRows) PetscValidPointer(rows, 3); 6130 6131 PetscCall(PetscMalloc1(numRows, &jdxm)); 6132 for (i = 0; i < numRows; ++i) { 6133 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6134 for (j = 0; j < 3 - sdim; ++j) dxm++; 6135 /* Local index in X dir */ 6136 tmp = *dxm++ - starts[0]; 6137 /* Loop over remaining dimensions */ 6138 for (j = 0; j < dim - 1; ++j) { 6139 /* If nonlocal, set index to be negative */ 6140 if ((*dxm++ - starts[j + 1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6141 /* Update local index */ 6142 else tmp = tmp * dims[j] + *(dxm - 1) - starts[j + 1]; 6143 } 6144 /* Skip component slot if necessary */ 6145 if (mat->stencil.noc) dxm++; 6146 /* Local row number */ 6147 if (tmp >= 0) jdxm[numNewRows++] = tmp; 6148 } 6149 PetscCall(MatZeroRowsLocal(mat, numNewRows, jdxm, diag, x, b)); 6150 PetscCall(PetscFree(jdxm)); 6151 PetscFunctionReturn(0); 6152 } 6153 6154 /*@ 6155 MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal) 6156 of a set of rows and columns of a matrix. 6157 6158 Collective on mat 6159 6160 Input Parameters: 6161 + mat - the matrix 6162 . numRows - the number of rows/columns to remove 6163 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 6164 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6165 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6166 - b - optional vector of right hand side, that will be adjusted by provided solution 6167 6168 Notes: 6169 See `MatZeroRowsColumns()` for details on how this routine operates. 6170 6171 The grid coordinates are across the entire grid, not just the local portion 6172 6173 In Fortran idxm and idxn should be declared as 6174 $ MatStencil idxm(4,m) 6175 and the values inserted using 6176 $ idxm(MatStencil_i,1) = i 6177 $ idxm(MatStencil_j,1) = j 6178 $ idxm(MatStencil_k,1) = k 6179 $ idxm(MatStencil_c,1) = c 6180 etc 6181 6182 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6183 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6184 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6185 `DM_BOUNDARY_PERIODIC` boundary type. 6186 6187 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 6188 a single value per point) you can skip filling those indices. 6189 6190 Level: intermediate 6191 6192 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6193 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRows()` 6194 @*/ 6195 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat, PetscInt numRows, const MatStencil rows[], PetscScalar diag, Vec x, Vec b) { 6196 PetscInt dim = mat->stencil.dim; 6197 PetscInt sdim = dim - (1 - (PetscInt)mat->stencil.noc); 6198 PetscInt *dims = mat->stencil.dims + 1; 6199 PetscInt *starts = mat->stencil.starts; 6200 PetscInt *dxm = (PetscInt *)rows; 6201 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6202 6203 PetscFunctionBegin; 6204 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6205 PetscValidType(mat, 1); 6206 if (numRows) PetscValidPointer(rows, 3); 6207 6208 PetscCall(PetscMalloc1(numRows, &jdxm)); 6209 for (i = 0; i < numRows; ++i) { 6210 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6211 for (j = 0; j < 3 - sdim; ++j) dxm++; 6212 /* Local index in X dir */ 6213 tmp = *dxm++ - starts[0]; 6214 /* Loop over remaining dimensions */ 6215 for (j = 0; j < dim - 1; ++j) { 6216 /* If nonlocal, set index to be negative */ 6217 if ((*dxm++ - starts[j + 1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6218 /* Update local index */ 6219 else tmp = tmp * dims[j] + *(dxm - 1) - starts[j + 1]; 6220 } 6221 /* Skip component slot if necessary */ 6222 if (mat->stencil.noc) dxm++; 6223 /* Local row number */ 6224 if (tmp >= 0) jdxm[numNewRows++] = tmp; 6225 } 6226 PetscCall(MatZeroRowsColumnsLocal(mat, numNewRows, jdxm, diag, x, b)); 6227 PetscCall(PetscFree(jdxm)); 6228 PetscFunctionReturn(0); 6229 } 6230 6231 /*@C 6232 MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal) 6233 of a set of rows of a matrix; using local numbering of rows. 6234 6235 Collective on mat 6236 6237 Input Parameters: 6238 + mat - the matrix 6239 . numRows - the number of rows to remove 6240 . rows - the local row indices 6241 . diag - value put in all diagonals of eliminated rows 6242 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6243 - b - optional vector of right hand side, that will be adjusted by provided solution 6244 6245 Notes: 6246 Before calling `MatZeroRowsLocal()`, the user must first set the 6247 local-to-global mapping by calling MatSetLocalToGlobalMapping(), this is often already set for matrices obtained with `DMCreateMatrix()`. 6248 6249 See `MatZeroRows()` for details on how this routine operates. 6250 6251 Level: intermediate 6252 6253 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRows()`, `MatSetOption()`, 6254 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6255 @*/ 6256 PetscErrorCode MatZeroRowsLocal(Mat mat, PetscInt numRows, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) { 6257 PetscFunctionBegin; 6258 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6259 PetscValidType(mat, 1); 6260 if (numRows) PetscValidIntPointer(rows, 3); 6261 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 6262 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 6263 MatCheckPreallocated(mat, 1); 6264 6265 if (mat->ops->zerorowslocal) { 6266 PetscUseTypeMethod(mat, zerorowslocal, numRows, rows, diag, x, b); 6267 } else { 6268 IS is, newis; 6269 const PetscInt *newRows; 6270 6271 PetscCheck(mat->rmap->mapping, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Need to provide local to global mapping to matrix first"); 6272 PetscCall(ISCreateGeneral(PETSC_COMM_SELF, numRows, rows, PETSC_COPY_VALUES, &is)); 6273 PetscCall(ISLocalToGlobalMappingApplyIS(mat->rmap->mapping, is, &newis)); 6274 PetscCall(ISGetIndices(newis, &newRows)); 6275 PetscUseTypeMethod(mat, zerorows, numRows, newRows, diag, x, b); 6276 PetscCall(ISRestoreIndices(newis, &newRows)); 6277 PetscCall(ISDestroy(&newis)); 6278 PetscCall(ISDestroy(&is)); 6279 } 6280 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6281 PetscFunctionReturn(0); 6282 } 6283 6284 /*@ 6285 MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal) 6286 of a set of rows of a matrix; using local numbering of rows. 6287 6288 Collective on mat 6289 6290 Input Parameters: 6291 + mat - the matrix 6292 . is - index set of rows to remove 6293 . diag - value put in all diagonals of eliminated rows 6294 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6295 - b - optional vector of right hand side, that will be adjusted by provided solution 6296 6297 Notes: 6298 Before calling `MatZeroRowsLocalIS()`, the user must first set the 6299 local-to-global mapping by calling `MatSetLocalToGlobalMapping()`, this is often already set for matrices obtained with `DMCreateMatrix()`. 6300 6301 See `MatZeroRows()` for details on how this routine operates. 6302 6303 Level: intermediate 6304 6305 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRows()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6306 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6307 @*/ 6308 PetscErrorCode MatZeroRowsLocalIS(Mat mat, IS is, PetscScalar diag, Vec x, Vec b) { 6309 PetscInt numRows; 6310 const PetscInt *rows; 6311 6312 PetscFunctionBegin; 6313 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6314 PetscValidType(mat, 1); 6315 PetscValidHeaderSpecific(is, IS_CLASSID, 2); 6316 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 6317 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 6318 MatCheckPreallocated(mat, 1); 6319 6320 PetscCall(ISGetLocalSize(is, &numRows)); 6321 PetscCall(ISGetIndices(is, &rows)); 6322 PetscCall(MatZeroRowsLocal(mat, numRows, rows, diag, x, b)); 6323 PetscCall(ISRestoreIndices(is, &rows)); 6324 PetscFunctionReturn(0); 6325 } 6326 6327 /*@ 6328 MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal) 6329 of a set of rows and columns of a matrix; using local numbering of rows. 6330 6331 Collective on mat 6332 6333 Input Parameters: 6334 + mat - the matrix 6335 . numRows - the number of rows to remove 6336 . rows - the global row indices 6337 . diag - value put in all diagonals of eliminated rows 6338 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6339 - b - optional vector of right hand side, that will be adjusted by provided solution 6340 6341 Notes: 6342 Before calling `MatZeroRowsColumnsLocal()`, the user must first set the 6343 local-to-global mapping by calling `MatSetLocalToGlobalMapping()`, this is often already set for matrices obtained with `DMCreateMatrix()`. 6344 6345 See `MatZeroRowsColumns()` for details on how this routine operates. 6346 6347 Level: intermediate 6348 6349 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6350 `MatZeroRows()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6351 @*/ 6352 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat, PetscInt numRows, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) { 6353 IS is, newis; 6354 const PetscInt *newRows; 6355 6356 PetscFunctionBegin; 6357 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6358 PetscValidType(mat, 1); 6359 if (numRows) PetscValidIntPointer(rows, 3); 6360 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 6361 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 6362 MatCheckPreallocated(mat, 1); 6363 6364 PetscCheck(mat->cmap->mapping, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Need to provide local to global mapping to matrix first"); 6365 PetscCall(ISCreateGeneral(PETSC_COMM_SELF, numRows, rows, PETSC_COPY_VALUES, &is)); 6366 PetscCall(ISLocalToGlobalMappingApplyIS(mat->cmap->mapping, is, &newis)); 6367 PetscCall(ISGetIndices(newis, &newRows)); 6368 PetscUseTypeMethod(mat, zerorowscolumns, numRows, newRows, diag, x, b); 6369 PetscCall(ISRestoreIndices(newis, &newRows)); 6370 PetscCall(ISDestroy(&newis)); 6371 PetscCall(ISDestroy(&is)); 6372 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6373 PetscFunctionReturn(0); 6374 } 6375 6376 /*@ 6377 MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal) 6378 of a set of rows and columns of a matrix; using local numbering of rows. 6379 6380 Collective on Mat 6381 6382 Input Parameters: 6383 + mat - the matrix 6384 . is - index set of rows to remove 6385 . diag - value put in all diagonals of eliminated rows 6386 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6387 - b - optional vector of right hand side, that will be adjusted by provided solution 6388 6389 Notes: 6390 Before calling `MatZeroRowsColumnsLocalIS()`, the user must first set the 6391 local-to-global mapping by calling `MatSetLocalToGlobalMapping()`, this is often already set for matrices obtained with `DMCreateMatrix()`. 6392 6393 See `MatZeroRowsColumns()` for details on how this routine operates. 6394 6395 Level: intermediate 6396 6397 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6398 `MatZeroRowsColumnsLocal()`, `MatZeroRows()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6399 @*/ 6400 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat, IS is, PetscScalar diag, Vec x, Vec b) { 6401 PetscInt numRows; 6402 const PetscInt *rows; 6403 6404 PetscFunctionBegin; 6405 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6406 PetscValidType(mat, 1); 6407 PetscValidHeaderSpecific(is, IS_CLASSID, 2); 6408 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 6409 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 6410 MatCheckPreallocated(mat, 1); 6411 6412 PetscCall(ISGetLocalSize(is, &numRows)); 6413 PetscCall(ISGetIndices(is, &rows)); 6414 PetscCall(MatZeroRowsColumnsLocal(mat, numRows, rows, diag, x, b)); 6415 PetscCall(ISRestoreIndices(is, &rows)); 6416 PetscFunctionReturn(0); 6417 } 6418 6419 /*@C 6420 MatGetSize - Returns the numbers of rows and columns in a matrix. 6421 6422 Not Collective 6423 6424 Input Parameter: 6425 . mat - the matrix 6426 6427 Output Parameters: 6428 + m - the number of global rows 6429 - n - the number of global columns 6430 6431 Note: both output parameters can be NULL on input. 6432 6433 Level: beginner 6434 6435 .seealso: `Mat`, `MatSetSizes()`, `MatGetLocalSize()` 6436 @*/ 6437 PetscErrorCode MatGetSize(Mat mat, PetscInt *m, PetscInt *n) { 6438 PetscFunctionBegin; 6439 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6440 if (m) *m = mat->rmap->N; 6441 if (n) *n = mat->cmap->N; 6442 PetscFunctionReturn(0); 6443 } 6444 6445 /*@C 6446 MatGetLocalSize - For most matrix formats, excluding `MATELEMENTAL` and `MATSCALAPACK`, Returns the number of local rows and local columns 6447 of a matrix. For all matrices this is the local size of the left and right vectors as returned by `MatCreateVecs()`. 6448 6449 Not Collective 6450 6451 Input Parameter: 6452 . mat - the matrix 6453 6454 Output Parameters: 6455 + m - the number of local rows, use `NULL` to not obtain this value 6456 - n - the number of local columns, use `NULL` to not obtain this value 6457 6458 Level: beginner 6459 6460 .seealso: `Mat`, `MatSetSizes()`, `MatGetSize()` 6461 @*/ 6462 PetscErrorCode MatGetLocalSize(Mat mat, PetscInt *m, PetscInt *n) { 6463 PetscFunctionBegin; 6464 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6465 if (m) PetscValidIntPointer(m, 2); 6466 if (n) PetscValidIntPointer(n, 3); 6467 if (m) *m = mat->rmap->n; 6468 if (n) *n = mat->cmap->n; 6469 PetscFunctionReturn(0); 6470 } 6471 6472 /*@C 6473 MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies this matrix by that are owned by 6474 this processor. (The columns of the "diagonal block" for most sparse matrix formats). See :any:`<sec_matlayout>` for details on matrix layouts. 6475 6476 Not Collective, unless matrix has not been allocated, then collective on mat 6477 6478 Input Parameter: 6479 . mat - the matrix 6480 6481 Output Parameters: 6482 + m - the global index of the first local column, use `NULL` to not obtain this value 6483 - n - one more than the global index of the last local column, use `NULL` to not obtain this value 6484 6485 Level: developer 6486 6487 .seealso: `Mat`, `MatGetOwnershipRange()`, `MatGetOwnershipRanges()`, `MatGetOwnershipRangesColumn()`, `PetscLayout` 6488 @*/ 6489 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat, PetscInt *m, PetscInt *n) { 6490 PetscFunctionBegin; 6491 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6492 PetscValidType(mat, 1); 6493 if (m) PetscValidIntPointer(m, 2); 6494 if (n) PetscValidIntPointer(n, 3); 6495 MatCheckPreallocated(mat, 1); 6496 if (m) *m = mat->cmap->rstart; 6497 if (n) *n = mat->cmap->rend; 6498 PetscFunctionReturn(0); 6499 } 6500 6501 /*@C 6502 MatGetOwnershipRange - For matrices that own values by row, excludes `MATELEMENTAL` and `MATSCALAPACK`, returns the range of matrix rows owned by 6503 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 6504 vector product with this matrix. See :any:`<sec_matlayout>` for details on matrix layouts 6505 6506 Not Collective 6507 6508 Input Parameter: 6509 . mat - the matrix 6510 6511 Output Parameters: 6512 + m - the global index of the first local row, use `NULL` to not obtain this value 6513 - n - one more than the global index of the last local row, use `NULL` to not obtain this value 6514 6515 Note: 6516 This function requires that the matrix be preallocated. If you have not preallocated, consider using 6517 `PetscSplitOwnership`(`MPI_Comm` comm, `PetscInt` *n, `PetscInt` *N) 6518 and then `MPI_Scan()` to calculate prefix sums of the local sizes. 6519 6520 Level: beginner 6521 6522 .seealso: `MatGetOwnershipRanges()`, `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRangesColumn()`, `PetscSplitOwnership()`, `PetscSplitOwnershipBlock()`, 6523 `PetscLayout` 6524 @*/ 6525 PetscErrorCode MatGetOwnershipRange(Mat mat, PetscInt *m, PetscInt *n) { 6526 PetscFunctionBegin; 6527 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6528 PetscValidType(mat, 1); 6529 if (m) PetscValidIntPointer(m, 2); 6530 if (n) PetscValidIntPointer(n, 3); 6531 MatCheckPreallocated(mat, 1); 6532 if (m) *m = mat->rmap->rstart; 6533 if (n) *n = mat->rmap->rend; 6534 PetscFunctionReturn(0); 6535 } 6536 6537 /*@C 6538 MatGetOwnershipRanges - For matrices that own values by row, excludes `MATELEMENTAL` and `MATSCALAPACK`, returns the range of matrix rows owned by 6539 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 6540 vector product with this matrix. See :any:`<sec_matlayout>` for details on matrix layouts 6541 6542 Not Collective, unless matrix has not been allocated, then collective on mat 6543 6544 Input Parameters: 6545 . mat - the matrix 6546 6547 Output Parameters: 6548 . ranges - start of each processors portion plus one more than the total length at the end 6549 6550 Level: beginner 6551 6552 .seealso: `Mat`, `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRangesColumn()`, `PetscLayout` 6553 @*/ 6554 PetscErrorCode MatGetOwnershipRanges(Mat mat, const PetscInt **ranges) { 6555 PetscFunctionBegin; 6556 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6557 PetscValidType(mat, 1); 6558 MatCheckPreallocated(mat, 1); 6559 PetscCall(PetscLayoutGetRanges(mat->rmap, ranges)); 6560 PetscFunctionReturn(0); 6561 } 6562 6563 /*@C 6564 MatGetOwnershipRangesColumn - Returns the ranges of matrix columns associated with rows of a vector one multiplies this vector by that are owned by 6565 each processor. (The columns of the "diagonal blocks", for most sparse matrix formats). See :any:`<sec_matlayout>` for details on matrix layouts. 6566 6567 Not Collective, unless matrix has not been allocated, then collective on Mat 6568 6569 Input Parameters: 6570 . mat - the matrix 6571 6572 Output Parameters: 6573 . ranges - start of each processors portion plus one more then the total length at the end 6574 6575 Level: beginner 6576 6577 .seealso: `Mat`, `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRanges()` 6578 @*/ 6579 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat, const PetscInt **ranges) { 6580 PetscFunctionBegin; 6581 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6582 PetscValidType(mat, 1); 6583 MatCheckPreallocated(mat, 1); 6584 PetscCall(PetscLayoutGetRanges(mat->cmap, ranges)); 6585 PetscFunctionReturn(0); 6586 } 6587 6588 /*@C 6589 MatGetOwnershipIS - Get row and column ownership of a matrices' values as index sets. For most matrices, excluding `MATELEMENTAL` and `MATSCALAPACK`, this 6590 corresponds to values returned by `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`. For `MATELEMENTAL` and `MATSCALAPACK` the ownership 6591 is more complicated. See :any:`<sec_matlayout>` for details on matrix layouts. 6592 6593 Not Collective 6594 6595 Input Parameter: 6596 . A - matrix 6597 6598 Output Parameters: 6599 + rows - rows in which this process owns elements, , use `NULL` to not obtain this value 6600 - cols - columns in which this process owns elements, use `NULL` to not obtain this value 6601 6602 Level: intermediate 6603 6604 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`, `MatSetValues()`, ``MATELEMENTAL``, ``MATSCALAPACK`` 6605 @*/ 6606 PetscErrorCode MatGetOwnershipIS(Mat A, IS *rows, IS *cols) { 6607 PetscErrorCode (*f)(Mat, IS *, IS *); 6608 6609 PetscFunctionBegin; 6610 MatCheckPreallocated(A, 1); 6611 PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatGetOwnershipIS_C", &f)); 6612 if (f) { 6613 PetscCall((*f)(A, rows, cols)); 6614 } else { /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */ 6615 if (rows) PetscCall(ISCreateStride(PETSC_COMM_SELF, A->rmap->n, A->rmap->rstart, 1, rows)); 6616 if (cols) PetscCall(ISCreateStride(PETSC_COMM_SELF, A->cmap->N, 0, 1, cols)); 6617 } 6618 PetscFunctionReturn(0); 6619 } 6620 6621 /*@C 6622 MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix obtained with `MatGetFactor()` 6623 Uses levels of fill only, not drop tolerance. Use `MatLUFactorNumeric()` 6624 to complete the factorization. 6625 6626 Collective on fact 6627 6628 Input Parameters: 6629 + fact - the factorized matrix obtained with `MatGetFactor()` 6630 . mat - the matrix 6631 . row - row permutation 6632 . column - column permutation 6633 - info - structure containing 6634 $ levels - number of levels of fill. 6635 $ expected fill - as ratio of original fill. 6636 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 6637 missing diagonal entries) 6638 6639 Output Parameters: 6640 . fact - new matrix that has been symbolically factored 6641 6642 Level: developer 6643 6644 Notes: 6645 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 6646 6647 Most users should employ the `KSP` interface for linear solvers 6648 instead of working directly with matrix algebra routines such as this. 6649 See, e.g., `KSPCreate()`. 6650 6651 Uses the definition of level of fill as in Y. Saad, 2003 6652 6653 Developer Note: 6654 The Fortran interface is not autogenerated as the f90 6655 interface definition cannot be generated correctly [due to `MatFactorInfo`] 6656 6657 References: 6658 . * - Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6659 6660 .seealso: `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()` 6661 `MatGetOrdering()`, `MatFactorInfo` 6662 @*/ 6663 PetscErrorCode MatILUFactorSymbolic(Mat fact, Mat mat, IS row, IS col, const MatFactorInfo *info) { 6664 PetscFunctionBegin; 6665 PetscValidHeaderSpecific(mat, MAT_CLASSID, 2); 6666 PetscValidType(mat, 2); 6667 if (row) PetscValidHeaderSpecific(row, IS_CLASSID, 3); 6668 if (col) PetscValidHeaderSpecific(col, IS_CLASSID, 4); 6669 PetscValidPointer(info, 5); 6670 PetscValidPointer(fact, 1); 6671 PetscCheck(info->levels >= 0, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_OUTOFRANGE, "Levels of fill negative %" PetscInt_FMT, (PetscInt)info->levels); 6672 PetscCheck(info->fill >= 1.0, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_OUTOFRANGE, "Expected fill less than 1.0 %g", (double)info->fill); 6673 if (!fact->ops->ilufactorsymbolic) { 6674 MatSolverType stype; 6675 PetscCall(MatFactorGetSolverType(fact, &stype)); 6676 SETERRQ(PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Matrix type %s symbolic ILU using solver type %s", ((PetscObject)mat)->type_name, stype); 6677 } 6678 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 6679 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 6680 MatCheckPreallocated(mat, 2); 6681 6682 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_ILUFactorSymbolic, mat, row, col, 0)); 6683 PetscCall((fact->ops->ilufactorsymbolic)(fact, mat, row, col, info)); 6684 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_ILUFactorSymbolic, mat, row, col, 0)); 6685 PetscFunctionReturn(0); 6686 } 6687 6688 /*@C 6689 MatICCFactorSymbolic - Performs symbolic incomplete 6690 Cholesky factorization for a symmetric matrix. Use 6691 `MatCholeskyFactorNumeric()` to complete the factorization. 6692 6693 Collective on fact 6694 6695 Input Parameters: 6696 + fact - the factorized matrix obtained with `MatGetFactor()` 6697 . mat - the matrix to be factored 6698 . perm - row and column permutation 6699 - info - structure containing 6700 $ levels - number of levels of fill. 6701 $ expected fill - as ratio of original fill. 6702 6703 Output Parameter: 6704 . fact - the factored matrix 6705 6706 Level: developer 6707 6708 Notes: 6709 Most users should employ the `KSP` interface for linear solvers 6710 instead of working directly with matrix algebra routines such as this. 6711 See, e.g., `KSPCreate()`. 6712 6713 This uses the definition of level of fill as in Y. Saad, 2003 6714 6715 Developer Note: 6716 The Fortran interface is not autogenerated as the f90 6717 interface definition cannot be generated correctly [due to `MatFactorInfo`] 6718 6719 References: 6720 . * - Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6721 6722 .seealso: `MatGetFactor()`, `MatCholeskyFactorNumeric()`, `MatCholeskyFactor()`, `MatFactorInfo` 6723 @*/ 6724 PetscErrorCode MatICCFactorSymbolic(Mat fact, Mat mat, IS perm, const MatFactorInfo *info) { 6725 PetscFunctionBegin; 6726 PetscValidHeaderSpecific(mat, MAT_CLASSID, 2); 6727 PetscValidType(mat, 2); 6728 if (perm) PetscValidHeaderSpecific(perm, IS_CLASSID, 3); 6729 PetscValidPointer(info, 4); 6730 PetscValidPointer(fact, 1); 6731 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 6732 PetscCheck(info->levels >= 0, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_OUTOFRANGE, "Levels negative %" PetscInt_FMT, (PetscInt)info->levels); 6733 PetscCheck(info->fill >= 1.0, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_OUTOFRANGE, "Expected fill less than 1.0 %g", (double)info->fill); 6734 if (!(fact)->ops->iccfactorsymbolic) { 6735 MatSolverType stype; 6736 PetscCall(MatFactorGetSolverType(fact, &stype)); 6737 SETERRQ(PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Matrix type %s symbolic ICC using solver type %s", ((PetscObject)mat)->type_name, stype); 6738 } 6739 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 6740 MatCheckPreallocated(mat, 2); 6741 6742 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_ICCFactorSymbolic, mat, perm, 0, 0)); 6743 PetscCall((fact->ops->iccfactorsymbolic)(fact, mat, perm, info)); 6744 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_ICCFactorSymbolic, mat, perm, 0, 0)); 6745 PetscFunctionReturn(0); 6746 } 6747 6748 /*@C 6749 MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat 6750 points to an array of valid matrices, they may be reused to store the new 6751 submatrices. 6752 6753 Collective on mat 6754 6755 Input Parameters: 6756 + mat - the matrix 6757 . n - the number of submatrixes to be extracted (on this processor, may be zero) 6758 . irow, icol - index sets of rows and columns to extract 6759 - scall - either `MAT_INITIAL_MATRIX` or `MAT_REUSE_MATRIX` 6760 6761 Output Parameter: 6762 . submat - the array of submatrices 6763 6764 Notes: 6765 `MatCreateSubMatrices()` can extract ONLY sequential submatrices 6766 (from both sequential and parallel matrices). Use `MatCreateSubMatrix()` 6767 to extract a parallel submatrix. 6768 6769 Some matrix types place restrictions on the row and column 6770 indices, such as that they be sorted or that they be equal to each other. 6771 6772 The index sets may not have duplicate entries. 6773 6774 When extracting submatrices from a parallel matrix, each processor can 6775 form a different submatrix by setting the rows and columns of its 6776 individual index sets according to the local submatrix desired. 6777 6778 When finished using the submatrices, the user should destroy 6779 them with `MatDestroySubMatrices()`. 6780 6781 `MAT_REUSE_MATRIX` can only be used when the nonzero structure of the 6782 original matrix has not changed from that last call to `MatCreateSubMatrices()`. 6783 6784 This routine creates the matrices in submat; you should NOT create them before 6785 calling it. It also allocates the array of matrix pointers submat. 6786 6787 For `MATBAIJ` matrices the index sets must respect the block structure, that is if they 6788 request one row/column in a block, they must request all rows/columns that are in 6789 that block. For example, if the block size is 2 you cannot request just row 0 and 6790 column 0. 6791 6792 Fortran Note: 6793 The Fortran interface is slightly different from that given below; it 6794 requires one to pass in as submat a `Mat` (integer) array of size at least n+1. 6795 6796 Level: advanced 6797 6798 .seealso: `Mat`, `MatDestroySubMatrices()`, `MatCreateSubMatrix()`, `MatGetRow()`, `MatGetDiagonal()`, `MatReuse` 6799 @*/ 6800 PetscErrorCode MatCreateSubMatrices(Mat mat, PetscInt n, const IS irow[], const IS icol[], MatReuse scall, Mat *submat[]) { 6801 PetscInt i; 6802 PetscBool eq; 6803 6804 PetscFunctionBegin; 6805 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6806 PetscValidType(mat, 1); 6807 if (n) { 6808 PetscValidPointer(irow, 3); 6809 for (i = 0; i < n; i++) PetscValidHeaderSpecific(irow[i], IS_CLASSID, 3); 6810 PetscValidPointer(icol, 4); 6811 for (i = 0; i < n; i++) PetscValidHeaderSpecific(icol[i], IS_CLASSID, 4); 6812 } 6813 PetscValidPointer(submat, 6); 6814 if (n && scall == MAT_REUSE_MATRIX) { 6815 PetscValidPointer(*submat, 6); 6816 for (i = 0; i < n; i++) PetscValidHeaderSpecific((*submat)[i], MAT_CLASSID, 6); 6817 } 6818 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 6819 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 6820 MatCheckPreallocated(mat, 1); 6821 PetscCall(PetscLogEventBegin(MAT_CreateSubMats, mat, 0, 0, 0)); 6822 PetscUseTypeMethod(mat, createsubmatrices, n, irow, icol, scall, submat); 6823 PetscCall(PetscLogEventEnd(MAT_CreateSubMats, mat, 0, 0, 0)); 6824 for (i = 0; i < n; i++) { 6825 (*submat)[i]->factortype = MAT_FACTOR_NONE; /* in case in place factorization was previously done on submatrix */ 6826 PetscCall(ISEqualUnsorted(irow[i], icol[i], &eq)); 6827 if (eq) PetscCall(MatPropagateSymmetryOptions(mat, (*submat)[i])); 6828 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 6829 if (mat->boundtocpu && mat->bindingpropagates) { 6830 PetscCall(MatBindToCPU((*submat)[i], PETSC_TRUE)); 6831 PetscCall(MatSetBindingPropagates((*submat)[i], PETSC_TRUE)); 6832 } 6833 #endif 6834 } 6835 PetscFunctionReturn(0); 6836 } 6837 6838 /*@C 6839 MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of `IS` that may live on subcomms). 6840 6841 Collective on mat 6842 6843 Input Parameters: 6844 + mat - the matrix 6845 . n - the number of submatrixes to be extracted 6846 . irow, icol - index sets of rows and columns to extract 6847 - scall - either `MAT_INITIAL_MATRIX` or `MAT_REUSE_MATRIX` 6848 6849 Output Parameter: 6850 . submat - the array of submatrices 6851 6852 Level: advanced 6853 6854 Note: 6855 This is used by `PCGASM` 6856 6857 .seealso: `PCGASM`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRow()`, `MatGetDiagonal()`, `MatReuse` 6858 @*/ 6859 PetscErrorCode MatCreateSubMatricesMPI(Mat mat, PetscInt n, const IS irow[], const IS icol[], MatReuse scall, Mat *submat[]) { 6860 PetscInt i; 6861 PetscBool eq; 6862 6863 PetscFunctionBegin; 6864 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6865 PetscValidType(mat, 1); 6866 if (n) { 6867 PetscValidPointer(irow, 3); 6868 PetscValidHeaderSpecific(*irow, IS_CLASSID, 3); 6869 PetscValidPointer(icol, 4); 6870 PetscValidHeaderSpecific(*icol, IS_CLASSID, 4); 6871 } 6872 PetscValidPointer(submat, 6); 6873 if (n && scall == MAT_REUSE_MATRIX) { 6874 PetscValidPointer(*submat, 6); 6875 PetscValidHeaderSpecific(**submat, MAT_CLASSID, 6); 6876 } 6877 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 6878 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 6879 MatCheckPreallocated(mat, 1); 6880 6881 PetscCall(PetscLogEventBegin(MAT_CreateSubMats, mat, 0, 0, 0)); 6882 PetscUseTypeMethod(mat, createsubmatricesmpi, n, irow, icol, scall, submat); 6883 PetscCall(PetscLogEventEnd(MAT_CreateSubMats, mat, 0, 0, 0)); 6884 for (i = 0; i < n; i++) { 6885 PetscCall(ISEqualUnsorted(irow[i], icol[i], &eq)); 6886 if (eq) PetscCall(MatPropagateSymmetryOptions(mat, (*submat)[i])); 6887 } 6888 PetscFunctionReturn(0); 6889 } 6890 6891 /*@C 6892 MatDestroyMatrices - Destroys an array of matrices. 6893 6894 Collective on mat 6895 6896 Input Parameters: 6897 + n - the number of local matrices 6898 - mat - the matrices (note that this is a pointer to the array of matrices) 6899 6900 Level: advanced 6901 6902 Note: 6903 Frees not only the matrices, but also the array that contains the matrices 6904 In Fortran will not free the array. 6905 6906 .seealso: `Mat`, `MatCreateSubMatrices()` `MatDestroySubMatrices()` 6907 @*/ 6908 PetscErrorCode MatDestroyMatrices(PetscInt n, Mat *mat[]) { 6909 PetscInt i; 6910 6911 PetscFunctionBegin; 6912 if (!*mat) PetscFunctionReturn(0); 6913 PetscCheck(n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Trying to destroy negative number of matrices %" PetscInt_FMT, n); 6914 PetscValidPointer(mat, 2); 6915 6916 for (i = 0; i < n; i++) PetscCall(MatDestroy(&(*mat)[i])); 6917 6918 /* memory is allocated even if n = 0 */ 6919 PetscCall(PetscFree(*mat)); 6920 PetscFunctionReturn(0); 6921 } 6922 6923 /*@C 6924 MatDestroySubMatrices - Destroys a set of matrices obtained with `MatCreateSubMatrices()`. 6925 6926 Collective on mat 6927 6928 Input Parameters: 6929 + n - the number of local matrices 6930 - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling 6931 sequence of MatCreateSubMatrices()) 6932 6933 Level: advanced 6934 6935 Note: 6936 Frees not only the matrices, but also the array that contains the matrices 6937 In Fortran will not free the array. 6938 6939 .seealso: `MatCreateSubMatrices()`, `MatDestroyMatrices()` 6940 @*/ 6941 PetscErrorCode MatDestroySubMatrices(PetscInt n, Mat *mat[]) { 6942 Mat mat0; 6943 6944 PetscFunctionBegin; 6945 if (!*mat) PetscFunctionReturn(0); 6946 /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */ 6947 PetscCheck(n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Trying to destroy negative number of matrices %" PetscInt_FMT, n); 6948 PetscValidPointer(mat, 2); 6949 6950 mat0 = (*mat)[0]; 6951 if (mat0 && mat0->ops->destroysubmatrices) { 6952 PetscCall((mat0->ops->destroysubmatrices)(n, mat)); 6953 } else { 6954 PetscCall(MatDestroyMatrices(n, mat)); 6955 } 6956 PetscFunctionReturn(0); 6957 } 6958 6959 /*@C 6960 MatGetSeqNonzeroStructure - Extracts the nonzero structure from a matrix and stores it, in its entirety, on each process 6961 6962 Collective on mat 6963 6964 Input Parameters: 6965 . mat - the matrix 6966 6967 Output Parameter: 6968 . matstruct - the sequential matrix with the nonzero structure of mat 6969 6970 Level: developer 6971 6972 .seealso: `Mat`, `MatDestroySeqNonzeroStructure()`, `MatCreateSubMatrices()`, `MatDestroyMatrices()` 6973 @*/ 6974 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat, Mat *matstruct) { 6975 PetscFunctionBegin; 6976 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6977 PetscValidPointer(matstruct, 2); 6978 6979 PetscValidType(mat, 1); 6980 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 6981 MatCheckPreallocated(mat, 1); 6982 6983 PetscCall(PetscLogEventBegin(MAT_GetSeqNonzeroStructure, mat, 0, 0, 0)); 6984 PetscUseTypeMethod(mat, getseqnonzerostructure, matstruct); 6985 PetscCall(PetscLogEventEnd(MAT_GetSeqNonzeroStructure, mat, 0, 0, 0)); 6986 PetscFunctionReturn(0); 6987 } 6988 6989 /*@C 6990 MatDestroySeqNonzeroStructure - Destroys matrix obtained with `MatGetSeqNonzeroStructure()`. 6991 6992 Collective on mat 6993 6994 Input Parameters: 6995 . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling 6996 sequence of `MatGetSequentialNonzeroStructure()`) 6997 6998 Level: advanced 6999 7000 Note: 7001 Frees not only the matrices, but also the array that contains the matrices 7002 7003 .seealso: `Mat`, `MatGetSeqNonzeroStructure()` 7004 @*/ 7005 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat) { 7006 PetscFunctionBegin; 7007 PetscValidPointer(mat, 1); 7008 PetscCall(MatDestroy(mat)); 7009 PetscFunctionReturn(0); 7010 } 7011 7012 /*@ 7013 MatIncreaseOverlap - Given a set of submatrices indicated by index sets, 7014 replaces the index sets by larger ones that represent submatrices with 7015 additional overlap. 7016 7017 Collective on mat 7018 7019 Input Parameters: 7020 + mat - the matrix 7021 . n - the number of index sets 7022 . is - the array of index sets (these index sets will changed during the call) 7023 - ov - the additional overlap requested 7024 7025 Options Database: 7026 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7027 7028 Level: developer 7029 7030 Developer Note: 7031 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. 7032 7033 .seealso: `Mat`, `PCASM`, `MatIncreaseOverlapSplit()`, `MatCreateSubMatrices()` 7034 @*/ 7035 PetscErrorCode MatIncreaseOverlap(Mat mat, PetscInt n, IS is[], PetscInt ov) { 7036 PetscInt i, bs, cbs; 7037 7038 PetscFunctionBegin; 7039 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7040 PetscValidType(mat, 1); 7041 PetscValidLogicalCollectiveInt(mat, n, 2); 7042 PetscCheck(n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Must have one or more domains, you have %" PetscInt_FMT, n); 7043 if (n) { 7044 PetscValidPointer(is, 3); 7045 for (i = 0; i < n; i++) PetscValidHeaderSpecific(is[i], IS_CLASSID, 3); 7046 } 7047 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 7048 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 7049 MatCheckPreallocated(mat, 1); 7050 7051 if (!ov || !n) PetscFunctionReturn(0); 7052 PetscCall(PetscLogEventBegin(MAT_IncreaseOverlap, mat, 0, 0, 0)); 7053 PetscUseTypeMethod(mat, increaseoverlap, n, is, ov); 7054 PetscCall(PetscLogEventEnd(MAT_IncreaseOverlap, mat, 0, 0, 0)); 7055 PetscCall(MatGetBlockSizes(mat, &bs, &cbs)); 7056 if (bs == cbs) { 7057 for (i = 0; i < n; i++) PetscCall(ISSetBlockSize(is[i], bs)); 7058 } 7059 PetscFunctionReturn(0); 7060 } 7061 7062 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat, IS *, PetscInt); 7063 7064 /*@ 7065 MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across 7066 a sub communicator, replaces the index sets by larger ones that represent submatrices with 7067 additional overlap. 7068 7069 Collective on mat 7070 7071 Input Parameters: 7072 + mat - the matrix 7073 . n - the number of index sets 7074 . is - the array of index sets (these index sets will changed during the call) 7075 - ov - the additional overlap requested 7076 7077 ` Options Database: 7078 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7079 7080 Level: developer 7081 7082 .seealso: `MatCreateSubMatrices()`, `MatIncreaseOverlap()` 7083 @*/ 7084 PetscErrorCode MatIncreaseOverlapSplit(Mat mat, PetscInt n, IS is[], PetscInt ov) { 7085 PetscInt i; 7086 7087 PetscFunctionBegin; 7088 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7089 PetscValidType(mat, 1); 7090 PetscCheck(n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Must have one or more domains, you have %" PetscInt_FMT, n); 7091 if (n) { 7092 PetscValidPointer(is, 3); 7093 PetscValidHeaderSpecific(*is, IS_CLASSID, 3); 7094 } 7095 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 7096 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 7097 MatCheckPreallocated(mat, 1); 7098 if (!ov) PetscFunctionReturn(0); 7099 PetscCall(PetscLogEventBegin(MAT_IncreaseOverlap, mat, 0, 0, 0)); 7100 for (i = 0; i < n; i++) PetscCall(MatIncreaseOverlapSplit_Single(mat, &is[i], ov)); 7101 PetscCall(PetscLogEventEnd(MAT_IncreaseOverlap, mat, 0, 0, 0)); 7102 PetscFunctionReturn(0); 7103 } 7104 7105 /*@ 7106 MatGetBlockSize - Returns the matrix block size. 7107 7108 Not Collective 7109 7110 Input Parameter: 7111 . mat - the matrix 7112 7113 Output Parameter: 7114 . bs - block size 7115 7116 Notes: 7117 Block row formats are `MATBAIJ` and `MATSBAIJ` ALWAYS have square block storage in the matrix. 7118 7119 If the block size has not been set yet this routine returns 1. 7120 7121 Level: intermediate 7122 7123 .seealso: `MATBAIJ`, `MATSBAIJ`, `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSizes()` 7124 @*/ 7125 PetscErrorCode MatGetBlockSize(Mat mat, PetscInt *bs) { 7126 PetscFunctionBegin; 7127 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7128 PetscValidIntPointer(bs, 2); 7129 *bs = PetscAbs(mat->rmap->bs); 7130 PetscFunctionReturn(0); 7131 } 7132 7133 /*@ 7134 MatGetBlockSizes - Returns the matrix block row and column sizes. 7135 7136 Not Collective 7137 7138 Input Parameter: 7139 . mat - the matrix 7140 7141 Output Parameters: 7142 + rbs - row block size 7143 - cbs - column block size 7144 7145 Notes: 7146 Block row formats are `MATBAIJ` and `MATSBAIJ` ALWAYS have square block storage in the matrix. 7147 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7148 7149 If a block size has not been set yet this routine returns 1. 7150 7151 Level: intermediate 7152 7153 .seealso: `MATBAIJ`, `MATSBAIJ`, `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSize()`, `MatSetBlockSizes()` 7154 @*/ 7155 PetscErrorCode MatGetBlockSizes(Mat mat, PetscInt *rbs, PetscInt *cbs) { 7156 PetscFunctionBegin; 7157 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7158 if (rbs) PetscValidIntPointer(rbs, 2); 7159 if (cbs) PetscValidIntPointer(cbs, 3); 7160 if (rbs) *rbs = PetscAbs(mat->rmap->bs); 7161 if (cbs) *cbs = PetscAbs(mat->cmap->bs); 7162 PetscFunctionReturn(0); 7163 } 7164 7165 /*@ 7166 MatSetBlockSize - Sets the matrix block size. 7167 7168 Logically Collective on mat 7169 7170 Input Parameters: 7171 + mat - the matrix 7172 - bs - block size 7173 7174 Notes: 7175 Block row formats are `MATBAIJ` and `MATSBAIJ` formats ALWAYS have square block storage in the matrix. 7176 This must be called before `MatSetUp()` or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7177 7178 For `MATAIJ` matrix format, this function can be called at a later stage, provided that the specified block size 7179 is compatible with the matrix local sizes. 7180 7181 Level: intermediate 7182 7183 .seealso: `MATBAIJ`, `MATSBAIJ`, `MATAIJ`, `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`, `MatGetBlockSizes()` 7184 @*/ 7185 PetscErrorCode MatSetBlockSize(Mat mat, PetscInt bs) { 7186 PetscFunctionBegin; 7187 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7188 PetscValidLogicalCollectiveInt(mat, bs, 2); 7189 PetscCall(MatSetBlockSizes(mat, bs, bs)); 7190 PetscFunctionReturn(0); 7191 } 7192 7193 typedef struct { 7194 PetscInt n; 7195 IS *is; 7196 Mat *mat; 7197 PetscObjectState nonzerostate; 7198 Mat C; 7199 } EnvelopeData; 7200 7201 static PetscErrorCode EnvelopeDataDestroy(EnvelopeData *edata) { 7202 for (PetscInt i = 0; i < edata->n; i++) PetscCall(ISDestroy(&edata->is[i])); 7203 PetscCall(PetscFree(edata->is)); 7204 PetscCall(PetscFree(edata)); 7205 return 0; 7206 } 7207 7208 /* 7209 MatComputeVariableBlockEnvelope - Given a matrix whose nonzeros are in blocks along the diagonal this computes and stores 7210 the sizes of these blocks in the matrix. An individual block may lie over several processes. 7211 7212 Collective on mat 7213 7214 Input Parameter: 7215 . mat - the matrix 7216 7217 Notes: 7218 There can be zeros within the blocks 7219 7220 The blocks can overlap between processes, including laying on more than two processes 7221 7222 .seealso: `Mat`, `MatInvertVariableBlockEnvelope()`, `MatSetVariableBlockSizes()` 7223 */ 7224 static PetscErrorCode MatComputeVariableBlockEnvelope(Mat mat) { 7225 PetscInt n, *sizes, *starts, i = 0, env = 0, tbs = 0, lblocks = 0, rstart, II, ln = 0, cnt = 0, cstart, cend; 7226 PetscInt *diag, *odiag, sc; 7227 VecScatter scatter; 7228 PetscScalar *seqv; 7229 const PetscScalar *parv; 7230 const PetscInt *ia, *ja; 7231 PetscBool set, flag, done; 7232 Mat AA = mat, A; 7233 MPI_Comm comm; 7234 PetscMPIInt rank, size, tag; 7235 MPI_Status status; 7236 PetscContainer container; 7237 EnvelopeData *edata; 7238 Vec seq, par; 7239 IS isglobal; 7240 7241 PetscFunctionBegin; 7242 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7243 PetscCall(MatIsSymmetricKnown(mat, &set, &flag)); 7244 if (!set || !flag) { 7245 /* TOO: only needs nonzero structure of transpose */ 7246 PetscCall(MatTranspose(mat, MAT_INITIAL_MATRIX, &AA)); 7247 PetscCall(MatAXPY(AA, 1.0, mat, DIFFERENT_NONZERO_PATTERN)); 7248 } 7249 PetscCall(MatAIJGetLocalMat(AA, &A)); 7250 PetscCall(MatGetRowIJ(A, 0, PETSC_FALSE, PETSC_FALSE, &n, &ia, &ja, &done)); 7251 PetscCheck(done, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Unable to get IJ structure from matrix"); 7252 7253 PetscCall(MatGetLocalSize(mat, &n, NULL)); 7254 PetscCall(PetscObjectGetNewTag((PetscObject)mat, &tag)); 7255 PetscCall(PetscObjectGetComm((PetscObject)mat, &comm)); 7256 PetscCallMPI(MPI_Comm_size(comm, &size)); 7257 PetscCallMPI(MPI_Comm_rank(comm, &rank)); 7258 7259 PetscCall(PetscMalloc2(n, &sizes, n, &starts)); 7260 7261 if (rank > 0) { 7262 PetscCallMPI(MPI_Recv(&env, 1, MPIU_INT, rank - 1, tag, comm, &status)); 7263 PetscCallMPI(MPI_Recv(&tbs, 1, MPIU_INT, rank - 1, tag, comm, &status)); 7264 } 7265 PetscCall(MatGetOwnershipRange(mat, &rstart, NULL)); 7266 for (i = 0; i < n; i++) { 7267 env = PetscMax(env, ja[ia[i + 1] - 1]); 7268 II = rstart + i; 7269 if (env == II) { 7270 starts[lblocks] = tbs; 7271 sizes[lblocks++] = 1 + II - tbs; 7272 tbs = 1 + II; 7273 } 7274 } 7275 if (rank < size - 1) { 7276 PetscCallMPI(MPI_Send(&env, 1, MPIU_INT, rank + 1, tag, comm)); 7277 PetscCallMPI(MPI_Send(&tbs, 1, MPIU_INT, rank + 1, tag, comm)); 7278 } 7279 7280 PetscCall(MatRestoreRowIJ(A, 0, PETSC_FALSE, PETSC_FALSE, &n, &ia, &ja, &done)); 7281 if (!set || !flag) PetscCall(MatDestroy(&AA)); 7282 PetscCall(MatDestroy(&A)); 7283 7284 PetscCall(PetscNew(&edata)); 7285 PetscCall(MatGetNonzeroState(mat, &edata->nonzerostate)); 7286 edata->n = lblocks; 7287 /* create IS needed for extracting blocks from the original matrix */ 7288 PetscCall(PetscMalloc1(lblocks, &edata->is)); 7289 for (PetscInt i = 0; i < lblocks; i++) PetscCall(ISCreateStride(PETSC_COMM_SELF, sizes[i], starts[i], 1, &edata->is[i])); 7290 7291 /* Create the resulting inverse matrix structure with preallocation information */ 7292 PetscCall(MatCreate(PetscObjectComm((PetscObject)mat), &edata->C)); 7293 PetscCall(MatSetSizes(edata->C, mat->rmap->n, mat->cmap->n, mat->rmap->N, mat->cmap->N)); 7294 PetscCall(MatSetBlockSizesFromMats(edata->C, mat, mat)); 7295 PetscCall(MatSetType(edata->C, MATAIJ)); 7296 7297 /* Communicate the start and end of each row, from each block to the correct rank */ 7298 /* TODO: Use PetscSF instead of VecScatter */ 7299 for (PetscInt i = 0; i < lblocks; i++) ln += sizes[i]; 7300 PetscCall(VecCreateSeq(PETSC_COMM_SELF, 2 * ln, &seq)); 7301 PetscCall(VecGetArrayWrite(seq, &seqv)); 7302 for (PetscInt i = 0; i < lblocks; i++) { 7303 for (PetscInt j = 0; j < sizes[i]; j++) { 7304 seqv[cnt] = starts[i]; 7305 seqv[cnt + 1] = starts[i] + sizes[i]; 7306 cnt += 2; 7307 } 7308 } 7309 PetscCall(VecRestoreArrayWrite(seq, &seqv)); 7310 PetscCallMPI(MPI_Scan(&cnt, &sc, 1, MPIU_INT, MPI_SUM, PetscObjectComm((PetscObject)mat))); 7311 sc -= cnt; 7312 PetscCall(VecCreateMPI(PetscObjectComm((PetscObject)mat), 2 * mat->rmap->n, 2 * mat->rmap->N, &par)); 7313 PetscCall(ISCreateStride(PETSC_COMM_SELF, cnt, sc, 1, &isglobal)); 7314 PetscCall(VecScatterCreate(seq, NULL, par, isglobal, &scatter)); 7315 PetscCall(ISDestroy(&isglobal)); 7316 PetscCall(VecScatterBegin(scatter, seq, par, INSERT_VALUES, SCATTER_FORWARD)); 7317 PetscCall(VecScatterEnd(scatter, seq, par, INSERT_VALUES, SCATTER_FORWARD)); 7318 PetscCall(VecScatterDestroy(&scatter)); 7319 PetscCall(VecDestroy(&seq)); 7320 PetscCall(MatGetOwnershipRangeColumn(mat, &cstart, &cend)); 7321 PetscCall(PetscMalloc2(mat->rmap->n, &diag, mat->rmap->n, &odiag)); 7322 PetscCall(VecGetArrayRead(par, &parv)); 7323 cnt = 0; 7324 PetscCall(MatGetSize(mat, NULL, &n)); 7325 for (PetscInt i = 0; i < mat->rmap->n; i++) { 7326 PetscInt start, end, d = 0, od = 0; 7327 7328 start = (PetscInt)PetscRealPart(parv[cnt]); 7329 end = (PetscInt)PetscRealPart(parv[cnt + 1]); 7330 cnt += 2; 7331 7332 if (start < cstart) { 7333 od += cstart - start + n - cend; 7334 d += cend - cstart; 7335 } else if (start < cend) { 7336 od += n - cend; 7337 d += cend - start; 7338 } else od += n - start; 7339 if (end <= cstart) { 7340 od -= cstart - end + n - cend; 7341 d -= cend - cstart; 7342 } else if (end < cend) { 7343 od -= n - cend; 7344 d -= cend - end; 7345 } else od -= n - end; 7346 7347 odiag[i] = od; 7348 diag[i] = d; 7349 } 7350 PetscCall(VecRestoreArrayRead(par, &parv)); 7351 PetscCall(VecDestroy(&par)); 7352 PetscCall(MatXAIJSetPreallocation(edata->C, mat->rmap->bs, diag, odiag, NULL, NULL)); 7353 PetscCall(PetscFree2(diag, odiag)); 7354 PetscCall(PetscFree2(sizes, starts)); 7355 7356 PetscCall(PetscContainerCreate(PETSC_COMM_SELF, &container)); 7357 PetscCall(PetscContainerSetPointer(container, edata)); 7358 PetscCall(PetscContainerSetUserDestroy(container, (PetscErrorCode(*)(void *))EnvelopeDataDestroy)); 7359 PetscCall(PetscObjectCompose((PetscObject)mat, "EnvelopeData", (PetscObject)container)); 7360 PetscCall(PetscObjectDereference((PetscObject)container)); 7361 PetscFunctionReturn(0); 7362 } 7363 7364 /*@ 7365 MatInvertVariableBlockEnvelope - set matrix C to be the inverted block diagonal of matrix A 7366 7367 Collective on A 7368 7369 Input Parameters: 7370 . A - the matrix 7371 7372 Output Parameters: 7373 . C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set. 7374 7375 Note: 7376 For efficiency the matrix A should have all the nonzero entries clustered in smallish blocks along the diagonal. 7377 7378 Level: advanced 7379 7380 .seealso: `MatInvertBlockDiagonal()`, `MatComputeBlockDiagonal()` 7381 @*/ 7382 PetscErrorCode MatInvertVariableBlockEnvelope(Mat A, MatReuse reuse, Mat *C) { 7383 PetscContainer container; 7384 EnvelopeData *edata; 7385 PetscObjectState nonzerostate; 7386 7387 PetscFunctionBegin; 7388 PetscCall(PetscObjectQuery((PetscObject)A, "EnvelopeData", (PetscObject *)&container)); 7389 if (!container) { 7390 PetscCall(MatComputeVariableBlockEnvelope(A)); 7391 PetscCall(PetscObjectQuery((PetscObject)A, "EnvelopeData", (PetscObject *)&container)); 7392 } 7393 PetscCall(PetscContainerGetPointer(container, (void **)&edata)); 7394 PetscCall(MatGetNonzeroState(A, &nonzerostate)); 7395 PetscCheck(nonzerostate <= edata->nonzerostate, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Cannot handle changes to matrix nonzero structure"); 7396 PetscCheck(reuse != MAT_REUSE_MATRIX || *C == edata->C, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "C matrix must be the same as previously output"); 7397 7398 PetscCall(MatCreateSubMatrices(A, edata->n, edata->is, edata->is, MAT_INITIAL_MATRIX, &edata->mat)); 7399 *C = edata->C; 7400 7401 for (PetscInt i = 0; i < edata->n; i++) { 7402 Mat D; 7403 PetscScalar *dvalues; 7404 7405 PetscCall(MatConvert(edata->mat[i], MATSEQDENSE, MAT_INITIAL_MATRIX, &D)); 7406 PetscCall(MatSetOption(*C, MAT_ROW_ORIENTED, PETSC_FALSE)); 7407 PetscCall(MatSeqDenseInvert(D)); 7408 PetscCall(MatDenseGetArray(D, &dvalues)); 7409 PetscCall(MatSetValuesIS(*C, edata->is[i], edata->is[i], dvalues, INSERT_VALUES)); 7410 PetscCall(MatDestroy(&D)); 7411 } 7412 PetscCall(MatDestroySubMatrices(edata->n, &edata->mat)); 7413 PetscCall(MatAssemblyBegin(*C, MAT_FINAL_ASSEMBLY)); 7414 PetscCall(MatAssemblyEnd(*C, MAT_FINAL_ASSEMBLY)); 7415 PetscFunctionReturn(0); 7416 } 7417 7418 /*@ 7419 MatSetVariableBlockSizes - Sets diagonal point-blocks of the matrix that need not be of the same size 7420 7421 Logically Collective on mat 7422 7423 Input Parameters: 7424 + mat - the matrix 7425 . nblocks - the number of blocks on this process, each block can only exist on a single process 7426 - bsizes - the block sizes 7427 7428 Notes: 7429 Currently used by `PCVPBJACOBI` for `MATAIJ` matrices 7430 7431 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. 7432 7433 Level: intermediate 7434 7435 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`, `MatGetBlockSizes()`, `MatGetVariableBlockSizes()`, 7436 `MatComputeVariableBlockEnvelope()`, `PCVPBJACOBI` 7437 @*/ 7438 PetscErrorCode MatSetVariableBlockSizes(Mat mat, PetscInt nblocks, PetscInt *bsizes) { 7439 PetscInt i, ncnt = 0, nlocal; 7440 7441 PetscFunctionBegin; 7442 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7443 PetscCheck(nblocks >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Number of local blocks must be great than or equal to zero"); 7444 PetscCall(MatGetLocalSize(mat, &nlocal, NULL)); 7445 for (i = 0; i < nblocks; i++) ncnt += bsizes[i]; 7446 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); 7447 PetscCall(PetscFree(mat->bsizes)); 7448 mat->nblocks = nblocks; 7449 PetscCall(PetscMalloc1(nblocks, &mat->bsizes)); 7450 PetscCall(PetscArraycpy(mat->bsizes, bsizes, nblocks)); 7451 PetscFunctionReturn(0); 7452 } 7453 7454 /*@C 7455 MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size 7456 7457 Logically Collective on mat 7458 7459 Input Parameter: 7460 . mat - the matrix 7461 7462 Output Parameters: 7463 + nblocks - the number of blocks on this process 7464 - bsizes - the block sizes 7465 7466 Fortran Note: 7467 Currently not supported from Fortran 7468 7469 Level: intermediate 7470 7471 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`, `MatGetBlockSizes()`, `MatSetVariableBlockSizes()`, `MatComputeVariableBlockEnvelope()` 7472 @*/ 7473 PetscErrorCode MatGetVariableBlockSizes(Mat mat, PetscInt *nblocks, const PetscInt **bsizes) { 7474 PetscFunctionBegin; 7475 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7476 *nblocks = mat->nblocks; 7477 *bsizes = mat->bsizes; 7478 PetscFunctionReturn(0); 7479 } 7480 7481 /*@ 7482 MatSetBlockSizes - Sets the matrix block row and column sizes. 7483 7484 Logically Collective on mat 7485 7486 Input Parameters: 7487 + mat - the matrix 7488 . rbs - row block size 7489 - cbs - column block size 7490 7491 Notes: 7492 Block row formats are `MATBAIJ` and `MATSBAIJ`. These formats ALWAYS have square block storage in the matrix. 7493 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7494 This must be called before `MatSetUp()` or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7495 7496 For `MATAIJ` matrix this function can be called at a later stage, provided that the specified block sizes 7497 are compatible with the matrix local sizes. 7498 7499 The row and column block size determine the blocksize of the "row" and "column" vectors returned by `MatCreateVecs()`. 7500 7501 Level: intermediate 7502 7503 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSize()`, `MatGetBlockSizes()` 7504 @*/ 7505 PetscErrorCode MatSetBlockSizes(Mat mat, PetscInt rbs, PetscInt cbs) { 7506 PetscFunctionBegin; 7507 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7508 PetscValidLogicalCollectiveInt(mat, rbs, 2); 7509 PetscValidLogicalCollectiveInt(mat, cbs, 3); 7510 PetscTryTypeMethod(mat, setblocksizes, rbs, cbs); 7511 if (mat->rmap->refcnt) { 7512 ISLocalToGlobalMapping l2g = NULL; 7513 PetscLayout nmap = NULL; 7514 7515 PetscCall(PetscLayoutDuplicate(mat->rmap, &nmap)); 7516 if (mat->rmap->mapping) PetscCall(ISLocalToGlobalMappingDuplicate(mat->rmap->mapping, &l2g)); 7517 PetscCall(PetscLayoutDestroy(&mat->rmap)); 7518 mat->rmap = nmap; 7519 mat->rmap->mapping = l2g; 7520 } 7521 if (mat->cmap->refcnt) { 7522 ISLocalToGlobalMapping l2g = NULL; 7523 PetscLayout nmap = NULL; 7524 7525 PetscCall(PetscLayoutDuplicate(mat->cmap, &nmap)); 7526 if (mat->cmap->mapping) PetscCall(ISLocalToGlobalMappingDuplicate(mat->cmap->mapping, &l2g)); 7527 PetscCall(PetscLayoutDestroy(&mat->cmap)); 7528 mat->cmap = nmap; 7529 mat->cmap->mapping = l2g; 7530 } 7531 PetscCall(PetscLayoutSetBlockSize(mat->rmap, rbs)); 7532 PetscCall(PetscLayoutSetBlockSize(mat->cmap, cbs)); 7533 PetscFunctionReturn(0); 7534 } 7535 7536 /*@ 7537 MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices 7538 7539 Logically Collective on mat 7540 7541 Input Parameters: 7542 + mat - the matrix 7543 . fromRow - matrix from which to copy row block size 7544 - fromCol - matrix from which to copy column block size (can be same as fromRow) 7545 7546 Level: developer 7547 7548 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()` 7549 @*/ 7550 PetscErrorCode MatSetBlockSizesFromMats(Mat mat, Mat fromRow, Mat fromCol) { 7551 PetscFunctionBegin; 7552 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7553 PetscValidHeaderSpecific(fromRow, MAT_CLASSID, 2); 7554 PetscValidHeaderSpecific(fromCol, MAT_CLASSID, 3); 7555 if (fromRow->rmap->bs > 0) PetscCall(PetscLayoutSetBlockSize(mat->rmap, fromRow->rmap->bs)); 7556 if (fromCol->cmap->bs > 0) PetscCall(PetscLayoutSetBlockSize(mat->cmap, fromCol->cmap->bs)); 7557 PetscFunctionReturn(0); 7558 } 7559 7560 /*@ 7561 MatResidual - Default routine to calculate the residual r = b - Ax 7562 7563 Collective on mat 7564 7565 Input Parameters: 7566 + mat - the matrix 7567 . b - the right-hand-side 7568 - x - the approximate solution 7569 7570 Output Parameter: 7571 . r - location to store the residual 7572 7573 Level: developer 7574 7575 .seealso: `Mat`, `MatMult()`, `MatMultAdd()`, `PCMGSetResidual()` 7576 @*/ 7577 PetscErrorCode MatResidual(Mat mat, Vec b, Vec x, Vec r) { 7578 PetscFunctionBegin; 7579 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7580 PetscValidHeaderSpecific(b, VEC_CLASSID, 2); 7581 PetscValidHeaderSpecific(x, VEC_CLASSID, 3); 7582 PetscValidHeaderSpecific(r, VEC_CLASSID, 4); 7583 PetscValidType(mat, 1); 7584 MatCheckPreallocated(mat, 1); 7585 PetscCall(PetscLogEventBegin(MAT_Residual, mat, 0, 0, 0)); 7586 if (!mat->ops->residual) { 7587 PetscCall(MatMult(mat, x, r)); 7588 PetscCall(VecAYPX(r, -1.0, b)); 7589 } else { 7590 PetscUseTypeMethod(mat, residual, b, x, r); 7591 } 7592 PetscCall(PetscLogEventEnd(MAT_Residual, mat, 0, 0, 0)); 7593 PetscFunctionReturn(0); 7594 } 7595 7596 /*@C 7597 MatGetRowIJ - Returns the compressed row storage i and j indices for the local rows of a sparse matrix 7598 7599 Collective on mat 7600 7601 Input Parameters: 7602 + mat - the matrix 7603 . shift - 0 or 1 indicating we want the indices starting at 0 or 1 7604 . symmetric - `PETSC_TRUE` or `PETSC_FALSE` indicating the matrix data structure should be symmetrized 7605 - inodecompressed - `PETSC_TRUE` or `PETSC_FALSE` indicats if the nonzero structure of the 7606 inodes or the nonzero elements is wanted. For `MATBAIJ` matrices the compressed version is 7607 always used. 7608 7609 Output Parameters: 7610 + n - number of local rows in the (possibly compressed) matrix 7611 . ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix 7612 . ja - the column indices 7613 - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers 7614 are responsible for handling the case when done == `PETSC_FALSE` and ia and ja are not set 7615 7616 Level: developer 7617 7618 Notes: 7619 You CANNOT change any of the ia[] or ja[] values. 7620 7621 Use `MatRestoreRowIJ()` when you are finished accessing the ia[] and ja[] values. 7622 7623 Fortran Notes: 7624 In Fortran use 7625 $ 7626 $ PetscInt ia(1), ja(1) 7627 $ PetscOffset iia, jja 7628 $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr) 7629 $ ! Access the ith and jth entries via ia(iia + i) and ja(jja + j) 7630 7631 or 7632 $ 7633 $ PetscInt, pointer :: ia(:),ja(:) 7634 $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr) 7635 $ ! Access the ith and jth entries via ia(i) and ja(j) 7636 7637 .seealso: `Mat`, `MATAIJ`, `MatGetColumnIJ()`, `MatRestoreRowIJ()`, `MatSeqAIJGetArray()` 7638 @*/ 7639 PetscErrorCode MatGetRowIJ(Mat mat, PetscInt shift, PetscBool symmetric, PetscBool inodecompressed, PetscInt *n, const PetscInt *ia[], const PetscInt *ja[], PetscBool *done) { 7640 PetscFunctionBegin; 7641 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7642 PetscValidType(mat, 1); 7643 if (n) PetscValidIntPointer(n, 5); 7644 if (ia) PetscValidPointer(ia, 6); 7645 if (ja) PetscValidPointer(ja, 7); 7646 if (done) PetscValidBoolPointer(done, 8); 7647 MatCheckPreallocated(mat, 1); 7648 if (!mat->ops->getrowij && done) *done = PETSC_FALSE; 7649 else { 7650 if (done) *done = PETSC_TRUE; 7651 PetscCall(PetscLogEventBegin(MAT_GetRowIJ, mat, 0, 0, 0)); 7652 PetscUseTypeMethod(mat, getrowij, shift, symmetric, inodecompressed, n, ia, ja, done); 7653 PetscCall(PetscLogEventEnd(MAT_GetRowIJ, mat, 0, 0, 0)); 7654 } 7655 PetscFunctionReturn(0); 7656 } 7657 7658 /*@C 7659 MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices. 7660 7661 Collective on mat 7662 7663 Input Parameters: 7664 + mat - the matrix 7665 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7666 . symmetric - `PETSC_TRUE` or `PETSC_FALSE` indicating the matrix data structure should be 7667 symmetrized 7668 . inodecompressed - `PETSC_TRUE` or `PETSC_FALSE` indicating if the nonzero structure of the 7669 inodes or the nonzero elements is wanted. For `MATBAIJ` matrices the compressed version is 7670 always used. 7671 . n - number of columns in the (possibly compressed) matrix 7672 . ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix 7673 - ja - the row indices 7674 7675 Output Parameters: 7676 . done - `PETSC_TRUE` or `PETSC_FALSE`, indicating whether the values have been returned 7677 7678 Level: developer 7679 7680 .seealso: `MatGetRowIJ()`, `MatRestoreColumnIJ()` 7681 @*/ 7682 PetscErrorCode MatGetColumnIJ(Mat mat, PetscInt shift, PetscBool symmetric, PetscBool inodecompressed, PetscInt *n, const PetscInt *ia[], const PetscInt *ja[], PetscBool *done) { 7683 PetscFunctionBegin; 7684 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7685 PetscValidType(mat, 1); 7686 PetscValidIntPointer(n, 5); 7687 if (ia) PetscValidPointer(ia, 6); 7688 if (ja) PetscValidPointer(ja, 7); 7689 PetscValidBoolPointer(done, 8); 7690 MatCheckPreallocated(mat, 1); 7691 if (!mat->ops->getcolumnij) *done = PETSC_FALSE; 7692 else { 7693 *done = PETSC_TRUE; 7694 PetscUseTypeMethod(mat, getcolumnij, shift, symmetric, inodecompressed, n, ia, ja, done); 7695 } 7696 PetscFunctionReturn(0); 7697 } 7698 7699 /*@C 7700 MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with `MatGetRowIJ()`. 7701 7702 Collective on mat 7703 7704 Input Parameters: 7705 + mat - the matrix 7706 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7707 . symmetric - `PETSC_TRUE` or `PETSC_FALSE` indicating the matrix data structure should be symmetrized 7708 . inodecompressed - `PETSC_TRUE` or `PETSC_FALSE` indicating if the nonzero structure of the 7709 inodes or the nonzero elements is wanted. For `MATBAIJ` matrices the compressed version is 7710 always used. 7711 . n - size of (possibly compressed) matrix 7712 . ia - the row pointers 7713 - ja - the column indices 7714 7715 Output Parameters: 7716 . done - `PETSC_TRUE` or `PETSC_FALSE` indicated that the values have been returned 7717 7718 Note: 7719 This routine zeros out n, ia, and ja. This is to prevent accidental 7720 us of the array after it has been restored. If you pass NULL, it will 7721 not zero the pointers. Use of ia or ja after `MatRestoreRowIJ()` is invalid. 7722 7723 Level: developer 7724 7725 .seealso: `MatGetRowIJ()`, `MatRestoreColumnIJ()` 7726 @*/ 7727 PetscErrorCode MatRestoreRowIJ(Mat mat, PetscInt shift, PetscBool symmetric, PetscBool inodecompressed, PetscInt *n, const PetscInt *ia[], const PetscInt *ja[], PetscBool *done) { 7728 PetscFunctionBegin; 7729 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7730 PetscValidType(mat, 1); 7731 if (ia) PetscValidPointer(ia, 6); 7732 if (ja) PetscValidPointer(ja, 7); 7733 if (done) PetscValidBoolPointer(done, 8); 7734 MatCheckPreallocated(mat, 1); 7735 7736 if (!mat->ops->restorerowij && done) *done = PETSC_FALSE; 7737 else { 7738 if (done) *done = PETSC_TRUE; 7739 PetscUseTypeMethod(mat, restorerowij, shift, symmetric, inodecompressed, n, ia, ja, done); 7740 if (n) *n = 0; 7741 if (ia) *ia = NULL; 7742 if (ja) *ja = NULL; 7743 } 7744 PetscFunctionReturn(0); 7745 } 7746 7747 /*@C 7748 MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with `MatGetColumnIJ()`. 7749 7750 Collective on Mat 7751 7752 Input Parameters: 7753 + mat - the matrix 7754 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7755 . symmetric - `PETSC_TRUE` or `PETSC_FALSE` indicating the matrix data structure should be symmetrized 7756 - inodecompressed - `PETSC_TRUE` or `PETSC_FALSE` indicating if the nonzero structure of the 7757 inodes or the nonzero elements is wanted. For `MATBAIJ` matrices the compressed version is 7758 always used. 7759 7760 Output Parameters: 7761 + n - size of (possibly compressed) matrix 7762 . ia - the column pointers 7763 . ja - the row indices 7764 - done - `PETSC_TRUE` or `PETSC_FALSE` indicated that the values have been returned 7765 7766 Level: developer 7767 7768 .seealso: `MatGetColumnIJ()`, `MatRestoreRowIJ()` 7769 @*/ 7770 PetscErrorCode MatRestoreColumnIJ(Mat mat, PetscInt shift, PetscBool symmetric, PetscBool inodecompressed, PetscInt *n, const PetscInt *ia[], const PetscInt *ja[], PetscBool *done) { 7771 PetscFunctionBegin; 7772 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7773 PetscValidType(mat, 1); 7774 if (ia) PetscValidPointer(ia, 6); 7775 if (ja) PetscValidPointer(ja, 7); 7776 PetscValidBoolPointer(done, 8); 7777 MatCheckPreallocated(mat, 1); 7778 7779 if (!mat->ops->restorecolumnij) *done = PETSC_FALSE; 7780 else { 7781 *done = PETSC_TRUE; 7782 PetscUseTypeMethod(mat, restorecolumnij, shift, symmetric, inodecompressed, n, ia, ja, done); 7783 if (n) *n = 0; 7784 if (ia) *ia = NULL; 7785 if (ja) *ja = NULL; 7786 } 7787 PetscFunctionReturn(0); 7788 } 7789 7790 /*@C 7791 MatColoringPatch -Used inside matrix coloring routines that use `MatGetRowIJ()` and/or `MatGetColumnIJ()`. 7792 7793 Collective on mat 7794 7795 Input Parameters: 7796 + mat - the matrix 7797 . ncolors - max color value 7798 . n - number of entries in colorarray 7799 - colorarray - array indicating color for each column 7800 7801 Output Parameters: 7802 . iscoloring - coloring generated using colorarray information 7803 7804 Level: developer 7805 7806 .seealso: `MatGetRowIJ()`, `MatGetColumnIJ()` 7807 @*/ 7808 PetscErrorCode MatColoringPatch(Mat mat, PetscInt ncolors, PetscInt n, ISColoringValue colorarray[], ISColoring *iscoloring) { 7809 PetscFunctionBegin; 7810 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7811 PetscValidType(mat, 1); 7812 PetscValidIntPointer(colorarray, 4); 7813 PetscValidPointer(iscoloring, 5); 7814 MatCheckPreallocated(mat, 1); 7815 7816 if (!mat->ops->coloringpatch) { 7817 PetscCall(ISColoringCreate(PetscObjectComm((PetscObject)mat), ncolors, n, colorarray, PETSC_OWN_POINTER, iscoloring)); 7818 } else { 7819 PetscUseTypeMethod(mat, coloringpatch, ncolors, n, colorarray, iscoloring); 7820 } 7821 PetscFunctionReturn(0); 7822 } 7823 7824 /*@ 7825 MatSetUnfactored - Resets a factored matrix to be treated as unfactored. 7826 7827 Logically Collective on mat 7828 7829 Input Parameter: 7830 . mat - the factored matrix to be reset 7831 7832 Notes: 7833 This routine should be used only with factored matrices formed by in-place 7834 factorization via ILU(0) (or by in-place LU factorization for the `MATSEQDENSE` 7835 format). This option can save memory, for example, when solving nonlinear 7836 systems with a matrix-free Newton-Krylov method and a matrix-based, in-place 7837 ILU(0) preconditioner. 7838 7839 Note that one can specify in-place ILU(0) factorization by calling 7840 .vb 7841 PCType(pc,PCILU); 7842 PCFactorSeUseInPlace(pc); 7843 .ve 7844 or by using the options -pc_type ilu -pc_factor_in_place 7845 7846 In-place factorization ILU(0) can also be used as a local 7847 solver for the blocks within the block Jacobi or additive Schwarz 7848 methods (runtime option: -sub_pc_factor_in_place). See Users-Manual: ch_pc 7849 for details on setting local solver options. 7850 7851 Most users should employ the `KSP` interface for linear solvers 7852 instead of working directly with matrix algebra routines such as this. 7853 See, e.g., `KSPCreate()`. 7854 7855 Level: developer 7856 7857 .seealso: `PCFactorSetUseInPlace()`, `PCFactorGetUseInPlace()` 7858 @*/ 7859 PetscErrorCode MatSetUnfactored(Mat mat) { 7860 PetscFunctionBegin; 7861 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7862 PetscValidType(mat, 1); 7863 MatCheckPreallocated(mat, 1); 7864 mat->factortype = MAT_FACTOR_NONE; 7865 if (!mat->ops->setunfactored) PetscFunctionReturn(0); 7866 PetscUseTypeMethod(mat, setunfactored); 7867 PetscFunctionReturn(0); 7868 } 7869 7870 /*MC 7871 MatDenseGetArrayF90 - Accesses a matrix array from Fortran 7872 7873 Synopsis: 7874 MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7875 7876 Not collective 7877 7878 Input Parameter: 7879 . x - matrix 7880 7881 Output Parameters: 7882 + xx_v - the Fortran pointer to the array 7883 - ierr - error code 7884 7885 Example of Usage: 7886 .vb 7887 PetscScalar, pointer xx_v(:,:) 7888 .... 7889 call MatDenseGetArrayF90(x,xx_v,ierr) 7890 a = xx_v(3) 7891 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7892 .ve 7893 7894 Level: advanced 7895 7896 .seealso: `MatDenseRestoreArrayF90()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatSeqAIJGetArrayF90()` 7897 7898 M*/ 7899 7900 /*MC 7901 MatDenseRestoreArrayF90 - Restores a matrix array that has been 7902 accessed with `MatDenseGetArrayF90()`. 7903 7904 Synopsis: 7905 MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7906 7907 Not collective 7908 7909 Input Parameters: 7910 + x - matrix 7911 - xx_v - the Fortran90 pointer to the array 7912 7913 Output Parameter: 7914 . ierr - error code 7915 7916 Example of Usage: 7917 .vb 7918 PetscScalar, pointer xx_v(:,:) 7919 .... 7920 call MatDenseGetArrayF90(x,xx_v,ierr) 7921 a = xx_v(3) 7922 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7923 .ve 7924 7925 Level: advanced 7926 7927 .seealso: `MatDenseGetArrayF90()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatSeqAIJRestoreArrayF90()` 7928 7929 M*/ 7930 7931 /*MC 7932 MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran. 7933 7934 Synopsis: 7935 MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7936 7937 Not collective 7938 7939 Input Parameter: 7940 . x - matrix 7941 7942 Output Parameters: 7943 + xx_v - the Fortran pointer to the array 7944 - ierr - error code 7945 7946 Example of Usage: 7947 .vb 7948 PetscScalar, pointer xx_v(:) 7949 .... 7950 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 7951 a = xx_v(3) 7952 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 7953 .ve 7954 7955 Level: advanced 7956 7957 .seealso: `MatSeqAIJRestoreArrayF90()`, `MatSeqAIJGetArray()`, `MatSeqAIJRestoreArray()`, `MatDenseGetArrayF90()` 7958 7959 M*/ 7960 7961 /*MC 7962 MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been 7963 accessed with `MatSeqAIJGetArrayF90()`. 7964 7965 Synopsis: 7966 MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7967 7968 Not collective 7969 7970 Input Parameters: 7971 + x - matrix 7972 - xx_v - the Fortran90 pointer to the array 7973 7974 Output Parameter: 7975 . ierr - error code 7976 7977 Example of Usage: 7978 .vb 7979 PetscScalar, pointer xx_v(:) 7980 .... 7981 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 7982 a = xx_v(3) 7983 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 7984 .ve 7985 7986 Level: advanced 7987 7988 .seealso: `MatSeqAIJGetArrayF90()`, `MatSeqAIJGetArray()`, `MatSeqAIJRestoreArray()`, `MatDenseRestoreArrayF90()` 7989 7990 M*/ 7991 7992 /*@ 7993 MatCreateSubMatrix - Gets a single submatrix on the same number of processors 7994 as the original matrix. 7995 7996 Collective on mat 7997 7998 Input Parameters: 7999 + mat - the original matrix 8000 . isrow - parallel IS containing the rows this processor should obtain 8001 . 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. 8002 - cll - either `MAT_INITIAL_MATRIX` or `MAT_REUSE_MATRIX` 8003 8004 Output Parameter: 8005 . newmat - the new submatrix, of the same type as the old 8006 8007 Level: advanced 8008 8009 Notes: 8010 The submatrix will be able to be multiplied with vectors using the same layout as iscol. 8011 8012 Some matrix types place restrictions on the row and column indices, such 8013 as that they be sorted or that they be equal to each other. 8014 8015 The index sets may not have duplicate entries. 8016 8017 The first time this is called you should use a cll of `MAT_INITIAL_MATRIX`, 8018 the `MatCreateSubMatrix()` routine will create the newmat for you. Any additional calls 8019 to this routine with a mat of the same nonzero structure and with a call of `MAT_REUSE_MATRIX` 8020 will reuse the matrix generated the first time. You should call `MatDestroy()` on newmat when 8021 you are finished using it. 8022 8023 The communicator of the newly obtained matrix is ALWAYS the same as the communicator of 8024 the input matrix. 8025 8026 If iscol is NULL then all columns are obtained (not supported in Fortran). 8027 8028 Example usage: 8029 Consider the following 8x8 matrix with 34 non-zero values, that is 8030 assembled across 3 processors. Let's assume that proc0 owns 3 rows, 8031 proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown 8032 as follows: 8033 8034 .vb 8035 1 2 0 | 0 3 0 | 0 4 8036 Proc0 0 5 6 | 7 0 0 | 8 0 8037 9 0 10 | 11 0 0 | 12 0 8038 ------------------------------------- 8039 13 0 14 | 15 16 17 | 0 0 8040 Proc1 0 18 0 | 19 20 21 | 0 0 8041 0 0 0 | 22 23 0 | 24 0 8042 ------------------------------------- 8043 Proc2 25 26 27 | 0 0 28 | 29 0 8044 30 0 0 | 31 32 33 | 0 34 8045 .ve 8046 8047 Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is 8048 8049 .vb 8050 2 0 | 0 3 0 | 0 8051 Proc0 5 6 | 7 0 0 | 8 8052 ------------------------------- 8053 Proc1 18 0 | 19 20 21 | 0 8054 ------------------------------- 8055 Proc2 26 27 | 0 0 28 | 29 8056 0 0 | 31 32 33 | 0 8057 .ve 8058 8059 .seealso: `Mat`, `MatCreateSubMatrices()`, `MatCreateSubMatricesMPI()`, `MatCreateSubMatrixVirtual()`, `MatSubMatrixVirtualUpdate()` 8060 @*/ 8061 PetscErrorCode MatCreateSubMatrix(Mat mat, IS isrow, IS iscol, MatReuse cll, Mat *newmat) { 8062 PetscMPIInt size; 8063 Mat *local; 8064 IS iscoltmp; 8065 PetscBool flg; 8066 8067 PetscFunctionBegin; 8068 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8069 PetscValidHeaderSpecific(isrow, IS_CLASSID, 2); 8070 if (iscol) PetscValidHeaderSpecific(iscol, IS_CLASSID, 3); 8071 PetscValidPointer(newmat, 5); 8072 if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat, MAT_CLASSID, 5); 8073 PetscValidType(mat, 1); 8074 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 8075 PetscCheck(cll != MAT_IGNORE_MATRIX, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Cannot use MAT_IGNORE_MATRIX"); 8076 8077 MatCheckPreallocated(mat, 1); 8078 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size)); 8079 8080 if (!iscol || isrow == iscol) { 8081 PetscBool stride; 8082 PetscMPIInt grabentirematrix = 0, grab; 8083 PetscCall(PetscObjectTypeCompare((PetscObject)isrow, ISSTRIDE, &stride)); 8084 if (stride) { 8085 PetscInt first, step, n, rstart, rend; 8086 PetscCall(ISStrideGetInfo(isrow, &first, &step)); 8087 if (step == 1) { 8088 PetscCall(MatGetOwnershipRange(mat, &rstart, &rend)); 8089 if (rstart == first) { 8090 PetscCall(ISGetLocalSize(isrow, &n)); 8091 if (n == rend - rstart) grabentirematrix = 1; 8092 } 8093 } 8094 } 8095 PetscCall(MPIU_Allreduce(&grabentirematrix, &grab, 1, MPI_INT, MPI_MIN, PetscObjectComm((PetscObject)mat))); 8096 if (grab) { 8097 PetscCall(PetscInfo(mat, "Getting entire matrix as submatrix\n")); 8098 if (cll == MAT_INITIAL_MATRIX) { 8099 *newmat = mat; 8100 PetscCall(PetscObjectReference((PetscObject)mat)); 8101 } 8102 PetscFunctionReturn(0); 8103 } 8104 } 8105 8106 if (!iscol) { 8107 PetscCall(ISCreateStride(PetscObjectComm((PetscObject)mat), mat->cmap->n, mat->cmap->rstart, 1, &iscoltmp)); 8108 } else { 8109 iscoltmp = iscol; 8110 } 8111 8112 /* if original matrix is on just one processor then use submatrix generated */ 8113 if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) { 8114 PetscCall(MatCreateSubMatrices(mat, 1, &isrow, &iscoltmp, MAT_REUSE_MATRIX, &newmat)); 8115 goto setproperties; 8116 } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) { 8117 PetscCall(MatCreateSubMatrices(mat, 1, &isrow, &iscoltmp, MAT_INITIAL_MATRIX, &local)); 8118 *newmat = *local; 8119 PetscCall(PetscFree(local)); 8120 goto setproperties; 8121 } else if (!mat->ops->createsubmatrix) { 8122 /* Create a new matrix type that implements the operation using the full matrix */ 8123 PetscCall(PetscLogEventBegin(MAT_CreateSubMat, mat, 0, 0, 0)); 8124 switch (cll) { 8125 case MAT_INITIAL_MATRIX: PetscCall(MatCreateSubMatrixVirtual(mat, isrow, iscoltmp, newmat)); break; 8126 case MAT_REUSE_MATRIX: PetscCall(MatSubMatrixVirtualUpdate(*newmat, mat, isrow, iscoltmp)); break; 8127 default: SETERRQ(PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_OUTOFRANGE, "Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX"); 8128 } 8129 PetscCall(PetscLogEventEnd(MAT_CreateSubMat, mat, 0, 0, 0)); 8130 goto setproperties; 8131 } 8132 8133 PetscCall(PetscLogEventBegin(MAT_CreateSubMat, mat, 0, 0, 0)); 8134 PetscUseTypeMethod(mat, createsubmatrix, isrow, iscoltmp, cll, newmat); 8135 PetscCall(PetscLogEventEnd(MAT_CreateSubMat, mat, 0, 0, 0)); 8136 8137 setproperties: 8138 PetscCall(ISEqualUnsorted(isrow, iscoltmp, &flg)); 8139 if (flg) PetscCall(MatPropagateSymmetryOptions(mat, *newmat)); 8140 if (!iscol) PetscCall(ISDestroy(&iscoltmp)); 8141 if (*newmat && cll == MAT_INITIAL_MATRIX) PetscCall(PetscObjectStateIncrease((PetscObject)*newmat)); 8142 PetscFunctionReturn(0); 8143 } 8144 8145 /*@ 8146 MatPropagateSymmetryOptions - Propagates symmetry options set on a matrix to another matrix 8147 8148 Not Collective 8149 8150 Input Parameters: 8151 + A - the matrix we wish to propagate options from 8152 - B - the matrix we wish to propagate options to 8153 8154 Level: beginner 8155 8156 Note: 8157 Propagates the options associated to `MAT_SYMMETRY_ETERNAL`, `MAT_STRUCTURALLY_SYMMETRIC`, `MAT_HERMITIAN`, `MAT_SPD`, `MAT_SYMMETRIC`, and `MAT_STRUCTURAL_SYMMETRY_ETERNAL` 8158 8159 .seealso: `MatSetOption()`, `MatIsSymmetricKnown()`, `MatIsSPDKnown()`, `MatIsHermitianKnown()`, MatIsStructurallySymmetricKnown()` 8160 @*/ 8161 PetscErrorCode MatPropagateSymmetryOptions(Mat A, Mat B) { 8162 PetscFunctionBegin; 8163 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8164 PetscValidHeaderSpecific(B, MAT_CLASSID, 2); 8165 B->symmetry_eternal = A->symmetry_eternal; 8166 B->structural_symmetry_eternal = A->structural_symmetry_eternal; 8167 B->symmetric = A->symmetric; 8168 B->structurally_symmetric = A->structurally_symmetric; 8169 B->spd = A->spd; 8170 B->hermitian = A->hermitian; 8171 PetscFunctionReturn(0); 8172 } 8173 8174 /*@ 8175 MatStashSetInitialSize - sets the sizes of the matrix stash, that is 8176 used during the assembly process to store values that belong to 8177 other processors. 8178 8179 Not Collective 8180 8181 Input Parameters: 8182 + mat - the matrix 8183 . size - the initial size of the stash. 8184 - bsize - the initial size of the block-stash(if used). 8185 8186 Options Database Keys: 8187 + -matstash_initial_size <size> or <size0,size1,...sizep-1> 8188 - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1> 8189 8190 Level: intermediate 8191 8192 Notes: 8193 The block-stash is used for values set with `MatSetValuesBlocked()` while 8194 the stash is used for values set with `MatSetValues()` 8195 8196 Run with the option -info and look for output of the form 8197 MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs. 8198 to determine the appropriate value, MM, to use for size and 8199 MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs. 8200 to determine the value, BMM to use for bsize 8201 8202 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `Mat`, `MatStashGetInfo()` 8203 @*/ 8204 PetscErrorCode MatStashSetInitialSize(Mat mat, PetscInt size, PetscInt bsize) { 8205 PetscFunctionBegin; 8206 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8207 PetscValidType(mat, 1); 8208 PetscCall(MatStashSetInitialSize_Private(&mat->stash, size)); 8209 PetscCall(MatStashSetInitialSize_Private(&mat->bstash, bsize)); 8210 PetscFunctionReturn(0); 8211 } 8212 8213 /*@ 8214 MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 8215 the matrix 8216 8217 Neighbor-wise Collective on mat 8218 8219 Input Parameters: 8220 + mat - the matrix 8221 . x,y - the vectors 8222 - w - where the result is stored 8223 8224 Level: intermediate 8225 8226 Notes: 8227 w may be the same vector as y. 8228 8229 This allows one to use either the restriction or interpolation (its transpose) 8230 matrix to do the interpolation 8231 8232 .seealso: `MatMultAdd()`, `MatMultTransposeAdd()`, `MatRestrict()`, `PCMG` 8233 @*/ 8234 PetscErrorCode MatInterpolateAdd(Mat A, Vec x, Vec y, Vec w) { 8235 PetscInt M, N, Ny; 8236 8237 PetscFunctionBegin; 8238 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8239 PetscValidHeaderSpecific(x, VEC_CLASSID, 2); 8240 PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 8241 PetscValidHeaderSpecific(w, VEC_CLASSID, 4); 8242 PetscCall(MatGetSize(A, &M, &N)); 8243 PetscCall(VecGetSize(y, &Ny)); 8244 if (M == Ny) { 8245 PetscCall(MatMultAdd(A, x, y, w)); 8246 } else { 8247 PetscCall(MatMultTransposeAdd(A, x, y, w)); 8248 } 8249 PetscFunctionReturn(0); 8250 } 8251 8252 /*@ 8253 MatInterpolate - y = A*x or A'*x depending on the shape of 8254 the matrix 8255 8256 Neighbor-wise Collective on mat 8257 8258 Input Parameters: 8259 + mat - the matrix 8260 - x,y - the vectors 8261 8262 Level: intermediate 8263 8264 Note: 8265 This allows one to use either the restriction or interpolation (its transpose) 8266 matrix to do the interpolation 8267 8268 .seealso: `MatMultAdd()`, `MatMultTransposeAdd()`, `MatRestrict()`, `PCMG` 8269 @*/ 8270 PetscErrorCode MatInterpolate(Mat A, Vec x, Vec y) { 8271 PetscInt M, N, Ny; 8272 8273 PetscFunctionBegin; 8274 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8275 PetscValidHeaderSpecific(x, VEC_CLASSID, 2); 8276 PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 8277 PetscCall(MatGetSize(A, &M, &N)); 8278 PetscCall(VecGetSize(y, &Ny)); 8279 if (M == Ny) { 8280 PetscCall(MatMult(A, x, y)); 8281 } else { 8282 PetscCall(MatMultTranspose(A, x, y)); 8283 } 8284 PetscFunctionReturn(0); 8285 } 8286 8287 /*@ 8288 MatRestrict - y = A*x or A'*x 8289 8290 Neighbor-wise Collective on Mat 8291 8292 Input Parameters: 8293 + mat - the matrix 8294 - x,y - the vectors 8295 8296 Level: intermediate 8297 8298 Note: 8299 This allows one to use either the restriction or interpolation (its transpose) 8300 matrix to do the restriction 8301 8302 .seealso: `MatMultAdd()`, `MatMultTransposeAdd()`, `MatInterpolate()`, `PCMG` 8303 @*/ 8304 PetscErrorCode MatRestrict(Mat A, Vec x, Vec y) { 8305 PetscInt M, N, Ny; 8306 8307 PetscFunctionBegin; 8308 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8309 PetscValidHeaderSpecific(x, VEC_CLASSID, 2); 8310 PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 8311 PetscCall(MatGetSize(A, &M, &N)); 8312 PetscCall(VecGetSize(y, &Ny)); 8313 if (M == Ny) { 8314 PetscCall(MatMult(A, x, y)); 8315 } else { 8316 PetscCall(MatMultTranspose(A, x, y)); 8317 } 8318 PetscFunctionReturn(0); 8319 } 8320 8321 /*@ 8322 MatMatInterpolateAdd - Y = W + A*X or W + A'*X 8323 8324 Neighbor-wise Collective on Mat 8325 8326 Input Parameters: 8327 + mat - the matrix 8328 - w, x - the input dense matrices 8329 8330 Output Parameters: 8331 . y - the output dense matrix 8332 8333 Level: intermediate 8334 8335 Note: 8336 This allows one to use either the restriction or interpolation (its transpose) 8337 matrix to do the interpolation. y matrix can be reused if already created with the proper sizes, 8338 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8339 8340 .seealso: `MatInterpolateAdd()`, `MatMatInterpolate()`, `MatMatRestrict()`, `PCMG` 8341 @*/ 8342 PetscErrorCode MatMatInterpolateAdd(Mat A, Mat x, Mat w, Mat *y) { 8343 PetscInt M, N, Mx, Nx, Mo, My = 0, Ny = 0; 8344 PetscBool trans = PETSC_TRUE; 8345 MatReuse reuse = MAT_INITIAL_MATRIX; 8346 8347 PetscFunctionBegin; 8348 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8349 PetscValidHeaderSpecific(x, MAT_CLASSID, 2); 8350 PetscValidType(x, 2); 8351 if (w) PetscValidHeaderSpecific(w, MAT_CLASSID, 3); 8352 if (*y) PetscValidHeaderSpecific(*y, MAT_CLASSID, 4); 8353 PetscCall(MatGetSize(A, &M, &N)); 8354 PetscCall(MatGetSize(x, &Mx, &Nx)); 8355 if (N == Mx) trans = PETSC_FALSE; 8356 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); 8357 Mo = trans ? N : M; 8358 if (*y) { 8359 PetscCall(MatGetSize(*y, &My, &Ny)); 8360 if (Mo == My && Nx == Ny) { 8361 reuse = MAT_REUSE_MATRIX; 8362 } else { 8363 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); 8364 PetscCall(MatDestroy(y)); 8365 } 8366 } 8367 8368 if (w && *y == w) { /* this is to minimize changes in PCMG */ 8369 PetscBool flg; 8370 8371 PetscCall(PetscObjectQuery((PetscObject)*y, "__MatMatIntAdd_w", (PetscObject *)&w)); 8372 if (w) { 8373 PetscInt My, Ny, Mw, Nw; 8374 8375 PetscCall(PetscObjectTypeCompare((PetscObject)*y, ((PetscObject)w)->type_name, &flg)); 8376 PetscCall(MatGetSize(*y, &My, &Ny)); 8377 PetscCall(MatGetSize(w, &Mw, &Nw)); 8378 if (!flg || My != Mw || Ny != Nw) w = NULL; 8379 } 8380 if (!w) { 8381 PetscCall(MatDuplicate(*y, MAT_COPY_VALUES, &w)); 8382 PetscCall(PetscObjectCompose((PetscObject)*y, "__MatMatIntAdd_w", (PetscObject)w)); 8383 PetscCall(PetscLogObjectParent((PetscObject)*y, (PetscObject)w)); 8384 PetscCall(PetscObjectDereference((PetscObject)w)); 8385 } else { 8386 PetscCall(MatCopy(*y, w, UNKNOWN_NONZERO_PATTERN)); 8387 } 8388 } 8389 if (!trans) { 8390 PetscCall(MatMatMult(A, x, reuse, PETSC_DEFAULT, y)); 8391 } else { 8392 PetscCall(MatTransposeMatMult(A, x, reuse, PETSC_DEFAULT, y)); 8393 } 8394 if (w) PetscCall(MatAXPY(*y, 1.0, w, UNKNOWN_NONZERO_PATTERN)); 8395 PetscFunctionReturn(0); 8396 } 8397 8398 /*@ 8399 MatMatInterpolate - Y = A*X or A'*X 8400 8401 Neighbor-wise Collective on Mat 8402 8403 Input Parameters: 8404 + mat - the matrix 8405 - x - the input dense matrix 8406 8407 Output Parameters: 8408 . y - the output dense matrix 8409 8410 Level: intermediate 8411 8412 Note: 8413 This allows one to use either the restriction or interpolation (its transpose) 8414 matrix to do the interpolation. y matrix can be reused if already created with the proper sizes, 8415 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8416 8417 .seealso: `MatInterpolate()`, `MatRestrict()`, `MatMatRestrict()`, `PCMG` 8418 @*/ 8419 PetscErrorCode MatMatInterpolate(Mat A, Mat x, Mat *y) { 8420 PetscFunctionBegin; 8421 PetscCall(MatMatInterpolateAdd(A, x, NULL, y)); 8422 PetscFunctionReturn(0); 8423 } 8424 8425 /*@ 8426 MatMatRestrict - Y = A*X or A'*X 8427 8428 Neighbor-wise Collective on Mat 8429 8430 Input Parameters: 8431 + mat - the matrix 8432 - x - the input dense matrix 8433 8434 Output Parameters: 8435 . y - the output dense matrix 8436 8437 Level: intermediate 8438 8439 Note: 8440 This allows one to use either the restriction or interpolation (its transpose) 8441 matrix to do the restriction. y matrix can be reused if already created with the proper sizes, 8442 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8443 8444 .seealso: `MatRestrict()`, `MatInterpolate()`, `MatMatInterpolate()`, `PCMG` 8445 @*/ 8446 PetscErrorCode MatMatRestrict(Mat A, Mat x, Mat *y) { 8447 PetscFunctionBegin; 8448 PetscCall(MatMatInterpolateAdd(A, x, NULL, y)); 8449 PetscFunctionReturn(0); 8450 } 8451 8452 /*@ 8453 MatGetNullSpace - retrieves the null space of a matrix. 8454 8455 Logically Collective on mat 8456 8457 Input Parameters: 8458 + mat - the matrix 8459 - nullsp - the null space object 8460 8461 Level: developer 8462 8463 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatSetNullSpace()`, `MatNullSpace` 8464 @*/ 8465 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp) { 8466 PetscFunctionBegin; 8467 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8468 PetscValidPointer(nullsp, 2); 8469 *nullsp = (mat->symmetric == PETSC_BOOL3_TRUE && !mat->nullsp) ? mat->transnullsp : mat->nullsp; 8470 PetscFunctionReturn(0); 8471 } 8472 8473 /*@ 8474 MatSetNullSpace - attaches a null space to a matrix. 8475 8476 Logically Collective on mat 8477 8478 Input Parameters: 8479 + mat - the matrix 8480 - nullsp - the null space object 8481 8482 Level: advanced 8483 8484 Notes: 8485 This null space is used by the `KSP` linear solvers to solve singular systems. 8486 8487 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 8488 8489 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 8490 to zero but the linear system will still be solved in a least squares sense. 8491 8492 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8493 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). 8494 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 8495 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 8496 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). 8497 This \hat{b} can be obtained by calling MatNullSpaceRemove() with the null space of the transpose of the matrix. 8498 8499 If the matrix is known to be symmetric because it is an `MATSBAIJ` matrix or one as called 8500 `MatSetOption`(mat,`MAT_SYMMETRIC` or possibly `MAT_SYMMETRY_ETERNAL`,`PETSC_TRUE`); this 8501 routine also automatically calls `MatSetTransposeNullSpace()`. 8502 8503 The user should call `MatNullSpaceDestroy()`. 8504 8505 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatGetNullSpace()`, `MatSetTransposeNullSpace()`, `MatGetTransposeNullSpace()`, `MatNullSpaceRemove()`, 8506 `KSPSetPCSide()` 8507 @*/ 8508 PetscErrorCode MatSetNullSpace(Mat mat, MatNullSpace nullsp) { 8509 PetscFunctionBegin; 8510 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8511 if (nullsp) PetscValidHeaderSpecific(nullsp, MAT_NULLSPACE_CLASSID, 2); 8512 if (nullsp) PetscCall(PetscObjectReference((PetscObject)nullsp)); 8513 PetscCall(MatNullSpaceDestroy(&mat->nullsp)); 8514 mat->nullsp = nullsp; 8515 if (mat->symmetric == PETSC_BOOL3_TRUE) PetscCall(MatSetTransposeNullSpace(mat, nullsp)); 8516 PetscFunctionReturn(0); 8517 } 8518 8519 /*@ 8520 MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix. 8521 8522 Logically Collective on mat 8523 8524 Input Parameters: 8525 + mat - the matrix 8526 - nullsp - the null space object 8527 8528 Level: developer 8529 8530 .seealso: `MatNullSpace`, `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatSetTransposeNullSpace()`, `MatSetNullSpace()`, `MatGetNullSpace()` 8531 @*/ 8532 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp) { 8533 PetscFunctionBegin; 8534 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8535 PetscValidType(mat, 1); 8536 PetscValidPointer(nullsp, 2); 8537 *nullsp = (mat->symmetric == PETSC_BOOL3_TRUE && !mat->transnullsp) ? mat->nullsp : mat->transnullsp; 8538 PetscFunctionReturn(0); 8539 } 8540 8541 /*@ 8542 MatSetTransposeNullSpace - attaches the null space of a transpose of a matrix to the matrix 8543 8544 Logically Collective on mat 8545 8546 Input Parameters: 8547 + mat - the matrix 8548 - nullsp - the null space object 8549 8550 Level: advanced 8551 8552 Notes: 8553 This allows solving singular linear systems defined by the transpose of the matrix using `KSP` solvers with left preconditioning. 8554 8555 See `MatSetNullSpace()` 8556 8557 .seealso: `MatNullSpace`, `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatGetNullSpace()`, `MatSetNullSpace()`, `MatGetTransposeNullSpace()`, `MatNullSpaceRemove()`, `KSPSetPCSide()` 8558 @*/ 8559 PetscErrorCode MatSetTransposeNullSpace(Mat mat, MatNullSpace nullsp) { 8560 PetscFunctionBegin; 8561 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8562 if (nullsp) PetscValidHeaderSpecific(nullsp, MAT_NULLSPACE_CLASSID, 2); 8563 if (nullsp) PetscCall(PetscObjectReference((PetscObject)nullsp)); 8564 PetscCall(MatNullSpaceDestroy(&mat->transnullsp)); 8565 mat->transnullsp = nullsp; 8566 PetscFunctionReturn(0); 8567 } 8568 8569 /*@ 8570 MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions 8571 This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix. 8572 8573 Logically Collective on mat 8574 8575 Input Parameters: 8576 + mat - the matrix 8577 - nullsp - the null space object 8578 8579 Level: advanced 8580 8581 Notes: 8582 Overwrites any previous near null space that may have been attached 8583 8584 You can remove the null space by calling this routine with an nullsp of NULL 8585 8586 .seealso: `MatNullSpace`, `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNullSpace()`, `MatNullSpaceCreateRigidBody()`, `MatGetNearNullSpace()` 8587 @*/ 8588 PetscErrorCode MatSetNearNullSpace(Mat mat, MatNullSpace nullsp) { 8589 PetscFunctionBegin; 8590 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8591 PetscValidType(mat, 1); 8592 if (nullsp) PetscValidHeaderSpecific(nullsp, MAT_NULLSPACE_CLASSID, 2); 8593 MatCheckPreallocated(mat, 1); 8594 if (nullsp) PetscCall(PetscObjectReference((PetscObject)nullsp)); 8595 PetscCall(MatNullSpaceDestroy(&mat->nearnullsp)); 8596 mat->nearnullsp = nullsp; 8597 PetscFunctionReturn(0); 8598 } 8599 8600 /*@ 8601 MatGetNearNullSpace - Get null space attached with `MatSetNearNullSpace()` 8602 8603 Not Collective 8604 8605 Input Parameter: 8606 . mat - the matrix 8607 8608 Output Parameter: 8609 . nullsp - the null space object, NULL if not set 8610 8611 Level: advanced 8612 8613 .seealso: `MatNullSpace`, `MatSetNearNullSpace()`, `MatGetNullSpace()`, `MatNullSpaceCreate()` 8614 @*/ 8615 PetscErrorCode MatGetNearNullSpace(Mat mat, MatNullSpace *nullsp) { 8616 PetscFunctionBegin; 8617 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8618 PetscValidType(mat, 1); 8619 PetscValidPointer(nullsp, 2); 8620 MatCheckPreallocated(mat, 1); 8621 *nullsp = mat->nearnullsp; 8622 PetscFunctionReturn(0); 8623 } 8624 8625 /*@C 8626 MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix. 8627 8628 Collective on mat 8629 8630 Input Parameters: 8631 + mat - the matrix 8632 . row - row/column permutation 8633 . fill - expected fill factor >= 1.0 8634 - level - level of fill, for ICC(k) 8635 8636 Notes: 8637 Probably really in-place only when level of fill is zero, otherwise allocates 8638 new space to store factored matrix and deletes previous memory. 8639 8640 Most users should employ the `KSP` interface for linear solvers 8641 instead of working directly with matrix algebra routines such as this. 8642 See, e.g., `KSPCreate()`. 8643 8644 Level: developer 8645 8646 Developer Note: 8647 The Fortran interface is not autogenerated as the f90 8648 interface definition cannot be generated correctly [due to `MatFactorInfo`] 8649 8650 .seealso: `MatGetFactor()`, `MatICCFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()` 8651 @*/ 8652 PetscErrorCode MatICCFactor(Mat mat, IS row, const MatFactorInfo *info) { 8653 PetscFunctionBegin; 8654 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8655 PetscValidType(mat, 1); 8656 if (row) PetscValidHeaderSpecific(row, IS_CLASSID, 2); 8657 PetscValidPointer(info, 3); 8658 PetscCheck(mat->rmap->N == mat->cmap->N, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONG, "matrix must be square"); 8659 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 8660 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 8661 MatCheckPreallocated(mat, 1); 8662 PetscUseTypeMethod(mat, iccfactor, row, info); 8663 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 8664 PetscFunctionReturn(0); 8665 } 8666 8667 /*@ 8668 MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 8669 ghosted ones. 8670 8671 Not Collective 8672 8673 Input Parameters: 8674 + mat - the matrix 8675 - diag - the diagonal values, including ghost ones 8676 8677 Level: developer 8678 8679 Notes: 8680 Works only for `MATMPIAIJ` and `MATMPIBAIJ` matrices 8681 8682 This allows one to avoid during communication to perform the scaling that must be done with `MatDiagonalScale()` 8683 8684 .seealso: `MatDiagonalScale()` 8685 @*/ 8686 PetscErrorCode MatDiagonalScaleLocal(Mat mat, Vec diag) { 8687 PetscMPIInt size; 8688 8689 PetscFunctionBegin; 8690 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8691 PetscValidHeaderSpecific(diag, VEC_CLASSID, 2); 8692 PetscValidType(mat, 1); 8693 8694 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Matrix must be already assembled"); 8695 PetscCall(PetscLogEventBegin(MAT_Scale, mat, 0, 0, 0)); 8696 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size)); 8697 if (size == 1) { 8698 PetscInt n, m; 8699 PetscCall(VecGetSize(diag, &n)); 8700 PetscCall(MatGetSize(mat, NULL, &m)); 8701 if (m == n) { 8702 PetscCall(MatDiagonalScale(mat, NULL, diag)); 8703 } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Only supported for sequential matrices when no ghost points/periodic conditions"); 8704 } else { 8705 PetscUseMethod(mat, "MatDiagonalScaleLocal_C", (Mat, Vec), (mat, diag)); 8706 } 8707 PetscCall(PetscLogEventEnd(MAT_Scale, mat, 0, 0, 0)); 8708 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 8709 PetscFunctionReturn(0); 8710 } 8711 8712 /*@ 8713 MatGetInertia - Gets the inertia from a factored matrix 8714 8715 Collective on mat 8716 8717 Input Parameter: 8718 . mat - the matrix 8719 8720 Output Parameters: 8721 + nneg - number of negative eigenvalues 8722 . nzero - number of zero eigenvalues 8723 - npos - number of positive eigenvalues 8724 8725 Level: advanced 8726 8727 Note: 8728 Matrix must have been factored by `MatCholeskyFactor()` 8729 8730 .seealso: `MatGetFactor()`, `MatCholeskyFactor()` 8731 @*/ 8732 PetscErrorCode MatGetInertia(Mat mat, PetscInt *nneg, PetscInt *nzero, PetscInt *npos) { 8733 PetscFunctionBegin; 8734 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8735 PetscValidType(mat, 1); 8736 PetscCheck(mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Unfactored matrix"); 8737 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Numeric factor mat is not assembled"); 8738 PetscUseTypeMethod(mat, getinertia, nneg, nzero, npos); 8739 PetscFunctionReturn(0); 8740 } 8741 8742 /* ----------------------------------------------------------------*/ 8743 /*@C 8744 MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors 8745 8746 Neighbor-wise Collective on mat 8747 8748 Input Parameters: 8749 + mat - the factored matrix obtained with `MatGetFactor()` 8750 - b - the right-hand-side vectors 8751 8752 Output Parameter: 8753 . x - the result vectors 8754 8755 Note: 8756 The vectors b and x cannot be the same. I.e., one cannot 8757 call `MatSolves`(A,x,x). 8758 8759 Level: developer 8760 8761 .seealso: `Vecs`, `MatSolveAdd()`, `MatSolveTranspose()`, `MatSolveTransposeAdd()`, `MatSolve()` 8762 @*/ 8763 PetscErrorCode MatSolves(Mat mat, Vecs b, Vecs x) { 8764 PetscFunctionBegin; 8765 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8766 PetscValidType(mat, 1); 8767 PetscCheck(x != b, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_IDN, "x and b must be different vectors"); 8768 PetscCheck(mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Unfactored matrix"); 8769 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 8770 8771 MatCheckPreallocated(mat, 1); 8772 PetscCall(PetscLogEventBegin(MAT_Solves, mat, 0, 0, 0)); 8773 PetscUseTypeMethod(mat, solves, b, x); 8774 PetscCall(PetscLogEventEnd(MAT_Solves, mat, 0, 0, 0)); 8775 PetscFunctionReturn(0); 8776 } 8777 8778 /*@ 8779 MatIsSymmetric - Test whether a matrix is symmetric 8780 8781 Collective on mat 8782 8783 Input Parameters: 8784 + A - the matrix to test 8785 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose) 8786 8787 Output Parameters: 8788 . flg - the result 8789 8790 Notes: 8791 For real numbers `MatIsSymmetric()` and `MatIsHermitian()` return identical results 8792 8793 If the matrix does not yet know if it is symmetric or not this can be an expensive operation, also available `MatIsSymmetricKnown()` 8794 8795 One can declare that a matrix is symmetric with `MatSetOption`(mat,`MAT_SYMMETRIC`,`PETSC_TRUE`) and if it is known to remain symmetric 8796 after changes to the matrices values one can call `MatSetOption`(mat,`MAT_SYMMETRY_ETERNAL`,`PETSC_TRUE`) 8797 8798 Level: intermediate 8799 8800 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetricKnown()`, 8801 `MAT_SYMMETRIC`, `MAT_SYMMETRY_ETERNAL`, `MatSetOption()` 8802 @*/ 8803 PetscErrorCode MatIsSymmetric(Mat A, PetscReal tol, PetscBool *flg) { 8804 PetscFunctionBegin; 8805 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8806 PetscValidBoolPointer(flg, 3); 8807 8808 if (A->symmetric == PETSC_BOOL3_TRUE) *flg = PETSC_TRUE; 8809 else if (A->symmetric == PETSC_BOOL3_FALSE) *flg = PETSC_FALSE; 8810 else { 8811 if (!A->ops->issymmetric) { 8812 MatType mattype; 8813 PetscCall(MatGetType(A, &mattype)); 8814 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Matrix of type %s does not support checking for symmetric", mattype); 8815 } 8816 PetscUseTypeMethod(A, issymmetric, tol, flg); 8817 if (!tol) PetscCall(MatSetOption(A, MAT_SYMMETRIC, *flg)); 8818 } 8819 PetscFunctionReturn(0); 8820 } 8821 8822 /*@ 8823 MatIsHermitian - Test whether a matrix is Hermitian 8824 8825 Collective on Mat 8826 8827 Input Parameters: 8828 + A - the matrix to test 8829 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian) 8830 8831 Output Parameters: 8832 . flg - the result 8833 8834 Level: intermediate 8835 8836 Notes: 8837 For real numbers `MatIsSymmetric()` and `MatIsHermitian()` return identical results 8838 8839 If the matrix does not yet know if it is Hermitian or not this can be an expensive operation, also available `MatIsHermitianKnown()` 8840 8841 One can declare that a matrix is Hermitian with `MatSetOption`(mat,`MAT_HERMITIAN`,`PETSC_TRUE`) and if it is known to remain Hermitian 8842 after changes to the matrices values one can call `MatSetOption`(mat,`MAT_SYMEMTRY_ETERNAL`,`PETSC_TRUE`) 8843 8844 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitianKnown()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, 8845 `MatIsSymmetricKnown()`, `MatIsSymmetric()`, `MAT_HERMITIAN`, `MAT_SYMMETRY_ETERNAL`, `MatSetOption()` 8846 @*/ 8847 PetscErrorCode MatIsHermitian(Mat A, PetscReal tol, PetscBool *flg) { 8848 PetscFunctionBegin; 8849 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8850 PetscValidBoolPointer(flg, 3); 8851 8852 if (A->hermitian == PETSC_BOOL3_TRUE) *flg = PETSC_TRUE; 8853 else if (A->hermitian == PETSC_BOOL3_FALSE) *flg = PETSC_FALSE; 8854 else { 8855 if (!A->ops->ishermitian) { 8856 MatType mattype; 8857 PetscCall(MatGetType(A, &mattype)); 8858 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Matrix of type %s does not support checking for hermitian", mattype); 8859 } 8860 PetscUseTypeMethod(A, ishermitian, tol, flg); 8861 if (!tol) PetscCall(MatSetOption(A, MAT_HERMITIAN, *flg)); 8862 } 8863 PetscFunctionReturn(0); 8864 } 8865 8866 /*@ 8867 MatIsSymmetricKnown - Checks if a matrix knows if it is symmetric or not and its symmetric state 8868 8869 Not Collective 8870 8871 Input Parameter: 8872 . A - the matrix to check 8873 8874 Output Parameters: 8875 + set - `PETSC_TRUE` if the matrix knows its symmetry state (this tells you if the next flag is valid) 8876 - flg - the result (only valid if set is `PETSC_TRUE`) 8877 8878 Level: advanced 8879 8880 Notes: 8881 Does not check the matrix values directly, so this may return unknown (set = `PETSC_FALSE`). Use `MatIsSymmetric()` 8882 if you want it explicitly checked 8883 8884 One can declare that a matrix is symmetric with `MatSetOption`(mat,`MAT_SYMMETRIC`,`PETSC_TRUE`) and if it is known to remain symmetric 8885 after changes to the matrices values one can call `MatSetOption`(mat,`MAT_SYMMETRY_ETERNAL`,`PETSC_TRUE`) 8886 8887 .seealso: `MAT_SYMMETRY_ETERNAL`, `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitianKnown()` 8888 @*/ 8889 PetscErrorCode MatIsSymmetricKnown(Mat A, PetscBool *set, PetscBool *flg) { 8890 PetscFunctionBegin; 8891 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8892 PetscValidBoolPointer(set, 2); 8893 PetscValidBoolPointer(flg, 3); 8894 if (A->symmetric != PETSC_BOOL3_UNKNOWN) { 8895 *set = PETSC_TRUE; 8896 *flg = PetscBool3ToBool(A->symmetric); 8897 } else { 8898 *set = PETSC_FALSE; 8899 } 8900 PetscFunctionReturn(0); 8901 } 8902 8903 /*@ 8904 MatIsSPDKnown - Checks if a matrix knows if it is symmetric positive definite or not and its symmetric positive definite state 8905 8906 Not Collective 8907 8908 Input Parameter: 8909 . A - the matrix to check 8910 8911 Output Parameters: 8912 + set - `PETSC_TRUE` if the matrix knows its symmetric positive definite state (this tells you if the next flag is valid) 8913 - flg - the result (only valid if set is `PETSC_TRUE`) 8914 8915 Level: advanced 8916 8917 Notes: 8918 Does not check the matrix values directly, so this may return unknown (set = `PETSC_FALSE`). 8919 8920 One can declare that a matrix is SPD with `MatSetOption`(mat,`MAT_SPD`,`PETSC_TRUE`) and if it is known to remain SPD 8921 after changes to the matrices values one can call `MatSetOption`(mat,`MAT_SPD_ETERNAL`,`PETSC_TRUE`) 8922 8923 .seealso: `MAT_SPD_ETERNAL`, `MAT_SPD`, `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitianKnown()` 8924 @*/ 8925 PetscErrorCode MatIsSPDKnown(Mat A, PetscBool *set, PetscBool *flg) { 8926 PetscFunctionBegin; 8927 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8928 PetscValidBoolPointer(set, 2); 8929 PetscValidBoolPointer(flg, 3); 8930 if (A->spd != PETSC_BOOL3_UNKNOWN) { 8931 *set = PETSC_TRUE; 8932 *flg = PetscBool3ToBool(A->spd); 8933 } else { 8934 *set = PETSC_FALSE; 8935 } 8936 PetscFunctionReturn(0); 8937 } 8938 8939 /*@ 8940 MatIsHermitianKnown - Checks if a matrix knows if it is Hermitian or not and its Hermitian state 8941 8942 Not Collective 8943 8944 Input Parameter: 8945 . A - the matrix to check 8946 8947 Output Parameters: 8948 + set - `PETSC_TRUE` if the matrix knows its Hermitian state (this tells you if the next flag is valid) 8949 - flg - the result (only valid if set is `PETSC_TRUE`) 8950 8951 Level: advanced 8952 8953 Notes: 8954 Does not check the matrix values directly, so this may return unknown (set = `PETSC_FALSE`). Use `MatIsHermitian()` 8955 if you want it explicitly checked 8956 8957 One can declare that a matrix is Hermitian with `MatSetOption`(mat,`MAT_HERMITIAN`,`PETSC_TRUE`) and if it is known to remain Hermitian 8958 after changes to the matrices values one can call `MatSetOption`(mat,`MAT_SYMMETRY_ETERNAL`,`PETSC_TRUE`) 8959 8960 .seealso: `MAT_SYMMETRY_ETERNAL`, `MAT_HERMITIAN`, `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()` 8961 @*/ 8962 PetscErrorCode MatIsHermitianKnown(Mat A, PetscBool *set, PetscBool *flg) { 8963 PetscFunctionBegin; 8964 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8965 PetscValidBoolPointer(set, 2); 8966 PetscValidBoolPointer(flg, 3); 8967 if (A->hermitian != PETSC_BOOL3_UNKNOWN) { 8968 *set = PETSC_TRUE; 8969 *flg = PetscBool3ToBool(A->hermitian); 8970 } else { 8971 *set = PETSC_FALSE; 8972 } 8973 PetscFunctionReturn(0); 8974 } 8975 8976 /*@ 8977 MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric 8978 8979 Collective on Mat 8980 8981 Input Parameter: 8982 . A - the matrix to test 8983 8984 Output Parameters: 8985 . flg - the result 8986 8987 Notes: 8988 If the matrix does yet know it is structurally symmetric this can be an expensive operation, also available `MatIsStructurallySymmetricKnown()` 8989 8990 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 8991 symmetric after changes to the matrices values one can call `MatSetOption`(mat,`MAT_STRUCTURAL_SYMMETRY_ETERNAL`,`PETSC_TRUE`) 8992 8993 Level: intermediate 8994 8995 .seealso: `MAT_STRUCTURALLY_SYMMETRIC`, `MAT_STRUCTURAL_SYMMETRY_ETERNAL`, `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsSymmetric()`, `MatSetOption()`, `MatIsStructurallySymmetricKnown()` 8996 @*/ 8997 PetscErrorCode MatIsStructurallySymmetric(Mat A, PetscBool *flg) { 8998 PetscFunctionBegin; 8999 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 9000 PetscValidBoolPointer(flg, 2); 9001 if (A->structurally_symmetric != PETSC_BOOL3_UNKNOWN) { 9002 *flg = PetscBool3ToBool(A->structurally_symmetric); 9003 } else { 9004 PetscUseTypeMethod(A, isstructurallysymmetric, flg); 9005 PetscCall(MatSetOption(A, MAT_STRUCTURALLY_SYMMETRIC, *flg)); 9006 } 9007 PetscFunctionReturn(0); 9008 } 9009 9010 /*@ 9011 MatIsStructurallySymmetricKnown - Checks if a matrix knows if it is structurally symmetric or not and its structurally symmetric state 9012 9013 Not Collective 9014 9015 Input Parameter: 9016 . A - the matrix to check 9017 9018 Output Parameters: 9019 + set - PETSC_TRUE if the matrix knows its structurally symmetric state (this tells you if the next flag is valid) 9020 - flg - the result (only valid if set is PETSC_TRUE) 9021 9022 Level: advanced 9023 9024 Notes: 9025 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 9026 symmetric after changes to the matrices values one can call `MatSetOption`(mat,`MAT_STRUCTURAL_SYMMETRY_ETERNAL`,`PETSC_TRUE`) 9027 9028 Use `MatIsStructurallySymmetric()` to explicitly check if a matrix is structurally symmetric (this is an expensive operation) 9029 9030 .seealso: `MAT_STRUCTURALLY_SYMMETRIC`, `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitianKnown()` 9031 @*/ 9032 PetscErrorCode MatIsStructurallySymmetricKnown(Mat A, PetscBool *set, PetscBool *flg) { 9033 PetscFunctionBegin; 9034 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 9035 PetscValidBoolPointer(set, 2); 9036 PetscValidBoolPointer(flg, 3); 9037 if (A->structurally_symmetric != PETSC_BOOL3_UNKNOWN) { 9038 *set = PETSC_TRUE; 9039 *flg = PetscBool3ToBool(A->structurally_symmetric); 9040 } else { 9041 *set = PETSC_FALSE; 9042 } 9043 PetscFunctionReturn(0); 9044 } 9045 9046 /*@ 9047 MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need 9048 to be communicated to other processors during the `MatAssemblyBegin()`/`MatAssemblyEnd()` process 9049 9050 Not collective 9051 9052 Input Parameter: 9053 . mat - the matrix 9054 9055 Output Parameters: 9056 + nstash - the size of the stash 9057 . reallocs - the number of additional mallocs incurred. 9058 . bnstash - the size of the block stash 9059 - breallocs - the number of additional mallocs incurred.in the block stash 9060 9061 Level: advanced 9062 9063 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `Mat`, `MatStashSetInitialSize()` 9064 @*/ 9065 PetscErrorCode MatStashGetInfo(Mat mat, PetscInt *nstash, PetscInt *reallocs, PetscInt *bnstash, PetscInt *breallocs) { 9066 PetscFunctionBegin; 9067 PetscCall(MatStashGetInfo_Private(&mat->stash, nstash, reallocs)); 9068 PetscCall(MatStashGetInfo_Private(&mat->bstash, bnstash, breallocs)); 9069 PetscFunctionReturn(0); 9070 } 9071 9072 /*@C 9073 MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same 9074 parallel layout, `PetscLayout` for rows and columns 9075 9076 Collective on mat 9077 9078 Input Parameter: 9079 . mat - the matrix 9080 9081 Output Parameters: 9082 + right - (optional) vector that the matrix can be multiplied against 9083 - left - (optional) vector that the matrix vector product can be stored in 9084 9085 Notes: 9086 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()`. 9087 9088 These are new vectors which are not owned by the mat, they should be destroyed in `VecDestroy()` when no longer needed 9089 9090 Level: advanced 9091 9092 .seealso: `Mat`, `Vec`, `VecCreate()`, `VecDestroy()`, `DMCreateGlobalVector()` 9093 @*/ 9094 PetscErrorCode MatCreateVecs(Mat mat, Vec *right, Vec *left) { 9095 PetscFunctionBegin; 9096 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 9097 PetscValidType(mat, 1); 9098 if (mat->ops->getvecs) { 9099 PetscUseTypeMethod(mat, getvecs, right, left); 9100 } else { 9101 PetscInt rbs, cbs; 9102 PetscCall(MatGetBlockSizes(mat, &rbs, &cbs)); 9103 if (right) { 9104 PetscCheck(mat->cmap->n >= 0, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "PetscLayout for columns not yet setup"); 9105 PetscCall(VecCreate(PetscObjectComm((PetscObject)mat), right)); 9106 PetscCall(VecSetSizes(*right, mat->cmap->n, PETSC_DETERMINE)); 9107 PetscCall(VecSetBlockSize(*right, cbs)); 9108 PetscCall(VecSetType(*right, mat->defaultvectype)); 9109 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 9110 if (mat->boundtocpu && mat->bindingpropagates) { 9111 PetscCall(VecSetBindingPropagates(*right, PETSC_TRUE)); 9112 PetscCall(VecBindToCPU(*right, PETSC_TRUE)); 9113 } 9114 #endif 9115 PetscCall(PetscLayoutReference(mat->cmap, &(*right)->map)); 9116 } 9117 if (left) { 9118 PetscCheck(mat->rmap->n >= 0, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "PetscLayout for rows not yet setup"); 9119 PetscCall(VecCreate(PetscObjectComm((PetscObject)mat), left)); 9120 PetscCall(VecSetSizes(*left, mat->rmap->n, PETSC_DETERMINE)); 9121 PetscCall(VecSetBlockSize(*left, rbs)); 9122 PetscCall(VecSetType(*left, mat->defaultvectype)); 9123 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 9124 if (mat->boundtocpu && mat->bindingpropagates) { 9125 PetscCall(VecSetBindingPropagates(*left, PETSC_TRUE)); 9126 PetscCall(VecBindToCPU(*left, PETSC_TRUE)); 9127 } 9128 #endif 9129 PetscCall(PetscLayoutReference(mat->rmap, &(*left)->map)); 9130 } 9131 } 9132 PetscFunctionReturn(0); 9133 } 9134 9135 /*@C 9136 MatFactorInfoInitialize - Initializes a `MatFactorInfo` data structure 9137 with default values. 9138 9139 Not Collective 9140 9141 Input Parameters: 9142 . info - the `MatFactorInfo` data structure 9143 9144 Notes: 9145 The solvers are generally used through the `KSP` and `PC` objects, for example 9146 `PCLU`, `PCILU`, `PCCHOLESKY`, `PCICC` 9147 9148 Once the data structure is initialized one may change certain entries as desired for the particular factorization to be performed 9149 9150 Level: developer 9151 9152 Developer Note: 9153 The Fortran interface is not autogenerated as the f90 9154 interface definition cannot be generated correctly [due to `MatFactorInfo`] 9155 9156 .seealso: `MatGetFactor()`, `MatFactorInfo` 9157 @*/ 9158 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info) { 9159 PetscFunctionBegin; 9160 PetscCall(PetscMemzero(info, sizeof(MatFactorInfo))); 9161 PetscFunctionReturn(0); 9162 } 9163 9164 /*@ 9165 MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed 9166 9167 Collective on mat 9168 9169 Input Parameters: 9170 + mat - the factored matrix 9171 - is - the index set defining the Schur indices (0-based) 9172 9173 Notes: 9174 Call `MatFactorSolveSchurComplement()` or `MatFactorSolveSchurComplementTranspose()` after this call to solve a Schur complement system. 9175 9176 You can call `MatFactorGetSchurComplement()` or `MatFactorCreateSchurComplement()` after this call. 9177 9178 This functionality is only supported for `MATSOLVERMUMPS` and `MATSOLVERMKL_PARDISO` 9179 9180 Level: advanced 9181 9182 .seealso: `MatGetFactor()`, `MatFactorGetSchurComplement()`, `MatFactorRestoreSchurComplement()`, `MatFactorCreateSchurComplement()`, `MatFactorSolveSchurComplement()`, 9183 `MatFactorSolveSchurComplementTranspose()`, `MatFactorSolveSchurComplement()`, `MATSOLVERMUMPS`, `MATSOLVERMKL_PARDISO` 9184 9185 @*/ 9186 PetscErrorCode MatFactorSetSchurIS(Mat mat, IS is) { 9187 PetscErrorCode (*f)(Mat, IS); 9188 9189 PetscFunctionBegin; 9190 PetscValidType(mat, 1); 9191 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 9192 PetscValidType(is, 2); 9193 PetscValidHeaderSpecific(is, IS_CLASSID, 2); 9194 PetscCheckSameComm(mat, 1, is, 2); 9195 PetscCheck(mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Only for factored matrix"); 9196 PetscCall(PetscObjectQueryFunction((PetscObject)mat, "MatFactorSetSchurIS_C", &f)); 9197 PetscCheck(f, PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "The selected MatSolverType does not support Schur complement computation. You should use MATSOLVERMUMPS or MATSOLVERMKL_PARDISO"); 9198 PetscCall(MatDestroy(&mat->schur)); 9199 PetscCall((*f)(mat, is)); 9200 PetscCheck(mat->schur, PetscObjectComm((PetscObject)mat), PETSC_ERR_PLIB, "Schur complement has not been created"); 9201 PetscFunctionReturn(0); 9202 } 9203 9204 /*@ 9205 MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step 9206 9207 Logically Collective on mat 9208 9209 Input Parameters: 9210 + F - the factored matrix obtained by calling `MatGetFactor()` 9211 . S - location where to return the Schur complement, can be NULL 9212 - status - the status of the Schur complement matrix, can be NULL 9213 9214 Notes: 9215 You must call `MatFactorSetSchurIS()` before calling this routine. 9216 9217 This functionality is only supported for `MATSOLVERMUMPS` and `MATSOLVERMKL_PARDISO` 9218 9219 The routine provides a copy of the Schur matrix stored within the solver data structures. 9220 The caller must destroy the object when it is no longer needed. 9221 If `MatFactorInvertSchurComplement()` has been called, the routine gets back the inverse. 9222 9223 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) 9224 9225 See `MatCreateSchurComplement()` or `MatGetSchurComplement()` for ways to create virtual or approximate Schur complements. 9226 9227 Developer Note: 9228 The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc 9229 matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix. 9230 9231 Level: advanced 9232 9233 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorGetSchurComplement()`, `MatFactorSchurStatus`, `MATSOLVERMUMPS`, `MATSOLVERMKL_PARDISO` 9234 @*/ 9235 PetscErrorCode MatFactorCreateSchurComplement(Mat F, Mat *S, MatFactorSchurStatus *status) { 9236 PetscFunctionBegin; 9237 PetscValidHeaderSpecific(F, MAT_CLASSID, 1); 9238 if (S) PetscValidPointer(S, 2); 9239 if (status) PetscValidPointer(status, 3); 9240 if (S) { 9241 PetscErrorCode (*f)(Mat, Mat *); 9242 9243 PetscCall(PetscObjectQueryFunction((PetscObject)F, "MatFactorCreateSchurComplement_C", &f)); 9244 if (f) { 9245 PetscCall((*f)(F, S)); 9246 } else { 9247 PetscCall(MatDuplicate(F->schur, MAT_COPY_VALUES, S)); 9248 } 9249 } 9250 if (status) *status = F->schur_status; 9251 PetscFunctionReturn(0); 9252 } 9253 9254 /*@ 9255 MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix 9256 9257 Logically Collective on mat 9258 9259 Input Parameters: 9260 + F - the factored matrix obtained by calling `MatGetFactor()` 9261 . *S - location where to return the Schur complement, can be NULL 9262 - status - the status of the Schur complement matrix, can be NULL 9263 9264 Notes: 9265 You must call `MatFactorSetSchurIS()` before calling this routine. 9266 9267 Schur complement mode is currently implemented for sequential matrices with factor type of `MATSOLVERMUMPS` 9268 9269 The routine returns a the Schur Complement stored within the data strutures of the solver. 9270 9271 If `MatFactorInvertSchurComplement()` has previously been called, the returned matrix is actually the inverse of the Schur complement. 9272 9273 The returned matrix should not be destroyed; the caller should call `MatFactorRestoreSchurComplement()` when the object is no longer needed. 9274 9275 Use `MatFactorCreateSchurComplement()` to create a copy of the Schur complement matrix that is within a factored matrix 9276 9277 See `MatCreateSchurComplement()` or `MatGetSchurComplement()` for ways to create virtual or approximate Schur complements. 9278 9279 Level: advanced 9280 9281 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorRestoreSchurComplement()`, `MatFactorCreateSchurComplement()`, `MatFactorSchurStatus` 9282 @*/ 9283 PetscErrorCode MatFactorGetSchurComplement(Mat F, Mat *S, MatFactorSchurStatus *status) { 9284 PetscFunctionBegin; 9285 PetscValidHeaderSpecific(F, MAT_CLASSID, 1); 9286 if (S) PetscValidPointer(S, 2); 9287 if (status) PetscValidPointer(status, 3); 9288 if (S) *S = F->schur; 9289 if (status) *status = F->schur_status; 9290 PetscFunctionReturn(0); 9291 } 9292 9293 /*@ 9294 MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to `MatFactorGetSchurComplement()` 9295 9296 Logically Collective on mat 9297 9298 Input Parameters: 9299 + F - the factored matrix obtained by calling `MatGetFactor()` 9300 . *S - location where the Schur complement is stored 9301 - status - the status of the Schur complement matrix (see `MatFactorSchurStatus`) 9302 9303 Level: advanced 9304 9305 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorRestoreSchurComplement()`, `MatFactorCreateSchurComplement()`, `MatFactorSchurStatus` 9306 @*/ 9307 PetscErrorCode MatFactorRestoreSchurComplement(Mat F, Mat *S, MatFactorSchurStatus status) { 9308 PetscFunctionBegin; 9309 PetscValidHeaderSpecific(F, MAT_CLASSID, 1); 9310 if (S) { 9311 PetscValidHeaderSpecific(*S, MAT_CLASSID, 2); 9312 *S = NULL; 9313 } 9314 F->schur_status = status; 9315 PetscCall(MatFactorUpdateSchurStatus_Private(F)); 9316 PetscFunctionReturn(0); 9317 } 9318 9319 /*@ 9320 MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step 9321 9322 Logically Collective on mat 9323 9324 Input Parameters: 9325 + F - the factored matrix obtained by calling `MatGetFactor()` 9326 . rhs - location where the right hand side of the Schur complement system is stored 9327 - sol - location where the solution of the Schur complement system has to be returned 9328 9329 Notes: 9330 The sizes of the vectors should match the size of the Schur complement 9331 9332 Must be called after `MatFactorSetSchurIS()` 9333 9334 Level: advanced 9335 9336 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorSolveSchurComplement()` 9337 @*/ 9338 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol) { 9339 PetscFunctionBegin; 9340 PetscValidType(F, 1); 9341 PetscValidType(rhs, 2); 9342 PetscValidType(sol, 3); 9343 PetscValidHeaderSpecific(F, MAT_CLASSID, 1); 9344 PetscValidHeaderSpecific(rhs, VEC_CLASSID, 2); 9345 PetscValidHeaderSpecific(sol, VEC_CLASSID, 3); 9346 PetscCheckSameComm(F, 1, rhs, 2); 9347 PetscCheckSameComm(F, 1, sol, 3); 9348 PetscCall(MatFactorFactorizeSchurComplement(F)); 9349 switch (F->schur_status) { 9350 case MAT_FACTOR_SCHUR_FACTORED: PetscCall(MatSolveTranspose(F->schur, rhs, sol)); break; 9351 case MAT_FACTOR_SCHUR_INVERTED: PetscCall(MatMultTranspose(F->schur, rhs, sol)); break; 9352 default: SETERRQ(PetscObjectComm((PetscObject)F), PETSC_ERR_SUP, "Unhandled MatFactorSchurStatus %d", F->schur_status); 9353 } 9354 PetscFunctionReturn(0); 9355 } 9356 9357 /*@ 9358 MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step 9359 9360 Logically Collective on mat 9361 9362 Input Parameters: 9363 + F - the factored matrix obtained by calling `MatGetFactor()` 9364 . rhs - location where the right hand side of the Schur complement system is stored 9365 - sol - location where the solution of the Schur complement system has to be returned 9366 9367 Notes: 9368 The sizes of the vectors should match the size of the Schur complement 9369 9370 Must be called after `MatFactorSetSchurIS()` 9371 9372 Level: advanced 9373 9374 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorSolveSchurComplementTranspose()` 9375 @*/ 9376 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol) { 9377 PetscFunctionBegin; 9378 PetscValidType(F, 1); 9379 PetscValidType(rhs, 2); 9380 PetscValidType(sol, 3); 9381 PetscValidHeaderSpecific(F, MAT_CLASSID, 1); 9382 PetscValidHeaderSpecific(rhs, VEC_CLASSID, 2); 9383 PetscValidHeaderSpecific(sol, VEC_CLASSID, 3); 9384 PetscCheckSameComm(F, 1, rhs, 2); 9385 PetscCheckSameComm(F, 1, sol, 3); 9386 PetscCall(MatFactorFactorizeSchurComplement(F)); 9387 switch (F->schur_status) { 9388 case MAT_FACTOR_SCHUR_FACTORED: PetscCall(MatSolve(F->schur, rhs, sol)); break; 9389 case MAT_FACTOR_SCHUR_INVERTED: PetscCall(MatMult(F->schur, rhs, sol)); break; 9390 default: SETERRQ(PetscObjectComm((PetscObject)F), PETSC_ERR_SUP, "Unhandled MatFactorSchurStatus %d", F->schur_status); 9391 } 9392 PetscFunctionReturn(0); 9393 } 9394 9395 /*@ 9396 MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step 9397 9398 Logically Collective on F 9399 9400 Input Parameters: 9401 . F - the factored matrix obtained by calling `MatGetFactor()` 9402 9403 Notes: 9404 Must be called after `MatFactorSetSchurIS()`. 9405 9406 Call `MatFactorGetSchurComplement()` or `MatFactorCreateSchurComplement()` AFTER this call to actually compute the inverse and get access to it. 9407 9408 Level: advanced 9409 9410 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorGetSchurComplement()`, `MatFactorCreateSchurComplement()` 9411 @*/ 9412 PetscErrorCode MatFactorInvertSchurComplement(Mat F) { 9413 PetscFunctionBegin; 9414 PetscValidType(F, 1); 9415 PetscValidHeaderSpecific(F, MAT_CLASSID, 1); 9416 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0); 9417 PetscCall(MatFactorFactorizeSchurComplement(F)); 9418 PetscCall(MatFactorInvertSchurComplement_Private(F)); 9419 F->schur_status = MAT_FACTOR_SCHUR_INVERTED; 9420 PetscFunctionReturn(0); 9421 } 9422 9423 /*@ 9424 MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step 9425 9426 Logically Collective on mat 9427 9428 Input Parameters: 9429 . F - the factored matrix obtained by calling `MatGetFactor()` 9430 9431 Note: 9432 Must be called after `MatFactorSetSchurIS()` 9433 9434 Level: advanced 9435 9436 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorInvertSchurComplement()` 9437 @*/ 9438 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F) { 9439 PetscFunctionBegin; 9440 PetscValidType(F, 1); 9441 PetscValidHeaderSpecific(F, MAT_CLASSID, 1); 9442 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0); 9443 PetscCall(MatFactorFactorizeSchurComplement_Private(F)); 9444 F->schur_status = MAT_FACTOR_SCHUR_FACTORED; 9445 PetscFunctionReturn(0); 9446 } 9447 9448 /*@ 9449 MatPtAP - Creates the matrix product C = P^T * A * P 9450 9451 Neighbor-wise Collective on A 9452 9453 Input Parameters: 9454 + A - the matrix 9455 . P - the projection matrix 9456 . scall - either `MAT_INITIAL_MATRIX` or `MAT_REUSE_MATRIX` 9457 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use `PETSC_DEFAULT` if you do not have a good estimate 9458 if the result is a dense matrix this is irrelevant 9459 9460 Output Parameters: 9461 . C - the product matrix 9462 9463 Notes: 9464 C will be created and must be destroyed by the user with `MatDestroy()`. 9465 9466 An alternative approach to this function is to use `MatProductCreate()` and set the desired options before the computation is done 9467 9468 Developer Note: 9469 For matrix types without special implementation the function fallbacks to `MatMatMult()` followed by `MatTransposeMatMult()`. 9470 9471 Level: intermediate 9472 9473 .seealso: `MatProductCreate()`, `MatMatMult()`, `MatRARt()` 9474 @*/ 9475 PetscErrorCode MatPtAP(Mat A, Mat P, MatReuse scall, PetscReal fill, Mat *C) { 9476 PetscFunctionBegin; 9477 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*C, 5); 9478 PetscCheck(scall != MAT_INPLACE_MATRIX, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Inplace product not supported"); 9479 9480 if (scall == MAT_INITIAL_MATRIX) { 9481 PetscCall(MatProductCreate(A, P, NULL, C)); 9482 PetscCall(MatProductSetType(*C, MATPRODUCT_PtAP)); 9483 PetscCall(MatProductSetAlgorithm(*C, "default")); 9484 PetscCall(MatProductSetFill(*C, fill)); 9485 9486 (*C)->product->api_user = PETSC_TRUE; 9487 PetscCall(MatProductSetFromOptions(*C)); 9488 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); 9489 PetscCall(MatProductSymbolic(*C)); 9490 } else { /* scall == MAT_REUSE_MATRIX */ 9491 PetscCall(MatProductReplaceMats(A, P, NULL, *C)); 9492 } 9493 9494 PetscCall(MatProductNumeric(*C)); 9495 (*C)->symmetric = A->symmetric; 9496 (*C)->spd = A->spd; 9497 PetscFunctionReturn(0); 9498 } 9499 9500 /*@ 9501 MatRARt - Creates the matrix product C = R * A * R^T 9502 9503 Neighbor-wise Collective on A 9504 9505 Input Parameters: 9506 + A - the matrix 9507 . R - the projection matrix 9508 . scall - either `MAT_INITIAL_MATRIX` or `MAT_REUSE_MATRIX` 9509 - fill - expected fill as ratio of nnz(C)/nnz(A), use `PETSC_DEFAULT` if you do not have a good estimate 9510 if the result is a dense matrix this is irrelevant 9511 9512 Output Parameters: 9513 . C - the product matrix 9514 9515 Notes: 9516 C will be created and must be destroyed by the user with `MatDestroy()`. 9517 9518 An alternative approach to this function is to use `MatProductCreate()` and set the desired options before the computation is done 9519 9520 This routine is currently only implemented for pairs of `MATAIJ` matrices and classes 9521 which inherit from `MATAIJ`. Due to PETSc sparse matrix block row distribution among processes, 9522 parallel MatRARt is implemented via explicit transpose of R, which could be very expensive. 9523 We recommend using MatPtAP(). 9524 9525 Level: intermediate 9526 9527 .seealso: `MatProductCreate()`, `MatMatMult()`, `MatPtAP()` 9528 @*/ 9529 PetscErrorCode MatRARt(Mat A, Mat R, MatReuse scall, PetscReal fill, Mat *C) { 9530 PetscFunctionBegin; 9531 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*C, 5); 9532 PetscCheck(scall != MAT_INPLACE_MATRIX, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Inplace product not supported"); 9533 9534 if (scall == MAT_INITIAL_MATRIX) { 9535 PetscCall(MatProductCreate(A, R, NULL, C)); 9536 PetscCall(MatProductSetType(*C, MATPRODUCT_RARt)); 9537 PetscCall(MatProductSetAlgorithm(*C, "default")); 9538 PetscCall(MatProductSetFill(*C, fill)); 9539 9540 (*C)->product->api_user = PETSC_TRUE; 9541 PetscCall(MatProductSetFromOptions(*C)); 9542 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); 9543 PetscCall(MatProductSymbolic(*C)); 9544 } else { /* scall == MAT_REUSE_MATRIX */ 9545 PetscCall(MatProductReplaceMats(A, R, NULL, *C)); 9546 } 9547 9548 PetscCall(MatProductNumeric(*C)); 9549 if (A->symmetric == PETSC_BOOL3_TRUE) PetscCall(MatSetOption(*C, MAT_SYMMETRIC, PETSC_TRUE)); 9550 PetscFunctionReturn(0); 9551 } 9552 9553 static PetscErrorCode MatProduct_Private(Mat A, Mat B, MatReuse scall, PetscReal fill, MatProductType ptype, Mat *C) { 9554 PetscFunctionBegin; 9555 PetscCheck(scall != MAT_INPLACE_MATRIX, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Inplace product not supported"); 9556 9557 if (scall == MAT_INITIAL_MATRIX) { 9558 PetscCall(PetscInfo(A, "Calling MatProduct API with MAT_INITIAL_MATRIX and product type %s\n", MatProductTypes[ptype])); 9559 PetscCall(MatProductCreate(A, B, NULL, C)); 9560 PetscCall(MatProductSetType(*C, ptype)); 9561 PetscCall(MatProductSetAlgorithm(*C, MATPRODUCTALGORITHMDEFAULT)); 9562 PetscCall(MatProductSetFill(*C, fill)); 9563 9564 (*C)->product->api_user = PETSC_TRUE; 9565 PetscCall(MatProductSetFromOptions(*C)); 9566 PetscCall(MatProductSymbolic(*C)); 9567 } else { /* scall == MAT_REUSE_MATRIX */ 9568 Mat_Product *product = (*C)->product; 9569 PetscBool isdense; 9570 9571 PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)(*C), &isdense, MATSEQDENSE, MATMPIDENSE, "")); 9572 if (isdense && product && product->type != ptype) { 9573 PetscCall(MatProductClear(*C)); 9574 product = NULL; 9575 } 9576 PetscCall(PetscInfo(A, "Calling MatProduct API with MAT_REUSE_MATRIX %s product present and product type %s\n", product ? "with" : "without", MatProductTypes[ptype])); 9577 if (!product) { /* user provide the dense matrix *C without calling MatProductCreate() or reusing it from previous calls */ 9578 if (isdense) { 9579 PetscCall(MatProductCreate_Private(A, B, NULL, *C)); 9580 product = (*C)->product; 9581 product->fill = fill; 9582 product->api_user = PETSC_TRUE; 9583 product->clear = PETSC_TRUE; 9584 9585 PetscCall(MatProductSetType(*C, ptype)); 9586 PetscCall(MatProductSetFromOptions(*C)); 9587 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); 9588 PetscCall(MatProductSymbolic(*C)); 9589 } else SETERRQ(PetscObjectComm((PetscObject)(*C)), PETSC_ERR_SUP, "Call MatProductCreate() first"); 9590 } else { /* user may change input matrices A or B when REUSE */ 9591 PetscCall(MatProductReplaceMats(A, B, NULL, *C)); 9592 } 9593 } 9594 PetscCall(MatProductNumeric(*C)); 9595 PetscFunctionReturn(0); 9596 } 9597 9598 /*@ 9599 MatMatMult - Performs matrix-matrix multiplication C=A*B. 9600 9601 Neighbor-wise Collective on A 9602 9603 Input Parameters: 9604 + A - the left matrix 9605 . B - the right matrix 9606 . scall - either `MAT_INITIAL_MATRIX` or `MAT_REUSE_MATRIX` 9607 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use `PETSC_DEFAULT` if you do not have a good estimate 9608 if the result is a dense matrix this is irrelevant 9609 9610 Output Parameters: 9611 . C - the product matrix 9612 9613 Notes: 9614 Unless scall is `MAT_REUSE_MATRIX` C will be created. 9615 9616 `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 9617 call to this function with `MAT_INITIAL_MATRIX`. 9618 9619 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value actually needed. 9620 9621 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`, 9622 rather than first having `MatMatMult()` create it for you. You can NEVER do this if the matrix C is sparse. 9623 9624 Example of Usage: 9625 .vb 9626 MatProductCreate(A,B,NULL,&C); 9627 MatProductSetType(C,MATPRODUCT_AB); 9628 MatProductSymbolic(C); 9629 MatProductNumeric(C); // compute C=A * B 9630 MatProductReplaceMats(A1,B1,NULL,C); // compute C=A1 * B1 9631 MatProductNumeric(C); 9632 MatProductReplaceMats(A2,NULL,NULL,C); // compute C=A2 * B1 9633 MatProductNumeric(C); 9634 .ve 9635 9636 Level: intermediate 9637 9638 .seealso: `MatProductType`, `MATPRODUCT_AB`, `MatTransposeMatMult()`, `MatMatTransposeMult()`, `MatPtAP()`, `MatProductCreate()`, `MatProductSymbolic()`, `MatProductReplaceMats()`, `MatProductNumeric()` 9639 @*/ 9640 PetscErrorCode MatMatMult(Mat A, Mat B, MatReuse scall, PetscReal fill, Mat *C) { 9641 PetscFunctionBegin; 9642 PetscCall(MatProduct_Private(A, B, scall, fill, MATPRODUCT_AB, C)); 9643 PetscFunctionReturn(0); 9644 } 9645 9646 /*@ 9647 MatMatTransposeMult - Performs matrix-matrix multiplication C=A*B^T. 9648 9649 Neighbor-wise Collective on A 9650 9651 Input Parameters: 9652 + A - the left matrix 9653 . B - the right matrix 9654 . scall - either `MAT_INITIAL_MATRIX` or `MAT_REUSE_MATRIX` 9655 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use `PETSC_DEFAULT` if not known 9656 9657 Output Parameters: 9658 . C - the product matrix 9659 9660 Notes: 9661 C will be created if `MAT_INITIAL_MATRIX` and must be destroyed by the user with `MatDestroy()`. 9662 9663 `MAT_REUSE_MATRIX` can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9664 9665 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9666 actually needed. 9667 9668 This routine is currently only implemented for pairs of `MATSEQAIJ` matrices, for the `MATSEQDENSE` class, 9669 and for pairs of `MATMPIDENSE` matrices. 9670 9671 This routine is shorthand for using `MatProductCreate()` with the `MatProductType` of `MATPRODUCT_ABt` 9672 9673 Options Database Keys: 9674 . -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorithms for `MATMPIDENSE` matrices: the 9675 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity; 9676 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity. 9677 9678 Level: intermediate 9679 9680 .seealso: `MatProductCreate()`, `MATPRODUCT_ABt`, `MatMatMult()`, `MatTransposeMatMult()` `MatPtAP()`, `MatProductCreate()`, `MatProductAlgorithm`, `MatProductType`, `MATPRODUCT_ABt` 9681 @*/ 9682 PetscErrorCode MatMatTransposeMult(Mat A, Mat B, MatReuse scall, PetscReal fill, Mat *C) { 9683 PetscFunctionBegin; 9684 PetscCall(MatProduct_Private(A, B, scall, fill, MATPRODUCT_ABt, C)); 9685 if (A == B) PetscCall(MatSetOption(*C, MAT_SYMMETRIC, PETSC_TRUE)); 9686 PetscFunctionReturn(0); 9687 } 9688 9689 /*@ 9690 MatTransposeMatMult - Performs matrix-matrix multiplication C=A^T*B. 9691 9692 Neighbor-wise Collective on A 9693 9694 Input Parameters: 9695 + A - the left matrix 9696 . B - the right matrix 9697 . scall - either `MAT_INITIAL_MATRIX` or `MAT_REUSE_MATRIX` 9698 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use `PETSC_DEFAULT` if not known 9699 9700 Output Parameters: 9701 . C - the product matrix 9702 9703 Notes: 9704 C will be created if `MAT_INITIAL_MATRIX` and must be destroyed by the user with `MatDestroy()`. 9705 9706 `MAT_REUSE_MATRIX` can only be used if the matrices A and B have the same nonzero pattern as in the previous call. 9707 9708 This routine is shorthand for using `MatProductCreate()` with the `MatProductType` of `MATPRODUCT_AtB` 9709 9710 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9711 actually needed. 9712 9713 This routine is currently implemented for pairs of `MATAIJ` matrices and pairs of `MATSEQDENSE` matrices and classes 9714 which inherit from `MATSEQAIJ`. C will be of the same type as the input matrices. 9715 9716 Level: intermediate 9717 9718 .seealso: `MatProductCreate()`, `MATPRODUCT_AtB`, `MatMatMult()`, `MatMatTransposeMult()`, `MatPtAP()` 9719 @*/ 9720 PetscErrorCode MatTransposeMatMult(Mat A, Mat B, MatReuse scall, PetscReal fill, Mat *C) { 9721 PetscFunctionBegin; 9722 PetscCall(MatProduct_Private(A, B, scall, fill, MATPRODUCT_AtB, C)); 9723 PetscFunctionReturn(0); 9724 } 9725 9726 /*@ 9727 MatMatMatMult - Performs matrix-matrix-matrix multiplication D=A*B*C. 9728 9729 Neighbor-wise Collective on A 9730 9731 Input Parameters: 9732 + A - the left matrix 9733 . B - the middle matrix 9734 . C - the right matrix 9735 . scall - either `MAT_INITIAL_MATRIX` or `MAT_REUSE_MATRIX` 9736 - 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 9737 if the result is a dense matrix this is irrelevant 9738 9739 Output Parameters: 9740 . D - the product matrix 9741 9742 Notes: 9743 Unless scall is `MAT_REUSE_MATRIX` D will be created. 9744 9745 `MAT_REUSE_MATRIX` can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call 9746 9747 This routine is shorthand for using `MatProductCreate()` with the `MatProductType` of `MATPRODUCT_ABC` 9748 9749 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9750 actually needed. 9751 9752 If you have many matrices with the same non-zero structure to multiply, you 9753 should use `MAT_REUSE_MATRIX` in all calls but the first 9754 9755 Level: intermediate 9756 9757 .seealso: `MatProductCreate()`, `MATPRODUCT_ABC`, `MatMatMult`, `MatPtAP()`, `MatMatTransposeMult()`, `MatTransposeMatMult()` 9758 @*/ 9759 PetscErrorCode MatMatMatMult(Mat A, Mat B, Mat C, MatReuse scall, PetscReal fill, Mat *D) { 9760 PetscFunctionBegin; 9761 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*D, 6); 9762 PetscCheck(scall != MAT_INPLACE_MATRIX, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Inplace product not supported"); 9763 9764 if (scall == MAT_INITIAL_MATRIX) { 9765 PetscCall(MatProductCreate(A, B, C, D)); 9766 PetscCall(MatProductSetType(*D, MATPRODUCT_ABC)); 9767 PetscCall(MatProductSetAlgorithm(*D, "default")); 9768 PetscCall(MatProductSetFill(*D, fill)); 9769 9770 (*D)->product->api_user = PETSC_TRUE; 9771 PetscCall(MatProductSetFromOptions(*D)); 9772 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, 9773 ((PetscObject)C)->type_name); 9774 PetscCall(MatProductSymbolic(*D)); 9775 } else { /* user may change input matrices when REUSE */ 9776 PetscCall(MatProductReplaceMats(A, B, C, *D)); 9777 } 9778 PetscCall(MatProductNumeric(*D)); 9779 PetscFunctionReturn(0); 9780 } 9781 9782 /*@ 9783 MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators. 9784 9785 Collective on mat 9786 9787 Input Parameters: 9788 + mat - the matrix 9789 . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices) 9790 . subcomm - MPI communicator split from the communicator where mat resides in (or `MPI_COMM_NULL` if nsubcomm is used) 9791 - reuse - either `MAT_INITIAL_MATRIX` or `MAT_REUSE_MATRIX` 9792 9793 Output Parameter: 9794 . matredundant - redundant matrix 9795 9796 Notes: 9797 `MAT_REUSE_MATRIX` can only be used when the nonzero structure of the 9798 original matrix has not changed from that last call to MatCreateRedundantMatrix(). 9799 9800 This routine creates the duplicated matrices in the subcommunicators; you should NOT create them before 9801 calling it. 9802 9803 `PetscSubcommCreate()` can be used to manage the creation of the subcomm but need not be. 9804 9805 Level: advanced 9806 9807 .seealso: `MatDestroy()`, `PetscSubcommCreate()`, `PetscSubComm` 9808 @*/ 9809 PetscErrorCode MatCreateRedundantMatrix(Mat mat, PetscInt nsubcomm, MPI_Comm subcomm, MatReuse reuse, Mat *matredundant) { 9810 MPI_Comm comm; 9811 PetscMPIInt size; 9812 PetscInt mloc_sub, nloc_sub, rstart, rend, M = mat->rmap->N, N = mat->cmap->N, bs = mat->rmap->bs; 9813 Mat_Redundant *redund = NULL; 9814 PetscSubcomm psubcomm = NULL; 9815 MPI_Comm subcomm_in = subcomm; 9816 Mat *matseq; 9817 IS isrow, iscol; 9818 PetscBool newsubcomm = PETSC_FALSE; 9819 9820 PetscFunctionBegin; 9821 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 9822 if (nsubcomm && reuse == MAT_REUSE_MATRIX) { 9823 PetscValidPointer(*matredundant, 5); 9824 PetscValidHeaderSpecific(*matredundant, MAT_CLASSID, 5); 9825 } 9826 9827 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size)); 9828 if (size == 1 || nsubcomm == 1) { 9829 if (reuse == MAT_INITIAL_MATRIX) { 9830 PetscCall(MatDuplicate(mat, MAT_COPY_VALUES, matredundant)); 9831 } else { 9832 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"); 9833 PetscCall(MatCopy(mat, *matredundant, SAME_NONZERO_PATTERN)); 9834 } 9835 PetscFunctionReturn(0); 9836 } 9837 9838 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 9839 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 9840 MatCheckPreallocated(mat, 1); 9841 9842 PetscCall(PetscLogEventBegin(MAT_RedundantMat, mat, 0, 0, 0)); 9843 if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */ 9844 /* create psubcomm, then get subcomm */ 9845 PetscCall(PetscObjectGetComm((PetscObject)mat, &comm)); 9846 PetscCallMPI(MPI_Comm_size(comm, &size)); 9847 PetscCheck(nsubcomm >= 1 && nsubcomm <= size, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "nsubcomm must between 1 and %d", size); 9848 9849 PetscCall(PetscSubcommCreate(comm, &psubcomm)); 9850 PetscCall(PetscSubcommSetNumber(psubcomm, nsubcomm)); 9851 PetscCall(PetscSubcommSetType(psubcomm, PETSC_SUBCOMM_CONTIGUOUS)); 9852 PetscCall(PetscSubcommSetFromOptions(psubcomm)); 9853 PetscCall(PetscCommDuplicate(PetscSubcommChild(psubcomm), &subcomm, NULL)); 9854 newsubcomm = PETSC_TRUE; 9855 PetscCall(PetscSubcommDestroy(&psubcomm)); 9856 } 9857 9858 /* get isrow, iscol and a local sequential matrix matseq[0] */ 9859 if (reuse == MAT_INITIAL_MATRIX) { 9860 mloc_sub = PETSC_DECIDE; 9861 nloc_sub = PETSC_DECIDE; 9862 if (bs < 1) { 9863 PetscCall(PetscSplitOwnership(subcomm, &mloc_sub, &M)); 9864 PetscCall(PetscSplitOwnership(subcomm, &nloc_sub, &N)); 9865 } else { 9866 PetscCall(PetscSplitOwnershipBlock(subcomm, bs, &mloc_sub, &M)); 9867 PetscCall(PetscSplitOwnershipBlock(subcomm, bs, &nloc_sub, &N)); 9868 } 9869 PetscCallMPI(MPI_Scan(&mloc_sub, &rend, 1, MPIU_INT, MPI_SUM, subcomm)); 9870 rstart = rend - mloc_sub; 9871 PetscCall(ISCreateStride(PETSC_COMM_SELF, mloc_sub, rstart, 1, &isrow)); 9872 PetscCall(ISCreateStride(PETSC_COMM_SELF, N, 0, 1, &iscol)); 9873 } else { /* reuse == MAT_REUSE_MATRIX */ 9874 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"); 9875 /* retrieve subcomm */ 9876 PetscCall(PetscObjectGetComm((PetscObject)(*matredundant), &subcomm)); 9877 redund = (*matredundant)->redundant; 9878 isrow = redund->isrow; 9879 iscol = redund->iscol; 9880 matseq = redund->matseq; 9881 } 9882 PetscCall(MatCreateSubMatrices(mat, 1, &isrow, &iscol, reuse, &matseq)); 9883 9884 /* get matredundant over subcomm */ 9885 if (reuse == MAT_INITIAL_MATRIX) { 9886 PetscCall(MatCreateMPIMatConcatenateSeqMat(subcomm, matseq[0], nloc_sub, reuse, matredundant)); 9887 9888 /* create a supporting struct and attach it to C for reuse */ 9889 PetscCall(PetscNewLog(*matredundant, &redund)); 9890 (*matredundant)->redundant = redund; 9891 redund->isrow = isrow; 9892 redund->iscol = iscol; 9893 redund->matseq = matseq; 9894 if (newsubcomm) { 9895 redund->subcomm = subcomm; 9896 } else { 9897 redund->subcomm = MPI_COMM_NULL; 9898 } 9899 } else { 9900 PetscCall(MatCreateMPIMatConcatenateSeqMat(subcomm, matseq[0], PETSC_DECIDE, reuse, matredundant)); 9901 } 9902 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 9903 if (matseq[0]->boundtocpu && matseq[0]->bindingpropagates) { 9904 PetscCall(MatBindToCPU(*matredundant, PETSC_TRUE)); 9905 PetscCall(MatSetBindingPropagates(*matredundant, PETSC_TRUE)); 9906 } 9907 #endif 9908 PetscCall(PetscLogEventEnd(MAT_RedundantMat, mat, 0, 0, 0)); 9909 PetscFunctionReturn(0); 9910 } 9911 9912 /*@C 9913 MatGetMultiProcBlock - Create multiple 'parallel submatrices' from 9914 a given `Mat`. Each submatrix can span multiple procs. 9915 9916 Collective on mat 9917 9918 Input Parameters: 9919 + mat - the matrix 9920 . subcomm - the subcommunicator obtained by MPI_Com_split(comm) 9921 - scall - either `MAT_INITIAL_MATRIX` or `MAT_REUSE_MATRIX` 9922 9923 Output Parameter: 9924 . subMat - 'parallel submatrices each spans a given subcomm 9925 9926 Notes: 9927 The submatrix partition across processors is dictated by 'subComm' a 9928 communicator obtained by MPI_comm_split() or via `PetscSubcommCreate()`. The subComm 9929 is not restriced to be grouped with consecutive original ranks. 9930 9931 Due the MPI_Comm_split() usage, the parallel layout of the submatrices 9932 map directly to the layout of the original matrix [wrt the local 9933 row,col partitioning]. So the original 'DiagonalMat' naturally maps 9934 into the 'DiagonalMat' of the subMat, hence it is used directly from 9935 the subMat. However the offDiagMat looses some columns - and this is 9936 reconstructed with `MatSetValues()` 9937 9938 This is used by `PCBJACOBI` when a single block spans multiple MPI ranks 9939 9940 Level: advanced 9941 9942 .seealso: `MatCreateRedundantMatrix()`, `MatCreateSubMatrices()`, `PCBJACOBI` 9943 @*/ 9944 PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall, Mat *subMat) { 9945 PetscMPIInt commsize, subCommSize; 9946 9947 PetscFunctionBegin; 9948 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat), &commsize)); 9949 PetscCallMPI(MPI_Comm_size(subComm, &subCommSize)); 9950 PetscCheck(subCommSize <= commsize, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_OUTOFRANGE, "CommSize %d < SubCommZize %d", commsize, subCommSize); 9951 9952 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"); 9953 PetscCall(PetscLogEventBegin(MAT_GetMultiProcBlock, mat, 0, 0, 0)); 9954 PetscUseTypeMethod(mat, getmultiprocblock, subComm, scall, subMat); 9955 PetscCall(PetscLogEventEnd(MAT_GetMultiProcBlock, mat, 0, 0, 0)); 9956 PetscFunctionReturn(0); 9957 } 9958 9959 /*@ 9960 MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering 9961 9962 Not Collective 9963 9964 Input Parameters: 9965 + mat - matrix to extract local submatrix from 9966 . isrow - local row indices for submatrix 9967 - iscol - local column indices for submatrix 9968 9969 Output Parameter: 9970 . submat - the submatrix 9971 9972 Level: intermediate 9973 9974 Notes: 9975 The submat should be returned with `MatRestoreLocalSubMatrix()`. 9976 9977 Depending on the format of mat, the returned submat may not implement `MatMult()`. Its communicator may be 9978 the same as mat, it may be `PETSC_COMM_SELF`, or some other subcomm of mat's. 9979 9980 The submat always implements `MatSetValuesLocal()`. If isrow and iscol have the same block size, then 9981 `MatSetValuesBlockedLocal()` will also be implemented. 9982 9983 The mat must have had a `ISLocalToGlobalMapping` provided to it with `MatSetLocalToGlobalMapping()`. 9984 Matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided. 9985 9986 .seealso: `MatRestoreLocalSubMatrix()`, `MatCreateLocalRef()`, `MatSetLocalToGlobalMapping()` 9987 @*/ 9988 PetscErrorCode MatGetLocalSubMatrix(Mat mat, IS isrow, IS iscol, Mat *submat) { 9989 PetscFunctionBegin; 9990 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 9991 PetscValidHeaderSpecific(isrow, IS_CLASSID, 2); 9992 PetscValidHeaderSpecific(iscol, IS_CLASSID, 3); 9993 PetscCheckSameComm(isrow, 2, iscol, 3); 9994 PetscValidPointer(submat, 4); 9995 PetscCheck(mat->rmap->mapping, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Matrix must have local to global mapping provided before this call"); 9996 9997 if (mat->ops->getlocalsubmatrix) { 9998 PetscUseTypeMethod(mat, getlocalsubmatrix, isrow, iscol, submat); 9999 } else { 10000 PetscCall(MatCreateLocalRef(mat, isrow, iscol, submat)); 10001 } 10002 PetscFunctionReturn(0); 10003 } 10004 10005 /*@ 10006 MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering obtained with `MatGetLocalSubMatrix()` 10007 10008 Not Collective 10009 10010 Input Parameters: 10011 + mat - matrix to extract local submatrix from 10012 . isrow - local row indices for submatrix 10013 . iscol - local column indices for submatrix 10014 - submat - the submatrix 10015 10016 Level: intermediate 10017 10018 .seealso: `MatGetLocalSubMatrix()` 10019 @*/ 10020 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat, IS isrow, IS iscol, Mat *submat) { 10021 PetscFunctionBegin; 10022 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 10023 PetscValidHeaderSpecific(isrow, IS_CLASSID, 2); 10024 PetscValidHeaderSpecific(iscol, IS_CLASSID, 3); 10025 PetscCheckSameComm(isrow, 2, iscol, 3); 10026 PetscValidPointer(submat, 4); 10027 if (*submat) PetscValidHeaderSpecific(*submat, MAT_CLASSID, 4); 10028 10029 if (mat->ops->restorelocalsubmatrix) { 10030 PetscUseTypeMethod(mat, restorelocalsubmatrix, isrow, iscol, submat); 10031 } else { 10032 PetscCall(MatDestroy(submat)); 10033 } 10034 *submat = NULL; 10035 PetscFunctionReturn(0); 10036 } 10037 10038 /* --------------------------------------------------------*/ 10039 /*@ 10040 MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix 10041 10042 Collective on mat 10043 10044 Input Parameter: 10045 . mat - the matrix 10046 10047 Output Parameter: 10048 . is - if any rows have zero diagonals this contains the list of them 10049 10050 Level: developer 10051 10052 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 10053 @*/ 10054 PetscErrorCode MatFindZeroDiagonals(Mat mat, IS *is) { 10055 PetscFunctionBegin; 10056 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 10057 PetscValidType(mat, 1); 10058 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 10059 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 10060 10061 if (!mat->ops->findzerodiagonals) { 10062 Vec diag; 10063 const PetscScalar *a; 10064 PetscInt *rows; 10065 PetscInt rStart, rEnd, r, nrow = 0; 10066 10067 PetscCall(MatCreateVecs(mat, &diag, NULL)); 10068 PetscCall(MatGetDiagonal(mat, diag)); 10069 PetscCall(MatGetOwnershipRange(mat, &rStart, &rEnd)); 10070 PetscCall(VecGetArrayRead(diag, &a)); 10071 for (r = 0; r < rEnd - rStart; ++r) 10072 if (a[r] == 0.0) ++nrow; 10073 PetscCall(PetscMalloc1(nrow, &rows)); 10074 nrow = 0; 10075 for (r = 0; r < rEnd - rStart; ++r) 10076 if (a[r] == 0.0) rows[nrow++] = r + rStart; 10077 PetscCall(VecRestoreArrayRead(diag, &a)); 10078 PetscCall(VecDestroy(&diag)); 10079 PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)mat), nrow, rows, PETSC_OWN_POINTER, is)); 10080 } else { 10081 PetscUseTypeMethod(mat, findzerodiagonals, is); 10082 } 10083 PetscFunctionReturn(0); 10084 } 10085 10086 /*@ 10087 MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size) 10088 10089 Collective on mat 10090 10091 Input Parameter: 10092 . mat - the matrix 10093 10094 Output Parameter: 10095 . is - contains the list of rows with off block diagonal entries 10096 10097 Level: developer 10098 10099 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 10100 @*/ 10101 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat, IS *is) { 10102 PetscFunctionBegin; 10103 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 10104 PetscValidType(mat, 1); 10105 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 10106 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 10107 10108 PetscUseTypeMethod(mat, findoffblockdiagonalentries, is); 10109 PetscFunctionReturn(0); 10110 } 10111 10112 /*@C 10113 MatInvertBlockDiagonal - Inverts the block diagonal entries. 10114 10115 Collective on mat 10116 10117 Input Parameters: 10118 . mat - the matrix 10119 10120 Output Parameters: 10121 . values - the block inverses in column major order (FORTRAN-like) 10122 10123 Notes: 10124 The size of the blocks is determined by the block size of the matrix. 10125 10126 The blocks never overlap between two MPI ranks, use `MatInvertVariableBlockEnvelope()` for that case 10127 10128 The blocks all have the same size, use `MatInvertVariableBlockDiagonal()` for variable block size 10129 10130 Fortran Note: 10131 This routine is not available from Fortran. 10132 10133 Level: advanced 10134 10135 .seealso: `MatInvertVariableBlockEnvelope()`, `MatInvertBlockDiagonalMat()` 10136 @*/ 10137 PetscErrorCode MatInvertBlockDiagonal(Mat mat, const PetscScalar **values) { 10138 PetscFunctionBegin; 10139 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 10140 PetscCheck(mat->assembled, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 10141 PetscCheck(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 10142 PetscUseTypeMethod(mat, invertblockdiagonal, values); 10143 PetscFunctionReturn(0); 10144 } 10145 10146 /*@C 10147 MatInvertVariableBlockDiagonal - Inverts the point block diagonal entries. 10148 10149 Collective on mat 10150 10151 Input Parameters: 10152 + mat - the matrix 10153 . nblocks - the number of blocks on the process, set with `MatSetVariableBlockSizes()` 10154 - bsizes - the size of each block on the process, set with `MatSetVariableBlockSizes()` 10155 10156 Output Parameters: 10157 . values - the block inverses in column major order (FORTRAN-like) 10158 10159 Notes: 10160 Use `MatInvertBlockDiagonal()` if all blocks have the same size 10161 10162 The blocks never overlap between two MPI ranks, use `MatInvertVariableBlockEnvelope()` for that case 10163 10164 Fortran Note: 10165 This routine is not available from Fortran. 10166 10167 Level: advanced 10168 10169 .seealso: `MatInvertBlockDiagonal()`, `MatSetVariableBlockSizes()`, `MatInvertVariableBlockEnvelope()` 10170 @*/ 10171 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat, PetscInt nblocks, const PetscInt *bsizes, PetscScalar *values) { 10172 PetscFunctionBegin; 10173 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 10174 PetscCheck(mat->assembled, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 10175 PetscCheck(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 10176 PetscUseTypeMethod(mat, invertvariableblockdiagonal, nblocks, bsizes, values); 10177 PetscFunctionReturn(0); 10178 } 10179 10180 /*@ 10181 MatInvertBlockDiagonalMat - set the values of matrix C to be the inverted block diagonal of matrix A 10182 10183 Collective on Mat 10184 10185 Input Parameters: 10186 + A - the matrix 10187 - C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set. 10188 10189 Note: 10190 The blocksize of the matrix is used to determine the blocks on the diagonal of C 10191 10192 Level: advanced 10193 10194 .seealso: `MatInvertBlockDiagonal()` 10195 @*/ 10196 PetscErrorCode MatInvertBlockDiagonalMat(Mat A, Mat C) { 10197 const PetscScalar *vals; 10198 PetscInt *dnnz; 10199 PetscInt m, rstart, rend, bs, i, j; 10200 10201 PetscFunctionBegin; 10202 PetscCall(MatInvertBlockDiagonal(A, &vals)); 10203 PetscCall(MatGetBlockSize(A, &bs)); 10204 PetscCall(MatGetLocalSize(A, &m, NULL)); 10205 PetscCall(MatSetLayouts(C, A->rmap, A->cmap)); 10206 PetscCall(PetscMalloc1(m / bs, &dnnz)); 10207 for (j = 0; j < m / bs; j++) dnnz[j] = 1; 10208 PetscCall(MatXAIJSetPreallocation(C, bs, dnnz, NULL, NULL, NULL)); 10209 PetscCall(PetscFree(dnnz)); 10210 PetscCall(MatGetOwnershipRange(C, &rstart, &rend)); 10211 PetscCall(MatSetOption(C, MAT_ROW_ORIENTED, PETSC_FALSE)); 10212 for (i = rstart / bs; i < rend / bs; i++) PetscCall(MatSetValuesBlocked(C, 1, &i, 1, &i, &vals[(i - rstart / bs) * bs * bs], INSERT_VALUES)); 10213 PetscCall(MatAssemblyBegin(C, MAT_FINAL_ASSEMBLY)); 10214 PetscCall(MatAssemblyEnd(C, MAT_FINAL_ASSEMBLY)); 10215 PetscCall(MatSetOption(C, MAT_ROW_ORIENTED, PETSC_TRUE)); 10216 PetscFunctionReturn(0); 10217 } 10218 10219 /*@C 10220 MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created 10221 via `MatTransposeColoringCreate()`. 10222 10223 Collective on c 10224 10225 Input Parameter: 10226 . c - coloring context 10227 10228 Level: intermediate 10229 10230 .seealso: `MatTransposeColoringCreate()` 10231 @*/ 10232 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c) { 10233 MatTransposeColoring matcolor = *c; 10234 10235 PetscFunctionBegin; 10236 if (!matcolor) PetscFunctionReturn(0); 10237 if (--((PetscObject)matcolor)->refct > 0) { 10238 matcolor = NULL; 10239 PetscFunctionReturn(0); 10240 } 10241 10242 PetscCall(PetscFree3(matcolor->ncolumns, matcolor->nrows, matcolor->colorforrow)); 10243 PetscCall(PetscFree(matcolor->rows)); 10244 PetscCall(PetscFree(matcolor->den2sp)); 10245 PetscCall(PetscFree(matcolor->colorforcol)); 10246 PetscCall(PetscFree(matcolor->columns)); 10247 if (matcolor->brows > 0) PetscCall(PetscFree(matcolor->lstart)); 10248 PetscCall(PetscHeaderDestroy(c)); 10249 PetscFunctionReturn(0); 10250 } 10251 10252 /*@C 10253 MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which 10254 a `MatTransposeColoring` context has been created, computes a dense B^T by applying 10255 `MatTransposeColoring` to sparse B. 10256 10257 Collective on coloring 10258 10259 Input Parameters: 10260 + B - sparse matrix B 10261 . Btdense - symbolic dense matrix B^T 10262 - coloring - coloring context created with `MatTransposeColoringCreate()` 10263 10264 Output Parameter: 10265 . Btdense - dense matrix B^T 10266 10267 Level: developer 10268 10269 Note: 10270 These are used internally for some implementations of `MatRARt()` 10271 10272 .seealso: `MatTransposeColoringCreate()`, `MatTransposeColoringDestroy()`, `MatTransColoringApplyDenToSp()` 10273 10274 @*/ 10275 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring, Mat B, Mat Btdense) { 10276 PetscFunctionBegin; 10277 PetscValidHeaderSpecific(B, MAT_CLASSID, 2); 10278 PetscValidHeaderSpecific(Btdense, MAT_CLASSID, 3); 10279 PetscValidHeaderSpecific(coloring, MAT_TRANSPOSECOLORING_CLASSID, 1); 10280 10281 PetscCall((B->ops->transcoloringapplysptoden)(coloring, B, Btdense)); 10282 PetscFunctionReturn(0); 10283 } 10284 10285 /*@C 10286 MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which 10287 a `MatTransposeColoring` context has been created and a dense matrix Cden=A*Btdense 10288 in which Btdens is obtained from `MatTransColoringApplySpToDen()`, recover sparse matrix 10289 Csp from Cden. 10290 10291 Collective on matcoloring 10292 10293 Input Parameters: 10294 + coloring - coloring context created with `MatTransposeColoringCreate()` 10295 - Cden - matrix product of a sparse matrix and a dense matrix Btdense 10296 10297 Output Parameter: 10298 . Csp - sparse matrix 10299 10300 Level: developer 10301 10302 Note: 10303 These are used internally for some implementations of `MatRARt()` 10304 10305 .seealso: `MatTransposeColoringCreate()`, `MatTransposeColoringDestroy()`, `MatTransColoringApplySpToDen()` 10306 10307 @*/ 10308 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring, Mat Cden, Mat Csp) { 10309 PetscFunctionBegin; 10310 PetscValidHeaderSpecific(matcoloring, MAT_TRANSPOSECOLORING_CLASSID, 1); 10311 PetscValidHeaderSpecific(Cden, MAT_CLASSID, 2); 10312 PetscValidHeaderSpecific(Csp, MAT_CLASSID, 3); 10313 10314 PetscCall((Csp->ops->transcoloringapplydentosp)(matcoloring, Cden, Csp)); 10315 PetscCall(MatAssemblyBegin(Csp, MAT_FINAL_ASSEMBLY)); 10316 PetscCall(MatAssemblyEnd(Csp, MAT_FINAL_ASSEMBLY)); 10317 PetscFunctionReturn(0); 10318 } 10319 10320 /*@C 10321 MatTransposeColoringCreate - Creates a matrix coloring context for the matrix product C=A*B^T. 10322 10323 Collective on mat 10324 10325 Input Parameters: 10326 + mat - the matrix product C 10327 - iscoloring - the coloring of the matrix; usually obtained with `MatColoringCreate()` or `DMCreateColoring()` 10328 10329 Output Parameter: 10330 . color - the new coloring context 10331 10332 Level: intermediate 10333 10334 .seealso: `MatTransposeColoringDestroy()`, `MatTransColoringApplySpToDen()`, 10335 `MatTransColoringApplyDenToSp()` 10336 @*/ 10337 PetscErrorCode MatTransposeColoringCreate(Mat mat, ISColoring iscoloring, MatTransposeColoring *color) { 10338 MatTransposeColoring c; 10339 MPI_Comm comm; 10340 10341 PetscFunctionBegin; 10342 PetscCall(PetscLogEventBegin(MAT_TransposeColoringCreate, mat, 0, 0, 0)); 10343 PetscCall(PetscObjectGetComm((PetscObject)mat, &comm)); 10344 PetscCall(PetscHeaderCreate(c, MAT_TRANSPOSECOLORING_CLASSID, "MatTransposeColoring", "Matrix product C=A*B^T via coloring", "Mat", comm, MatTransposeColoringDestroy, NULL)); 10345 10346 c->ctype = iscoloring->ctype; 10347 if (mat->ops->transposecoloringcreate) { 10348 PetscUseTypeMethod(mat, transposecoloringcreate, iscoloring, c); 10349 } else SETERRQ(PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Code not yet written for matrix type %s", ((PetscObject)mat)->type_name); 10350 10351 *color = c; 10352 PetscCall(PetscLogEventEnd(MAT_TransposeColoringCreate, mat, 0, 0, 0)); 10353 PetscFunctionReturn(0); 10354 } 10355 10356 /*@ 10357 MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the 10358 matrix has had no new nonzero locations added to (or removed from) the matrix since the previous call then the value will be the 10359 same, otherwise it will be larger 10360 10361 Not Collective 10362 10363 Input Parameter: 10364 . A - the matrix 10365 10366 Output Parameter: 10367 . state - the current state 10368 10369 Notes: 10370 You can only compare states from two different calls to the SAME matrix, you cannot compare calls between 10371 different matrices 10372 10373 Use `PetscObjectStateGet()` to check for changes to the numerical values in a matrix 10374 10375 Use the result of `PetscObjectGetId()` to compare if a previously checked matrix is the same as the current matrix, do not compare object pointers. 10376 10377 Level: intermediate 10378 10379 .seealso: `PetscObjectStateGet()`, `PetscObjectGetId()` 10380 @*/ 10381 PetscErrorCode MatGetNonzeroState(Mat mat, PetscObjectState *state) { 10382 PetscFunctionBegin; 10383 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 10384 *state = mat->nonzerostate; 10385 PetscFunctionReturn(0); 10386 } 10387 10388 /*@ 10389 MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential 10390 matrices from each processor 10391 10392 Collective 10393 10394 Input Parameters: 10395 + comm - the communicators the parallel matrix will live on 10396 . seqmat - the input sequential matrices 10397 . n - number of local columns (or `PETSC_DECIDE`) 10398 - reuse - either `MAT_INITIAL_MATRIX` or `MAT_REUSE_MATRIX` 10399 10400 Output Parameter: 10401 . mpimat - the parallel matrix generated 10402 10403 Level: developer 10404 10405 Note: 10406 The number of columns of the matrix in EACH processor MUST be the same. 10407 10408 .seealso: `Mat` 10409 @*/ 10410 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm, Mat seqmat, PetscInt n, MatReuse reuse, Mat *mpimat) { 10411 PetscMPIInt size; 10412 10413 PetscFunctionBegin; 10414 PetscCallMPI(MPI_Comm_size(comm, &size)); 10415 if (size == 1) { 10416 if (reuse == MAT_INITIAL_MATRIX) { 10417 PetscCall(MatDuplicate(seqmat, MAT_COPY_VALUES, mpimat)); 10418 } else { 10419 PetscCall(MatCopy(seqmat, *mpimat, SAME_NONZERO_PATTERN)); 10420 } 10421 PetscFunctionReturn(0); 10422 } 10423 10424 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"); 10425 10426 PetscCall(PetscLogEventBegin(MAT_Merge, seqmat, 0, 0, 0)); 10427 PetscCall((*seqmat->ops->creatempimatconcatenateseqmat)(comm, seqmat, n, reuse, mpimat)); 10428 PetscCall(PetscLogEventEnd(MAT_Merge, seqmat, 0, 0, 0)); 10429 PetscFunctionReturn(0); 10430 } 10431 10432 /*@ 10433 MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent ranks' ownership ranges. 10434 10435 Collective on A 10436 10437 Input Parameters: 10438 + A - the matrix to create subdomains from 10439 - N - requested number of subdomains 10440 10441 Output Parameters: 10442 + n - number of subdomains resulting on this rank 10443 - iss - `IS` list with indices of subdomains on this rank 10444 10445 Level: advanced 10446 10447 Note: 10448 The number of subdomains must be smaller than the communicator size 10449 10450 .seealso: `Mat`, `IS` 10451 @*/ 10452 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A, PetscInt N, PetscInt *n, IS *iss[]) { 10453 MPI_Comm comm, subcomm; 10454 PetscMPIInt size, rank, color; 10455 PetscInt rstart, rend, k; 10456 10457 PetscFunctionBegin; 10458 PetscCall(PetscObjectGetComm((PetscObject)A, &comm)); 10459 PetscCallMPI(MPI_Comm_size(comm, &size)); 10460 PetscCallMPI(MPI_Comm_rank(comm, &rank)); 10461 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); 10462 *n = 1; 10463 k = ((PetscInt)size) / N + ((PetscInt)size % N > 0); /* There are up to k ranks to a color */ 10464 color = rank / k; 10465 PetscCallMPI(MPI_Comm_split(comm, color, rank, &subcomm)); 10466 PetscCall(PetscMalloc1(1, iss)); 10467 PetscCall(MatGetOwnershipRange(A, &rstart, &rend)); 10468 PetscCall(ISCreateStride(subcomm, rend - rstart, rstart, 1, iss[0])); 10469 PetscCallMPI(MPI_Comm_free(&subcomm)); 10470 PetscFunctionReturn(0); 10471 } 10472 10473 /*@ 10474 MatGalerkin - Constructs the coarse grid problem matrix via Galerkin projection. 10475 10476 If the interpolation and restriction operators are the same, uses `MatPtAP()`. 10477 If they are not the same, uses `MatMatMatMult()`. 10478 10479 Once the coarse grid problem is constructed, correct for interpolation operators 10480 that are not of full rank, which can legitimately happen in the case of non-nested 10481 geometric multigrid. 10482 10483 Input Parameters: 10484 + restrct - restriction operator 10485 . dA - fine grid matrix 10486 . interpolate - interpolation operator 10487 . reuse - either `MAT_INITIAL_MATRIX` or `MAT_REUSE_MATRIX` 10488 - fill - expected fill, use `PETSC_DEFAULT` if you do not have a good estimate 10489 10490 Output Parameters: 10491 . A - the Galerkin coarse matrix 10492 10493 Options Database Key: 10494 . -pc_mg_galerkin <both,pmat,mat,none> - for what matrices the Galerkin process should be used 10495 10496 Level: developer 10497 10498 .seealso: `MatPtAP()`, `MatMatMatMult()` 10499 @*/ 10500 PetscErrorCode MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A) { 10501 IS zerorows; 10502 Vec diag; 10503 10504 PetscFunctionBegin; 10505 PetscCheck(reuse != MAT_INPLACE_MATRIX, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Inplace product not supported"); 10506 /* Construct the coarse grid matrix */ 10507 if (interpolate == restrct) { 10508 PetscCall(MatPtAP(dA, interpolate, reuse, fill, A)); 10509 } else { 10510 PetscCall(MatMatMatMult(restrct, dA, interpolate, reuse, fill, A)); 10511 } 10512 10513 /* If the interpolation matrix is not of full rank, A will have zero rows. 10514 This can legitimately happen in the case of non-nested geometric multigrid. 10515 In that event, we set the rows of the matrix to the rows of the identity, 10516 ignoring the equations (as the RHS will also be zero). */ 10517 10518 PetscCall(MatFindZeroRows(*A, &zerorows)); 10519 10520 if (zerorows != NULL) { /* if there are any zero rows */ 10521 PetscCall(MatCreateVecs(*A, &diag, NULL)); 10522 PetscCall(MatGetDiagonal(*A, diag)); 10523 PetscCall(VecISSet(diag, zerorows, 1.0)); 10524 PetscCall(MatDiagonalSet(*A, diag, INSERT_VALUES)); 10525 PetscCall(VecDestroy(&diag)); 10526 PetscCall(ISDestroy(&zerorows)); 10527 } 10528 PetscFunctionReturn(0); 10529 } 10530 10531 /*@C 10532 MatSetOperation - Allows user to set a matrix operation for any matrix type 10533 10534 Logically Collective on mat 10535 10536 Input Parameters: 10537 + mat - the matrix 10538 . op - the name of the operation 10539 - f - the function that provides the operation 10540 10541 Level: developer 10542 10543 Usage: 10544 $ extern PetscErrorCode usermult(Mat,Vec,Vec); 10545 $ PetscCall(MatCreateXXX(comm,...&A); 10546 $ PetscCall(MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult); 10547 10548 Notes: 10549 See the file include/petscmat.h for a complete list of matrix 10550 operations, which all have the form MATOP_<OPERATION>, where 10551 <OPERATION> is the name (in all capital letters) of the 10552 user interface routine (e.g., MatMult() -> MATOP_MULT). 10553 10554 All user-provided functions (except for `MATOP_DESTROY`) should have the same calling 10555 sequence as the usual matrix interface routines, since they 10556 are intended to be accessed via the usual matrix interface 10557 routines, e.g., 10558 $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 10559 10560 In particular each function MUST return an error code of 0 on success and 10561 nonzero on failure. 10562 10563 This routine is distinct from `MatShellSetOperation()` in that it can be called on any matrix type. 10564 10565 .seealso: `MatGetOperation()`, `MatCreateShell()`, `MatShellSetContext()`, `MatShellSetOperation()` 10566 @*/ 10567 PetscErrorCode MatSetOperation(Mat mat, MatOperation op, void (*f)(void)) { 10568 PetscFunctionBegin; 10569 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 10570 if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) mat->ops->viewnative = mat->ops->view; 10571 (((void (**)(void))mat->ops)[op]) = f; 10572 PetscFunctionReturn(0); 10573 } 10574 10575 /*@C 10576 MatGetOperation - Gets a matrix operation for any matrix type. 10577 10578 Not Collective 10579 10580 Input Parameters: 10581 + mat - the matrix 10582 - op - the name of the operation 10583 10584 Output Parameter: 10585 . f - the function that provides the operation 10586 10587 Level: developer 10588 10589 Usage: 10590 $ PetscErrorCode (*usermult)(Mat,Vec,Vec); 10591 $ MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult); 10592 10593 Notes: 10594 See the file include/petscmat.h for a complete list of matrix 10595 operations, which all have the form MATOP_<OPERATION>, where 10596 <OPERATION> is the name (in all capital letters) of the 10597 user interface routine (e.g., `MatMult()` -> `MATOP_MULT`). 10598 10599 This routine is distinct from `MatShellGetOperation()` in that it can be called on any matrix type. 10600 10601 .seealso: `MatSetOperation()`, `MatCreateShell()`, `MatShellGetContext()`, `MatShellGetOperation()` 10602 @*/ 10603 PetscErrorCode MatGetOperation(Mat mat, MatOperation op, void (**f)(void)) { 10604 PetscFunctionBegin; 10605 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 10606 *f = (((void (**)(void))mat->ops)[op]); 10607 PetscFunctionReturn(0); 10608 } 10609 10610 /*@ 10611 MatHasOperation - Determines whether the given matrix supports the particular operation. 10612 10613 Not Collective 10614 10615 Input Parameters: 10616 + mat - the matrix 10617 - op - the operation, for example, `MATOP_GET_DIAGONAL` 10618 10619 Output Parameter: 10620 . has - either `PETSC_TRUE` or `PETSC_FALSE` 10621 10622 Level: advanced 10623 10624 Note: 10625 See the file include/petscmat.h for a complete list of matrix 10626 operations, which all have the form MATOP_<OPERATION>, where 10627 <OPERATION> is the name (in all capital letters) of the 10628 user-level routine. E.g., `MatNorm()` -> `MATOP_NORM`. 10629 10630 .seealso: `MatCreateShell()`, `MatGetOperation()`, `MatSetOperation()` 10631 @*/ 10632 PetscErrorCode MatHasOperation(Mat mat, MatOperation op, PetscBool *has) { 10633 PetscFunctionBegin; 10634 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 10635 PetscValidBoolPointer(has, 3); 10636 if (mat->ops->hasoperation) { 10637 PetscUseTypeMethod(mat, hasoperation, op, has); 10638 } else { 10639 if (((void **)mat->ops)[op]) *has = PETSC_TRUE; 10640 else { 10641 *has = PETSC_FALSE; 10642 if (op == MATOP_CREATE_SUBMATRIX) { 10643 PetscMPIInt size; 10644 10645 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size)); 10646 if (size == 1) PetscCall(MatHasOperation(mat, MATOP_CREATE_SUBMATRICES, has)); 10647 } 10648 } 10649 } 10650 PetscFunctionReturn(0); 10651 } 10652 10653 /*@ 10654 MatHasCongruentLayouts - Determines whether the rows and columns layouts of the matrix are congruent 10655 10656 Collective on mat 10657 10658 Input Parameters: 10659 . mat - the matrix 10660 10661 Output Parameter: 10662 . cong - either `PETSC_TRUE` or `PETSC_FALSE` 10663 10664 Level: beginner 10665 10666 .seealso: `MatCreate()`, `MatSetSizes()`, `PetscLayout` 10667 @*/ 10668 PetscErrorCode MatHasCongruentLayouts(Mat mat, PetscBool *cong) { 10669 PetscFunctionBegin; 10670 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 10671 PetscValidType(mat, 1); 10672 PetscValidBoolPointer(cong, 2); 10673 if (!mat->rmap || !mat->cmap) { 10674 *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE; 10675 PetscFunctionReturn(0); 10676 } 10677 if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */ 10678 PetscCall(PetscLayoutSetUp(mat->rmap)); 10679 PetscCall(PetscLayoutSetUp(mat->cmap)); 10680 PetscCall(PetscLayoutCompare(mat->rmap, mat->cmap, cong)); 10681 if (*cong) mat->congruentlayouts = 1; 10682 else mat->congruentlayouts = 0; 10683 } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE; 10684 PetscFunctionReturn(0); 10685 } 10686 10687 PetscErrorCode MatSetInf(Mat A) { 10688 PetscFunctionBegin; 10689 PetscUseTypeMethod(A, setinf); 10690 PetscFunctionReturn(0); 10691 } 10692 10693 /*C 10694 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 10695 10696 Collective on mat 10697 10698 Input Parameters: 10699 + A - the matrix 10700 - sym - `PETSC_TRUE` indicates that the graph will be symmetrized 10701 . scale - `PETSC_TRUE` indicates that the graph will be scaled with the diagonal 10702 10703 Output Parameter: 10704 . graph - the resulting graph 10705 10706 Level: advanced 10707 10708 .seealso: `MatCreate()`, `MatFilter()` 10709 */ 10710 PETSC_EXTERN PetscErrorCode MatCreateGraph(Mat A, PetscBool sym, PetscBool scale, Mat *graph) { 10711 PetscFunctionBegin; 10712 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 10713 PetscValidType(A, 1); 10714 PetscValidPointer(graph, 3); 10715 PetscUseTypeMethod(A, creategraph, sym, scale, graph); 10716 PetscFunctionReturn(0); 10717 } 10718 10719 /*C 10720 MatFilter - filters a matrices values with an absolut value equal to or below a give threshold 10721 10722 Collective on mat 10723 10724 Input Parameter: 10725 . value - filter value - < 0: does nothing; == 0: removes only 0.0 entries; otherwise: removes entries <= value 10726 10727 Input/Output Parameter: 10728 . A - the `Mat` to filter in place 10729 10730 Level: developer 10731 10732 Note: 10733 This is called before graph coarsers are called in `PCGAMG` 10734 10735 .seealso: `MatCreate()`, `MatCreateGraph()` 10736 */ 10737 PETSC_EXTERN PetscErrorCode MatFilter(Mat G, PetscReal value, Mat *F) { 10738 PetscFunctionBegin; 10739 PetscValidHeaderSpecific(G, MAT_CLASSID, 1); 10740 PetscValidType(G, 1); 10741 PetscValidPointer(F, 3); 10742 if (value >= 0.0) PetscCall((G->ops->filter)(G, value, F)); 10743 PetscFunctionReturn(0); 10744 } 10745