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