1 /* 2 This is where the abstract matrix operations are defined 3 */ 4 5 #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/ 6 #include <petsc/private/isimpl.h> 7 #include <petsc/private/vecimpl.h> 8 9 /* Logging support */ 10 PetscClassId MAT_CLASSID; 11 PetscClassId MAT_COLORING_CLASSID; 12 PetscClassId MAT_FDCOLORING_CLASSID; 13 PetscClassId MAT_TRANSPOSECOLORING_CLASSID; 14 15 PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultAdd, MAT_MultTranspose; 16 PetscLogEvent MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve, MAT_MatTrSolve; 17 PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic; 18 PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor; 19 PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin; 20 PetscLogEvent MAT_QRFactorNumeric, MAT_QRFactorSymbolic, MAT_QRFactor; 21 PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_CreateSubMats, MAT_GetOrdering, MAT_RedundantMat, MAT_GetSeqNonzeroStructure; 22 PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_PartitioningND, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate; 23 PetscLogEvent MAT_FDColoringSetUp, MAT_FDColoringApply, MAT_Transpose, MAT_FDColoringFunction, MAT_CreateSubMat; 24 PetscLogEvent MAT_TransposeColoringCreate; 25 PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric; 26 PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric, MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric; 27 PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric; 28 PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric; 29 PetscLogEvent MAT_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric; 30 PetscLogEvent MAT_MultHermitianTranspose, MAT_MultHermitianTransposeAdd; 31 PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_GetBrowsOfAcols; 32 PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym; 33 PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure; 34 PetscLogEvent MAT_GetMultiProcBlock; 35 PetscLogEvent MAT_CUSPARSECopyToGPU, MAT_CUSPARSECopyFromGPU, MAT_CUSPARSEGenerateTranspose, MAT_CUSPARSESolveAnalysis; 36 PetscLogEvent MAT_PreallCOO, MAT_SetVCOO; 37 PetscLogEvent MAT_SetValuesBatch; 38 PetscLogEvent MAT_ViennaCLCopyToGPU; 39 PetscLogEvent MAT_DenseCopyToGPU, MAT_DenseCopyFromGPU; 40 PetscLogEvent MAT_Merge, MAT_Residual, MAT_SetRandom; 41 PetscLogEvent MAT_FactorFactS, MAT_FactorInvS; 42 PetscLogEvent MATCOLORING_Apply, MATCOLORING_Comm, MATCOLORING_Local, MATCOLORING_ISCreate, MATCOLORING_SetUp, MATCOLORING_Weights; 43 PetscLogEvent MAT_H2Opus_Build, MAT_H2Opus_Compress, MAT_H2Opus_Orthog, MAT_H2Opus_LR; 44 45 const char *const MatFactorTypes[] = {"NONE", "LU", "CHOLESKY", "ILU", "ICC", "ILUDT", "QR", "MatFactorType", "MAT_FACTOR_", NULL}; 46 47 /*@ 48 MatSetRandom - Sets all components of a matrix to random numbers. For sparse matrices that have been preallocated but not been assembled it randomly selects appropriate locations, 49 for sparse matrices that already have locations it fills the locations with random numbers 50 51 Logically Collective on Mat 52 53 Input Parameters: 54 + x - the matrix 55 - rctx - the random number context, formed by `PetscRandomCreate()`, or NULL and 56 it will create one internally. 57 58 Output Parameter: 59 . x - the matrix 60 61 Example of Usage: 62 .vb 63 PetscRandomCreate(PETSC_COMM_WORLD,&rctx); 64 MatSetRandom(x,rctx); 65 PetscRandomDestroy(rctx); 66 .ve 67 68 Level: intermediate 69 70 .seealso: `MatZeroEntries()`, `MatSetValues()`, `PetscRandomCreate()`, `PetscRandomDestroy()` 71 @*/ 72 PetscErrorCode MatSetRandom(Mat x, PetscRandom rctx) { 73 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 @*/ 122 PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat, PetscReal *pivot, PetscInt *row) { 123 PetscFunctionBegin; 124 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 125 PetscValidRealPointer(pivot, 2); 126 PetscValidIntPointer(row, 3); 127 *pivot = mat->factorerror_zeropivot_value; 128 *row = mat->factorerror_zeropivot_row; 129 PetscFunctionReturn(0); 130 } 131 132 /*@ 133 MatFactorGetError - gets the error code from a factorization 134 135 Logically Collective on Mat 136 137 Input Parameters: 138 . mat - the factored matrix 139 140 Output Parameter: 141 . err - the error code 142 143 Level: advanced 144 145 Notes: 146 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 147 148 .seealso: `MatZeroEntries()`, `MatFactor()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()`, `MatFactorClearError()`, `MatFactorGetErrorZeroPivot()`, 149 `MatErrorCode` 150 @*/ 151 PetscErrorCode MatFactorGetError(Mat mat, MatFactorError *err) { 152 PetscFunctionBegin; 153 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 154 PetscValidPointer(err, 2); 155 *err = mat->factorerrortype; 156 PetscFunctionReturn(0); 157 } 158 159 /*@ 160 MatFactorClearError - clears the error code in a factorization 161 162 Logically Collective on Mat 163 164 Input Parameter: 165 . mat - the factored matrix 166 167 Level: developer 168 169 Notes: 170 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 171 172 .seealso: `MatZeroEntries()`, `MatFactor()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()`, `MatFactorGetError()`, `MatFactorGetErrorZeroPivot()`, 173 `MatGetErrorCode()`, `MatErrorCode` 174 @*/ 175 PetscErrorCode MatFactorClearError(Mat mat) { 176 PetscFunctionBegin; 177 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 178 mat->factorerrortype = MAT_FACTOR_NOERROR; 179 mat->factorerror_zeropivot_value = 0.0; 180 mat->factorerror_zeropivot_row = 0; 181 PetscFunctionReturn(0); 182 } 183 184 PETSC_INTERN PetscErrorCode MatFindNonzeroRowsOrCols_Basic(Mat mat, PetscBool cols, PetscReal tol, IS *nonzero) { 185 Vec r, l; 186 const PetscScalar *al; 187 PetscInt i, nz, gnz, N, n; 188 189 PetscFunctionBegin; 190 PetscCall(MatCreateVecs(mat, &r, &l)); 191 if (!cols) { /* nonzero rows */ 192 PetscCall(MatGetSize(mat, &N, NULL)); 193 PetscCall(MatGetLocalSize(mat, &n, NULL)); 194 PetscCall(VecSet(l, 0.0)); 195 PetscCall(VecSetRandom(r, NULL)); 196 PetscCall(MatMult(mat, r, l)); 197 PetscCall(VecGetArrayRead(l, &al)); 198 } else { /* nonzero columns */ 199 PetscCall(MatGetSize(mat, NULL, &N)); 200 PetscCall(MatGetLocalSize(mat, NULL, &n)); 201 PetscCall(VecSet(r, 0.0)); 202 PetscCall(VecSetRandom(l, NULL)); 203 PetscCall(MatMultTranspose(mat, l, r)); 204 PetscCall(VecGetArrayRead(r, &al)); 205 } 206 if (tol <= 0.0) { 207 for (i = 0, nz = 0; i < n; i++) 208 if (al[i] != 0.0) nz++; 209 } else { 210 for (i = 0, nz = 0; i < n; i++) 211 if (PetscAbsScalar(al[i]) > tol) nz++; 212 } 213 PetscCall(MPIU_Allreduce(&nz, &gnz, 1, MPIU_INT, MPI_SUM, PetscObjectComm((PetscObject)mat))); 214 if (gnz != N) { 215 PetscInt *nzr; 216 PetscCall(PetscMalloc1(nz, &nzr)); 217 if (nz) { 218 if (tol < 0) { 219 for (i = 0, nz = 0; i < n; i++) 220 if (al[i] != 0.0) nzr[nz++] = i; 221 } else { 222 for (i = 0, nz = 0; i < n; i++) 223 if (PetscAbsScalar(al[i]) > tol) nzr[nz++] = i; 224 } 225 } 226 PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)mat), nz, nzr, PETSC_OWN_POINTER, nonzero)); 227 } else *nonzero = NULL; 228 if (!cols) { /* nonzero rows */ 229 PetscCall(VecRestoreArrayRead(l, &al)); 230 } else { 231 PetscCall(VecRestoreArrayRead(r, &al)); 232 } 233 PetscCall(VecDestroy(&l)); 234 PetscCall(VecDestroy(&r)); 235 PetscFunctionReturn(0); 236 } 237 238 /*@ 239 MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix 240 241 Input Parameter: 242 . A - the matrix 243 244 Output Parameter: 245 . keptrows - the rows that are not completely zero 246 247 Notes: 248 keptrows is set to NULL if all rows are nonzero. 249 250 Level: intermediate 251 252 @*/ 253 PetscErrorCode MatFindNonzeroRows(Mat mat, IS *keptrows) { 254 PetscFunctionBegin; 255 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 256 PetscValidType(mat, 1); 257 PetscValidPointer(keptrows, 2); 258 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 259 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 260 if (mat->ops->findnonzerorows) PetscUseTypeMethod(mat, findnonzerorows, keptrows); 261 else PetscCall(MatFindNonzeroRowsOrCols_Basic(mat, PETSC_FALSE, 0.0, keptrows)); 262 PetscFunctionReturn(0); 263 } 264 265 /*@ 266 MatFindZeroRows - Locate all rows that are completely zero in the matrix 267 268 Input Parameter: 269 . A - the matrix 270 271 Output Parameter: 272 . zerorows - the rows that are completely zero 273 274 Notes: 275 zerorows is set to NULL if no rows are zero. 276 277 Level: intermediate 278 279 @*/ 280 PetscErrorCode MatFindZeroRows(Mat mat, IS *zerorows) { 281 IS keptrows; 282 PetscInt m, n; 283 284 PetscFunctionBegin; 285 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 286 PetscValidType(mat, 1); 287 PetscValidPointer(zerorows, 2); 288 PetscCall(MatFindNonzeroRows(mat, &keptrows)); 289 /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows. 290 In keeping with this convention, we set zerorows to NULL if there are no zero 291 rows. */ 292 if (keptrows == NULL) { 293 *zerorows = NULL; 294 } else { 295 PetscCall(MatGetOwnershipRange(mat, &m, &n)); 296 PetscCall(ISComplement(keptrows, m, n, zerorows)); 297 PetscCall(ISDestroy(&keptrows)); 298 } 299 PetscFunctionReturn(0); 300 } 301 302 /*@ 303 MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling 304 305 Not Collective 306 307 Input Parameters: 308 . A - the matrix 309 310 Output Parameters: 311 . a - the diagonal part (which is a SEQUENTIAL matrix) 312 313 Notes: 314 See the manual page for `MatCreateAIJ()` for more information on the "diagonal part" of the matrix. 315 316 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. 317 318 Level: advanced 319 320 .seelaso: `MatCreateAIJ()` 321 @*/ 322 PetscErrorCode MatGetDiagonalBlock(Mat A, Mat *a) { 323 PetscFunctionBegin; 324 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 325 PetscValidType(A, 1); 326 PetscValidPointer(a, 2); 327 PetscCheck(!A->factortype, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 328 if (A->ops->getdiagonalblock) PetscUseTypeMethod(A, getdiagonalblock, a); 329 else { 330 PetscMPIInt size; 331 332 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)A), &size)); 333 PetscCheck(size == 1, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Not for parallel matrix type %s", ((PetscObject)A)->type_name); 334 *a = A; 335 } 336 PetscFunctionReturn(0); 337 } 338 339 /*@ 340 MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries. 341 342 Collective on Mat 343 344 Input Parameters: 345 . mat - the matrix 346 347 Output Parameter: 348 . trace - the sum of the diagonal entries 349 350 Level: advanced 351 352 @*/ 353 PetscErrorCode MatGetTrace(Mat mat, PetscScalar *trace) { 354 Vec diag; 355 356 PetscFunctionBegin; 357 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 358 PetscValidScalarPointer(trace, 2); 359 PetscCall(MatCreateVecs(mat, &diag, NULL)); 360 PetscCall(MatGetDiagonal(mat, diag)); 361 PetscCall(VecSum(diag, trace)); 362 PetscCall(VecDestroy(&diag)); 363 PetscFunctionReturn(0); 364 } 365 366 /*@ 367 MatRealPart - Zeros out the imaginary part of the matrix 368 369 Logically Collective on Mat 370 371 Input Parameters: 372 . mat - the matrix 373 374 Level: advanced 375 376 .seealso: `MatImaginaryPart()` 377 @*/ 378 PetscErrorCode MatRealPart(Mat mat) { 379 PetscFunctionBegin; 380 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 381 PetscValidType(mat, 1); 382 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 383 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 384 MatCheckPreallocated(mat, 1); 385 PetscUseTypeMethod(mat, realpart); 386 PetscFunctionReturn(0); 387 } 388 389 /*@C 390 MatGetGhosts - Get the global indices of all ghost nodes defined by the sparse matrix 391 392 Collective on Mat 393 394 Input Parameter: 395 . mat - the matrix 396 397 Output Parameters: 398 + nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block) 399 - ghosts - the global indices of the ghost points 400 401 Notes: 402 the nghosts and ghosts are suitable to pass into `VecCreateGhost()` 403 404 Level: advanced 405 406 @*/ 407 PetscErrorCode MatGetGhosts(Mat mat, PetscInt *nghosts, const PetscInt *ghosts[]) { 408 PetscFunctionBegin; 409 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 410 PetscValidType(mat, 1); 411 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 412 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 413 if (mat->ops->getghosts) PetscUseTypeMethod(mat, getghosts, nghosts, ghosts); 414 else { 415 if (nghosts) *nghosts = 0; 416 if (ghosts) *ghosts = NULL; 417 } 418 PetscFunctionReturn(0); 419 } 420 421 /*@ 422 MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part 423 424 Logically Collective on Mat 425 426 Input Parameters: 427 . mat - the matrix 428 429 Level: advanced 430 431 .seealso: `MatRealPart()` 432 @*/ 433 PetscErrorCode MatImaginaryPart(Mat mat) { 434 PetscFunctionBegin; 435 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 436 PetscValidType(mat, 1); 437 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 438 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 439 MatCheckPreallocated(mat, 1); 440 PetscUseTypeMethod(mat, imaginarypart); 441 PetscFunctionReturn(0); 442 } 443 444 /*@ 445 MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices) 446 447 Not Collective 448 449 Input Parameter: 450 . mat - the matrix 451 452 Output Parameters: 453 + missing - is any diagonal missing 454 - dd - first diagonal entry that is missing (optional) on this process 455 456 Level: advanced 457 458 .seealso: `MatRealPart()` 459 @*/ 460 PetscErrorCode MatMissingDiagonal(Mat mat, PetscBool *missing, PetscInt *dd) { 461 PetscFunctionBegin; 462 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 463 PetscValidType(mat, 1); 464 PetscValidBoolPointer(missing, 2); 465 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix %s", ((PetscObject)mat)->type_name); 466 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 467 PetscUseTypeMethod(mat, missingdiagonal, missing, dd); 468 PetscFunctionReturn(0); 469 } 470 471 /*@C 472 MatGetRow - Gets a row of a matrix. You MUST call `MatRestoreRow()` 473 for each row that you get to ensure that your application does 474 not bleed memory. 475 476 Not Collective 477 478 Input Parameters: 479 + mat - the matrix 480 - row - the row to get 481 482 Output Parameters: 483 + ncols - if not NULL, the number of nonzeros in the row 484 . cols - if not NULL, the column numbers 485 - vals - if not NULL, the values 486 487 Notes: 488 This routine is provided for people who need to have direct access 489 to the structure of a matrix. We hope that we provide enough 490 high-level matrix routines that few users will need it. 491 492 `MatGetRow()` always returns 0-based column indices, regardless of 493 whether the internal representation is 0-based (default) or 1-based. 494 495 For better efficiency, set cols and/or vals to NULL if you do 496 not wish to extract these quantities. 497 498 The user can only examine the values extracted with `MatGetRow()`; 499 the values cannot be altered. To change the matrix entries, one 500 must use `MatSetValues()`. 501 502 You can only have one call to `MatGetRow()` outstanding for a particular 503 matrix at a time, per processor. `MatGetRow()` can only obtain rows 504 associated with the given processor, it cannot get rows from the 505 other processors; for that we suggest using `MatCreateSubMatrices()`, then 506 MatGetRow() on the submatrix. The row index passed to `MatGetRow()` 507 is in the global number of rows. 508 509 Use `MatGetRowIJ()` and `MatRestoreRowIJ()` to access all the local indices of the sparse matrix. 510 511 Use `MatSeqAIJGetArray()` and similar functions to access the numerical values for certain matrix types directly. 512 513 Fortran Notes: 514 The calling sequence from Fortran is 515 .vb 516 MatGetRow(matrix,row,ncols,cols,values,ierr) 517 Mat matrix (input) 518 integer row (input) 519 integer ncols (output) 520 integer cols(maxcols) (output) 521 double precision (or double complex) values(maxcols) output 522 .ve 523 where maxcols >= maximum nonzeros in any row of the matrix. 524 525 Caution: 526 Do not try to change the contents of the output arrays (cols and vals). 527 In some cases, this may corrupt the matrix. 528 529 Level: advanced 530 531 .seealso: `MatRestoreRow()`, `MatSetValues()`, `MatGetValues()`, `MatCreateSubMatrices()`, `MatGetDiagonal()`, `MatGetRowIJ()`, `MatRestoreRowIJ()` 532 @*/ 533 PetscErrorCode MatGetRow(Mat mat, PetscInt row, PetscInt *ncols, const PetscInt *cols[], const PetscScalar *vals[]) { 534 PetscInt incols; 535 536 PetscFunctionBegin; 537 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 538 PetscValidType(mat, 1); 539 PetscCheck(mat->assembled, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 540 PetscCheck(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 541 MatCheckPreallocated(mat, 1); 542 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); 543 PetscCall(PetscLogEventBegin(MAT_GetRow, mat, 0, 0, 0)); 544 PetscCall((*mat->ops->getrow)(mat, row, &incols, (PetscInt **)cols, (PetscScalar **)vals)); 545 if (ncols) *ncols = incols; 546 PetscCall(PetscLogEventEnd(MAT_GetRow, mat, 0, 0, 0)); 547 PetscFunctionReturn(0); 548 } 549 550 /*@ 551 MatConjugate - replaces the matrix values with their complex conjugates 552 553 Logically Collective on Mat 554 555 Input Parameters: 556 . mat - the matrix 557 558 Level: advanced 559 560 .seealso: `VecConjugate()`, `MatTranspose()` 561 @*/ 562 PetscErrorCode MatConjugate(Mat mat) { 563 PetscFunctionBegin; 564 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 565 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 566 if (PetscDefined(USE_COMPLEX) && mat->hermitian != PETSC_BOOL3_TRUE) { 567 PetscUseTypeMethod(mat, conjugate); 568 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 569 } 570 PetscFunctionReturn(0); 571 } 572 573 /*@C 574 MatRestoreRow - Frees any temporary space allocated by `MatGetRow()`. 575 576 Not Collective 577 578 Input Parameters: 579 + mat - the matrix 580 . row - the row to get 581 . ncols, cols - the number of nonzeros and their columns 582 - vals - if nonzero the column values 583 584 Notes: 585 This routine should be called after you have finished examining the entries. 586 587 This routine zeros out ncols, cols, and vals. This is to prevent accidental 588 us of the array after it has been restored. If you pass NULL, it will 589 not zero the pointers. Use of cols or vals after `MatRestoreRow()` is invalid. 590 591 Fortran Notes: 592 The calling sequence from Fortran is 593 .vb 594 MatRestoreRow(matrix,row,ncols,cols,values,ierr) 595 Mat matrix (input) 596 integer row (input) 597 integer ncols (output) 598 integer cols(maxcols) (output) 599 double precision (or double complex) values(maxcols) output 600 .ve 601 Where maxcols >= maximum nonzeros in any row of the matrix. 602 603 In Fortran `MatRestoreRow()` MUST be called after `MatGetRow()` 604 before another call to `MatGetRow()` can be made. 605 606 Level: advanced 607 608 .seealso: `MatGetRow()` 609 @*/ 610 PetscErrorCode MatRestoreRow(Mat mat, PetscInt row, PetscInt *ncols, const PetscInt *cols[], const PetscScalar *vals[]) { 611 PetscFunctionBegin; 612 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 613 if (ncols) PetscValidIntPointer(ncols, 3); 614 PetscCheck(mat->assembled, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 615 if (!mat->ops->restorerow) PetscFunctionReturn(0); 616 PetscCall((*mat->ops->restorerow)(mat, row, ncols, (PetscInt **)cols, (PetscScalar **)vals)); 617 if (ncols) *ncols = 0; 618 if (cols) *cols = NULL; 619 if (vals) *vals = NULL; 620 PetscFunctionReturn(0); 621 } 622 623 /*@ 624 MatGetRowUpperTriangular - Sets a flag to enable calls to `MatGetRow()` for matrix in `MATSBAIJ` format. 625 You should call `MatRestoreRowUpperTriangular()` after calling` MatGetRow()` and `MatRestoreRow()` to disable the flag. 626 627 Not Collective 628 629 Input Parameters: 630 . mat - the matrix 631 632 Notes: 633 The flag is to ensure that users are aware of `MatGetRow()` only provides the upper triangular part of the row for the matrices in `MATSBAIJ` format. 634 635 Level: advanced 636 637 .seealso: `MatRestoreRowUpperTriangular()` 638 @*/ 639 PetscErrorCode MatGetRowUpperTriangular(Mat mat) { 640 PetscFunctionBegin; 641 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 642 PetscValidType(mat, 1); 643 PetscCheck(mat->assembled, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 644 PetscCheck(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 645 MatCheckPreallocated(mat, 1); 646 if (!mat->ops->getrowuppertriangular) PetscFunctionReturn(0); 647 PetscUseTypeMethod(mat, getrowuppertriangular); 648 PetscFunctionReturn(0); 649 } 650 651 /*@ 652 MatRestoreRowUpperTriangular - Disable calls to `MatGetRow()` for matrix in `MATSBAIJ` format. 653 654 Not Collective 655 656 Input Parameters: 657 . mat - the matrix 658 659 Notes: 660 This routine should be called after you have finished calls to `MatGetRow()` and `MatRestoreRow()`. 661 662 Level: advanced 663 664 .seealso: `MatGetRowUpperTriangular()` 665 @*/ 666 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat) { 667 PetscFunctionBegin; 668 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 669 PetscValidType(mat, 1); 670 PetscCheck(mat->assembled, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 671 PetscCheck(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 672 MatCheckPreallocated(mat, 1); 673 if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0); 674 PetscUseTypeMethod(mat, restorerowuppertriangular); 675 PetscFunctionReturn(0); 676 } 677 678 /*@C 679 MatSetOptionsPrefix - Sets the prefix used for searching for all 680 Mat options in the database. 681 682 Logically Collective on Mat 683 684 Input Parameters: 685 + A - the Mat context 686 - prefix - the prefix to prepend to all option names 687 688 Notes: 689 A hyphen (-) must NOT be given at the beginning of the prefix name. 690 The first character of all runtime options is AUTOMATICALLY the hyphen. 691 692 This is NOT used for options for the factorization of the matrix. Normally the 693 prefix is automatically passed in from the PC calling the factorization. To set 694 it directly use `MatSetOptionsPrefixFactor()` 695 696 Level: advanced 697 698 .seealso: `MatSetFromOptions()`, `MatSetOptionsPrefixFactor()` 699 @*/ 700 PetscErrorCode MatSetOptionsPrefix(Mat A, const char prefix[]) { 701 PetscFunctionBegin; 702 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 703 PetscCall(PetscObjectSetOptionsPrefix((PetscObject)A, prefix)); 704 PetscFunctionReturn(0); 705 } 706 707 /*@C 708 MatSetOptionsPrefixFactor - Sets the prefix used for searching for all Mat factor options in the database for 709 for matrices created with `MatGetFactor()` 710 711 Logically Collective on Mat 712 713 Input Parameters: 714 + A - the Mat context 715 - prefix - the prefix to prepend to all option names for the factored matrix 716 717 Notes: 718 A hyphen (-) must NOT be given at the beginning of the prefix name. 719 The first character of all runtime options is AUTOMATICALLY the hyphen. 720 721 Normally the prefix is automatically passed in from the PC calling the factorization. To set 722 it directly when not using `KSP`/`PC` use `MatSetOptionsPrefixFactor()` 723 724 Level: developer 725 726 .seealso: `MatSetFromOptions()`, `MatSetOptionsPrefix()`, `MatAppendOptionsPrefixFactor()` 727 @*/ 728 PetscErrorCode MatSetOptionsPrefixFactor(Mat A, const char prefix[]) { 729 PetscFunctionBegin; 730 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 731 if (prefix) { 732 PetscValidCharPointer(prefix, 2); 733 PetscCheck(prefix[0] != '-', PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Options prefix should not begin with a hyphen"); 734 if (prefix != A->factorprefix) { 735 PetscCall(PetscFree(A->factorprefix)); 736 PetscCall(PetscStrallocpy(prefix, &A->factorprefix)); 737 } 738 } else PetscCall(PetscFree(A->factorprefix)); 739 PetscFunctionReturn(0); 740 } 741 742 /*@C 743 MatAppendOptionsPrefixFactor - Appends to the prefix used for searching for all Mat factor options in the database for 744 for matrices created with `MatGetFactor()` 745 746 Logically Collective on Mat 747 748 Input Parameters: 749 + A - the Mat context 750 - prefix - the prefix to prepend to all option names for the factored matrix 751 752 Notes: 753 A hyphen (-) must NOT be given at the beginning of the prefix name. 754 The first character of all runtime options is AUTOMATICALLY the hyphen. 755 756 Normally the prefix is automatically passed in from the PC calling the factorization. To set 757 it directly when not using `KSP`/`PC` use `MatAppendOptionsPrefixFactor()` 758 759 Level: developer 760 .seealso: `PetscOptionsCreate()`, `PetscOptionsDestroy()`, `PetscObjectSetOptionsPrefix()`, `PetscObjectPrependOptionsPrefix()`, 761 `PetscObjectGetOptionsPrefix()`, `TSAppendOptionsPrefix()`, `SNESAppendOptionsPrefix()`, `KSPAppendOptionsPrefix()`, `MatSetOptionsPrefixFactor()`, 762 `MatSetOptionsPrefix()` 763 @*/ 764 PetscErrorCode MatAppendOptionsPrefixFactor(Mat A, const char prefix[]) { 765 char *buf = A->factorprefix; 766 size_t len1, len2; 767 768 PetscFunctionBegin; 769 PetscValidHeader(A, 1); 770 if (!prefix) PetscFunctionReturn(0); 771 if (!buf) { 772 PetscCall(MatSetOptionsPrefixFactor(A, prefix)); 773 PetscFunctionReturn(0); 774 } 775 PetscCheck(prefix[0] != '-', PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Options prefix should not begin with a hyphen"); 776 777 PetscCall(PetscStrlen(prefix, &len1)); 778 PetscCall(PetscStrlen(buf, &len2)); 779 PetscCall(PetscMalloc1(1 + len1 + len2, &A->factorprefix)); 780 PetscCall(PetscStrcpy(A->factorprefix, buf)); 781 PetscCall(PetscStrcat(A->factorprefix, prefix)); 782 PetscCall(PetscFree(buf)); 783 PetscFunctionReturn(0); 784 } 785 786 /*@C 787 MatAppendOptionsPrefix - Appends to the prefix used for searching for all 788 Mat options in the database. 789 790 Logically Collective on Mat 791 792 Input Parameters: 793 + A - the Mat context 794 - prefix - the prefix to prepend to all option names 795 796 Notes: 797 A hyphen (-) must NOT be given at the beginning of the prefix name. 798 The first character of all runtime options is AUTOMATICALLY the hyphen. 799 800 Level: advanced 801 802 .seealso: `MatGetOptionsPrefix()` 803 @*/ 804 PetscErrorCode MatAppendOptionsPrefix(Mat A, const char prefix[]) { 805 PetscFunctionBegin; 806 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 807 PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)A, prefix)); 808 PetscFunctionReturn(0); 809 } 810 811 /*@C 812 MatGetOptionsPrefix - Gets the prefix used for searching for all 813 Mat options in the database. 814 815 Not Collective 816 817 Input Parameter: 818 . A - the Mat context 819 820 Output Parameter: 821 . prefix - pointer to the prefix string used 822 823 Notes: 824 On the fortran side, the user should pass in a string 'prefix' of 825 sufficient length to hold the prefix. 826 827 Level: advanced 828 829 .seealso: `MatAppendOptionsPrefix()` 830 @*/ 831 PetscErrorCode MatGetOptionsPrefix(Mat A, const char *prefix[]) { 832 PetscFunctionBegin; 833 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 834 PetscValidPointer(prefix, 2); 835 PetscCall(PetscObjectGetOptionsPrefix((PetscObject)A, prefix)); 836 PetscFunctionReturn(0); 837 } 838 839 /*@ 840 MatResetPreallocation - Reset mat to use the original nonzero pattern provided by users. 841 842 Collective on Mat 843 844 Input Parameters: 845 . A - the Mat context 846 847 Notes: 848 The allocated memory will be shrunk after calling `MatAssemblyBegin()` and `MatAssemblyEnd()` with `MAT_FINAL_ASSEMBLY`. 849 850 Users can reset the preallocation to access the original memory. 851 852 Currently only supported for `MATMPIAIJ` and `MATSEQAIJ` matrices. 853 854 Level: beginner 855 856 .seealso: `MatSeqAIJSetPreallocation()`, `MatMPIAIJSetPreallocation()`, `MatXAIJSetPreallocation()` 857 @*/ 858 PetscErrorCode MatResetPreallocation(Mat A) { 859 PetscFunctionBegin; 860 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 861 PetscValidType(A, 1); 862 PetscUseMethod(A, "MatResetPreallocation_C", (Mat), (A)); 863 PetscFunctionReturn(0); 864 } 865 866 /*@ 867 MatSetUp - Sets up the internal matrix data structures for later use. 868 869 Collective on Mat 870 871 Input Parameters: 872 . A - the Mat context 873 874 Notes: 875 If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used. 876 877 If a suitable preallocation routine is used, this function does not need to be called. 878 879 See the Performance chapter of the PETSc users manual for how to preallocate matrices 880 881 Level: beginner 882 883 .seealso: `MatCreate()`, `MatDestroy()` 884 @*/ 885 PetscErrorCode MatSetUp(Mat A) { 886 PetscFunctionBegin; 887 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 888 if (!((PetscObject)A)->type_name) { 889 PetscMPIInt size; 890 891 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)A), &size)); 892 PetscCall(MatSetType(A, size == 1 ? MATSEQAIJ : MATMPIAIJ)); 893 } 894 if (!A->preallocated && A->ops->setup) { 895 PetscCall(PetscInfo(A, "Warning not preallocating matrix storage\n")); 896 PetscUseTypeMethod(A, setup); 897 } 898 PetscCall(PetscLayoutSetUp(A->rmap)); 899 PetscCall(PetscLayoutSetUp(A->cmap)); 900 A->preallocated = PETSC_TRUE; 901 PetscFunctionReturn(0); 902 } 903 904 #if defined(PETSC_HAVE_SAWS) 905 #include <petscviewersaws.h> 906 #endif 907 908 /*@C 909 MatViewFromOptions - View from Options 910 911 Collective on Mat 912 913 Input Parameters: 914 + A - the Mat context 915 . obj - Optional object 916 - name - command line option 917 918 Level: intermediate 919 .seealso: `Mat`, `MatView`, `PetscObjectViewFromOptions()`, `MatCreate()` 920 @*/ 921 PetscErrorCode MatViewFromOptions(Mat A, PetscObject obj, const char name[]) { 922 PetscFunctionBegin; 923 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 924 PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name)); 925 PetscFunctionReturn(0); 926 } 927 928 /*@C 929 MatView - Visualizes a matrix object. 930 931 Collective on Mat 932 933 Input Parameters: 934 + mat - the matrix 935 - viewer - visualization context 936 937 Notes: 938 The available visualization contexts include 939 + `PETSC_VIEWER_STDOUT_SELF` - for sequential matrices 940 . `PETSC_VIEWER_STDOUT_WORLD` - for parallel matrices created on `PETSC_COMM_WORLD` 941 . `PETSC_VIEWER_STDOUT_`(comm) - for matrices created on MPI communicator comm 942 - `PETSC_VIEWER_DRAW_WORLD` - graphical display of nonzero structure 943 944 The user can open alternative visualization contexts with 945 + `PetscViewerASCIIOpen()` - Outputs matrix to a specified file 946 . `PetscViewerBinaryOpen()` - Outputs matrix in binary to a 947 specified file; corresponding input uses MatLoad() 948 . `PetscViewerDrawOpen()` - Outputs nonzero matrix structure to 949 an X window display 950 - `PetscViewerSocketOpen()` - Outputs matrix to Socket viewer. 951 Currently only the sequential dense and AIJ 952 matrix types support the Socket viewer. 953 954 The user can call `PetscViewerPushFormat()` to specify the output 955 format of ASCII printed objects (when using `PETSC_VIEWER_STDOUT_SELF`, 956 `PETSC_VIEWER_STDOUT_WORLD` and `PetscViewerASCIIOpen()`). Available formats include 957 + `PETSC_VIEWER_DEFAULT` - default, prints matrix contents 958 . `PETSC_VIEWER_ASCII_MATLAB` - prints matrix contents in Matlab format 959 . `PETSC_VIEWER_ASCII_DENSE` - prints entire matrix including zeros 960 . `PETSC_VIEWER_ASCII_COMMON` - prints matrix contents, using a sparse 961 format common among all matrix types 962 . `PETSC_VIEWER_ASCII_IMPL` - prints matrix contents, using an implementation-specific 963 format (which is in many cases the same as the default) 964 . `PETSC_VIEWER_ASCII_INFO` - prints basic information about the matrix 965 size and structure (not the matrix entries) 966 - `PETSC_VIEWER_ASCII_INFO_DETAIL` - prints more detailed information about 967 the matrix structure 968 969 Options Database Keys: 970 + -mat_view ::ascii_info - Prints info on matrix at conclusion of `MatAssemblyEnd()` 971 . -mat_view ::ascii_info_detail - Prints more detailed info 972 . -mat_view - Prints matrix in ASCII format 973 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 974 . -mat_view draw - PetscDraws nonzero structure of matrix, using `MatView()` and `PetscDrawOpenX()`. 975 . -display <name> - Sets display name (default is host) 976 . -draw_pause <sec> - Sets number of seconds to pause after display 977 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details) 978 . -viewer_socket_machine <machine> - 979 . -viewer_socket_port <port> - 980 . -mat_view binary - save matrix to file in binary format 981 - -viewer_binary_filename <name> - 982 983 Level: beginner 984 985 Notes: 986 The ASCII viewers are only recommended for small matrices on at most a moderate number of processes, 987 the program will seemingly hang and take hours for larger matrices, for larger matrices one should use the binary format. 988 989 In the debugger you can do "call MatView(mat,0)" to display the matrix. (The same holds for any PETSc object viewer). 990 991 See the manual page for `MatLoad()` for the exact format of the binary file when the binary 992 viewer is used. 993 994 See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary 995 viewer is used and lib/petsc/bin/PetscBinaryIO.py for loading them into Python. 996 997 One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure, 998 and then use the following mouse functions. 999 .vb 1000 left mouse: zoom in 1001 middle mouse: zoom out 1002 right mouse: continue with the simulation 1003 .ve 1004 1005 .seealso: `PetscViewerPushFormat()`, `PetscViewerASCIIOpen()`, `PetscViewerDrawOpen()`, 1006 `PetscViewerSocketOpen()`, `PetscViewerBinaryOpen()`, `MatLoad()` 1007 @*/ 1008 PetscErrorCode MatView(Mat mat, PetscViewer viewer) { 1009 PetscInt rows, cols, rbs, cbs; 1010 PetscBool isascii, isstring, issaws; 1011 PetscViewerFormat format; 1012 PetscMPIInt size; 1013 1014 PetscFunctionBegin; 1015 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 1016 PetscValidType(mat, 1); 1017 if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat), &viewer)); 1018 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1019 PetscCheckSameComm(mat, 1, viewer, 2); 1020 MatCheckPreallocated(mat, 1); 1021 1022 PetscCall(PetscViewerGetFormat(viewer, &format)); 1023 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size)); 1024 if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0); 1025 1026 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring)); 1027 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii)); 1028 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSAWS, &issaws)); 1029 if ((!isascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) { 1030 SETERRQ(PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "No viewers for factored matrix except ASCII info or info_detail"); 1031 } 1032 1033 PetscCall(PetscLogEventBegin(MAT_View, mat, viewer, 0, 0)); 1034 if (isascii) { 1035 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ORDER, "Must call MatAssemblyBegin/End() before viewing matrix"); 1036 PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)mat, viewer)); 1037 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1038 MatNullSpace nullsp, transnullsp; 1039 1040 PetscCall(PetscViewerASCIIPushTab(viewer)); 1041 PetscCall(MatGetSize(mat, &rows, &cols)); 1042 PetscCall(MatGetBlockSizes(mat, &rbs, &cbs)); 1043 if (rbs != 1 || cbs != 1) { 1044 if (rbs != cbs) PetscCall(PetscViewerASCIIPrintf(viewer, "rows=%" PetscInt_FMT ", cols=%" PetscInt_FMT ", rbs=%" PetscInt_FMT ", cbs=%" PetscInt_FMT "\n", rows, cols, rbs, cbs)); 1045 else PetscCall(PetscViewerASCIIPrintf(viewer, "rows=%" PetscInt_FMT ", cols=%" PetscInt_FMT ", bs=%" PetscInt_FMT "\n", rows, cols, rbs)); 1046 } else PetscCall(PetscViewerASCIIPrintf(viewer, "rows=%" PetscInt_FMT ", cols=%" PetscInt_FMT "\n", rows, cols)); 1047 if (mat->factortype) { 1048 MatSolverType solver; 1049 PetscCall(MatFactorGetSolverType(mat, &solver)); 1050 PetscCall(PetscViewerASCIIPrintf(viewer, "package used to perform factorization: %s\n", solver)); 1051 } 1052 if (mat->ops->getinfo) { 1053 MatInfo info; 1054 PetscCall(MatGetInfo(mat, MAT_GLOBAL_SUM, &info)); 1055 PetscCall(PetscViewerASCIIPrintf(viewer, "total: nonzeros=%.f, allocated nonzeros=%.f\n", info.nz_used, info.nz_allocated)); 1056 if (!mat->factortype) PetscCall(PetscViewerASCIIPrintf(viewer, "total number of mallocs used during MatSetValues calls=%" PetscInt_FMT "\n", (PetscInt)info.mallocs)); 1057 } 1058 PetscCall(MatGetNullSpace(mat, &nullsp)); 1059 PetscCall(MatGetTransposeNullSpace(mat, &transnullsp)); 1060 if (nullsp) PetscCall(PetscViewerASCIIPrintf(viewer, " has attached null space\n")); 1061 if (transnullsp && transnullsp != nullsp) PetscCall(PetscViewerASCIIPrintf(viewer, " has attached transposed null space\n")); 1062 PetscCall(MatGetNearNullSpace(mat, &nullsp)); 1063 if (nullsp) PetscCall(PetscViewerASCIIPrintf(viewer, " has attached near null space\n")); 1064 PetscCall(PetscViewerASCIIPushTab(viewer)); 1065 PetscCall(MatProductView(mat, viewer)); 1066 PetscCall(PetscViewerASCIIPopTab(viewer)); 1067 } 1068 } else if (issaws) { 1069 #if defined(PETSC_HAVE_SAWS) 1070 PetscMPIInt rank; 1071 1072 PetscCall(PetscObjectName((PetscObject)mat)); 1073 PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank)); 1074 if (!((PetscObject)mat)->amsmem && rank == 0) PetscCall(PetscObjectViewSAWs((PetscObject)mat, viewer)); 1075 #endif 1076 } else if (isstring) { 1077 const char *type; 1078 PetscCall(MatGetType(mat, &type)); 1079 PetscCall(PetscViewerStringSPrintf(viewer, " MatType: %-7.7s", type)); 1080 PetscTryTypeMethod(mat, view, viewer); 1081 } 1082 if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) { 1083 PetscCall(PetscViewerASCIIPushTab(viewer)); 1084 PetscUseTypeMethod(mat, viewnative, viewer); 1085 PetscCall(PetscViewerASCIIPopTab(viewer)); 1086 } else if (mat->ops->view) { 1087 PetscCall(PetscViewerASCIIPushTab(viewer)); 1088 PetscUseTypeMethod(mat, view, viewer); 1089 PetscCall(PetscViewerASCIIPopTab(viewer)); 1090 } 1091 if (isascii) { 1092 PetscCall(PetscViewerGetFormat(viewer, &format)); 1093 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) PetscCall(PetscViewerASCIIPopTab(viewer)); 1094 } 1095 PetscCall(PetscLogEventEnd(MAT_View, mat, viewer, 0, 0)); 1096 PetscFunctionReturn(0); 1097 } 1098 1099 #if defined(PETSC_USE_DEBUG) 1100 #include <../src/sys/totalview/tv_data_display.h> 1101 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat) { 1102 TV_add_row("Local rows", "int", &mat->rmap->n); 1103 TV_add_row("Local columns", "int", &mat->cmap->n); 1104 TV_add_row("Global rows", "int", &mat->rmap->N); 1105 TV_add_row("Global columns", "int", &mat->cmap->N); 1106 TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name); 1107 return TV_format_OK; 1108 } 1109 #endif 1110 1111 /*@C 1112 MatLoad - Loads a matrix that has been stored in binary/HDF5 format 1113 with `MatView()`. The matrix format is determined from the options database. 1114 Generates a parallel MPI matrix if the communicator has more than one 1115 processor. The default matrix type is AIJ. 1116 1117 Collective on PetscViewer 1118 1119 Input Parameters: 1120 + mat - the newly loaded matrix, this needs to have been created with `MatCreate()` 1121 or some related function before a call to `MatLoad()` 1122 - viewer - binary/HDF5 file viewer 1123 1124 Options Database Keys: 1125 Used with block matrix formats (`MATSEQBAIJ`, ...) to specify 1126 block size 1127 . -matload_block_size <bs> - set block size 1128 1129 Level: beginner 1130 1131 Notes: 1132 If the Mat type has not yet been given then `MATAIJ` is used, call `MatSetFromOptions()` on the 1133 Mat before calling this routine if you wish to set it from the options database. 1134 1135 `MatLoad()` automatically loads into the options database any options 1136 given in the file filename.info where filename is the name of the file 1137 that was passed to the `PetscViewerBinaryOpen()`. The options in the info 1138 file will be ignored if you use the -viewer_binary_skip_info option. 1139 1140 If the type or size of mat is not set before a call to `MatLoad()`, PETSc 1141 sets the default matrix type AIJ and sets the local and global sizes. 1142 If type and/or size is already set, then the same are used. 1143 1144 In parallel, each processor can load a subset of rows (or the 1145 entire matrix). This routine is especially useful when a large 1146 matrix is stored on disk and only part of it is desired on each 1147 processor. For example, a parallel solver may access only some of 1148 the rows from each processor. The algorithm used here reads 1149 relatively small blocks of data rather than reading the entire 1150 matrix and then subsetting it. 1151 1152 Viewer's `PetscViewerType` must be either `PETSCVIEWERBINARY` or `PETSCVIEWERHDF5`. 1153 Such viewer can be created using `PetscViewerBinaryOpen()` or `PetscViewerHDF5Open()`, 1154 or the sequence like 1155 .vb 1156 `PetscViewer` v; 1157 `PetscViewerCreate`(`PETSC_COMM_WORLD`,&v); 1158 `PetscViewerSetType`(v,`PETSCVIEWERBINARY`); 1159 `PetscViewerSetFromOptions`(v); 1160 `PetscViewerFileSetMode`(v,`FILE_MODE_READ`); 1161 `PetscViewerFileSetName`(v,"datafile"); 1162 .ve 1163 The optional `PetscViewerSetFromOptions()` call allows overriding `PetscViewerSetType()` using the option 1164 $ -viewer_type {binary,hdf5} 1165 1166 See the example src/ksp/ksp/tutorials/ex27.c with the first approach, 1167 and src/mat/tutorials/ex10.c with the second approach. 1168 1169 Notes about the PETSc binary format: 1170 In case of `PETSCVIEWERBINARY`, a native PETSc binary format is used. Each of the blocks 1171 is read onto rank 0 and then shipped to its destination rank, one after another. 1172 Multiple objects, both matrices and vectors, can be stored within the same file. 1173 Their PetscObject name is ignored; they are loaded in the order of their storage. 1174 1175 Most users should not need to know the details of the binary storage 1176 format, since `MatLoad()` and `MatView()` completely hide these details. 1177 But for anyone who's interested, the standard binary matrix storage 1178 format is 1179 1180 $ PetscInt MAT_FILE_CLASSID 1181 $ PetscInt number of rows 1182 $ PetscInt number of columns 1183 $ PetscInt total number of nonzeros 1184 $ PetscInt *number nonzeros in each row 1185 $ PetscInt *column indices of all nonzeros (starting index is zero) 1186 $ PetscScalar *values of all nonzeros 1187 1188 PETSc automatically does the byte swapping for 1189 machines that store the bytes reversed, e.g. DEC alpha, freebsd, 1190 Linux, Microsoft Windows and the Intel Paragon; thus if you write your own binary 1191 read/write routines you have to swap the bytes; see `PetscBinaryRead()` 1192 and `PetscBinaryWrite()` to see how this may be done. 1193 1194 Notes about the HDF5 (MATLAB MAT-File Version 7.3) format: 1195 In case of `PETSCVIEWERHDF5`, a parallel HDF5 reader is used. 1196 Each processor's chunk is loaded independently by its owning rank. 1197 Multiple objects, both matrices and vectors, can be stored within the same file. 1198 They are looked up by their PetscObject name. 1199 1200 As the MATLAB MAT-File Version 7.3 format is also a HDF5 flavor, we decided to use 1201 by default the same structure and naming of the AIJ arrays and column count 1202 within the HDF5 file. This means that a MAT file saved with -v7.3 flag, e.g. 1203 $ save example.mat A b -v7.3 1204 can be directly read by this routine (see Reference 1 for details). 1205 Note that depending on your MATLAB version, this format might be a default, 1206 otherwise you can set it as default in Preferences. 1207 1208 Unless -nocompression flag is used to save the file in MATLAB, 1209 PETSc must be configured with ZLIB package. 1210 1211 See also examples src/mat/tutorials/ex10.c and src/ksp/ksp/tutorials/ex27.c 1212 1213 Current HDF5 (MAT-File) limitations: 1214 This reader currently supports only real `MATSEQAIJ`, `MATMPIAIJ`, `MATSEQDENSE` and `MATMPIDENSE` matrices. 1215 1216 Corresponding `MatView()` is not yet implemented. 1217 1218 The loaded matrix is actually a transpose of the original one in MATLAB, 1219 unless you push `PETSC_VIEWER_HDF5_MAT` format (see examples above). 1220 With this format, matrix is automatically transposed by PETSc, 1221 unless the matrix is marked as SPD or symmetric 1222 (see `MatSetOption()`, `MAT_SPD`, `MAT_SYMMETRIC`). 1223 1224 References: 1225 . * - MATLAB(R) Documentation, manual page of save(), https://www.mathworks.com/help/matlab/ref/save.html#btox10b-1-version 1226 1227 .seealso: `PetscViewerBinaryOpen()`, `PetscViewerSetType()`, `MatView()`, `VecLoad()` 1228 1229 @*/ 1230 PetscErrorCode MatLoad(Mat mat, PetscViewer viewer) { 1231 PetscBool flg; 1232 1233 PetscFunctionBegin; 1234 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 1235 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1236 1237 if (!((PetscObject)mat)->type_name) PetscCall(MatSetType(mat, MATAIJ)); 1238 1239 flg = PETSC_FALSE; 1240 PetscCall(PetscOptionsGetBool(((PetscObject)mat)->options, ((PetscObject)mat)->prefix, "-matload_symmetric", &flg, NULL)); 1241 if (flg) { 1242 PetscCall(MatSetOption(mat, MAT_SYMMETRIC, PETSC_TRUE)); 1243 PetscCall(MatSetOption(mat, MAT_SYMMETRY_ETERNAL, PETSC_TRUE)); 1244 } 1245 flg = PETSC_FALSE; 1246 PetscCall(PetscOptionsGetBool(((PetscObject)mat)->options, ((PetscObject)mat)->prefix, "-matload_spd", &flg, NULL)); 1247 if (flg) PetscCall(MatSetOption(mat, MAT_SPD, PETSC_TRUE)); 1248 1249 PetscCall(PetscLogEventBegin(MAT_Load, mat, viewer, 0, 0)); 1250 PetscUseTypeMethod(mat, load, viewer); 1251 PetscCall(PetscLogEventEnd(MAT_Load, mat, viewer, 0, 0)); 1252 PetscFunctionReturn(0); 1253 } 1254 1255 static PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant) { 1256 Mat_Redundant *redund = *redundant; 1257 1258 PetscFunctionBegin; 1259 if (redund) { 1260 if (redund->matseq) { /* via MatCreateSubMatrices() */ 1261 PetscCall(ISDestroy(&redund->isrow)); 1262 PetscCall(ISDestroy(&redund->iscol)); 1263 PetscCall(MatDestroySubMatrices(1, &redund->matseq)); 1264 } else { 1265 PetscCall(PetscFree2(redund->send_rank, redund->recv_rank)); 1266 PetscCall(PetscFree(redund->sbuf_j)); 1267 PetscCall(PetscFree(redund->sbuf_a)); 1268 for (PetscInt i = 0; i < redund->nrecvs; i++) { 1269 PetscCall(PetscFree(redund->rbuf_j[i])); 1270 PetscCall(PetscFree(redund->rbuf_a[i])); 1271 } 1272 PetscCall(PetscFree4(redund->sbuf_nz, redund->rbuf_nz, redund->rbuf_j, redund->rbuf_a)); 1273 } 1274 1275 if (redund->subcomm) PetscCall(PetscCommDestroy(&redund->subcomm)); 1276 PetscCall(PetscFree(redund)); 1277 } 1278 PetscFunctionReturn(0); 1279 } 1280 1281 /*@C 1282 MatDestroy - Frees space taken by a matrix. 1283 1284 Collective on Mat 1285 1286 Input Parameter: 1287 . A - the matrix 1288 1289 Level: beginner 1290 1291 Developer Notes: 1292 Some special arrays of matrices are not destroyed in this routine but instead by the routines called by 1293 `MatDestroySubMatrices()`. Thus one must be sure that any changes here must also be made in those routines. 1294 MatHeaderMerge() and MatHeaderReplace() also manipulate the data in the `Mat` object and likely need changes 1295 if changes are needed here. 1296 @*/ 1297 PetscErrorCode MatDestroy(Mat *A) { 1298 PetscFunctionBegin; 1299 if (!*A) PetscFunctionReturn(0); 1300 PetscValidHeaderSpecific(*A, MAT_CLASSID, 1); 1301 if (--((PetscObject)(*A))->refct > 0) { 1302 *A = NULL; 1303 PetscFunctionReturn(0); 1304 } 1305 1306 /* if memory was published with SAWs then destroy it */ 1307 PetscCall(PetscObjectSAWsViewOff((PetscObject)*A)); 1308 PetscTryTypeMethod((*A), destroy); 1309 1310 PetscCall(PetscFree((*A)->factorprefix)); 1311 PetscCall(PetscFree((*A)->defaultvectype)); 1312 PetscCall(PetscFree((*A)->bsizes)); 1313 PetscCall(PetscFree((*A)->solvertype)); 1314 for (PetscInt i = 0; i < MAT_FACTOR_NUM_TYPES; i++) PetscCall(PetscFree((*A)->preferredordering[i])); 1315 if ((*A)->redundant && (*A)->redundant->matseq[0] == *A) (*A)->redundant->matseq[0] = NULL; 1316 PetscCall(MatDestroy_Redundant(&(*A)->redundant)); 1317 PetscCall(MatProductClear(*A)); 1318 PetscCall(MatNullSpaceDestroy(&(*A)->nullsp)); 1319 PetscCall(MatNullSpaceDestroy(&(*A)->transnullsp)); 1320 PetscCall(MatNullSpaceDestroy(&(*A)->nearnullsp)); 1321 PetscCall(MatDestroy(&(*A)->schur)); 1322 PetscCall(PetscLayoutDestroy(&(*A)->rmap)); 1323 PetscCall(PetscLayoutDestroy(&(*A)->cmap)); 1324 PetscCall(PetscHeaderDestroy(A)); 1325 PetscFunctionReturn(0); 1326 } 1327 1328 /*@C 1329 MatSetValues - Inserts or adds a block of values into a matrix. 1330 These values may be cached, so `MatAssemblyBegin()` and `MatAssemblyEnd()` 1331 MUST be called after all calls to `MatSetValues()` have been completed. 1332 1333 Not Collective 1334 1335 Input Parameters: 1336 + mat - the matrix 1337 . v - a logically two-dimensional array of values 1338 . m, idxm - the number of rows and their global indices 1339 . n, idxn - the number of columns and their global indices 1340 - addv - either `ADD_VALUES` or `INSERT_VALUES`, where 1341 `ADD_VALUES` adds values to any existing entries, and 1342 `INSERT_VALUES` replaces existing entries with new values 1343 1344 Notes: 1345 If you create the matrix yourself (that is not with a call to `DMCreateMatrix()`) then you MUST call MatXXXXSetPreallocation() or 1346 `MatSetUp()` before using this routine 1347 1348 By default the values, v, are row-oriented. See `MatSetOption()` for other options. 1349 1350 Calls to `MatSetValues()` with the `INSERT_VALUES` and `ADD_VALUES` 1351 options cannot be mixed without intervening calls to the assembly 1352 routines. 1353 1354 `MatSetValues()` uses 0-based row and column numbers in Fortran 1355 as well as in C. 1356 1357 Negative indices may be passed in idxm and idxn, these rows and columns are 1358 simply ignored. This allows easily inserting element stiffness matrices 1359 with homogeneous Dirchlet boundary conditions that you don't want represented 1360 in the matrix. 1361 1362 Efficiency Alert: 1363 The routine `MatSetValuesBlocked()` may offer much better efficiency 1364 for users of block sparse formats (`MATSEQBAIJ` and `MATMPIBAIJ`). 1365 1366 Level: beginner 1367 1368 Developer Notes: 1369 This is labeled with C so does not automatically generate Fortran stubs and interfaces 1370 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 1371 1372 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 1373 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES` 1374 @*/ 1375 PetscErrorCode MatSetValues(Mat mat, PetscInt m, const PetscInt idxm[], PetscInt n, const PetscInt idxn[], const PetscScalar v[], InsertMode addv) { 1376 PetscFunctionBeginHot; 1377 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 1378 PetscValidType(mat, 1); 1379 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1380 PetscValidIntPointer(idxm, 3); 1381 PetscValidIntPointer(idxn, 5); 1382 MatCheckPreallocated(mat, 1); 1383 1384 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 1385 else PetscCheck(mat->insertmode == addv, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cannot mix add values and insert values"); 1386 1387 if (PetscDefined(USE_DEBUG)) { 1388 PetscInt i, j; 1389 1390 PetscCheck(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 1391 for (i = 0; i < m; i++) { 1392 for (j = 0; j < n; j++) { 1393 if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i * n + j])) 1394 #if defined(PETSC_USE_COMPLEX) 1395 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]); 1396 #else 1397 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]); 1398 #endif 1399 } 1400 } 1401 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); 1402 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); 1403 } 1404 1405 if (mat->assembled) { 1406 mat->was_assembled = PETSC_TRUE; 1407 mat->assembled = PETSC_FALSE; 1408 } 1409 PetscCall(PetscLogEventBegin(MAT_SetValues, mat, 0, 0, 0)); 1410 PetscUseTypeMethod(mat, setvalues, m, idxm, n, idxn, v, addv); 1411 PetscCall(PetscLogEventEnd(MAT_SetValues, mat, 0, 0, 0)); 1412 PetscFunctionReturn(0); 1413 } 1414 1415 /*@C 1416 MatSetValuesIS - Inserts or adds a block of values into a matrix using IS to indicate the rows and columns 1417 These values may be cached, so `MatAssemblyBegin()` and `MatAssemblyEnd()` 1418 MUST be called after all calls to `MatSetValues()` have been completed. 1419 1420 Not Collective 1421 1422 Input Parameters: 1423 + mat - the matrix 1424 . v - a logically two-dimensional array of values 1425 . ism - the rows to provide 1426 . isn - the columns to provide 1427 - addv - either `ADD_VALUES` or `INSERT_VALUES`, where 1428 `ADD_VALUES` adds values to any existing entries, and 1429 `INSERT_VALUES` replaces existing entries with new values 1430 1431 Notes: 1432 If you create the matrix yourself (that is not with a call to `DMCreateMatrix()`) then you MUST call MatXXXXSetPreallocation() or 1433 `MatSetUp()` before using this routine 1434 1435 By default the values, v, are row-oriented. See `MatSetOption()` for other options. 1436 1437 Calls to `MatSetValues()` with the `INSERT_VALUES` and `ADD_VALUES` 1438 options cannot be mixed without intervening calls to the assembly 1439 routines. 1440 1441 MatSetValues() uses 0-based row and column numbers in Fortran 1442 as well as in C. 1443 1444 Negative indices may be passed in ism and isn, these rows and columns are 1445 simply ignored. This allows easily inserting element stiffness matrices 1446 with homogeneous Dirchlet boundary conditions that you don't want represented 1447 in the matrix. 1448 1449 Efficiency Alert: 1450 The routine `MatSetValuesBlocked()` may offer much better efficiency 1451 for users of block sparse formats (`MATSEQBAIJ` and `MATMPIBAIJ`). 1452 1453 Level: beginner 1454 1455 Developer Notes: 1456 This is labeled with C so does not automatically generate Fortran stubs and interfaces 1457 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 1458 1459 This is currently not optimized for any particular IS type 1460 1461 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 1462 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()` 1463 @*/ 1464 PetscErrorCode MatSetValuesIS(Mat mat, IS ism, IS isn, const PetscScalar v[], InsertMode addv) { 1465 PetscInt m, n; 1466 const PetscInt *rows, *cols; 1467 1468 PetscFunctionBeginHot; 1469 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 1470 PetscCall(ISGetIndices(ism, &rows)); 1471 PetscCall(ISGetIndices(isn, &cols)); 1472 PetscCall(ISGetLocalSize(ism, &m)); 1473 PetscCall(ISGetLocalSize(isn, &n)); 1474 PetscCall(MatSetValues(mat, m, rows, n, cols, v, addv)); 1475 PetscCall(ISRestoreIndices(ism, &rows)); 1476 PetscCall(ISRestoreIndices(isn, &cols)); 1477 PetscFunctionReturn(0); 1478 } 1479 1480 /*@ 1481 MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero 1482 values into a matrix 1483 1484 Not Collective 1485 1486 Input Parameters: 1487 + mat - the matrix 1488 . row - the (block) row to set 1489 - v - a logically two-dimensional array of values 1490 1491 Notes: 1492 By the values, v, are column-oriented (for the block version) and sorted 1493 1494 All the nonzeros in the row must be provided 1495 1496 The matrix must have previously had its column indices set 1497 1498 The row must belong to this process 1499 1500 Level: intermediate 1501 1502 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 1503 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()`, `MatSetValuesRow()`, `MatSetLocalToGlobalMapping()` 1504 @*/ 1505 PetscErrorCode MatSetValuesRowLocal(Mat mat, PetscInt row, const PetscScalar v[]) { 1506 PetscInt globalrow; 1507 1508 PetscFunctionBegin; 1509 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 1510 PetscValidType(mat, 1); 1511 PetscValidScalarPointer(v, 3); 1512 PetscCall(ISLocalToGlobalMappingApply(mat->rmap->mapping, 1, &row, &globalrow)); 1513 PetscCall(MatSetValuesRow(mat, globalrow, v)); 1514 PetscFunctionReturn(0); 1515 } 1516 1517 /*@ 1518 MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero 1519 values into a matrix 1520 1521 Not Collective 1522 1523 Input Parameters: 1524 + mat - the matrix 1525 . row - the (block) row to set 1526 - 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 1527 1528 Notes: 1529 The values, v, are column-oriented for the block version. 1530 1531 All the nonzeros in the row must be provided 1532 1533 THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually `MatSetValues()` is used. 1534 1535 The row must belong to this process 1536 1537 Level: advanced 1538 1539 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 1540 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()` 1541 @*/ 1542 PetscErrorCode MatSetValuesRow(Mat mat, PetscInt row, const PetscScalar v[]) { 1543 PetscFunctionBeginHot; 1544 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 1545 PetscValidType(mat, 1); 1546 MatCheckPreallocated(mat, 1); 1547 PetscValidScalarPointer(v, 3); 1548 PetscCheck(mat->insertmode != ADD_VALUES, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cannot mix add and insert values"); 1549 PetscCheck(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 1550 mat->insertmode = INSERT_VALUES; 1551 1552 if (mat->assembled) { 1553 mat->was_assembled = PETSC_TRUE; 1554 mat->assembled = PETSC_FALSE; 1555 } 1556 PetscCall(PetscLogEventBegin(MAT_SetValues, mat, 0, 0, 0)); 1557 PetscUseTypeMethod(mat, setvaluesrow, row, v); 1558 PetscCall(PetscLogEventEnd(MAT_SetValues, mat, 0, 0, 0)); 1559 PetscFunctionReturn(0); 1560 } 1561 1562 /*@ 1563 MatSetValuesStencil - Inserts or adds a block of values into a matrix. 1564 Using structured grid indexing 1565 1566 Not Collective 1567 1568 Input Parameters: 1569 + mat - the matrix 1570 . m - number of rows being entered 1571 . idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered 1572 . n - number of columns being entered 1573 . idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered 1574 . v - a logically two-dimensional array of values 1575 - addv - either ADD_VALUES or INSERT_VALUES, where 1576 ADD_VALUES adds values to any existing entries, and 1577 INSERT_VALUES replaces existing entries with new values 1578 1579 Notes: 1580 By default the values, v, are row-oriented. See `MatSetOption()` for other options. 1581 1582 Calls to `MatSetValuesStencil()` with the `INSERT_VALUES` and `ADD_VALUES` 1583 options cannot be mixed without intervening calls to the assembly 1584 routines. 1585 1586 The grid coordinates are across the entire grid, not just the local portion 1587 1588 `MatSetValuesStencil()` uses 0-based row and column numbers in Fortran 1589 as well as in C. 1590 1591 For setting/accessing vector values via array coordinates you can use the `DMDAVecGetArray()` routine 1592 1593 In order to use this routine you must either obtain the matrix with `DMCreateMatrix()` 1594 or call `MatSetLocalToGlobalMapping()` and `MatSetStencil()` first. 1595 1596 The columns and rows in the stencil passed in MUST be contained within the 1597 ghost region of the given process as set with DMDACreateXXX() or `MatSetStencil()`. For example, 1598 if you create a `DMDA` with an overlap of one grid level and on a particular process its first 1599 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1600 first i index you can use in your column and row indices in `MatSetStencil()` is 5. 1601 1602 In Fortran idxm and idxn should be declared as 1603 $ MatStencil idxm(4,m),idxn(4,n) 1604 and the values inserted using 1605 $ idxm(MatStencil_i,1) = i 1606 $ idxm(MatStencil_j,1) = j 1607 $ idxm(MatStencil_k,1) = k 1608 $ idxm(MatStencil_c,1) = c 1609 etc 1610 1611 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 1612 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 1613 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 1614 `DM_BOUNDARY_PERIODIC` boundary type. 1615 1616 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 1617 a single value per point) you can skip filling those indices. 1618 1619 Inspired by the structured grid interface to the HYPRE package 1620 (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods) 1621 1622 Efficiency Alert: 1623 The routine `MatSetValuesBlockedStencil()` may offer much better efficiency 1624 for users of block sparse formats (`MATSEQBAIJ` and `MATMPIBAIJ`). 1625 1626 Level: beginner 1627 1628 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()` 1629 `MatSetValues()`, `MatSetValuesBlockedStencil()`, `MatSetStencil()`, `DMCreateMatrix()`, `DMDAVecGetArray()`, `MatStencil` 1630 @*/ 1631 PetscErrorCode MatSetValuesStencil(Mat mat, PetscInt m, const MatStencil idxm[], PetscInt n, const MatStencil idxn[], const PetscScalar v[], InsertMode addv) { 1632 PetscInt buf[8192], *bufm = NULL, *bufn = NULL, *jdxm, *jdxn; 1633 PetscInt j, i, dim = mat->stencil.dim, *dims = mat->stencil.dims + 1, tmp; 1634 PetscInt *starts = mat->stencil.starts, *dxm = (PetscInt *)idxm, *dxn = (PetscInt *)idxn, sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1635 1636 PetscFunctionBegin; 1637 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1638 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 1639 PetscValidType(mat, 1); 1640 PetscValidPointer(idxm, 3); 1641 PetscValidPointer(idxn, 5); 1642 1643 if ((m + n) <= (PetscInt)(sizeof(buf) / sizeof(PetscInt))) { 1644 jdxm = buf; 1645 jdxn = buf + m; 1646 } else { 1647 PetscCall(PetscMalloc2(m, &bufm, n, &bufn)); 1648 jdxm = bufm; 1649 jdxn = bufn; 1650 } 1651 for (i = 0; i < m; i++) { 1652 for (j = 0; j < 3 - sdim; j++) dxm++; 1653 tmp = *dxm++ - starts[0]; 1654 for (j = 0; j < dim - 1; j++) { 1655 if ((*dxm++ - starts[j + 1]) < 0 || tmp < 0) tmp = -1; 1656 else tmp = tmp * dims[j] + *(dxm - 1) - starts[j + 1]; 1657 } 1658 if (mat->stencil.noc) dxm++; 1659 jdxm[i] = tmp; 1660 } 1661 for (i = 0; i < n; i++) { 1662 for (j = 0; j < 3 - sdim; j++) dxn++; 1663 tmp = *dxn++ - starts[0]; 1664 for (j = 0; j < dim - 1; j++) { 1665 if ((*dxn++ - starts[j + 1]) < 0 || tmp < 0) tmp = -1; 1666 else tmp = tmp * dims[j] + *(dxn - 1) - starts[j + 1]; 1667 } 1668 if (mat->stencil.noc) dxn++; 1669 jdxn[i] = tmp; 1670 } 1671 PetscCall(MatSetValuesLocal(mat, m, jdxm, n, jdxn, v, addv)); 1672 PetscCall(PetscFree2(bufm, bufn)); 1673 PetscFunctionReturn(0); 1674 } 1675 1676 /*@ 1677 MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix. 1678 Using structured grid indexing 1679 1680 Not Collective 1681 1682 Input Parameters: 1683 + mat - the matrix 1684 . m - number of rows being entered 1685 . idxm - grid coordinates for matrix rows being entered 1686 . n - number of columns being entered 1687 . idxn - grid coordinates for matrix columns being entered 1688 . v - a logically two-dimensional array of values 1689 - addv - either ADD_VALUES or INSERT_VALUES, where 1690 ADD_VALUES adds values to any existing entries, and 1691 INSERT_VALUES replaces existing entries with new values 1692 1693 Notes: 1694 By default the values, v, are row-oriented and unsorted. 1695 See MatSetOption() for other options. 1696 1697 Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES 1698 options cannot be mixed without intervening calls to the assembly 1699 routines. 1700 1701 The grid coordinates are across the entire grid, not just the local portion 1702 1703 MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran 1704 as well as in C. 1705 1706 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine 1707 1708 In order to use this routine you must either obtain the matrix with DMCreateMatrix() 1709 or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first. 1710 1711 The columns and rows in the stencil passed in MUST be contained within the 1712 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example, 1713 if you create a DMDA with an overlap of one grid level and on a particular process its first 1714 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1715 first i index you can use in your column and row indices in MatSetStencil() is 5. 1716 1717 In Fortran idxm and idxn should be declared as 1718 $ MatStencil idxm(4,m),idxn(4,n) 1719 and the values inserted using 1720 $ idxm(MatStencil_i,1) = i 1721 $ idxm(MatStencil_j,1) = j 1722 $ idxm(MatStencil_k,1) = k 1723 etc 1724 1725 Negative indices may be passed in idxm and idxn, these rows and columns are 1726 simply ignored. This allows easily inserting element stiffness matrices 1727 with homogeneous Dirchlet boundary conditions that you don't want represented 1728 in the matrix. 1729 1730 Inspired by the structured grid interface to the HYPRE package 1731 (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods) 1732 1733 Level: beginner 1734 1735 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()` 1736 `MatSetValues()`, `MatSetValuesStencil()`, `MatSetStencil()`, `DMCreateMatrix()`, `DMDAVecGetArray()`, `MatStencil`, 1737 `MatSetBlockSize()`, `MatSetLocalToGlobalMapping()` 1738 @*/ 1739 PetscErrorCode MatSetValuesBlockedStencil(Mat mat, PetscInt m, const MatStencil idxm[], PetscInt n, const MatStencil idxn[], const PetscScalar v[], InsertMode addv) { 1740 PetscInt buf[8192], *bufm = NULL, *bufn = NULL, *jdxm, *jdxn; 1741 PetscInt j, i, dim = mat->stencil.dim, *dims = mat->stencil.dims + 1, tmp; 1742 PetscInt *starts = mat->stencil.starts, *dxm = (PetscInt *)idxm, *dxn = (PetscInt *)idxn, sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1743 1744 PetscFunctionBegin; 1745 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1746 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 1747 PetscValidType(mat, 1); 1748 PetscValidPointer(idxm, 3); 1749 PetscValidPointer(idxn, 5); 1750 PetscValidScalarPointer(v, 6); 1751 1752 if ((m + n) <= (PetscInt)(sizeof(buf) / sizeof(PetscInt))) { 1753 jdxm = buf; 1754 jdxn = buf + m; 1755 } else { 1756 PetscCall(PetscMalloc2(m, &bufm, n, &bufn)); 1757 jdxm = bufm; 1758 jdxn = bufn; 1759 } 1760 for (i = 0; i < m; i++) { 1761 for (j = 0; j < 3 - sdim; j++) dxm++; 1762 tmp = *dxm++ - starts[0]; 1763 for (j = 0; j < sdim - 1; j++) { 1764 if ((*dxm++ - starts[j + 1]) < 0 || tmp < 0) tmp = -1; 1765 else tmp = tmp * dims[j] + *(dxm - 1) - starts[j + 1]; 1766 } 1767 dxm++; 1768 jdxm[i] = tmp; 1769 } 1770 for (i = 0; i < n; i++) { 1771 for (j = 0; j < 3 - sdim; j++) dxn++; 1772 tmp = *dxn++ - starts[0]; 1773 for (j = 0; j < sdim - 1; j++) { 1774 if ((*dxn++ - starts[j + 1]) < 0 || tmp < 0) tmp = -1; 1775 else tmp = tmp * dims[j] + *(dxn - 1) - starts[j + 1]; 1776 } 1777 dxn++; 1778 jdxn[i] = tmp; 1779 } 1780 PetscCall(MatSetValuesBlockedLocal(mat, m, jdxm, n, jdxn, v, addv)); 1781 PetscCall(PetscFree2(bufm, bufn)); 1782 PetscFunctionReturn(0); 1783 } 1784 1785 /*@ 1786 MatSetStencil - Sets the grid information for setting values into a matrix via 1787 MatSetValuesStencil() 1788 1789 Not Collective 1790 1791 Input Parameters: 1792 + mat - the matrix 1793 . dim - dimension of the grid 1, 2, or 3 1794 . dims - number of grid points in x, y, and z direction, including ghost points on your processor 1795 . starts - starting point of ghost nodes on your processor in x, y, and z direction 1796 - dof - number of degrees of freedom per node 1797 1798 Inspired by the structured grid interface to the HYPRE package 1799 (www.llnl.gov/CASC/hyper) 1800 1801 For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the 1802 user. 1803 1804 Level: beginner 1805 1806 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()` 1807 `MatSetValues()`, `MatSetValuesBlockedStencil()`, `MatSetValuesStencil()` 1808 @*/ 1809 PetscErrorCode MatSetStencil(Mat mat, PetscInt dim, const PetscInt dims[], const PetscInt starts[], PetscInt dof) { 1810 PetscFunctionBegin; 1811 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 1812 PetscValidIntPointer(dims, 3); 1813 PetscValidIntPointer(starts, 4); 1814 1815 mat->stencil.dim = dim + (dof > 1); 1816 for (PetscInt i = 0; i < dim; i++) { 1817 mat->stencil.dims[i] = dims[dim - i - 1]; /* copy the values in backwards */ 1818 mat->stencil.starts[i] = starts[dim - i - 1]; 1819 } 1820 mat->stencil.dims[dim] = dof; 1821 mat->stencil.starts[dim] = 0; 1822 mat->stencil.noc = (PetscBool)(dof == 1); 1823 PetscFunctionReturn(0); 1824 } 1825 1826 /*@C 1827 MatSetValuesBlocked - Inserts or adds a block of values into a matrix. 1828 1829 Not Collective 1830 1831 Input Parameters: 1832 + mat - the matrix 1833 . v - a logically two-dimensional array of values 1834 . m, idxm - the number of block rows and their global block indices 1835 . n, idxn - the number of block columns and their global block indices 1836 - addv - either ADD_VALUES or INSERT_VALUES, where 1837 ADD_VALUES adds values to any existing entries, and 1838 INSERT_VALUES replaces existing entries with new values 1839 1840 Notes: 1841 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call 1842 MatXXXXSetPreallocation() or MatSetUp() before using this routine. 1843 1844 The m and n count the NUMBER of blocks in the row direction and column direction, 1845 NOT the total number of rows/columns; for example, if the block size is 2 and 1846 you are passing in values for rows 2,3,4,5 then m would be 2 (not 4). 1847 The values in idxm would be 1 2; that is the first index for each block divided by 1848 the block size. 1849 1850 Note that you must call MatSetBlockSize() when constructing this matrix (before 1851 preallocating it). 1852 1853 By default the values, v, are row-oriented, so the layout of 1854 v is the same as for MatSetValues(). See MatSetOption() for other options. 1855 1856 Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES 1857 options cannot be mixed without intervening calls to the assembly 1858 routines. 1859 1860 MatSetValuesBlocked() uses 0-based row and column numbers in Fortran 1861 as well as in C. 1862 1863 Negative indices may be passed in idxm and idxn, these rows and columns are 1864 simply ignored. This allows easily inserting element stiffness matrices 1865 with homogeneous Dirchlet boundary conditions that you don't want represented 1866 in the matrix. 1867 1868 Each time an entry is set within a sparse matrix via MatSetValues(), 1869 internal searching must be done to determine where to place the 1870 data in the matrix storage space. By instead inserting blocks of 1871 entries via MatSetValuesBlocked(), the overhead of matrix assembly is 1872 reduced. 1873 1874 Example: 1875 $ Suppose m=n=2 and block size(bs) = 2 The array is 1876 $ 1877 $ 1 2 | 3 4 1878 $ 5 6 | 7 8 1879 $ - - - | - - - 1880 $ 9 10 | 11 12 1881 $ 13 14 | 15 16 1882 $ 1883 $ v[] should be passed in like 1884 $ v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] 1885 $ 1886 $ If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then 1887 $ v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16] 1888 1889 Level: intermediate 1890 1891 .seealso: `MatSetBlockSize()`, `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetValuesBlockedLocal()` 1892 @*/ 1893 PetscErrorCode MatSetValuesBlocked(Mat mat, PetscInt m, const PetscInt idxm[], PetscInt n, const PetscInt idxn[], const PetscScalar v[], InsertMode addv) { 1894 PetscFunctionBeginHot; 1895 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 1896 PetscValidType(mat, 1); 1897 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1898 PetscValidIntPointer(idxm, 3); 1899 PetscValidIntPointer(idxn, 5); 1900 MatCheckPreallocated(mat, 1); 1901 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 1902 else PetscCheck(mat->insertmode == addv, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cannot mix add values and insert values"); 1903 if (PetscDefined(USE_DEBUG)) { 1904 PetscCheck(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 1905 PetscCheck(mat->ops->setvaluesblocked || mat->ops->setvalues, PETSC_COMM_SELF, PETSC_ERR_SUP, "Mat type %s", ((PetscObject)mat)->type_name); 1906 } 1907 if (PetscDefined(USE_DEBUG)) { 1908 PetscInt rbs, cbs, M, N, i; 1909 PetscCall(MatGetBlockSizes(mat, &rbs, &cbs)); 1910 PetscCall(MatGetSize(mat, &M, &N)); 1911 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); 1912 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); 1913 } 1914 if (mat->assembled) { 1915 mat->was_assembled = PETSC_TRUE; 1916 mat->assembled = PETSC_FALSE; 1917 } 1918 PetscCall(PetscLogEventBegin(MAT_SetValues, mat, 0, 0, 0)); 1919 if (mat->ops->setvaluesblocked) { 1920 PetscUseTypeMethod(mat, setvaluesblocked, m, idxm, n, idxn, v, addv); 1921 } else { 1922 PetscInt buf[8192], *bufr = NULL, *bufc = NULL, *iidxm, *iidxn; 1923 PetscInt i, j, bs, cbs; 1924 1925 PetscCall(MatGetBlockSizes(mat, &bs, &cbs)); 1926 if (m * bs + n * cbs <= (PetscInt)(sizeof(buf) / sizeof(PetscInt))) { 1927 iidxm = buf; 1928 iidxn = buf + m * bs; 1929 } else { 1930 PetscCall(PetscMalloc2(m * bs, &bufr, n * cbs, &bufc)); 1931 iidxm = bufr; 1932 iidxn = bufc; 1933 } 1934 for (i = 0; i < m; i++) { 1935 for (j = 0; j < bs; j++) { iidxm[i * bs + j] = bs * idxm[i] + j; } 1936 } 1937 if (m != n || bs != cbs || idxm != idxn) { 1938 for (i = 0; i < n; i++) { 1939 for (j = 0; j < cbs; j++) { iidxn[i * cbs + j] = cbs * idxn[i] + j; } 1940 } 1941 } else iidxn = iidxm; 1942 PetscCall(MatSetValues(mat, m * bs, iidxm, n * cbs, iidxn, v, addv)); 1943 PetscCall(PetscFree2(bufr, bufc)); 1944 } 1945 PetscCall(PetscLogEventEnd(MAT_SetValues, mat, 0, 0, 0)); 1946 PetscFunctionReturn(0); 1947 } 1948 1949 /*@C 1950 MatGetValues - Gets a block of values from a matrix. 1951 1952 Not Collective; can only return values that are owned by the give process 1953 1954 Input Parameters: 1955 + mat - the matrix 1956 . v - a logically two-dimensional array for storing the values 1957 . m, idxm - the number of rows and their global indices 1958 - n, idxn - the number of columns and their global indices 1959 1960 Notes: 1961 The user must allocate space (m*n PetscScalars) for the values, v. 1962 The values, v, are then returned in a row-oriented format, 1963 analogous to that used by default in MatSetValues(). 1964 1965 MatGetValues() uses 0-based row and column numbers in 1966 Fortran as well as in C. 1967 1968 MatGetValues() requires that the matrix has been assembled 1969 with MatAssemblyBegin()/MatAssemblyEnd(). Thus, calls to 1970 MatSetValues() and MatGetValues() CANNOT be made in succession 1971 without intermediate matrix assembly. 1972 1973 Negative row or column indices will be ignored and those locations in v[] will be 1974 left unchanged. 1975 1976 For the standard row-based matrix formats, idxm[] can only contain rows owned by the requesting MPI rank. 1977 That is, rows with global index greater than or equal to rstart and less than rend where rstart and rend are obtainable 1978 from MatGetOwnershipRange(mat,&rstart,&rend). 1979 1980 Level: advanced 1981 1982 .seealso: `MatGetRow()`, `MatCreateSubMatrices()`, `MatSetValues()`, `MatGetOwnershipRange()`, `MatGetValuesLocal()`, `MatGetValue()` 1983 @*/ 1984 PetscErrorCode MatGetValues(Mat mat, PetscInt m, const PetscInt idxm[], PetscInt n, const PetscInt idxn[], PetscScalar v[]) { 1985 PetscFunctionBegin; 1986 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 1987 PetscValidType(mat, 1); 1988 if (!m || !n) PetscFunctionReturn(0); 1989 PetscValidIntPointer(idxm, 3); 1990 PetscValidIntPointer(idxn, 5); 1991 PetscValidScalarPointer(v, 6); 1992 PetscCheck(mat->assembled, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 1993 PetscCheck(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 1994 MatCheckPreallocated(mat, 1); 1995 1996 PetscCall(PetscLogEventBegin(MAT_GetValues, mat, 0, 0, 0)); 1997 PetscUseTypeMethod(mat, getvalues, m, idxm, n, idxn, v); 1998 PetscCall(PetscLogEventEnd(MAT_GetValues, mat, 0, 0, 0)); 1999 PetscFunctionReturn(0); 2000 } 2001 2002 /*@C 2003 MatGetValuesLocal - retrieves values from certain locations in a matrix using the local numbering of the indices 2004 defined previously by MatSetLocalToGlobalMapping() 2005 2006 Not Collective 2007 2008 Input Parameters: 2009 + mat - the matrix 2010 . nrow, irow - number of rows and their local indices 2011 - ncol, icol - number of columns and their local indices 2012 2013 Output Parameter: 2014 . y - a logically two-dimensional array of values 2015 2016 Notes: 2017 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine. 2018 2019 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, 2020 are greater than or equal to rstart and less than rend where rstart and rend are obtainable from MatGetOwnershipRange(mat,&rstart,&rend). One can 2021 determine if the resulting global row associated with the local row r is owned by the requesting MPI rank by applying the ISLocalToGlobalMapping set 2022 with MatSetLocalToGlobalMapping(). 2023 2024 Developer Notes: 2025 This is labelled with C so does not automatically generate Fortran stubs and interfaces 2026 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2027 2028 Level: advanced 2029 2030 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetLocalToGlobalMapping()`, 2031 `MatSetValuesLocal()`, `MatGetValues()` 2032 @*/ 2033 PetscErrorCode MatGetValuesLocal(Mat mat, PetscInt nrow, const PetscInt irow[], PetscInt ncol, const PetscInt icol[], PetscScalar y[]) { 2034 PetscFunctionBeginHot; 2035 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2036 PetscValidType(mat, 1); 2037 MatCheckPreallocated(mat, 1); 2038 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to retrieve */ 2039 PetscValidIntPointer(irow, 3); 2040 PetscValidIntPointer(icol, 5); 2041 if (PetscDefined(USE_DEBUG)) { 2042 PetscCheck(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 2043 PetscCheck(mat->ops->getvalueslocal || mat->ops->getvalues, PETSC_COMM_SELF, PETSC_ERR_SUP, "Mat type %s", ((PetscObject)mat)->type_name); 2044 } 2045 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 2046 PetscCall(PetscLogEventBegin(MAT_GetValues, mat, 0, 0, 0)); 2047 if (mat->ops->getvalueslocal) PetscUseTypeMethod(mat, getvalueslocal, nrow, irow, ncol, icol, y); 2048 else { 2049 PetscInt buf[8192], *bufr = NULL, *bufc = NULL, *irowm, *icolm; 2050 if ((nrow + ncol) <= (PetscInt)(sizeof(buf) / sizeof(PetscInt))) { 2051 irowm = buf; 2052 icolm = buf + nrow; 2053 } else { 2054 PetscCall(PetscMalloc2(nrow, &bufr, ncol, &bufc)); 2055 irowm = bufr; 2056 icolm = bufc; 2057 } 2058 PetscCheck(mat->rmap->mapping, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "MatGetValuesLocal() cannot proceed without local-to-global row mapping (See MatSetLocalToGlobalMapping())."); 2059 PetscCheck(mat->cmap->mapping, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "MatGetValuesLocal() cannot proceed without local-to-global column mapping (See MatSetLocalToGlobalMapping())."); 2060 PetscCall(ISLocalToGlobalMappingApply(mat->rmap->mapping, nrow, irow, irowm)); 2061 PetscCall(ISLocalToGlobalMappingApply(mat->cmap->mapping, ncol, icol, icolm)); 2062 PetscCall(MatGetValues(mat, nrow, irowm, ncol, icolm, y)); 2063 PetscCall(PetscFree2(bufr, bufc)); 2064 } 2065 PetscCall(PetscLogEventEnd(MAT_GetValues, mat, 0, 0, 0)); 2066 PetscFunctionReturn(0); 2067 } 2068 2069 /*@ 2070 MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and 2071 the same size. Currently, this can only be called once and creates the given matrix. 2072 2073 Not Collective 2074 2075 Input Parameters: 2076 + mat - the matrix 2077 . nb - the number of blocks 2078 . bs - the number of rows (and columns) in each block 2079 . rows - a concatenation of the rows for each block 2080 - v - a concatenation of logically two-dimensional arrays of values 2081 2082 Notes: 2083 In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix. 2084 2085 Level: advanced 2086 2087 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 2088 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()` 2089 @*/ 2090 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[]) { 2091 PetscFunctionBegin; 2092 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2093 PetscValidType(mat, 1); 2094 PetscValidIntPointer(rows, 4); 2095 PetscValidScalarPointer(v, 5); 2096 PetscAssert(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 2097 2098 PetscCall(PetscLogEventBegin(MAT_SetValuesBatch, mat, 0, 0, 0)); 2099 if (mat->ops->setvaluesbatch) PetscUseTypeMethod(mat, setvaluesbatch, nb, bs, rows, v); 2100 else { 2101 for (PetscInt b = 0; b < nb; ++b) PetscCall(MatSetValues(mat, bs, &rows[b * bs], bs, &rows[b * bs], &v[b * bs * bs], ADD_VALUES)); 2102 } 2103 PetscCall(PetscLogEventEnd(MAT_SetValuesBatch, mat, 0, 0, 0)); 2104 PetscFunctionReturn(0); 2105 } 2106 2107 /*@ 2108 MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by 2109 the routine MatSetValuesLocal() to allow users to insert matrix entries 2110 using a local (per-processor) numbering. 2111 2112 Not Collective 2113 2114 Input Parameters: 2115 + x - the matrix 2116 . rmapping - row mapping created with ISLocalToGlobalMappingCreate() or ISLocalToGlobalMappingCreateIS() 2117 - cmapping - column mapping 2118 2119 Level: intermediate 2120 2121 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetValuesLocal()`, `MatGetValuesLocal()` 2122 @*/ 2123 PetscErrorCode MatSetLocalToGlobalMapping(Mat x, ISLocalToGlobalMapping rmapping, ISLocalToGlobalMapping cmapping) { 2124 PetscFunctionBegin; 2125 PetscValidHeaderSpecific(x, MAT_CLASSID, 1); 2126 PetscValidType(x, 1); 2127 if (rmapping) PetscValidHeaderSpecific(rmapping, IS_LTOGM_CLASSID, 2); 2128 if (cmapping) PetscValidHeaderSpecific(cmapping, IS_LTOGM_CLASSID, 3); 2129 if (x->ops->setlocaltoglobalmapping) PetscUseTypeMethod(x, setlocaltoglobalmapping, rmapping, cmapping); 2130 else { 2131 PetscCall(PetscLayoutSetISLocalToGlobalMapping(x->rmap, rmapping)); 2132 PetscCall(PetscLayoutSetISLocalToGlobalMapping(x->cmap, cmapping)); 2133 } 2134 PetscFunctionReturn(0); 2135 } 2136 2137 /*@ 2138 MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping() 2139 2140 Not Collective 2141 2142 Input Parameter: 2143 . A - the matrix 2144 2145 Output Parameters: 2146 + rmapping - row mapping 2147 - cmapping - column mapping 2148 2149 Level: advanced 2150 2151 .seealso: `MatSetValuesLocal()` 2152 @*/ 2153 PetscErrorCode MatGetLocalToGlobalMapping(Mat A, ISLocalToGlobalMapping *rmapping, ISLocalToGlobalMapping *cmapping) { 2154 PetscFunctionBegin; 2155 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2156 PetscValidType(A, 1); 2157 if (rmapping) { 2158 PetscValidPointer(rmapping, 2); 2159 *rmapping = A->rmap->mapping; 2160 } 2161 if (cmapping) { 2162 PetscValidPointer(cmapping, 3); 2163 *cmapping = A->cmap->mapping; 2164 } 2165 PetscFunctionReturn(0); 2166 } 2167 2168 /*@ 2169 MatSetLayouts - Sets the PetscLayout objects for rows and columns of a matrix 2170 2171 Logically Collective on A 2172 2173 Input Parameters: 2174 + A - the matrix 2175 . rmap - row layout 2176 - cmap - column layout 2177 2178 Level: advanced 2179 2180 .seealso: `MatCreateVecs()`, `MatGetLocalToGlobalMapping()`, `MatGetLayouts()` 2181 @*/ 2182 PetscErrorCode MatSetLayouts(Mat A, PetscLayout rmap, PetscLayout cmap) { 2183 PetscFunctionBegin; 2184 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2185 PetscCall(PetscLayoutReference(rmap, &A->rmap)); 2186 PetscCall(PetscLayoutReference(cmap, &A->cmap)); 2187 PetscFunctionReturn(0); 2188 } 2189 2190 /*@ 2191 MatGetLayouts - Gets the PetscLayout objects for rows and columns 2192 2193 Not Collective 2194 2195 Input Parameter: 2196 . A - the matrix 2197 2198 Output Parameters: 2199 + rmap - row layout 2200 - cmap - column layout 2201 2202 Level: advanced 2203 2204 .seealso: `MatCreateVecs()`, `MatGetLocalToGlobalMapping()`, `MatSetLayouts()` 2205 @*/ 2206 PetscErrorCode MatGetLayouts(Mat A, PetscLayout *rmap, PetscLayout *cmap) { 2207 PetscFunctionBegin; 2208 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2209 PetscValidType(A, 1); 2210 if (rmap) { 2211 PetscValidPointer(rmap, 2); 2212 *rmap = A->rmap; 2213 } 2214 if (cmap) { 2215 PetscValidPointer(cmap, 3); 2216 *cmap = A->cmap; 2217 } 2218 PetscFunctionReturn(0); 2219 } 2220 2221 /*@C 2222 MatSetValuesLocal - Inserts or adds values into certain locations of a matrix, 2223 using a local numbering of the nodes. 2224 2225 Not Collective 2226 2227 Input Parameters: 2228 + mat - the matrix 2229 . nrow, irow - number of rows and their local indices 2230 . ncol, icol - number of columns and their local indices 2231 . y - a logically two-dimensional array of values 2232 - addv - either INSERT_VALUES or ADD_VALUES, where 2233 ADD_VALUES adds values to any existing entries, and 2234 INSERT_VALUES replaces existing entries with new values 2235 2236 Notes: 2237 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2238 MatSetUp() before using this routine 2239 2240 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine 2241 2242 Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES 2243 options cannot be mixed without intervening calls to the assembly 2244 routines. 2245 2246 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2247 MUST be called after all calls to MatSetValuesLocal() have been completed. 2248 2249 Level: intermediate 2250 2251 Developer Notes: 2252 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2253 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2254 2255 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetLocalToGlobalMapping()`, 2256 `MatSetValueLocal()`, `MatGetValuesLocal()` 2257 @*/ 2258 PetscErrorCode MatSetValuesLocal(Mat mat, PetscInt nrow, const PetscInt irow[], PetscInt ncol, const PetscInt icol[], const PetscScalar y[], InsertMode addv) { 2259 PetscFunctionBeginHot; 2260 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2261 PetscValidType(mat, 1); 2262 MatCheckPreallocated(mat, 1); 2263 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2264 PetscValidIntPointer(irow, 3); 2265 PetscValidIntPointer(icol, 5); 2266 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 2267 else PetscCheck(mat->insertmode == addv, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cannot mix add values and insert values"); 2268 if (PetscDefined(USE_DEBUG)) { 2269 PetscCheck(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 2270 PetscCheck(mat->ops->setvalueslocal || mat->ops->setvalues, PETSC_COMM_SELF, PETSC_ERR_SUP, "Mat type %s", ((PetscObject)mat)->type_name); 2271 } 2272 2273 if (mat->assembled) { 2274 mat->was_assembled = PETSC_TRUE; 2275 mat->assembled = PETSC_FALSE; 2276 } 2277 PetscCall(PetscLogEventBegin(MAT_SetValues, mat, 0, 0, 0)); 2278 if (mat->ops->setvalueslocal) PetscUseTypeMethod(mat, setvalueslocal, nrow, irow, ncol, icol, y, addv); 2279 else { 2280 PetscInt buf[8192], *bufr = NULL, *bufc = NULL; 2281 const PetscInt *irowm, *icolm; 2282 2283 if ((!mat->rmap->mapping && !mat->cmap->mapping) || (nrow + ncol) <= (PetscInt)(sizeof(buf) / sizeof(PetscInt))) { 2284 bufr = buf; 2285 bufc = buf + nrow; 2286 irowm = bufr; 2287 icolm = bufc; 2288 } else { 2289 PetscCall(PetscMalloc2(nrow, &bufr, ncol, &bufc)); 2290 irowm = bufr; 2291 icolm = bufc; 2292 } 2293 if (mat->rmap->mapping) PetscCall(ISLocalToGlobalMappingApply(mat->rmap->mapping, nrow, irow, bufr)); 2294 else irowm = irow; 2295 if (mat->cmap->mapping) { 2296 if (mat->cmap->mapping != mat->rmap->mapping || ncol != nrow || icol != irow) { 2297 PetscCall(ISLocalToGlobalMappingApply(mat->cmap->mapping, ncol, icol, bufc)); 2298 } else icolm = irowm; 2299 } else icolm = icol; 2300 PetscCall(MatSetValues(mat, nrow, irowm, ncol, icolm, y, addv)); 2301 if (bufr != buf) PetscCall(PetscFree2(bufr, bufc)); 2302 } 2303 PetscCall(PetscLogEventEnd(MAT_SetValues, mat, 0, 0, 0)); 2304 PetscFunctionReturn(0); 2305 } 2306 2307 /*@C 2308 MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix, 2309 using a local ordering of the nodes a block at a time. 2310 2311 Not Collective 2312 2313 Input Parameters: 2314 + x - the matrix 2315 . nrow, irow - number of rows and their local indices 2316 . ncol, icol - number of columns and their local indices 2317 . y - a logically two-dimensional array of values 2318 - addv - either INSERT_VALUES or ADD_VALUES, where 2319 ADD_VALUES adds values to any existing entries, and 2320 INSERT_VALUES replaces existing entries with new values 2321 2322 Notes: 2323 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2324 MatSetUp() before using this routine 2325 2326 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping() 2327 before using this routineBefore calling MatSetValuesLocal(), the user must first set the 2328 2329 Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES 2330 options cannot be mixed without intervening calls to the assembly 2331 routines. 2332 2333 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2334 MUST be called after all calls to MatSetValuesBlockedLocal() have been completed. 2335 2336 Level: intermediate 2337 2338 Developer Notes: 2339 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2340 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2341 2342 .seealso: `MatSetBlockSize()`, `MatSetLocalToGlobalMapping()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, 2343 `MatSetValuesLocal()`, `MatSetValuesBlocked()` 2344 @*/ 2345 PetscErrorCode MatSetValuesBlockedLocal(Mat mat, PetscInt nrow, const PetscInt irow[], PetscInt ncol, const PetscInt icol[], const PetscScalar y[], InsertMode addv) { 2346 PetscFunctionBeginHot; 2347 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2348 PetscValidType(mat, 1); 2349 MatCheckPreallocated(mat, 1); 2350 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2351 PetscValidIntPointer(irow, 3); 2352 PetscValidIntPointer(icol, 5); 2353 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 2354 else PetscCheck(mat->insertmode == addv, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cannot mix add values and insert values"); 2355 if (PetscDefined(USE_DEBUG)) { 2356 PetscCheck(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 2357 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); 2358 } 2359 2360 if (mat->assembled) { 2361 mat->was_assembled = PETSC_TRUE; 2362 mat->assembled = PETSC_FALSE; 2363 } 2364 if (PetscUnlikelyDebug(mat->rmap->mapping)) { /* Condition on the mapping existing, because MatSetValuesBlockedLocal_IS does not require it to be set. */ 2365 PetscInt irbs, rbs; 2366 PetscCall(MatGetBlockSizes(mat, &rbs, NULL)); 2367 PetscCall(ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping, &irbs)); 2368 PetscCheck(rbs == irbs, PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Different row block sizes! mat %" PetscInt_FMT ", row l2g map %" PetscInt_FMT, rbs, irbs); 2369 } 2370 if (PetscUnlikelyDebug(mat->cmap->mapping)) { 2371 PetscInt icbs, cbs; 2372 PetscCall(MatGetBlockSizes(mat, NULL, &cbs)); 2373 PetscCall(ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping, &icbs)); 2374 PetscCheck(cbs == icbs, PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Different col block sizes! mat %" PetscInt_FMT ", col l2g map %" PetscInt_FMT, cbs, icbs); 2375 } 2376 PetscCall(PetscLogEventBegin(MAT_SetValues, mat, 0, 0, 0)); 2377 if (mat->ops->setvaluesblockedlocal) PetscUseTypeMethod(mat, setvaluesblockedlocal, nrow, irow, ncol, icol, y, addv); 2378 else { 2379 PetscInt buf[8192], *bufr = NULL, *bufc = NULL; 2380 const PetscInt *irowm, *icolm; 2381 2382 if ((!mat->rmap->mapping && !mat->cmap->mapping) || (nrow + ncol) <= (PetscInt)(sizeof(buf) / sizeof(PetscInt))) { 2383 bufr = buf; 2384 bufc = buf + nrow; 2385 irowm = bufr; 2386 icolm = bufc; 2387 } else { 2388 PetscCall(PetscMalloc2(nrow, &bufr, ncol, &bufc)); 2389 irowm = bufr; 2390 icolm = bufc; 2391 } 2392 if (mat->rmap->mapping) PetscCall(ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping, nrow, irow, bufr)); 2393 else irowm = irow; 2394 if (mat->cmap->mapping) { 2395 if (mat->cmap->mapping != mat->rmap->mapping || ncol != nrow || icol != irow) { 2396 PetscCall(ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping, ncol, icol, bufc)); 2397 } else icolm = irowm; 2398 } else icolm = icol; 2399 PetscCall(MatSetValuesBlocked(mat, nrow, irowm, ncol, icolm, y, addv)); 2400 if (bufr != buf) PetscCall(PetscFree2(bufr, bufc)); 2401 } 2402 PetscCall(PetscLogEventEnd(MAT_SetValues, mat, 0, 0, 0)); 2403 PetscFunctionReturn(0); 2404 } 2405 2406 /*@ 2407 MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal 2408 2409 Collective on Mat 2410 2411 Input Parameters: 2412 + mat - the matrix 2413 - x - the vector to be multiplied 2414 2415 Output Parameters: 2416 . y - the result 2417 2418 Notes: 2419 The vectors x and y cannot be the same. I.e., one cannot 2420 call MatMult(A,y,y). 2421 2422 Level: developer 2423 2424 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 2425 @*/ 2426 PetscErrorCode MatMultDiagonalBlock(Mat mat, Vec x, Vec y) { 2427 PetscFunctionBegin; 2428 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2429 PetscValidType(mat, 1); 2430 PetscValidHeaderSpecific(x, VEC_CLASSID, 2); 2431 PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 2432 2433 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 2434 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 2435 PetscCheck(x != y, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "x and y must be different vectors"); 2436 MatCheckPreallocated(mat, 1); 2437 2438 PetscUseTypeMethod(mat, multdiagonalblock, x, y); 2439 PetscCall(PetscObjectStateIncrease((PetscObject)y)); 2440 PetscFunctionReturn(0); 2441 } 2442 2443 /* --------------------------------------------------------*/ 2444 /*@ 2445 MatMult - Computes the matrix-vector product, y = Ax. 2446 2447 Neighbor-wise Collective on Mat 2448 2449 Input Parameters: 2450 + mat - the matrix 2451 - x - the vector to be multiplied 2452 2453 Output Parameters: 2454 . y - the result 2455 2456 Notes: 2457 The vectors x and y cannot be the same. I.e., one cannot 2458 call MatMult(A,y,y). 2459 2460 Level: beginner 2461 2462 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 2463 @*/ 2464 PetscErrorCode MatMult(Mat mat, Vec x, Vec y) { 2465 PetscFunctionBegin; 2466 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2467 PetscValidType(mat, 1); 2468 PetscValidHeaderSpecific(x, VEC_CLASSID, 2); 2469 PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 2470 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 2471 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 2472 PetscCheck(x != y, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "x and y must be different vectors"); 2473 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); 2474 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); 2475 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); 2476 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); 2477 PetscCall(VecSetErrorIfLocked(y, 3)); 2478 if (mat->erroriffailure) PetscCall(VecValidValues(x, 2, PETSC_TRUE)); 2479 MatCheckPreallocated(mat, 1); 2480 2481 PetscCall(VecLockReadPush(x)); 2482 PetscCall(PetscLogEventBegin(MAT_Mult, mat, x, y, 0)); 2483 PetscUseTypeMethod(mat, mult, x, y); 2484 PetscCall(PetscLogEventEnd(MAT_Mult, mat, x, y, 0)); 2485 if (mat->erroriffailure) PetscCall(VecValidValues(y, 3, PETSC_FALSE)); 2486 PetscCall(VecLockReadPop(x)); 2487 PetscFunctionReturn(0); 2488 } 2489 2490 /*@ 2491 MatMultTranspose - Computes matrix transpose times a vector y = A^T * x. 2492 2493 Neighbor-wise Collective on Mat 2494 2495 Input Parameters: 2496 + mat - the matrix 2497 - x - the vector to be multiplied 2498 2499 Output Parameters: 2500 . y - the result 2501 2502 Notes: 2503 The vectors x and y cannot be the same. I.e., one cannot 2504 call MatMultTranspose(A,y,y). 2505 2506 For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple, 2507 use MatMultHermitianTranspose() 2508 2509 Level: beginner 2510 2511 .seealso: `MatMult()`, `MatMultAdd()`, `MatMultTransposeAdd()`, `MatMultHermitianTranspose()`, `MatTranspose()` 2512 @*/ 2513 PetscErrorCode MatMultTranspose(Mat mat, Vec x, Vec y) { 2514 PetscErrorCode (*op)(Mat, Vec, Vec) = NULL; 2515 2516 PetscFunctionBegin; 2517 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2518 PetscValidType(mat, 1); 2519 PetscValidHeaderSpecific(x, VEC_CLASSID, 2); 2520 PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 2521 2522 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 2523 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 2524 PetscCheck(x != y, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "x and y must be different vectors"); 2525 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); 2526 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); 2527 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); 2528 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); 2529 if (mat->erroriffailure) PetscCall(VecValidValues(x, 2, PETSC_TRUE)); 2530 MatCheckPreallocated(mat, 1); 2531 2532 if (!mat->ops->multtranspose) { 2533 if (mat->symmetric == PETSC_BOOL3_TRUE && mat->ops->mult) op = mat->ops->mult; 2534 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); 2535 } else op = mat->ops->multtranspose; 2536 PetscCall(PetscLogEventBegin(MAT_MultTranspose, mat, x, y, 0)); 2537 PetscCall(VecLockReadPush(x)); 2538 PetscCall((*op)(mat, x, y)); 2539 PetscCall(VecLockReadPop(x)); 2540 PetscCall(PetscLogEventEnd(MAT_MultTranspose, mat, x, y, 0)); 2541 PetscCall(PetscObjectStateIncrease((PetscObject)y)); 2542 if (mat->erroriffailure) PetscCall(VecValidValues(y, 3, PETSC_FALSE)); 2543 PetscFunctionReturn(0); 2544 } 2545 2546 /*@ 2547 MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector. 2548 2549 Neighbor-wise Collective on Mat 2550 2551 Input Parameters: 2552 + mat - the matrix 2553 - x - the vector to be multilplied 2554 2555 Output Parameters: 2556 . y - the result 2557 2558 Notes: 2559 The vectors x and y cannot be the same. I.e., one cannot 2560 call MatMultHermitianTranspose(A,y,y). 2561 2562 Also called the conjugate transpose, complex conjugate transpose, or adjoint. 2563 2564 For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical. 2565 2566 Level: beginner 2567 2568 .seealso: `MatMult()`, `MatMultAdd()`, `MatMultHermitianTransposeAdd()`, `MatMultTranspose()` 2569 @*/ 2570 PetscErrorCode MatMultHermitianTranspose(Mat mat, Vec x, Vec y) { 2571 PetscFunctionBegin; 2572 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2573 PetscValidType(mat, 1); 2574 PetscValidHeaderSpecific(x, VEC_CLASSID, 2); 2575 PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 2576 2577 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 2578 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 2579 PetscCheck(x != y, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "x and y must be different vectors"); 2580 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); 2581 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); 2582 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); 2583 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); 2584 MatCheckPreallocated(mat, 1); 2585 2586 PetscCall(PetscLogEventBegin(MAT_MultHermitianTranspose, mat, x, y, 0)); 2587 #if defined(PETSC_USE_COMPLEX) 2588 if (mat->ops->multhermitiantranspose || (mat->hermitian == PETSC_BOOL3_TRUE && mat->ops->mult)) { 2589 PetscCall(VecLockReadPush(x)); 2590 if (mat->ops->multhermitiantranspose) PetscUseTypeMethod(mat, multhermitiantranspose, x, y); 2591 else PetscUseTypeMethod(mat, mult, x, y); 2592 PetscCall(VecLockReadPop(x)); 2593 } else { 2594 Vec w; 2595 PetscCall(VecDuplicate(x, &w)); 2596 PetscCall(VecCopy(x, w)); 2597 PetscCall(VecConjugate(w)); 2598 PetscCall(MatMultTranspose(mat, w, y)); 2599 PetscCall(VecDestroy(&w)); 2600 PetscCall(VecConjugate(y)); 2601 } 2602 PetscCall(PetscObjectStateIncrease((PetscObject)y)); 2603 #else 2604 PetscCall(MatMultTranspose(mat, x, y)); 2605 #endif 2606 PetscCall(PetscLogEventEnd(MAT_MultHermitianTranspose, mat, x, y, 0)); 2607 PetscFunctionReturn(0); 2608 } 2609 2610 /*@ 2611 MatMultAdd - Computes v3 = v2 + A * v1. 2612 2613 Neighbor-wise Collective on Mat 2614 2615 Input Parameters: 2616 + mat - the matrix 2617 - v1, v2 - the vectors 2618 2619 Output Parameters: 2620 . v3 - the result 2621 2622 Notes: 2623 The vectors v1 and v3 cannot be the same. I.e., one cannot 2624 call MatMultAdd(A,v1,v2,v1). 2625 2626 Level: beginner 2627 2628 .seealso: `MatMultTranspose()`, `MatMult()`, `MatMultTransposeAdd()` 2629 @*/ 2630 PetscErrorCode MatMultAdd(Mat mat, Vec v1, Vec v2, Vec v3) { 2631 PetscFunctionBegin; 2632 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2633 PetscValidType(mat, 1); 2634 PetscValidHeaderSpecific(v1, VEC_CLASSID, 2); 2635 PetscValidHeaderSpecific(v2, VEC_CLASSID, 3); 2636 PetscValidHeaderSpecific(v3, VEC_CLASSID, 4); 2637 2638 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 2639 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 2640 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); 2641 /* 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); 2642 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); */ 2643 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); 2644 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); 2645 PetscCheck(v1 != v3, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_IDN, "v1 and v3 must be different vectors"); 2646 MatCheckPreallocated(mat, 1); 2647 2648 PetscCall(PetscLogEventBegin(MAT_MultAdd, mat, v1, v2, v3)); 2649 PetscCall(VecLockReadPush(v1)); 2650 PetscUseTypeMethod(mat, multadd, v1, v2, v3); 2651 PetscCall(VecLockReadPop(v1)); 2652 PetscCall(PetscLogEventEnd(MAT_MultAdd, mat, v1, v2, v3)); 2653 PetscCall(PetscObjectStateIncrease((PetscObject)v3)); 2654 PetscFunctionReturn(0); 2655 } 2656 2657 /*@ 2658 MatMultTransposeAdd - Computes v3 = v2 + A' * v1. 2659 2660 Neighbor-wise Collective on Mat 2661 2662 Input Parameters: 2663 + mat - the matrix 2664 - v1, v2 - the vectors 2665 2666 Output Parameters: 2667 . v3 - the result 2668 2669 Notes: 2670 The vectors v1 and v3 cannot be the same. I.e., one cannot 2671 call MatMultTransposeAdd(A,v1,v2,v1). 2672 2673 Level: beginner 2674 2675 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMult()` 2676 @*/ 2677 PetscErrorCode MatMultTransposeAdd(Mat mat, Vec v1, Vec v2, Vec v3) { 2678 PetscErrorCode (*op)(Mat, Vec, Vec, Vec) = (!mat->ops->multtransposeadd && mat->symmetric) ? mat->ops->multadd : mat->ops->multtransposeadd; 2679 2680 PetscFunctionBegin; 2681 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2682 PetscValidType(mat, 1); 2683 PetscValidHeaderSpecific(v1, VEC_CLASSID, 2); 2684 PetscValidHeaderSpecific(v2, VEC_CLASSID, 3); 2685 PetscValidHeaderSpecific(v3, VEC_CLASSID, 4); 2686 2687 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 2688 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 2689 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); 2690 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); 2691 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); 2692 PetscCheck(v1 != v3, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_IDN, "v1 and v3 must be different vectors"); 2693 PetscCheck(op, PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Mat type %s", ((PetscObject)mat)->type_name); 2694 MatCheckPreallocated(mat, 1); 2695 2696 PetscCall(PetscLogEventBegin(MAT_MultTransposeAdd, mat, v1, v2, v3)); 2697 PetscCall(VecLockReadPush(v1)); 2698 PetscCall((*op)(mat, v1, v2, v3)); 2699 PetscCall(VecLockReadPop(v1)); 2700 PetscCall(PetscLogEventEnd(MAT_MultTransposeAdd, mat, v1, v2, v3)); 2701 PetscCall(PetscObjectStateIncrease((PetscObject)v3)); 2702 PetscFunctionReturn(0); 2703 } 2704 2705 /*@ 2706 MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1. 2707 2708 Neighbor-wise Collective on Mat 2709 2710 Input Parameters: 2711 + mat - the matrix 2712 - v1, v2 - the vectors 2713 2714 Output Parameters: 2715 . v3 - the result 2716 2717 Notes: 2718 The vectors v1 and v3 cannot be the same. I.e., one cannot 2719 call MatMultHermitianTransposeAdd(A,v1,v2,v1). 2720 2721 Level: beginner 2722 2723 .seealso: `MatMultHermitianTranspose()`, `MatMultTranspose()`, `MatMultAdd()`, `MatMult()` 2724 @*/ 2725 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat, Vec v1, Vec v2, Vec v3) { 2726 PetscFunctionBegin; 2727 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2728 PetscValidType(mat, 1); 2729 PetscValidHeaderSpecific(v1, VEC_CLASSID, 2); 2730 PetscValidHeaderSpecific(v2, VEC_CLASSID, 3); 2731 PetscValidHeaderSpecific(v3, VEC_CLASSID, 4); 2732 2733 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 2734 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 2735 PetscCheck(v1 != v3, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_IDN, "v1 and v3 must be different vectors"); 2736 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); 2737 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); 2738 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); 2739 MatCheckPreallocated(mat, 1); 2740 2741 PetscCall(PetscLogEventBegin(MAT_MultHermitianTransposeAdd, mat, v1, v2, v3)); 2742 PetscCall(VecLockReadPush(v1)); 2743 if (mat->ops->multhermitiantransposeadd) PetscUseTypeMethod(mat, multhermitiantransposeadd, v1, v2, v3); 2744 else { 2745 Vec w, z; 2746 PetscCall(VecDuplicate(v1, &w)); 2747 PetscCall(VecCopy(v1, w)); 2748 PetscCall(VecConjugate(w)); 2749 PetscCall(VecDuplicate(v3, &z)); 2750 PetscCall(MatMultTranspose(mat, w, z)); 2751 PetscCall(VecDestroy(&w)); 2752 PetscCall(VecConjugate(z)); 2753 if (v2 != v3) { 2754 PetscCall(VecWAXPY(v3, 1.0, v2, z)); 2755 } else { 2756 PetscCall(VecAXPY(v3, 1.0, z)); 2757 } 2758 PetscCall(VecDestroy(&z)); 2759 } 2760 PetscCall(VecLockReadPop(v1)); 2761 PetscCall(PetscLogEventEnd(MAT_MultHermitianTransposeAdd, mat, v1, v2, v3)); 2762 PetscCall(PetscObjectStateIncrease((PetscObject)v3)); 2763 PetscFunctionReturn(0); 2764 } 2765 2766 /*@C 2767 MatGetFactorType - gets the type of factorization it is 2768 2769 Not Collective 2770 2771 Input Parameters: 2772 . mat - the matrix 2773 2774 Output Parameters: 2775 . t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT 2776 2777 Level: intermediate 2778 2779 .seealso: `MatFactorType`, `MatGetFactor()`, `MatSetFactorType()` 2780 @*/ 2781 PetscErrorCode MatGetFactorType(Mat mat, MatFactorType *t) { 2782 PetscFunctionBegin; 2783 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2784 PetscValidType(mat, 1); 2785 PetscValidPointer(t, 2); 2786 *t = mat->factortype; 2787 PetscFunctionReturn(0); 2788 } 2789 2790 /*@C 2791 MatSetFactorType - sets the type of factorization it is 2792 2793 Logically Collective on Mat 2794 2795 Input Parameters: 2796 + mat - the matrix 2797 - t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT 2798 2799 Level: intermediate 2800 2801 .seealso: `MatFactorType`, `MatGetFactor()`, `MatGetFactorType()` 2802 @*/ 2803 PetscErrorCode MatSetFactorType(Mat mat, MatFactorType t) { 2804 PetscFunctionBegin; 2805 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2806 PetscValidType(mat, 1); 2807 mat->factortype = t; 2808 PetscFunctionReturn(0); 2809 } 2810 2811 /* ------------------------------------------------------------*/ 2812 /*@C 2813 MatGetInfo - Returns information about matrix storage (number of 2814 nonzeros, memory, etc.). 2815 2816 Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag 2817 2818 Input Parameter: 2819 . mat - the matrix 2820 2821 Output Parameters: 2822 + flag - flag indicating the type of parameters to be returned 2823 (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors, 2824 MAT_GLOBAL_SUM - sum over all processors) 2825 - info - matrix information context 2826 2827 Notes: 2828 The MatInfo context contains a variety of matrix data, including 2829 number of nonzeros allocated and used, number of mallocs during 2830 matrix assembly, etc. Additional information for factored matrices 2831 is provided (such as the fill ratio, number of mallocs during 2832 factorization, etc.). Much of this info is printed to PETSC_STDOUT 2833 when using the runtime options 2834 $ -info -mat_view ::ascii_info 2835 2836 Example for C/C++ Users: 2837 See the file ${PETSC_DIR}/include/petscmat.h for a complete list of 2838 data within the MatInfo context. For example, 2839 .vb 2840 MatInfo info; 2841 Mat A; 2842 double mal, nz_a, nz_u; 2843 2844 MatGetInfo(A,MAT_LOCAL,&info); 2845 mal = info.mallocs; 2846 nz_a = info.nz_allocated; 2847 .ve 2848 2849 Example for Fortran Users: 2850 Fortran users should declare info as a double precision 2851 array of dimension MAT_INFO_SIZE, and then extract the parameters 2852 of interest. See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h 2853 a complete list of parameter names. 2854 .vb 2855 double precision info(MAT_INFO_SIZE) 2856 double precision mal, nz_a 2857 Mat A 2858 integer ierr 2859 2860 call MatGetInfo(A,MAT_LOCAL,info,ierr) 2861 mal = info(MAT_INFO_MALLOCS) 2862 nz_a = info(MAT_INFO_NZ_ALLOCATED) 2863 .ve 2864 2865 Level: intermediate 2866 2867 Developer Note: fortran interface is not autogenerated as the f90 2868 interface definition cannot be generated correctly [due to MatInfo] 2869 2870 .seealso: `MatStashGetInfo()` 2871 2872 @*/ 2873 PetscErrorCode MatGetInfo(Mat mat, MatInfoType flag, MatInfo *info) { 2874 PetscFunctionBegin; 2875 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2876 PetscValidType(mat, 1); 2877 PetscValidPointer(info, 3); 2878 MatCheckPreallocated(mat, 1); 2879 PetscUseTypeMethod(mat, getinfo, flag, info); 2880 PetscFunctionReturn(0); 2881 } 2882 2883 /* 2884 This is used by external packages where it is not easy to get the info from the actual 2885 matrix factorization. 2886 */ 2887 PetscErrorCode MatGetInfo_External(Mat A, MatInfoType flag, MatInfo *info) { 2888 PetscFunctionBegin; 2889 PetscCall(PetscMemzero(info, sizeof(MatInfo))); 2890 PetscFunctionReturn(0); 2891 } 2892 2893 /* ----------------------------------------------------------*/ 2894 2895 /*@C 2896 MatLUFactor - Performs in-place LU factorization of matrix. 2897 2898 Collective on Mat 2899 2900 Input Parameters: 2901 + mat - the matrix 2902 . row - row permutation 2903 . col - column permutation 2904 - info - options for factorization, includes 2905 $ fill - expected fill as ratio of original fill. 2906 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 2907 $ Run with the option -info to determine an optimal value to use 2908 2909 Notes: 2910 Most users should employ the simplified KSP interface for linear solvers 2911 instead of working directly with matrix algebra routines such as this. 2912 See, e.g., KSPCreate(). 2913 2914 This changes the state of the matrix to a factored matrix; it cannot be used 2915 for example with MatSetValues() unless one first calls MatSetUnfactored(). 2916 2917 Level: developer 2918 2919 .seealso: `MatLUFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()`, 2920 `MatGetOrdering()`, `MatSetUnfactored()`, `MatFactorInfo`, `MatGetFactor()` 2921 2922 Developer Note: fortran interface is not autogenerated as the f90 2923 interface definition cannot be generated correctly [due to MatFactorInfo] 2924 2925 @*/ 2926 PetscErrorCode MatLUFactor(Mat mat, IS row, IS col, const MatFactorInfo *info) { 2927 MatFactorInfo tinfo; 2928 2929 PetscFunctionBegin; 2930 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2931 if (row) PetscValidHeaderSpecific(row, IS_CLASSID, 2); 2932 if (col) PetscValidHeaderSpecific(col, IS_CLASSID, 3); 2933 if (info) PetscValidPointer(info, 4); 2934 PetscValidType(mat, 1); 2935 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 2936 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 2937 MatCheckPreallocated(mat, 1); 2938 if (!info) { 2939 PetscCall(MatFactorInfoInitialize(&tinfo)); 2940 info = &tinfo; 2941 } 2942 2943 PetscCall(PetscLogEventBegin(MAT_LUFactor, mat, row, col, 0)); 2944 PetscUseTypeMethod(mat, lufactor, row, col, info); 2945 PetscCall(PetscLogEventEnd(MAT_LUFactor, mat, row, col, 0)); 2946 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 2947 PetscFunctionReturn(0); 2948 } 2949 2950 /*@C 2951 MatILUFactor - Performs in-place ILU factorization of matrix. 2952 2953 Collective on Mat 2954 2955 Input Parameters: 2956 + mat - the matrix 2957 . row - row permutation 2958 . col - column permutation 2959 - info - structure containing 2960 $ levels - number of levels of fill. 2961 $ expected fill - as ratio of original fill. 2962 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 2963 missing diagonal entries) 2964 2965 Notes: 2966 Probably really in-place only when level of fill is zero, otherwise allocates 2967 new space to store factored matrix and deletes previous memory. 2968 2969 Most users should employ the simplified KSP interface for linear solvers 2970 instead of working directly with matrix algebra routines such as this. 2971 See, e.g., KSPCreate(). 2972 2973 Level: developer 2974 2975 .seealso: `MatILUFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()`, `MatFactorInfo` 2976 2977 Developer Note: fortran interface is not autogenerated as the f90 2978 interface definition cannot be generated correctly [due to MatFactorInfo] 2979 2980 @*/ 2981 PetscErrorCode MatILUFactor(Mat mat, IS row, IS col, const MatFactorInfo *info) { 2982 PetscFunctionBegin; 2983 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 2984 if (row) PetscValidHeaderSpecific(row, IS_CLASSID, 2); 2985 if (col) PetscValidHeaderSpecific(col, IS_CLASSID, 3); 2986 PetscValidPointer(info, 4); 2987 PetscValidType(mat, 1); 2988 PetscCheck(mat->rmap->N == mat->cmap->N, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONG, "matrix must be square"); 2989 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 2990 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 2991 MatCheckPreallocated(mat, 1); 2992 2993 PetscCall(PetscLogEventBegin(MAT_ILUFactor, mat, row, col, 0)); 2994 PetscUseTypeMethod(mat, ilufactor, row, col, info); 2995 PetscCall(PetscLogEventEnd(MAT_ILUFactor, mat, row, col, 0)); 2996 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 2997 PetscFunctionReturn(0); 2998 } 2999 3000 /*@C 3001 MatLUFactorSymbolic - Performs symbolic LU factorization of matrix. 3002 Call this routine before calling MatLUFactorNumeric(). 3003 3004 Collective on Mat 3005 3006 Input Parameters: 3007 + fact - the factor matrix obtained with MatGetFactor() 3008 . mat - the matrix 3009 . row, col - row and column permutations 3010 - info - options for factorization, includes 3011 $ fill - expected fill as ratio of original fill. 3012 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3013 $ Run with the option -info to determine an optimal value to use 3014 3015 Notes: 3016 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 3017 3018 Most users should employ the simplified KSP interface for linear solvers 3019 instead of working directly with matrix algebra routines such as this. 3020 See, e.g., KSPCreate(). 3021 3022 Level: developer 3023 3024 .seealso: `MatLUFactor()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()`, `MatFactorInfo`, `MatFactorInfoInitialize()` 3025 3026 Developer Note: fortran interface is not autogenerated as the f90 3027 interface definition cannot be generated correctly [due to MatFactorInfo] 3028 3029 @*/ 3030 PetscErrorCode MatLUFactorSymbolic(Mat fact, Mat mat, IS row, IS col, const MatFactorInfo *info) { 3031 MatFactorInfo tinfo; 3032 3033 PetscFunctionBegin; 3034 PetscValidHeaderSpecific(mat, MAT_CLASSID, 2); 3035 if (row) PetscValidHeaderSpecific(row, IS_CLASSID, 3); 3036 if (col) PetscValidHeaderSpecific(col, IS_CLASSID, 4); 3037 if (info) PetscValidPointer(info, 5); 3038 PetscValidType(mat, 2); 3039 PetscValidPointer(fact, 1); 3040 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 3041 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 3042 if (!(fact)->ops->lufactorsymbolic) { 3043 MatSolverType stype; 3044 PetscCall(MatFactorGetSolverType(fact, &stype)); 3045 SETERRQ(PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Matrix type %s symbolic LU using solver package %s", ((PetscObject)mat)->type_name, stype); 3046 } 3047 MatCheckPreallocated(mat, 2); 3048 if (!info) { 3049 PetscCall(MatFactorInfoInitialize(&tinfo)); 3050 info = &tinfo; 3051 } 3052 3053 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_LUFactorSymbolic, mat, row, col, 0)); 3054 PetscCall((fact->ops->lufactorsymbolic)(fact, mat, row, col, info)); 3055 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_LUFactorSymbolic, mat, row, col, 0)); 3056 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3057 PetscFunctionReturn(0); 3058 } 3059 3060 /*@C 3061 MatLUFactorNumeric - Performs numeric LU factorization of a matrix. 3062 Call this routine after first calling MatLUFactorSymbolic(). 3063 3064 Collective on Mat 3065 3066 Input Parameters: 3067 + fact - the factor matrix obtained with MatGetFactor() 3068 . mat - the matrix 3069 - info - options for factorization 3070 3071 Notes: 3072 See MatLUFactor() for in-place factorization. See 3073 MatCholeskyFactorNumeric() for the symmetric, positive definite case. 3074 3075 Most users should employ the simplified KSP interface for linear solvers 3076 instead of working directly with matrix algebra routines such as this. 3077 See, e.g., KSPCreate(). 3078 3079 Level: developer 3080 3081 .seealso: `MatLUFactorSymbolic()`, `MatLUFactor()`, `MatCholeskyFactor()` 3082 3083 Developer Note: fortran interface is not autogenerated as the f90 3084 interface definition cannot be generated correctly [due to MatFactorInfo] 3085 3086 @*/ 3087 PetscErrorCode MatLUFactorNumeric(Mat fact, Mat mat, const MatFactorInfo *info) { 3088 MatFactorInfo tinfo; 3089 3090 PetscFunctionBegin; 3091 PetscValidHeaderSpecific(mat, MAT_CLASSID, 2); 3092 PetscValidType(mat, 2); 3093 PetscValidPointer(fact, 1); 3094 PetscValidHeaderSpecific(fact, MAT_CLASSID, 1); 3095 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 3096 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, 3097 mat->rmap->N, (fact)->rmap->N, mat->cmap->N, (fact)->cmap->N); 3098 3099 PetscCheck((fact)->ops->lufactornumeric, PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Mat type %s numeric LU", ((PetscObject)mat)->type_name); 3100 MatCheckPreallocated(mat, 2); 3101 if (!info) { 3102 PetscCall(MatFactorInfoInitialize(&tinfo)); 3103 info = &tinfo; 3104 } 3105 3106 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_LUFactorNumeric, mat, fact, 0, 0)); 3107 else PetscCall(PetscLogEventBegin(MAT_LUFactor, mat, fact, 0, 0)); 3108 PetscCall((fact->ops->lufactornumeric)(fact, mat, info)); 3109 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_LUFactorNumeric, mat, fact, 0, 0)); 3110 else PetscCall(PetscLogEventEnd(MAT_LUFactor, mat, fact, 0, 0)); 3111 PetscCall(MatViewFromOptions(fact, NULL, "-mat_factor_view")); 3112 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3113 PetscFunctionReturn(0); 3114 } 3115 3116 /*@C 3117 MatCholeskyFactor - Performs in-place Cholesky factorization of a 3118 symmetric matrix. 3119 3120 Collective on Mat 3121 3122 Input Parameters: 3123 + mat - the matrix 3124 . perm - row and column permutations 3125 - f - expected fill as ratio of original fill 3126 3127 Notes: 3128 See MatLUFactor() for the nonsymmetric case. See also 3129 MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric(). 3130 3131 Most users should employ the simplified KSP interface for linear solvers 3132 instead of working directly with matrix algebra routines such as this. 3133 See, e.g., KSPCreate(). 3134 3135 Level: developer 3136 3137 .seealso: `MatLUFactor()`, `MatCholeskyFactorSymbolic()`, `MatCholeskyFactorNumeric()` 3138 `MatGetOrdering()` 3139 3140 Developer Note: fortran interface is not autogenerated as the f90 3141 interface definition cannot be generated correctly [due to MatFactorInfo] 3142 3143 @*/ 3144 PetscErrorCode MatCholeskyFactor(Mat mat, IS perm, const MatFactorInfo *info) { 3145 MatFactorInfo tinfo; 3146 3147 PetscFunctionBegin; 3148 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 3149 PetscValidType(mat, 1); 3150 if (perm) PetscValidHeaderSpecific(perm, IS_CLASSID, 2); 3151 if (info) PetscValidPointer(info, 3); 3152 PetscCheck(mat->rmap->N == mat->cmap->N, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONG, "Matrix must be square"); 3153 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 3154 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 3155 MatCheckPreallocated(mat, 1); 3156 if (!info) { 3157 PetscCall(MatFactorInfoInitialize(&tinfo)); 3158 info = &tinfo; 3159 } 3160 3161 PetscCall(PetscLogEventBegin(MAT_CholeskyFactor, mat, perm, 0, 0)); 3162 PetscUseTypeMethod(mat, choleskyfactor, perm, info); 3163 PetscCall(PetscLogEventEnd(MAT_CholeskyFactor, mat, perm, 0, 0)); 3164 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 3165 PetscFunctionReturn(0); 3166 } 3167 3168 /*@C 3169 MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization 3170 of a symmetric matrix. 3171 3172 Collective on Mat 3173 3174 Input Parameters: 3175 + fact - the factor matrix obtained with MatGetFactor() 3176 . mat - the matrix 3177 . perm - row and column permutations 3178 - info - options for factorization, includes 3179 $ fill - expected fill as ratio of original fill. 3180 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3181 $ Run with the option -info to determine an optimal value to use 3182 3183 Notes: 3184 See MatLUFactorSymbolic() for the nonsymmetric case. See also 3185 MatCholeskyFactor() and MatCholeskyFactorNumeric(). 3186 3187 Most users should employ the simplified KSP interface for linear solvers 3188 instead of working directly with matrix algebra routines such as this. 3189 See, e.g., KSPCreate(). 3190 3191 Level: developer 3192 3193 .seealso: `MatLUFactorSymbolic()`, `MatCholeskyFactor()`, `MatCholeskyFactorNumeric()` 3194 `MatGetOrdering()` 3195 3196 Developer Note: fortran interface is not autogenerated as the f90 3197 interface definition cannot be generated correctly [due to MatFactorInfo] 3198 3199 @*/ 3200 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact, Mat mat, IS perm, const MatFactorInfo *info) { 3201 MatFactorInfo tinfo; 3202 3203 PetscFunctionBegin; 3204 PetscValidHeaderSpecific(mat, MAT_CLASSID, 2); 3205 PetscValidType(mat, 2); 3206 if (perm) PetscValidHeaderSpecific(perm, IS_CLASSID, 3); 3207 if (info) PetscValidPointer(info, 4); 3208 PetscValidPointer(fact, 1); 3209 PetscCheck(mat->rmap->N == mat->cmap->N, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONG, "Matrix must be square"); 3210 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 3211 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 3212 if (!(fact)->ops->choleskyfactorsymbolic) { 3213 MatSolverType stype; 3214 PetscCall(MatFactorGetSolverType(fact, &stype)); 3215 SETERRQ(PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Mat type %s symbolic factor Cholesky using solver package %s", ((PetscObject)mat)->type_name, stype); 3216 } 3217 MatCheckPreallocated(mat, 2); 3218 if (!info) { 3219 PetscCall(MatFactorInfoInitialize(&tinfo)); 3220 info = &tinfo; 3221 } 3222 3223 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_CholeskyFactorSymbolic, mat, perm, 0, 0)); 3224 PetscCall((fact->ops->choleskyfactorsymbolic)(fact, mat, perm, info)); 3225 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_CholeskyFactorSymbolic, mat, perm, 0, 0)); 3226 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3227 PetscFunctionReturn(0); 3228 } 3229 3230 /*@C 3231 MatCholeskyFactorNumeric - Performs numeric Cholesky factorization 3232 of a symmetric matrix. Call this routine after first calling 3233 MatCholeskyFactorSymbolic(). 3234 3235 Collective on Mat 3236 3237 Input Parameters: 3238 + fact - the factor matrix obtained with MatGetFactor() 3239 . mat - the initial matrix 3240 . info - options for factorization 3241 - fact - the symbolic factor of mat 3242 3243 Notes: 3244 Most users should employ the simplified KSP interface for linear solvers 3245 instead of working directly with matrix algebra routines such as this. 3246 See, e.g., KSPCreate(). 3247 3248 Level: developer 3249 3250 .seealso: `MatCholeskyFactorSymbolic()`, `MatCholeskyFactor()`, `MatLUFactorNumeric()` 3251 3252 Developer Note: fortran interface is not autogenerated as the f90 3253 interface definition cannot be generated correctly [due to MatFactorInfo] 3254 3255 @*/ 3256 PetscErrorCode MatCholeskyFactorNumeric(Mat fact, Mat mat, const MatFactorInfo *info) { 3257 MatFactorInfo tinfo; 3258 3259 PetscFunctionBegin; 3260 PetscValidHeaderSpecific(mat, MAT_CLASSID, 2); 3261 PetscValidType(mat, 2); 3262 PetscValidPointer(fact, 1); 3263 PetscValidHeaderSpecific(fact, MAT_CLASSID, 1); 3264 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 3265 PetscCheck((fact)->ops->choleskyfactornumeric, PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Mat type %s numeric factor Cholesky", ((PetscObject)mat)->type_name); 3266 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, 3267 mat->rmap->N, (fact)->rmap->N, mat->cmap->N, (fact)->cmap->N); 3268 MatCheckPreallocated(mat, 2); 3269 if (!info) { 3270 PetscCall(MatFactorInfoInitialize(&tinfo)); 3271 info = &tinfo; 3272 } 3273 3274 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_CholeskyFactorNumeric, mat, fact, 0, 0)); 3275 else PetscCall(PetscLogEventBegin(MAT_CholeskyFactor, mat, fact, 0, 0)); 3276 PetscCall((fact->ops->choleskyfactornumeric)(fact, mat, info)); 3277 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_CholeskyFactorNumeric, mat, fact, 0, 0)); 3278 else PetscCall(PetscLogEventEnd(MAT_CholeskyFactor, mat, fact, 0, 0)); 3279 PetscCall(MatViewFromOptions(fact, NULL, "-mat_factor_view")); 3280 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3281 PetscFunctionReturn(0); 3282 } 3283 3284 /*@ 3285 MatQRFactor - Performs in-place QR factorization of matrix. 3286 3287 Collective on Mat 3288 3289 Input Parameters: 3290 + mat - the matrix 3291 . col - column permutation 3292 - info - options for factorization, includes 3293 $ fill - expected fill as ratio of original fill. 3294 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3295 $ Run with the option -info to determine an optimal value to use 3296 3297 Notes: 3298 Most users should employ the simplified KSP interface for linear solvers 3299 instead of working directly with matrix algebra routines such as this. 3300 See, e.g., KSPCreate(). 3301 3302 This changes the state of the matrix to a factored matrix; it cannot be used 3303 for example with MatSetValues() unless one first calls MatSetUnfactored(). 3304 3305 Level: developer 3306 3307 .seealso: `MatQRFactorSymbolic()`, `MatQRFactorNumeric()`, `MatLUFactor()`, 3308 `MatSetUnfactored()`, `MatFactorInfo`, `MatGetFactor()` 3309 3310 Developer Note: fortran interface is not autogenerated as the f90 3311 interface definition cannot be generated correctly [due to MatFactorInfo] 3312 3313 @*/ 3314 PetscErrorCode MatQRFactor(Mat mat, IS col, const MatFactorInfo *info) { 3315 PetscFunctionBegin; 3316 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 3317 if (col) PetscValidHeaderSpecific(col, IS_CLASSID, 2); 3318 if (info) PetscValidPointer(info, 3); 3319 PetscValidType(mat, 1); 3320 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 3321 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 3322 MatCheckPreallocated(mat, 1); 3323 PetscCall(PetscLogEventBegin(MAT_QRFactor, mat, col, 0, 0)); 3324 PetscUseMethod(mat, "MatQRFactor_C", (Mat, IS, const MatFactorInfo *), (mat, col, info)); 3325 PetscCall(PetscLogEventEnd(MAT_QRFactor, mat, col, 0, 0)); 3326 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 3327 PetscFunctionReturn(0); 3328 } 3329 3330 /*@ 3331 MatQRFactorSymbolic - Performs symbolic QR factorization of matrix. 3332 Call this routine before calling MatQRFactorNumeric(). 3333 3334 Collective on Mat 3335 3336 Input Parameters: 3337 + fact - the factor matrix obtained with MatGetFactor() 3338 . mat - the matrix 3339 . col - column permutation 3340 - info - options for factorization, includes 3341 $ fill - expected fill as ratio of original fill. 3342 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3343 $ Run with the option -info to determine an optimal value to use 3344 3345 Most users should employ the simplified KSP interface for linear solvers 3346 instead of working directly with matrix algebra routines such as this. 3347 See, e.g., KSPCreate(). 3348 3349 Level: developer 3350 3351 .seealso: `MatQRFactor()`, `MatQRFactorNumeric()`, `MatLUFactor()`, `MatFactorInfo`, `MatFactorInfoInitialize()` 3352 3353 Developer Note: fortran interface is not autogenerated as the f90 3354 interface definition cannot be generated correctly [due to MatFactorInfo] 3355 3356 @*/ 3357 PetscErrorCode MatQRFactorSymbolic(Mat fact, Mat mat, IS col, const MatFactorInfo *info) { 3358 MatFactorInfo tinfo; 3359 3360 PetscFunctionBegin; 3361 PetscValidHeaderSpecific(mat, MAT_CLASSID, 2); 3362 if (col) PetscValidHeaderSpecific(col, IS_CLASSID, 3); 3363 if (info) PetscValidPointer(info, 4); 3364 PetscValidType(mat, 2); 3365 PetscValidPointer(fact, 1); 3366 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 3367 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 3368 MatCheckPreallocated(mat, 2); 3369 if (!info) { 3370 PetscCall(MatFactorInfoInitialize(&tinfo)); 3371 info = &tinfo; 3372 } 3373 3374 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_QRFactorSymbolic, fact, mat, col, 0)); 3375 PetscUseMethod(fact, "MatQRFactorSymbolic_C", (Mat, Mat, IS, const MatFactorInfo *), (fact, mat, col, info)); 3376 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_QRFactorSymbolic, fact, mat, col, 0)); 3377 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3378 PetscFunctionReturn(0); 3379 } 3380 3381 /*@ 3382 MatQRFactorNumeric - Performs numeric QR factorization of a matrix. 3383 Call this routine after first calling MatQRFactorSymbolic(). 3384 3385 Collective on Mat 3386 3387 Input Parameters: 3388 + fact - the factor matrix obtained with MatGetFactor() 3389 . mat - the matrix 3390 - info - options for factorization 3391 3392 Notes: 3393 See MatQRFactor() for in-place factorization. 3394 3395 Most users should employ the simplified KSP interface for linear solvers 3396 instead of working directly with matrix algebra routines such as this. 3397 See, e.g., KSPCreate(). 3398 3399 Level: developer 3400 3401 .seealso: `MatQRFactorSymbolic()`, `MatLUFactor()` 3402 3403 Developer Note: fortran interface is not autogenerated as the f90 3404 interface definition cannot be generated correctly [due to MatFactorInfo] 3405 3406 @*/ 3407 PetscErrorCode MatQRFactorNumeric(Mat fact, Mat mat, const MatFactorInfo *info) { 3408 MatFactorInfo tinfo; 3409 3410 PetscFunctionBegin; 3411 PetscValidHeaderSpecific(mat, MAT_CLASSID, 2); 3412 PetscValidType(mat, 2); 3413 PetscValidPointer(fact, 1); 3414 PetscValidHeaderSpecific(fact, MAT_CLASSID, 1); 3415 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 3416 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, 3417 mat->rmap->N, (fact)->rmap->N, mat->cmap->N, (fact)->cmap->N); 3418 3419 MatCheckPreallocated(mat, 2); 3420 if (!info) { 3421 PetscCall(MatFactorInfoInitialize(&tinfo)); 3422 info = &tinfo; 3423 } 3424 3425 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_QRFactorNumeric, mat, fact, 0, 0)); 3426 else PetscCall(PetscLogEventBegin(MAT_QRFactor, mat, fact, 0, 0)); 3427 PetscUseMethod(fact, "MatQRFactorNumeric_C", (Mat, Mat, const MatFactorInfo *), (fact, mat, info)); 3428 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_QRFactorNumeric, mat, fact, 0, 0)); 3429 else PetscCall(PetscLogEventEnd(MAT_QRFactor, mat, fact, 0, 0)); 3430 PetscCall(MatViewFromOptions(fact, NULL, "-mat_factor_view")); 3431 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3432 PetscFunctionReturn(0); 3433 } 3434 3435 /* ----------------------------------------------------------------*/ 3436 /*@ 3437 MatSolve - Solves A x = b, given a factored matrix. 3438 3439 Neighbor-wise Collective on Mat 3440 3441 Input Parameters: 3442 + mat - the factored matrix 3443 - b - the right-hand-side vector 3444 3445 Output Parameter: 3446 . x - the result vector 3447 3448 Notes: 3449 The vectors b and x cannot be the same. I.e., one cannot 3450 call MatSolve(A,x,x). 3451 3452 Notes: 3453 Most users should employ the simplified KSP interface for linear solvers 3454 instead of working directly with matrix algebra routines such as this. 3455 See, e.g., KSPCreate(). 3456 3457 Level: developer 3458 3459 .seealso: `MatSolveAdd()`, `MatSolveTranspose()`, `MatSolveTransposeAdd()` 3460 @*/ 3461 PetscErrorCode MatSolve(Mat mat, Vec b, Vec x) { 3462 PetscFunctionBegin; 3463 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 3464 PetscValidType(mat, 1); 3465 PetscValidHeaderSpecific(b, VEC_CLASSID, 2); 3466 PetscValidHeaderSpecific(x, VEC_CLASSID, 3); 3467 PetscCheckSameComm(mat, 1, b, 2); 3468 PetscCheckSameComm(mat, 1, x, 3); 3469 PetscCheck(x != b, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_IDN, "x and b must be different vectors"); 3470 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); 3471 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); 3472 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); 3473 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3474 MatCheckPreallocated(mat, 1); 3475 3476 PetscCall(PetscLogEventBegin(MAT_Solve, mat, b, x, 0)); 3477 if (mat->factorerrortype) { 3478 PetscCall(PetscInfo(mat, "MatFactorError %d\n", mat->factorerrortype)); 3479 PetscCall(VecSetInf(x)); 3480 } else PetscUseTypeMethod(mat, solve, b, x); 3481 PetscCall(PetscLogEventEnd(MAT_Solve, mat, b, x, 0)); 3482 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3483 PetscFunctionReturn(0); 3484 } 3485 3486 static PetscErrorCode MatMatSolve_Basic(Mat A, Mat B, Mat X, PetscBool trans) { 3487 Vec b, x; 3488 PetscInt N, i; 3489 PetscErrorCode (*f)(Mat, Vec, Vec); 3490 PetscBool Abound, Bneedconv = PETSC_FALSE, Xneedconv = PETSC_FALSE; 3491 3492 PetscFunctionBegin; 3493 if (A->factorerrortype) { 3494 PetscCall(PetscInfo(A, "MatFactorError %d\n", A->factorerrortype)); 3495 PetscCall(MatSetInf(X)); 3496 PetscFunctionReturn(0); 3497 } 3498 f = (!trans || (!A->ops->solvetranspose && A->symmetric)) ? A->ops->solve : A->ops->solvetranspose; 3499 PetscCheck(f, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Mat type %s", ((PetscObject)A)->type_name); 3500 PetscCall(MatBoundToCPU(A, &Abound)); 3501 if (!Abound) { 3502 PetscCall(PetscObjectTypeCompareAny((PetscObject)B, &Bneedconv, MATSEQDENSE, MATMPIDENSE, "")); 3503 PetscCall(PetscObjectTypeCompareAny((PetscObject)X, &Xneedconv, MATSEQDENSE, MATMPIDENSE, "")); 3504 } 3505 if (Bneedconv) PetscCall(MatConvert(B, MATDENSECUDA, MAT_INPLACE_MATRIX, &B)); 3506 if (Xneedconv) PetscCall(MatConvert(X, MATDENSECUDA, MAT_INPLACE_MATRIX, &X)); 3507 PetscCall(MatGetSize(B, NULL, &N)); 3508 for (i = 0; i < N; i++) { 3509 PetscCall(MatDenseGetColumnVecRead(B, i, &b)); 3510 PetscCall(MatDenseGetColumnVecWrite(X, i, &x)); 3511 PetscCall((*f)(A, b, x)); 3512 PetscCall(MatDenseRestoreColumnVecWrite(X, i, &x)); 3513 PetscCall(MatDenseRestoreColumnVecRead(B, i, &b)); 3514 } 3515 if (Bneedconv) PetscCall(MatConvert(B, MATDENSE, MAT_INPLACE_MATRIX, &B)); 3516 if (Xneedconv) PetscCall(MatConvert(X, MATDENSE, MAT_INPLACE_MATRIX, &X)); 3517 PetscFunctionReturn(0); 3518 } 3519 3520 /*@ 3521 MatMatSolve - Solves A X = B, given a factored matrix. 3522 3523 Neighbor-wise Collective on Mat 3524 3525 Input Parameters: 3526 + A - the factored matrix 3527 - B - the right-hand-side matrix MATDENSE (or sparse -- when using MUMPS) 3528 3529 Output Parameter: 3530 . X - the result matrix (dense matrix) 3531 3532 Notes: 3533 If B is a MATDENSE matrix then one can call MatMatSolve(A,B,B) except with MKL_CPARDISO; 3534 otherwise, B and X cannot be the same. 3535 3536 Notes: 3537 Most users should usually employ the simplified KSP interface for linear solvers 3538 instead of working directly with matrix algebra routines such as this. 3539 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3540 at a time. 3541 3542 Level: developer 3543 3544 .seealso: `MatMatSolveTranspose()`, `MatLUFactor()`, `MatCholeskyFactor()` 3545 @*/ 3546 PetscErrorCode MatMatSolve(Mat A, Mat B, Mat X) { 3547 PetscFunctionBegin; 3548 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 3549 PetscValidType(A, 1); 3550 PetscValidHeaderSpecific(B, MAT_CLASSID, 2); 3551 PetscValidHeaderSpecific(X, MAT_CLASSID, 3); 3552 PetscCheckSameComm(A, 1, B, 2); 3553 PetscCheckSameComm(A, 1, X, 3); 3554 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); 3555 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); 3556 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"); 3557 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3558 PetscCheck(A->factortype, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Unfactored matrix"); 3559 MatCheckPreallocated(A, 1); 3560 3561 PetscCall(PetscLogEventBegin(MAT_MatSolve, A, B, X, 0)); 3562 if (!A->ops->matsolve) { 3563 PetscCall(PetscInfo(A, "Mat type %s using basic MatMatSolve\n", ((PetscObject)A)->type_name)); 3564 PetscCall(MatMatSolve_Basic(A, B, X, PETSC_FALSE)); 3565 } else PetscUseTypeMethod(A, matsolve, B, X); 3566 PetscCall(PetscLogEventEnd(MAT_MatSolve, A, B, X, 0)); 3567 PetscCall(PetscObjectStateIncrease((PetscObject)X)); 3568 PetscFunctionReturn(0); 3569 } 3570 3571 /*@ 3572 MatMatSolveTranspose - Solves A^T X = B, given a factored matrix. 3573 3574 Neighbor-wise Collective on Mat 3575 3576 Input Parameters: 3577 + A - the factored matrix 3578 - B - the right-hand-side matrix (dense matrix) 3579 3580 Output Parameter: 3581 . X - the result matrix (dense matrix) 3582 3583 Notes: 3584 The matrices B and X cannot be the same. I.e., one cannot 3585 call MatMatSolveTranspose(A,X,X). 3586 3587 Notes: 3588 Most users should usually employ the simplified KSP interface for linear solvers 3589 instead of working directly with matrix algebra routines such as this. 3590 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3591 at a time. 3592 3593 When using SuperLU_Dist or MUMPS as a parallel solver, PETSc will use their functionality to solve multiple right hand sides simultaneously. 3594 3595 Level: developer 3596 3597 .seealso: `MatMatSolve()`, `MatLUFactor()`, `MatCholeskyFactor()` 3598 @*/ 3599 PetscErrorCode MatMatSolveTranspose(Mat A, Mat B, Mat X) { 3600 PetscFunctionBegin; 3601 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 3602 PetscValidType(A, 1); 3603 PetscValidHeaderSpecific(B, MAT_CLASSID, 2); 3604 PetscValidHeaderSpecific(X, MAT_CLASSID, 3); 3605 PetscCheckSameComm(A, 1, B, 2); 3606 PetscCheckSameComm(A, 1, X, 3); 3607 PetscCheck(X != B, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_IDN, "X and B must be different matrices"); 3608 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); 3609 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); 3610 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); 3611 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"); 3612 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3613 PetscCheck(A->factortype, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Unfactored matrix"); 3614 MatCheckPreallocated(A, 1); 3615 3616 PetscCall(PetscLogEventBegin(MAT_MatSolve, A, B, X, 0)); 3617 if (!A->ops->matsolvetranspose) { 3618 PetscCall(PetscInfo(A, "Mat type %s using basic MatMatSolveTranspose\n", ((PetscObject)A)->type_name)); 3619 PetscCall(MatMatSolve_Basic(A, B, X, PETSC_TRUE)); 3620 } else PetscUseTypeMethod(A, matsolvetranspose, B, X); 3621 PetscCall(PetscLogEventEnd(MAT_MatSolve, A, B, X, 0)); 3622 PetscCall(PetscObjectStateIncrease((PetscObject)X)); 3623 PetscFunctionReturn(0); 3624 } 3625 3626 /*@ 3627 MatMatTransposeSolve - Solves A X = B^T, given a factored matrix. 3628 3629 Neighbor-wise Collective on Mat 3630 3631 Input Parameters: 3632 + A - the factored matrix 3633 - Bt - the transpose of right-hand-side matrix 3634 3635 Output Parameter: 3636 . X - the result matrix (dense matrix) 3637 3638 Notes: 3639 Most users should usually employ the simplified KSP interface for linear solvers 3640 instead of working directly with matrix algebra routines such as this. 3641 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3642 at a time. 3643 3644 For MUMPS, it only supports centralized sparse compressed column format on the host processor for right hand side matrix. User must create B^T in sparse compressed row format on the host processor and call MatMatTransposeSolve() to implement MUMPS' MatMatSolve(). 3645 3646 Level: developer 3647 3648 .seealso: `MatMatSolve()`, `MatMatSolveTranspose()`, `MatLUFactor()`, `MatCholeskyFactor()` 3649 @*/ 3650 PetscErrorCode MatMatTransposeSolve(Mat A, Mat Bt, Mat X) { 3651 PetscFunctionBegin; 3652 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 3653 PetscValidType(A, 1); 3654 PetscValidHeaderSpecific(Bt, MAT_CLASSID, 2); 3655 PetscValidHeaderSpecific(X, MAT_CLASSID, 3); 3656 PetscCheckSameComm(A, 1, Bt, 2); 3657 PetscCheckSameComm(A, 1, X, 3); 3658 3659 PetscCheck(X != Bt, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_IDN, "X and B must be different matrices"); 3660 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); 3661 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); 3662 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"); 3663 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3664 PetscCheck(A->factortype, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Unfactored matrix"); 3665 MatCheckPreallocated(A, 1); 3666 3667 PetscCall(PetscLogEventBegin(MAT_MatTrSolve, A, Bt, X, 0)); 3668 PetscUseTypeMethod(A, mattransposesolve, Bt, X); 3669 PetscCall(PetscLogEventEnd(MAT_MatTrSolve, A, Bt, X, 0)); 3670 PetscCall(PetscObjectStateIncrease((PetscObject)X)); 3671 PetscFunctionReturn(0); 3672 } 3673 3674 /*@ 3675 MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or 3676 U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U, 3677 3678 Neighbor-wise Collective on Mat 3679 3680 Input Parameters: 3681 + mat - the factored matrix 3682 - b - the right-hand-side vector 3683 3684 Output Parameter: 3685 . x - the result vector 3686 3687 Notes: 3688 MatSolve() should be used for most applications, as it performs 3689 a forward solve followed by a backward solve. 3690 3691 The vectors b and x cannot be the same, i.e., one cannot 3692 call MatForwardSolve(A,x,x). 3693 3694 For matrix in seqsbaij format with block size larger than 1, 3695 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3696 MatForwardSolve() solves U^T*D y = b, and 3697 MatBackwardSolve() solves U x = y. 3698 Thus they do not provide a symmetric preconditioner. 3699 3700 Most users should employ the simplified KSP interface for linear solvers 3701 instead of working directly with matrix algebra routines such as this. 3702 See, e.g., KSPCreate(). 3703 3704 Level: developer 3705 3706 .seealso: `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 seqsbaij 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 Most users should employ the simplified KSP interface for linear solvers 3757 instead of working directly with matrix algebra routines such as this. 3758 See, e.g., KSPCreate(). 3759 3760 Level: developer 3761 3762 .seealso: `MatSolve()`, `MatForwardSolve()` 3763 @*/ 3764 PetscErrorCode MatBackwardSolve(Mat mat, Vec b, Vec x) { 3765 PetscFunctionBegin; 3766 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 3767 PetscValidType(mat, 1); 3768 PetscValidHeaderSpecific(b, VEC_CLASSID, 2); 3769 PetscValidHeaderSpecific(x, VEC_CLASSID, 3); 3770 PetscCheckSameComm(mat, 1, b, 2); 3771 PetscCheckSameComm(mat, 1, x, 3); 3772 PetscCheck(x != b, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_IDN, "x and b must be different vectors"); 3773 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); 3774 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); 3775 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); 3776 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3777 MatCheckPreallocated(mat, 1); 3778 3779 PetscCall(PetscLogEventBegin(MAT_BackwardSolve, mat, b, x, 0)); 3780 PetscUseTypeMethod(mat, backwardsolve, b, x); 3781 PetscCall(PetscLogEventEnd(MAT_BackwardSolve, mat, b, x, 0)); 3782 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3783 PetscFunctionReturn(0); 3784 } 3785 3786 /*@ 3787 MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix. 3788 3789 Neighbor-wise Collective on Mat 3790 3791 Input Parameters: 3792 + mat - the factored matrix 3793 . b - the right-hand-side vector 3794 - y - the vector to be added to 3795 3796 Output Parameter: 3797 . x - the result vector 3798 3799 Notes: 3800 The vectors b and x cannot be the same. I.e., one cannot 3801 call MatSolveAdd(A,x,y,x). 3802 3803 Most users should employ the simplified KSP interface for linear solvers 3804 instead of working directly with matrix algebra routines such as this. 3805 See, e.g., KSPCreate(). 3806 3807 Level: developer 3808 3809 .seealso: `MatSolve()`, `MatSolveTranspose()`, `MatSolveTransposeAdd()` 3810 @*/ 3811 PetscErrorCode MatSolveAdd(Mat mat, Vec b, Vec y, Vec x) { 3812 PetscScalar one = 1.0; 3813 Vec tmp; 3814 3815 PetscFunctionBegin; 3816 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 3817 PetscValidType(mat, 1); 3818 PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 3819 PetscValidHeaderSpecific(b, VEC_CLASSID, 2); 3820 PetscValidHeaderSpecific(x, VEC_CLASSID, 4); 3821 PetscCheckSameComm(mat, 1, b, 2); 3822 PetscCheckSameComm(mat, 1, y, 3); 3823 PetscCheckSameComm(mat, 1, x, 4); 3824 PetscCheck(x != b, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_IDN, "x and b must be different vectors"); 3825 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); 3826 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); 3827 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); 3828 PetscCheck(mat->rmap->n == b->map->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Mat mat,Vec b: local dim %" PetscInt_FMT " %" PetscInt_FMT, mat->rmap->n, b->map->n); 3829 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); 3830 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3831 MatCheckPreallocated(mat, 1); 3832 3833 PetscCall(PetscLogEventBegin(MAT_SolveAdd, mat, b, x, y)); 3834 if (mat->factorerrortype) { 3835 PetscCall(PetscInfo(mat, "MatFactorError %d\n", mat->factorerrortype)); 3836 PetscCall(VecSetInf(x)); 3837 } else if (mat->ops->solveadd) { 3838 PetscUseTypeMethod(mat, solveadd, b, y, x); 3839 } else { 3840 /* do the solve then the add manually */ 3841 if (x != y) { 3842 PetscCall(MatSolve(mat, b, x)); 3843 PetscCall(VecAXPY(x, one, y)); 3844 } else { 3845 PetscCall(VecDuplicate(x, &tmp)); 3846 PetscCall(PetscLogObjectParent((PetscObject)mat, (PetscObject)tmp)); 3847 PetscCall(VecCopy(x, tmp)); 3848 PetscCall(MatSolve(mat, b, x)); 3849 PetscCall(VecAXPY(x, one, tmp)); 3850 PetscCall(VecDestroy(&tmp)); 3851 } 3852 } 3853 PetscCall(PetscLogEventEnd(MAT_SolveAdd, mat, b, x, y)); 3854 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3855 PetscFunctionReturn(0); 3856 } 3857 3858 /*@ 3859 MatSolveTranspose - Solves A' x = b, given a factored matrix. 3860 3861 Neighbor-wise Collective on Mat 3862 3863 Input Parameters: 3864 + mat - the factored matrix 3865 - b - the right-hand-side vector 3866 3867 Output Parameter: 3868 . x - the result vector 3869 3870 Notes: 3871 The vectors b and x cannot be the same. I.e., one cannot 3872 call MatSolveTranspose(A,x,x). 3873 3874 Most users should employ the simplified KSP interface for linear solvers 3875 instead of working directly with matrix algebra routines such as this. 3876 See, e.g., KSPCreate(). 3877 3878 Level: developer 3879 3880 .seealso: `MatSolve()`, `MatSolveAdd()`, `MatSolveTransposeAdd()` 3881 @*/ 3882 PetscErrorCode MatSolveTranspose(Mat mat, Vec b, Vec x) { 3883 PetscErrorCode (*f)(Mat, Vec, Vec) = (!mat->ops->solvetranspose && mat->symmetric) ? mat->ops->solve : mat->ops->solvetranspose; 3884 3885 PetscFunctionBegin; 3886 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 3887 PetscValidType(mat, 1); 3888 PetscValidHeaderSpecific(b, VEC_CLASSID, 2); 3889 PetscValidHeaderSpecific(x, VEC_CLASSID, 3); 3890 PetscCheckSameComm(mat, 1, b, 2); 3891 PetscCheckSameComm(mat, 1, x, 3); 3892 PetscCheck(x != b, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_IDN, "x and b must be different vectors"); 3893 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); 3894 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); 3895 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3896 MatCheckPreallocated(mat, 1); 3897 PetscCall(PetscLogEventBegin(MAT_SolveTranspose, mat, b, x, 0)); 3898 if (mat->factorerrortype) { 3899 PetscCall(PetscInfo(mat, "MatFactorError %d\n", mat->factorerrortype)); 3900 PetscCall(VecSetInf(x)); 3901 } else { 3902 PetscCheck(f, PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Matrix type %s", ((PetscObject)mat)->type_name); 3903 PetscCall((*f)(mat, b, x)); 3904 } 3905 PetscCall(PetscLogEventEnd(MAT_SolveTranspose, mat, b, x, 0)); 3906 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3907 PetscFunctionReturn(0); 3908 } 3909 3910 /*@ 3911 MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a 3912 factored matrix. 3913 3914 Neighbor-wise Collective on Mat 3915 3916 Input Parameters: 3917 + mat - the factored matrix 3918 . b - the right-hand-side vector 3919 - y - the vector to be added to 3920 3921 Output Parameter: 3922 . x - the result vector 3923 3924 Notes: 3925 The vectors b and x cannot be the same. I.e., one cannot 3926 call MatSolveTransposeAdd(A,x,y,x). 3927 3928 Most users should employ the simplified KSP interface for linear solvers 3929 instead of working directly with matrix algebra routines such as this. 3930 See, e.g., KSPCreate(). 3931 3932 Level: developer 3933 3934 .seealso: `MatSolve()`, `MatSolveAdd()`, `MatSolveTranspose()` 3935 @*/ 3936 PetscErrorCode MatSolveTransposeAdd(Mat mat, Vec b, Vec y, Vec x) { 3937 PetscScalar one = 1.0; 3938 Vec tmp; 3939 PetscErrorCode (*f)(Mat, Vec, Vec, Vec) = (!mat->ops->solvetransposeadd && mat->symmetric) ? mat->ops->solveadd : mat->ops->solvetransposeadd; 3940 3941 PetscFunctionBegin; 3942 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 3943 PetscValidType(mat, 1); 3944 PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 3945 PetscValidHeaderSpecific(b, VEC_CLASSID, 2); 3946 PetscValidHeaderSpecific(x, VEC_CLASSID, 4); 3947 PetscCheckSameComm(mat, 1, b, 2); 3948 PetscCheckSameComm(mat, 1, y, 3); 3949 PetscCheckSameComm(mat, 1, x, 4); 3950 PetscCheck(x != b, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_IDN, "x and b must be different vectors"); 3951 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); 3952 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); 3953 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); 3954 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); 3955 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3956 MatCheckPreallocated(mat, 1); 3957 3958 PetscCall(PetscLogEventBegin(MAT_SolveTransposeAdd, mat, b, x, y)); 3959 if (mat->factorerrortype) { 3960 PetscCall(PetscInfo(mat, "MatFactorError %d\n", mat->factorerrortype)); 3961 PetscCall(VecSetInf(x)); 3962 } else if (f) { 3963 PetscCall((*f)(mat, b, y, x)); 3964 } else { 3965 /* do the solve then the add manually */ 3966 if (x != y) { 3967 PetscCall(MatSolveTranspose(mat, b, x)); 3968 PetscCall(VecAXPY(x, one, y)); 3969 } else { 3970 PetscCall(VecDuplicate(x, &tmp)); 3971 PetscCall(PetscLogObjectParent((PetscObject)mat, (PetscObject)tmp)); 3972 PetscCall(VecCopy(x, tmp)); 3973 PetscCall(MatSolveTranspose(mat, b, x)); 3974 PetscCall(VecAXPY(x, one, tmp)); 3975 PetscCall(VecDestroy(&tmp)); 3976 } 3977 } 3978 PetscCall(PetscLogEventEnd(MAT_SolveTransposeAdd, mat, b, x, y)); 3979 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3980 PetscFunctionReturn(0); 3981 } 3982 /* ----------------------------------------------------------------*/ 3983 3984 /*@ 3985 MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps. 3986 3987 Neighbor-wise Collective on Mat 3988 3989 Input Parameters: 3990 + mat - the matrix 3991 . b - the right hand side 3992 . omega - the relaxation factor 3993 . flag - flag indicating the type of SOR (see below) 3994 . shift - diagonal shift 3995 . its - the number of iterations 3996 - lits - the number of local iterations 3997 3998 Output Parameter: 3999 . x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess) 4000 4001 SOR Flags: 4002 + SOR_FORWARD_SWEEP - forward SOR 4003 . SOR_BACKWARD_SWEEP - backward SOR 4004 . SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR) 4005 . SOR_LOCAL_FORWARD_SWEEP - local forward SOR 4006 . SOR_LOCAL_BACKWARD_SWEEP - local forward SOR 4007 . SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR 4008 . SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies 4009 upper/lower triangular part of matrix to 4010 vector (with omega) 4011 - SOR_ZERO_INITIAL_GUESS - zero initial guess 4012 4013 Notes: 4014 SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and 4015 SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings 4016 on each processor. 4017 4018 Application programmers will not generally use MatSOR() directly, 4019 but instead will employ the KSP/PC interface. 4020 4021 Notes: 4022 for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing 4023 4024 Notes for Advanced Users: 4025 The flags are implemented as bitwise inclusive or operations. 4026 For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP) 4027 to specify a zero initial guess for SSOR. 4028 4029 Most users should employ the simplified KSP interface for linear solvers 4030 instead of working directly with matrix algebra routines such as this. 4031 See, e.g., KSPCreate(). 4032 4033 Vectors x and b CANNOT be the same 4034 4035 Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes 4036 4037 Level: developer 4038 4039 @*/ 4040 PetscErrorCode MatSOR(Mat mat, Vec b, PetscReal omega, MatSORType flag, PetscReal shift, PetscInt its, PetscInt lits, Vec x) { 4041 PetscFunctionBegin; 4042 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4043 PetscValidType(mat, 1); 4044 PetscValidHeaderSpecific(b, VEC_CLASSID, 2); 4045 PetscValidHeaderSpecific(x, VEC_CLASSID, 8); 4046 PetscCheckSameComm(mat, 1, b, 2); 4047 PetscCheckSameComm(mat, 1, x, 8); 4048 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 4049 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 4050 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); 4051 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); 4052 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); 4053 PetscCheck(its > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Relaxation requires global its %" PetscInt_FMT " positive", its); 4054 PetscCheck(lits > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Relaxation requires local its %" PetscInt_FMT " positive", lits); 4055 PetscCheck(b != x, PETSC_COMM_SELF, PETSC_ERR_ARG_IDN, "b and x vector cannot be the same"); 4056 4057 MatCheckPreallocated(mat, 1); 4058 PetscCall(PetscLogEventBegin(MAT_SOR, mat, b, x, 0)); 4059 PetscUseTypeMethod(mat, sor, b, omega, flag, shift, its, lits, x); 4060 PetscCall(PetscLogEventEnd(MAT_SOR, mat, b, x, 0)); 4061 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 4062 PetscFunctionReturn(0); 4063 } 4064 4065 /* 4066 Default matrix copy routine. 4067 */ 4068 PetscErrorCode MatCopy_Basic(Mat A, Mat B, MatStructure str) { 4069 PetscInt i, rstart = 0, rend = 0, nz; 4070 const PetscInt *cwork; 4071 const PetscScalar *vwork; 4072 4073 PetscFunctionBegin; 4074 if (B->assembled) PetscCall(MatZeroEntries(B)); 4075 if (str == SAME_NONZERO_PATTERN) { 4076 PetscCall(MatGetOwnershipRange(A, &rstart, &rend)); 4077 for (i = rstart; i < rend; i++) { 4078 PetscCall(MatGetRow(A, i, &nz, &cwork, &vwork)); 4079 PetscCall(MatSetValues(B, 1, &i, nz, cwork, vwork, INSERT_VALUES)); 4080 PetscCall(MatRestoreRow(A, i, &nz, &cwork, &vwork)); 4081 } 4082 } else { 4083 PetscCall(MatAYPX(B, 0.0, A, str)); 4084 } 4085 PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 4086 PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 4087 PetscFunctionReturn(0); 4088 } 4089 4090 /*@ 4091 MatCopy - Copies a matrix to another matrix. 4092 4093 Collective on Mat 4094 4095 Input Parameters: 4096 + A - the matrix 4097 - str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN 4098 4099 Output Parameter: 4100 . B - where the copy is put 4101 4102 Notes: 4103 If you use SAME_NONZERO_PATTERN then the two matrices must have the same nonzero pattern or the routine will crash. 4104 4105 MatCopy() copies the matrix entries of a matrix to another existing 4106 matrix (after first zeroing the second matrix). A related routine is 4107 MatConvert(), which first creates a new matrix and then copies the data. 4108 4109 Level: intermediate 4110 4111 .seealso: `MatConvert()`, `MatDuplicate()` 4112 @*/ 4113 PetscErrorCode MatCopy(Mat A, Mat B, MatStructure str) { 4114 PetscInt i; 4115 4116 PetscFunctionBegin; 4117 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 4118 PetscValidHeaderSpecific(B, MAT_CLASSID, 2); 4119 PetscValidType(A, 1); 4120 PetscValidType(B, 2); 4121 PetscCheckSameComm(A, 1, B, 2); 4122 MatCheckPreallocated(B, 2); 4123 PetscCheck(A->assembled, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 4124 PetscCheck(!A->factortype, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 4125 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, 4126 A->cmap->N, B->cmap->N); 4127 MatCheckPreallocated(A, 1); 4128 if (A == B) PetscFunctionReturn(0); 4129 4130 PetscCall(PetscLogEventBegin(MAT_Copy, A, B, 0, 0)); 4131 if (A->ops->copy) PetscUseTypeMethod(A, copy, B, str); 4132 else PetscCall(MatCopy_Basic(A, B, str)); 4133 4134 B->stencil.dim = A->stencil.dim; 4135 B->stencil.noc = A->stencil.noc; 4136 for (i = 0; i <= A->stencil.dim; i++) { 4137 B->stencil.dims[i] = A->stencil.dims[i]; 4138 B->stencil.starts[i] = A->stencil.starts[i]; 4139 } 4140 4141 PetscCall(PetscLogEventEnd(MAT_Copy, A, B, 0, 0)); 4142 PetscCall(PetscObjectStateIncrease((PetscObject)B)); 4143 PetscFunctionReturn(0); 4144 } 4145 4146 /*@C 4147 MatConvert - Converts a matrix to another matrix, either of the same 4148 or different type. 4149 4150 Collective on Mat 4151 4152 Input Parameters: 4153 + mat - the matrix 4154 . newtype - new matrix type. Use MATSAME to create a new matrix of the 4155 same type as the original matrix. 4156 - reuse - denotes if the destination matrix is to be created or reused. 4157 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 4158 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). 4159 4160 Output Parameter: 4161 . M - pointer to place new matrix 4162 4163 Notes: 4164 MatConvert() first creates a new matrix and then copies the data from 4165 the first matrix. A related routine is MatCopy(), which copies the matrix 4166 entries of one matrix to another already existing matrix context. 4167 4168 Cannot be used to convert a sequential matrix to parallel or parallel to sequential, 4169 the MPI communicator of the generated matrix is always the same as the communicator 4170 of the input matrix. 4171 4172 Level: intermediate 4173 4174 .seealso: `MatCopy()`, `MatDuplicate()` 4175 @*/ 4176 PetscErrorCode MatConvert(Mat mat, MatType newtype, MatReuse reuse, Mat *M) { 4177 PetscBool sametype, issame, flg; 4178 PetscBool3 issymmetric, ishermitian; 4179 char convname[256], mtype[256]; 4180 Mat B; 4181 4182 PetscFunctionBegin; 4183 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4184 PetscValidType(mat, 1); 4185 PetscValidPointer(M, 4); 4186 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 4187 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 4188 MatCheckPreallocated(mat, 1); 4189 4190 PetscCall(PetscOptionsGetString(((PetscObject)mat)->options, ((PetscObject)mat)->prefix, "-matconvert_type", mtype, sizeof(mtype), &flg)); 4191 if (flg) newtype = mtype; 4192 4193 PetscCall(PetscObjectTypeCompare((PetscObject)mat, newtype, &sametype)); 4194 PetscCall(PetscStrcmp(newtype, "same", &issame)); 4195 PetscCheck(!(reuse == MAT_INPLACE_MATRIX) || !(mat != *M), PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "MAT_INPLACE_MATRIX requires same input and output matrix"); 4196 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"); 4197 4198 if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) { 4199 PetscCall(PetscInfo(mat, "Early return for inplace %s %d %d\n", ((PetscObject)mat)->type_name, sametype, issame)); 4200 PetscFunctionReturn(0); 4201 } 4202 4203 /* Cache Mat options because some converters use MatHeaderReplace */ 4204 issymmetric = mat->symmetric; 4205 ishermitian = mat->hermitian; 4206 4207 if ((sametype || issame) && (reuse == MAT_INITIAL_MATRIX) && mat->ops->duplicate) { 4208 PetscCall(PetscInfo(mat, "Calling duplicate for initial matrix %s %d %d\n", ((PetscObject)mat)->type_name, sametype, issame)); 4209 PetscUseTypeMethod(mat, duplicate, MAT_COPY_VALUES, M); 4210 } else { 4211 PetscErrorCode (*conv)(Mat, MatType, MatReuse, Mat *) = NULL; 4212 const char *prefix[3] = {"seq", "mpi", ""}; 4213 PetscInt i; 4214 /* 4215 Order of precedence: 4216 0) See if newtype is a superclass of the current matrix. 4217 1) See if a specialized converter is known to the current matrix. 4218 2) See if a specialized converter is known to the desired matrix class. 4219 3) See if a good general converter is registered for the desired class 4220 (as of 6/27/03 only MATMPIADJ falls into this category). 4221 4) See if a good general converter is known for the current matrix. 4222 5) Use a really basic converter. 4223 */ 4224 4225 /* 0) See if newtype is a superclass of the current matrix. 4226 i.e mat is mpiaij and newtype is aij */ 4227 for (i = 0; i < 2; i++) { 4228 PetscCall(PetscStrncpy(convname, prefix[i], sizeof(convname))); 4229 PetscCall(PetscStrlcat(convname, newtype, sizeof(convname))); 4230 PetscCall(PetscStrcmp(convname, ((PetscObject)mat)->type_name, &flg)); 4231 PetscCall(PetscInfo(mat, "Check superclass %s %s -> %d\n", convname, ((PetscObject)mat)->type_name, flg)); 4232 if (flg) { 4233 if (reuse == MAT_INPLACE_MATRIX) { 4234 PetscCall(PetscInfo(mat, "Early return\n")); 4235 PetscFunctionReturn(0); 4236 } else if (reuse == MAT_INITIAL_MATRIX && mat->ops->duplicate) { 4237 PetscCall(PetscInfo(mat, "Calling MatDuplicate\n")); 4238 PetscUseTypeMethod(mat, duplicate, MAT_COPY_VALUES, M); 4239 PetscFunctionReturn(0); 4240 } else if (reuse == MAT_REUSE_MATRIX && mat->ops->copy) { 4241 PetscCall(PetscInfo(mat, "Calling MatCopy\n")); 4242 PetscCall(MatCopy(mat, *M, SAME_NONZERO_PATTERN)); 4243 PetscFunctionReturn(0); 4244 } 4245 } 4246 } 4247 /* 1) See if a specialized converter is known to the current matrix and the desired class */ 4248 for (i = 0; i < 3; i++) { 4249 PetscCall(PetscStrncpy(convname, "MatConvert_", sizeof(convname))); 4250 PetscCall(PetscStrlcat(convname, ((PetscObject)mat)->type_name, sizeof(convname))); 4251 PetscCall(PetscStrlcat(convname, "_", sizeof(convname))); 4252 PetscCall(PetscStrlcat(convname, prefix[i], sizeof(convname))); 4253 PetscCall(PetscStrlcat(convname, issame ? ((PetscObject)mat)->type_name : newtype, sizeof(convname))); 4254 PetscCall(PetscStrlcat(convname, "_C", sizeof(convname))); 4255 PetscCall(PetscObjectQueryFunction((PetscObject)mat, convname, &conv)); 4256 PetscCall(PetscInfo(mat, "Check specialized (1) %s (%s) -> %d\n", convname, ((PetscObject)mat)->type_name, !!conv)); 4257 if (conv) goto foundconv; 4258 } 4259 4260 /* 2) See if a specialized converter is known to the desired matrix class. */ 4261 PetscCall(MatCreate(PetscObjectComm((PetscObject)mat), &B)); 4262 PetscCall(MatSetSizes(B, mat->rmap->n, mat->cmap->n, mat->rmap->N, mat->cmap->N)); 4263 PetscCall(MatSetType(B, newtype)); 4264 for (i = 0; i < 3; i++) { 4265 PetscCall(PetscStrncpy(convname, "MatConvert_", sizeof(convname))); 4266 PetscCall(PetscStrlcat(convname, ((PetscObject)mat)->type_name, sizeof(convname))); 4267 PetscCall(PetscStrlcat(convname, "_", sizeof(convname))); 4268 PetscCall(PetscStrlcat(convname, prefix[i], sizeof(convname))); 4269 PetscCall(PetscStrlcat(convname, newtype, sizeof(convname))); 4270 PetscCall(PetscStrlcat(convname, "_C", sizeof(convname))); 4271 PetscCall(PetscObjectQueryFunction((PetscObject)B, convname, &conv)); 4272 PetscCall(PetscInfo(mat, "Check specialized (2) %s (%s) -> %d\n", convname, ((PetscObject)B)->type_name, !!conv)); 4273 if (conv) { 4274 PetscCall(MatDestroy(&B)); 4275 goto foundconv; 4276 } 4277 } 4278 4279 /* 3) See if a good general converter is registered for the desired class */ 4280 conv = B->ops->convertfrom; 4281 PetscCall(PetscInfo(mat, "Check convertfrom (%s) -> %d\n", ((PetscObject)B)->type_name, !!conv)); 4282 PetscCall(MatDestroy(&B)); 4283 if (conv) goto foundconv; 4284 4285 /* 4) See if a good general converter is known for the current matrix */ 4286 if (mat->ops->convert) conv = mat->ops->convert; 4287 PetscCall(PetscInfo(mat, "Check general convert (%s) -> %d\n", ((PetscObject)mat)->type_name, !!conv)); 4288 if (conv) goto foundconv; 4289 4290 /* 5) Use a really basic converter. */ 4291 PetscCall(PetscInfo(mat, "Using MatConvert_Basic\n")); 4292 conv = MatConvert_Basic; 4293 4294 foundconv: 4295 PetscCall(PetscLogEventBegin(MAT_Convert, mat, 0, 0, 0)); 4296 PetscCall((*conv)(mat, newtype, reuse, M)); 4297 if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) { 4298 /* the block sizes must be same if the mappings are copied over */ 4299 (*M)->rmap->bs = mat->rmap->bs; 4300 (*M)->cmap->bs = mat->cmap->bs; 4301 PetscCall(PetscObjectReference((PetscObject)mat->rmap->mapping)); 4302 PetscCall(PetscObjectReference((PetscObject)mat->cmap->mapping)); 4303 (*M)->rmap->mapping = mat->rmap->mapping; 4304 (*M)->cmap->mapping = mat->cmap->mapping; 4305 } 4306 (*M)->stencil.dim = mat->stencil.dim; 4307 (*M)->stencil.noc = mat->stencil.noc; 4308 for (i = 0; i <= mat->stencil.dim; i++) { 4309 (*M)->stencil.dims[i] = mat->stencil.dims[i]; 4310 (*M)->stencil.starts[i] = mat->stencil.starts[i]; 4311 } 4312 PetscCall(PetscLogEventEnd(MAT_Convert, mat, 0, 0, 0)); 4313 } 4314 PetscCall(PetscObjectStateIncrease((PetscObject)*M)); 4315 4316 /* Copy Mat options */ 4317 if (issymmetric == PETSC_BOOL3_TRUE) PetscCall(MatSetOption(*M, MAT_SYMMETRIC, PETSC_TRUE)); 4318 else if (issymmetric == PETSC_BOOL3_FALSE) PetscCall(MatSetOption(*M, MAT_SYMMETRIC, PETSC_FALSE)); 4319 if (ishermitian == PETSC_BOOL3_TRUE) PetscCall(MatSetOption(*M, MAT_HERMITIAN, PETSC_TRUE)); 4320 else if (ishermitian == PETSC_BOOL3_FALSE) PetscCall(MatSetOption(*M, MAT_HERMITIAN, PETSC_FALSE)); 4321 PetscFunctionReturn(0); 4322 } 4323 4324 /*@C 4325 MatFactorGetSolverType - Returns name of the package providing the factorization routines 4326 4327 Not Collective 4328 4329 Input Parameter: 4330 . mat - the matrix, must be a factored matrix 4331 4332 Output Parameter: 4333 . type - the string name of the package (do not free this string) 4334 4335 Notes: 4336 In Fortran you pass in a empty string and the package name will be copied into it. 4337 (Make sure the string is long enough) 4338 4339 Level: intermediate 4340 4341 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()` 4342 @*/ 4343 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type) { 4344 PetscErrorCode (*conv)(Mat, MatSolverType *); 4345 4346 PetscFunctionBegin; 4347 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4348 PetscValidType(mat, 1); 4349 PetscValidPointer(type, 2); 4350 PetscCheck(mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Only for factored matrix"); 4351 PetscCall(PetscObjectQueryFunction((PetscObject)mat, "MatFactorGetSolverType_C", &conv)); 4352 if (conv) PetscCall((*conv)(mat, type)); 4353 else *type = MATSOLVERPETSC; 4354 PetscFunctionReturn(0); 4355 } 4356 4357 typedef struct _MatSolverTypeForSpecifcType *MatSolverTypeForSpecifcType; 4358 struct _MatSolverTypeForSpecifcType { 4359 MatType mtype; 4360 /* no entry for MAT_FACTOR_NONE */ 4361 PetscErrorCode (*createfactor[MAT_FACTOR_NUM_TYPES - 1])(Mat, MatFactorType, Mat *); 4362 MatSolverTypeForSpecifcType next; 4363 }; 4364 4365 typedef struct _MatSolverTypeHolder *MatSolverTypeHolder; 4366 struct _MatSolverTypeHolder { 4367 char *name; 4368 MatSolverTypeForSpecifcType handlers; 4369 MatSolverTypeHolder next; 4370 }; 4371 4372 static MatSolverTypeHolder MatSolverTypeHolders = NULL; 4373 4374 /*@C 4375 MatSolverTypeRegister - Registers a MatSolverType that works for a particular matrix type 4376 4377 Input Parameters: 4378 + package - name of the package, for example petsc or superlu 4379 . mtype - the matrix type that works with this package 4380 . ftype - the type of factorization supported by the package 4381 - createfactor - routine that will create the factored matrix ready to be used 4382 4383 Level: intermediate 4384 4385 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()` 4386 @*/ 4387 PetscErrorCode MatSolverTypeRegister(MatSolverType package, MatType mtype, MatFactorType ftype, PetscErrorCode (*createfactor)(Mat, MatFactorType, Mat *)) { 4388 MatSolverTypeHolder next = MatSolverTypeHolders, prev = NULL; 4389 PetscBool flg; 4390 MatSolverTypeForSpecifcType inext, iprev = NULL; 4391 4392 PetscFunctionBegin; 4393 PetscCall(MatInitializePackage()); 4394 if (!next) { 4395 PetscCall(PetscNew(&MatSolverTypeHolders)); 4396 PetscCall(PetscStrallocpy(package, &MatSolverTypeHolders->name)); 4397 PetscCall(PetscNew(&MatSolverTypeHolders->handlers)); 4398 PetscCall(PetscStrallocpy(mtype, (char **)&MatSolverTypeHolders->handlers->mtype)); 4399 MatSolverTypeHolders->handlers->createfactor[(int)ftype - 1] = createfactor; 4400 PetscFunctionReturn(0); 4401 } 4402 while (next) { 4403 PetscCall(PetscStrcasecmp(package, next->name, &flg)); 4404 if (flg) { 4405 PetscCheck(next->handlers, PETSC_COMM_SELF, PETSC_ERR_PLIB, "MatSolverTypeHolder is missing handlers"); 4406 inext = next->handlers; 4407 while (inext) { 4408 PetscCall(PetscStrcasecmp(mtype, inext->mtype, &flg)); 4409 if (flg) { 4410 inext->createfactor[(int)ftype - 1] = createfactor; 4411 PetscFunctionReturn(0); 4412 } 4413 iprev = inext; 4414 inext = inext->next; 4415 } 4416 PetscCall(PetscNew(&iprev->next)); 4417 PetscCall(PetscStrallocpy(mtype, (char **)&iprev->next->mtype)); 4418 iprev->next->createfactor[(int)ftype - 1] = createfactor; 4419 PetscFunctionReturn(0); 4420 } 4421 prev = next; 4422 next = next->next; 4423 } 4424 PetscCall(PetscNew(&prev->next)); 4425 PetscCall(PetscStrallocpy(package, &prev->next->name)); 4426 PetscCall(PetscNew(&prev->next->handlers)); 4427 PetscCall(PetscStrallocpy(mtype, (char **)&prev->next->handlers->mtype)); 4428 prev->next->handlers->createfactor[(int)ftype - 1] = createfactor; 4429 PetscFunctionReturn(0); 4430 } 4431 4432 /*@C 4433 MatSolverTypeGet - Gets the function that creates the factor matrix if it exist 4434 4435 Input Parameters: 4436 + type - name of the package, for example petsc or superlu 4437 . ftype - the type of factorization supported by the type 4438 - mtype - the matrix type that works with this type 4439 4440 Output Parameters: 4441 + foundtype - PETSC_TRUE if the type was registered 4442 . foundmtype - PETSC_TRUE if the type supports the requested mtype 4443 - createfactor - routine that will create the factored matrix ready to be used or NULL if not found 4444 4445 Level: intermediate 4446 4447 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatSolverTypeRegister()`, `MatGetFactor()` 4448 @*/ 4449 PetscErrorCode MatSolverTypeGet(MatSolverType type, MatType mtype, MatFactorType ftype, PetscBool *foundtype, PetscBool *foundmtype, PetscErrorCode (**createfactor)(Mat, MatFactorType, Mat *)) { 4450 MatSolverTypeHolder next = MatSolverTypeHolders; 4451 PetscBool flg; 4452 MatSolverTypeForSpecifcType inext; 4453 4454 PetscFunctionBegin; 4455 if (foundtype) *foundtype = PETSC_FALSE; 4456 if (foundmtype) *foundmtype = PETSC_FALSE; 4457 if (createfactor) *createfactor = NULL; 4458 4459 if (type) { 4460 while (next) { 4461 PetscCall(PetscStrcasecmp(type, next->name, &flg)); 4462 if (flg) { 4463 if (foundtype) *foundtype = PETSC_TRUE; 4464 inext = next->handlers; 4465 while (inext) { 4466 PetscCall(PetscStrbeginswith(mtype, inext->mtype, &flg)); 4467 if (flg) { 4468 if (foundmtype) *foundmtype = PETSC_TRUE; 4469 if (createfactor) *createfactor = inext->createfactor[(int)ftype - 1]; 4470 PetscFunctionReturn(0); 4471 } 4472 inext = inext->next; 4473 } 4474 } 4475 next = next->next; 4476 } 4477 } else { 4478 while (next) { 4479 inext = next->handlers; 4480 while (inext) { 4481 PetscCall(PetscStrcmp(mtype, inext->mtype, &flg)); 4482 if (flg && inext->createfactor[(int)ftype - 1]) { 4483 if (foundtype) *foundtype = PETSC_TRUE; 4484 if (foundmtype) *foundmtype = PETSC_TRUE; 4485 if (createfactor) *createfactor = inext->createfactor[(int)ftype - 1]; 4486 PetscFunctionReturn(0); 4487 } 4488 inext = inext->next; 4489 } 4490 next = next->next; 4491 } 4492 /* try with base classes inext->mtype */ 4493 next = MatSolverTypeHolders; 4494 while (next) { 4495 inext = next->handlers; 4496 while (inext) { 4497 PetscCall(PetscStrbeginswith(mtype, inext->mtype, &flg)); 4498 if (flg && inext->createfactor[(int)ftype - 1]) { 4499 if (foundtype) *foundtype = PETSC_TRUE; 4500 if (foundmtype) *foundmtype = PETSC_TRUE; 4501 if (createfactor) *createfactor = inext->createfactor[(int)ftype - 1]; 4502 PetscFunctionReturn(0); 4503 } 4504 inext = inext->next; 4505 } 4506 next = next->next; 4507 } 4508 } 4509 PetscFunctionReturn(0); 4510 } 4511 4512 PetscErrorCode MatSolverTypeDestroy(void) { 4513 MatSolverTypeHolder next = MatSolverTypeHolders, prev; 4514 MatSolverTypeForSpecifcType inext, iprev; 4515 4516 PetscFunctionBegin; 4517 while (next) { 4518 PetscCall(PetscFree(next->name)); 4519 inext = next->handlers; 4520 while (inext) { 4521 PetscCall(PetscFree(inext->mtype)); 4522 iprev = inext; 4523 inext = inext->next; 4524 PetscCall(PetscFree(iprev)); 4525 } 4526 prev = next; 4527 next = next->next; 4528 PetscCall(PetscFree(prev)); 4529 } 4530 MatSolverTypeHolders = NULL; 4531 PetscFunctionReturn(0); 4532 } 4533 4534 /*@C 4535 MatFactorGetCanUseOrdering - Indicates if the factorization can use the ordering provided in MatLUFactorSymbolic(), MatCholeskyFactorSymbolic() 4536 4537 Logically Collective on Mat 4538 4539 Input Parameters: 4540 . mat - the matrix 4541 4542 Output Parameters: 4543 . flg - PETSC_TRUE if uses the ordering 4544 4545 Notes: 4546 Most internal PETSc factorizations use the ordering passed to the factorization routine but external 4547 packages do not, thus we want to skip generating the ordering when it is not needed or used. 4548 4549 Level: developer 4550 4551 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()` 4552 @*/ 4553 PetscErrorCode MatFactorGetCanUseOrdering(Mat mat, PetscBool *flg) { 4554 PetscFunctionBegin; 4555 *flg = mat->canuseordering; 4556 PetscFunctionReturn(0); 4557 } 4558 4559 /*@C 4560 MatFactorGetPreferredOrdering - The preferred ordering for a particular matrix factor object 4561 4562 Logically Collective on Mat 4563 4564 Input Parameters: 4565 . mat - the matrix 4566 4567 Output Parameters: 4568 . otype - the preferred type 4569 4570 Level: developer 4571 4572 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()` 4573 @*/ 4574 PetscErrorCode MatFactorGetPreferredOrdering(Mat mat, MatFactorType ftype, MatOrderingType *otype) { 4575 PetscFunctionBegin; 4576 *otype = mat->preferredordering[ftype]; 4577 PetscCheck(*otype, PETSC_COMM_SELF, PETSC_ERR_PLIB, "MatFactor did not have a preferred ordering"); 4578 PetscFunctionReturn(0); 4579 } 4580 4581 /*@C 4582 MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic() 4583 4584 Collective on Mat 4585 4586 Input Parameters: 4587 + mat - the matrix 4588 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4589 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4590 4591 Output Parameters: 4592 . f - the factor matrix used with MatXXFactorSymbolic() calls 4593 4594 Options Database Key: 4595 . -mat_factor_bind_factorization <host, device> - Where to do matrix factorization? Default is device (might consume more device memory. 4596 One can choose host to save device memory). Currently only supported with SEQAIJCUSPARSE matrices. 4597 4598 Notes: 4599 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4600 such as pastix, superlu, mumps etc. 4601 4602 PETSc must have been ./configure to use the external solver, using the option --download-package 4603 4604 Some of the packages have options for controlling the factorization, these are in the form -prefix_mat_packagename_packageoption 4605 where prefix is normally obtained from the calling `KSP`/`PC`. If `MatGetFactor()` is called directly one can set 4606 call `MatSetOptionsPrefixFactor()` on the originating matrix or `MatSetOptionsPrefix()` on the resulting factor matrix. 4607 4608 Developer Notes: 4609 This should actually be called MatCreateFactor() since it creates a new factor object 4610 4611 Level: intermediate 4612 4613 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatFactorGetCanUseOrdering()`, `MatSolverTypeRegister()` 4614 @*/ 4615 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type, MatFactorType ftype, Mat *f) { 4616 PetscBool foundtype, foundmtype; 4617 PetscErrorCode (*conv)(Mat, MatFactorType, Mat *); 4618 4619 PetscFunctionBegin; 4620 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4621 PetscValidType(mat, 1); 4622 4623 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 4624 MatCheckPreallocated(mat, 1); 4625 4626 PetscCall(MatSolverTypeGet(type, ((PetscObject)mat)->type_name, ftype, &foundtype, &foundmtype, &conv)); 4627 if (!foundtype) { 4628 if (type) { 4629 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], 4630 ((PetscObject)mat)->type_name, type); 4631 } else { 4632 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); 4633 } 4634 } 4635 PetscCheck(foundmtype, PetscObjectComm((PetscObject)mat), PETSC_ERR_MISSING_FACTOR, "MatSolverType %s does not support matrix type %s", type, ((PetscObject)mat)->type_name); 4636 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); 4637 4638 PetscCall((*conv)(mat, ftype, f)); 4639 if (mat->factorprefix) PetscCall(MatSetOptionsPrefix(*f, mat->factorprefix)); 4640 PetscFunctionReturn(0); 4641 } 4642 4643 /*@C 4644 MatGetFactorAvailable - Returns a a flag if matrix supports particular type and factor type 4645 4646 Not Collective 4647 4648 Input Parameters: 4649 + mat - the matrix 4650 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4651 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4652 4653 Output Parameter: 4654 . flg - PETSC_TRUE if the factorization is available 4655 4656 Notes: 4657 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4658 such as pastix, superlu, mumps etc. 4659 4660 PETSc must have been ./configure to use the external solver, using the option --download-package 4661 4662 Developer Notes: 4663 This should actually be called MatCreateFactorAvailable() since MatGetFactor() creates a new factor object 4664 4665 Level: intermediate 4666 4667 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactor()`, `MatSolverTypeRegister()` 4668 @*/ 4669 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type, MatFactorType ftype, PetscBool *flg) { 4670 PetscErrorCode (*gconv)(Mat, MatFactorType, Mat *); 4671 4672 PetscFunctionBegin; 4673 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4674 PetscValidType(mat, 1); 4675 PetscValidBoolPointer(flg, 4); 4676 4677 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 4678 MatCheckPreallocated(mat, 1); 4679 4680 PetscCall(MatSolverTypeGet(type, ((PetscObject)mat)->type_name, ftype, NULL, NULL, &gconv)); 4681 *flg = gconv ? PETSC_TRUE : PETSC_FALSE; 4682 PetscFunctionReturn(0); 4683 } 4684 4685 /*@ 4686 MatDuplicate - Duplicates a matrix including the non-zero structure. 4687 4688 Collective on Mat 4689 4690 Input Parameters: 4691 + mat - the matrix 4692 - op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN. 4693 See the manual page for MatDuplicateOption for an explanation of these options. 4694 4695 Output Parameter: 4696 . M - pointer to place new matrix 4697 4698 Level: intermediate 4699 4700 Notes: 4701 You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN. 4702 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. 4703 When original mat is a product of matrix operation, e.g., an output of MatMatMult() or MatCreateSubMatrix(), only the simple matrix data structure of mat is duplicated and the internal data structures created for the reuse of previous matrix operations are not duplicated. User should not use MatDuplicate() to create new matrix M if M is intended to be reused as the product of matrix operation. 4704 4705 .seealso: `MatCopy()`, `MatConvert()`, `MatDuplicateOption` 4706 @*/ 4707 PetscErrorCode MatDuplicate(Mat mat, MatDuplicateOption op, Mat *M) { 4708 Mat B; 4709 VecType vtype; 4710 PetscInt i; 4711 PetscObject dm; 4712 void (*viewf)(void); 4713 4714 PetscFunctionBegin; 4715 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4716 PetscValidType(mat, 1); 4717 PetscValidPointer(M, 3); 4718 PetscCheck(op != MAT_COPY_VALUES || mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "MAT_COPY_VALUES not allowed for unassembled matrix"); 4719 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 4720 MatCheckPreallocated(mat, 1); 4721 4722 *M = NULL; 4723 PetscCall(PetscLogEventBegin(MAT_Convert, mat, 0, 0, 0)); 4724 PetscUseTypeMethod(mat, duplicate, op, M); 4725 PetscCall(PetscLogEventEnd(MAT_Convert, mat, 0, 0, 0)); 4726 B = *M; 4727 4728 PetscCall(MatGetOperation(mat, MATOP_VIEW, &viewf)); 4729 if (viewf) PetscCall(MatSetOperation(B, MATOP_VIEW, viewf)); 4730 PetscCall(MatGetVecType(mat, &vtype)); 4731 PetscCall(MatSetVecType(B, vtype)); 4732 4733 B->stencil.dim = mat->stencil.dim; 4734 B->stencil.noc = mat->stencil.noc; 4735 for (i = 0; i <= mat->stencil.dim; i++) { 4736 B->stencil.dims[i] = mat->stencil.dims[i]; 4737 B->stencil.starts[i] = mat->stencil.starts[i]; 4738 } 4739 4740 B->nooffproczerorows = mat->nooffproczerorows; 4741 B->nooffprocentries = mat->nooffprocentries; 4742 4743 PetscCall(PetscObjectQuery((PetscObject)mat, "__PETSc_dm", &dm)); 4744 if (dm) PetscCall(PetscObjectCompose((PetscObject)B, "__PETSc_dm", dm)); 4745 PetscCall(PetscObjectStateIncrease((PetscObject)B)); 4746 PetscFunctionReturn(0); 4747 } 4748 4749 /*@ 4750 MatGetDiagonal - Gets the diagonal of a matrix. 4751 4752 Logically Collective on Mat 4753 4754 Input Parameters: 4755 + mat - the matrix 4756 - v - the vector for storing the diagonal 4757 4758 Output Parameter: 4759 . v - the diagonal of the matrix 4760 4761 Level: intermediate 4762 4763 Note: 4764 Currently only correct in parallel for square matrices. 4765 4766 .seealso: `MatGetRow()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMaxAbs()` 4767 @*/ 4768 PetscErrorCode MatGetDiagonal(Mat mat, Vec v) { 4769 PetscFunctionBegin; 4770 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4771 PetscValidType(mat, 1); 4772 PetscValidHeaderSpecific(v, VEC_CLASSID, 2); 4773 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 4774 MatCheckPreallocated(mat, 1); 4775 4776 PetscUseTypeMethod(mat, getdiagonal, v); 4777 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 4778 PetscFunctionReturn(0); 4779 } 4780 4781 /*@C 4782 MatGetRowMin - Gets the minimum value (of the real part) of each 4783 row of the matrix 4784 4785 Logically Collective on Mat 4786 4787 Input Parameter: 4788 . mat - the matrix 4789 4790 Output Parameters: 4791 + v - the vector for storing the maximums 4792 - idx - the indices of the column found for each row (optional) 4793 4794 Level: intermediate 4795 4796 Notes: 4797 The result of this call are the same as if one converted the matrix to dense format 4798 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4799 4800 This code is only implemented for a couple of matrix formats. 4801 4802 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMaxAbs()`, 4803 `MatGetRowMax()` 4804 @*/ 4805 PetscErrorCode MatGetRowMin(Mat mat, Vec v, PetscInt idx[]) { 4806 PetscFunctionBegin; 4807 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4808 PetscValidType(mat, 1); 4809 PetscValidHeaderSpecific(v, VEC_CLASSID, 2); 4810 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 4811 4812 if (!mat->cmap->N) { 4813 PetscCall(VecSet(v, PETSC_MAX_REAL)); 4814 if (idx) { 4815 PetscInt i, m = mat->rmap->n; 4816 for (i = 0; i < m; i++) idx[i] = -1; 4817 } 4818 } else { 4819 MatCheckPreallocated(mat, 1); 4820 } 4821 PetscUseTypeMethod(mat, getrowmin, v, idx); 4822 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 4823 PetscFunctionReturn(0); 4824 } 4825 4826 /*@C 4827 MatGetRowMinAbs - Gets the minimum value (in absolute value) of each 4828 row of the matrix 4829 4830 Logically Collective on Mat 4831 4832 Input Parameter: 4833 . mat - the matrix 4834 4835 Output Parameters: 4836 + v - the vector for storing the minimums 4837 - idx - the indices of the column found for each row (or NULL if not needed) 4838 4839 Level: intermediate 4840 4841 Notes: 4842 if a row is completely empty or has only 0.0 values then the idx[] value for that 4843 row is 0 (the first column). 4844 4845 This code is only implemented for a couple of matrix formats. 4846 4847 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMax()`, `MatGetRowMaxAbs()`, `MatGetRowMin()` 4848 @*/ 4849 PetscErrorCode MatGetRowMinAbs(Mat mat, Vec v, PetscInt idx[]) { 4850 PetscFunctionBegin; 4851 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4852 PetscValidType(mat, 1); 4853 PetscValidHeaderSpecific(v, VEC_CLASSID, 2); 4854 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 4855 PetscCheck(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 4856 4857 if (!mat->cmap->N) { 4858 PetscCall(VecSet(v, 0.0)); 4859 if (idx) { 4860 PetscInt i, m = mat->rmap->n; 4861 for (i = 0; i < m; i++) idx[i] = -1; 4862 } 4863 } else { 4864 MatCheckPreallocated(mat, 1); 4865 if (idx) PetscCall(PetscArrayzero(idx, mat->rmap->n)); 4866 PetscUseTypeMethod(mat, getrowminabs, v, idx); 4867 } 4868 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 4869 PetscFunctionReturn(0); 4870 } 4871 4872 /*@C 4873 MatGetRowMax - Gets the maximum value (of the real part) of each 4874 row of the matrix 4875 4876 Logically Collective on Mat 4877 4878 Input Parameter: 4879 . mat - the matrix 4880 4881 Output Parameters: 4882 + v - the vector for storing the maximums 4883 - idx - the indices of the column found for each row (optional) 4884 4885 Level: intermediate 4886 4887 Notes: 4888 The result of this call are the same as if one converted the matrix to dense format 4889 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4890 4891 This code is only implemented for a couple of matrix formats. 4892 4893 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMaxAbs()`, `MatGetRowMin()` 4894 @*/ 4895 PetscErrorCode MatGetRowMax(Mat mat, Vec v, PetscInt idx[]) { 4896 PetscFunctionBegin; 4897 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4898 PetscValidType(mat, 1); 4899 PetscValidHeaderSpecific(v, VEC_CLASSID, 2); 4900 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 4901 4902 if (!mat->cmap->N) { 4903 PetscCall(VecSet(v, PETSC_MIN_REAL)); 4904 if (idx) { 4905 PetscInt i, m = mat->rmap->n; 4906 for (i = 0; i < m; i++) idx[i] = -1; 4907 } 4908 } else { 4909 MatCheckPreallocated(mat, 1); 4910 PetscUseTypeMethod(mat, getrowmax, v, idx); 4911 } 4912 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 4913 PetscFunctionReturn(0); 4914 } 4915 4916 /*@C 4917 MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each 4918 row of the matrix 4919 4920 Logically Collective on Mat 4921 4922 Input Parameter: 4923 . mat - the matrix 4924 4925 Output Parameters: 4926 + v - the vector for storing the maximums 4927 - idx - the indices of the column found for each row (or NULL if not needed) 4928 4929 Level: intermediate 4930 4931 Notes: 4932 if a row is completely empty or has only 0.0 values then the idx[] value for that 4933 row is 0 (the first column). 4934 4935 This code is only implemented for a couple of matrix formats. 4936 4937 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMax()`, `MatGetRowMin()` 4938 @*/ 4939 PetscErrorCode MatGetRowMaxAbs(Mat mat, Vec v, PetscInt idx[]) { 4940 PetscFunctionBegin; 4941 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4942 PetscValidType(mat, 1); 4943 PetscValidHeaderSpecific(v, VEC_CLASSID, 2); 4944 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 4945 4946 if (!mat->cmap->N) { 4947 PetscCall(VecSet(v, 0.0)); 4948 if (idx) { 4949 PetscInt i, m = mat->rmap->n; 4950 for (i = 0; i < m; i++) idx[i] = -1; 4951 } 4952 } else { 4953 MatCheckPreallocated(mat, 1); 4954 if (idx) PetscCall(PetscArrayzero(idx, mat->rmap->n)); 4955 PetscUseTypeMethod(mat, getrowmaxabs, v, idx); 4956 } 4957 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 4958 PetscFunctionReturn(0); 4959 } 4960 4961 /*@ 4962 MatGetRowSum - Gets the sum of each row of the matrix 4963 4964 Logically or Neighborhood Collective on Mat 4965 4966 Input Parameters: 4967 . mat - the matrix 4968 4969 Output Parameter: 4970 . v - the vector for storing the sum of rows 4971 4972 Level: intermediate 4973 4974 Notes: 4975 This code is slow since it is not currently specialized for different formats 4976 4977 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMax()`, `MatGetRowMin()` 4978 @*/ 4979 PetscErrorCode MatGetRowSum(Mat mat, Vec v) { 4980 Vec ones; 4981 4982 PetscFunctionBegin; 4983 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 4984 PetscValidType(mat, 1); 4985 PetscValidHeaderSpecific(v, VEC_CLASSID, 2); 4986 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 4987 MatCheckPreallocated(mat, 1); 4988 PetscCall(MatCreateVecs(mat, &ones, NULL)); 4989 PetscCall(VecSet(ones, 1.)); 4990 PetscCall(MatMult(mat, ones, v)); 4991 PetscCall(VecDestroy(&ones)); 4992 PetscFunctionReturn(0); 4993 } 4994 4995 /*@ 4996 MatTransposeSetPrecursor - Set the matrix from which the second matrix will receive numerical transpose data with a call to `MatTranspose`(A,`MAT_REUSE_MATRIX`,&B) 4997 when B was not obtained with `MatTranspose`(A,`MAT_INITIAL_MATRIX`,&B) 4998 4999 Collective on Mat 5000 5001 Input Parameter: 5002 . mat - the matrix to provide the transpose 5003 5004 Output Parameter: 5005 . 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 5006 5007 Level: advanced 5008 5009 Note: 5010 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 5011 routine allows bypassing that call. 5012 5013 .seealso: `MatTransposeSymbolic()`, `MatTranspose()`, `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse`, `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, `MAT_INPLACE_MATRIX` 5014 @*/ 5015 PetscErrorCode MatTransposeSetPrecursor(Mat mat, Mat B) { 5016 PetscContainer rB = NULL; 5017 MatParentState *rb = NULL; 5018 5019 PetscFunctionBegin; 5020 PetscCall(PetscNew(&rb)); 5021 rb->id = ((PetscObject)mat)->id; 5022 rb->state = 0; 5023 PetscCall(MatGetNonzeroState(mat, &rb->nonzerostate)); 5024 PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)B), &rB)); 5025 PetscCall(PetscContainerSetPointer(rB, rb)); 5026 PetscCall(PetscContainerSetUserDestroy(rB, PetscContainerUserDestroyDefault)); 5027 PetscCall(PetscObjectCompose((PetscObject)B, "MatTransposeParent", (PetscObject)rB)); 5028 PetscCall(PetscObjectDereference((PetscObject)rB)); 5029 PetscFunctionReturn(0); 5030 } 5031 5032 /*@ 5033 MatTranspose - Computes an in-place or out-of-place transpose of a matrix. 5034 5035 Collective on Mat 5036 5037 Input Parameters: 5038 + mat - the matrix to transpose 5039 - reuse - either `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, or `MAT_INPLACE_MATRIX` 5040 5041 Output Parameter: 5042 . B - the transpose 5043 5044 Notes: 5045 If you use `MAT_INPLACE_MATRIX` then you must pass in &mat for B 5046 5047 `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 5048 transpose, call `MatTransposeSetPrecursor`(mat,B) before calling this routine. 5049 5050 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. 5051 5052 Consider using `MatCreateTranspose()` instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed. 5053 5054 If mat is unchanged from the last call this function returns immediately without recomputing the result 5055 5056 If you only need the symbolic transpose, and not the numerical values, use `MatTransposeSymbolic()` 5057 5058 Level: intermediate 5059 5060 .seealso: `MatTransposeSetPrecursor()`, `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse`, `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, `MAT_INPLACE_MATRIX`, 5061 `MatTransposeSymbolic()` 5062 @*/ 5063 PetscErrorCode MatTranspose(Mat mat, MatReuse reuse, Mat *B) { 5064 PetscContainer rB = NULL; 5065 MatParentState *rb = NULL; 5066 5067 PetscFunctionBegin; 5068 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5069 PetscValidType(mat, 1); 5070 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 5071 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 5072 PetscCheck(reuse != MAT_INPLACE_MATRIX || mat == *B, PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "MAT_INPLACE_MATRIX requires last matrix to match first"); 5073 PetscCheck(reuse != MAT_REUSE_MATRIX || mat != *B, PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Perhaps you mean MAT_INPLACE_MATRIX"); 5074 MatCheckPreallocated(mat, 1); 5075 if (reuse == MAT_REUSE_MATRIX) { 5076 PetscCall(PetscObjectQuery((PetscObject)*B, "MatTransposeParent", (PetscObject *)&rB)); 5077 PetscCheck(rB, PetscObjectComm((PetscObject)*B), PETSC_ERR_ARG_WRONG, "Reuse matrix used was not generated from call to MatTranspose(). Suggest MatTransposeSetPrecursor()."); 5078 PetscCall(PetscContainerGetPointer(rB, (void **)&rb)); 5079 PetscCheck(rb->id == ((PetscObject)mat)->id, PetscObjectComm((PetscObject)*B), PETSC_ERR_ARG_WRONG, "Reuse matrix used was not generated from input matrix"); 5080 if (rb->state == ((PetscObject)mat)->state) PetscFunctionReturn(0); 5081 } 5082 5083 PetscCall(PetscLogEventBegin(MAT_Transpose, mat, 0, 0, 0)); 5084 if (reuse != MAT_INPLACE_MATRIX || mat->symmetric != PETSC_BOOL3_TRUE) { 5085 PetscUseTypeMethod(mat, transpose, reuse, B); 5086 PetscCall(PetscObjectStateIncrease((PetscObject)*B)); 5087 } 5088 PetscCall(PetscLogEventEnd(MAT_Transpose, mat, 0, 0, 0)); 5089 5090 if (reuse == MAT_INITIAL_MATRIX) PetscCall(MatTransposeSetPrecursor(mat, *B)); 5091 if (reuse != MAT_INPLACE_MATRIX) { 5092 PetscCall(PetscObjectQuery((PetscObject)*B, "MatTransposeParent", (PetscObject *)&rB)); 5093 PetscCall(PetscContainerGetPointer(rB, (void **)&rb)); 5094 rb->state = ((PetscObject)mat)->state; 5095 rb->nonzerostate = mat->nonzerostate; 5096 } 5097 PetscFunctionReturn(0); 5098 } 5099 5100 /*@ 5101 MatTransposeSymbolic - Computes the symbolic part of the transpose of a matrix. 5102 5103 Collective on Mat 5104 5105 Input Parameters: 5106 . A - the matrix to transpose 5107 5108 Output Parameter: 5109 . 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 5110 numerical portion. 5111 5112 Level: intermediate 5113 5114 Note: 5115 This is not supported for many matrix types, use `MatTranspose()` in those cases 5116 5117 .seealso: `MatTransposeSetPrecursor()`, `MatTranspose()`, `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse`, `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, `MAT_INPLACE_MATRIX` 5118 @*/ 5119 PetscErrorCode MatTransposeSymbolic(Mat A, Mat *B) { 5120 PetscFunctionBegin; 5121 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 5122 PetscValidType(A, 1); 5123 PetscCheck(A->assembled, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 5124 PetscCheck(!A->factortype, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 5125 PetscCheck(A->ops->transposesymbolic, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Mat type %s", ((PetscObject)A)->type_name); 5126 PetscCall(PetscLogEventBegin(MAT_Transpose, A, 0, 0, 0)); 5127 PetscCall((*A->ops->transposesymbolic)(A, B)); 5128 PetscCall(PetscLogEventEnd(MAT_Transpose, A, 0, 0, 0)); 5129 5130 PetscCall(MatTransposeSetPrecursor(A, *B)); 5131 PetscFunctionReturn(0); 5132 } 5133 5134 PetscErrorCode MatTransposeCheckNonzeroState_Private(Mat A, Mat B) { 5135 PetscContainer rB; 5136 MatParentState *rb; 5137 5138 PetscFunctionBegin; 5139 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 5140 PetscValidType(A, 1); 5141 PetscCheck(A->assembled, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 5142 PetscCheck(!A->factortype, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 5143 PetscCall(PetscObjectQuery((PetscObject)B, "MatTransposeParent", (PetscObject *)&rB)); 5144 PetscCheck(rB, PetscObjectComm((PetscObject)B), PETSC_ERR_ARG_WRONG, "Reuse matrix used was not generated from call to MatTranspose()"); 5145 PetscCall(PetscContainerGetPointer(rB, (void **)&rb)); 5146 PetscCheck(rb->id == ((PetscObject)A)->id, PetscObjectComm((PetscObject)B), PETSC_ERR_ARG_WRONG, "Reuse matrix used was not generated from input matrix"); 5147 PetscCheck(rb->nonzerostate == A->nonzerostate, PetscObjectComm((PetscObject)B), PETSC_ERR_ARG_WRONGSTATE, "Reuse matrix has changed nonzero structure"); 5148 PetscFunctionReturn(0); 5149 } 5150 5151 /*@ 5152 MatIsTranspose - Test whether a matrix is another one's transpose, 5153 or its own, in which case it tests symmetry. 5154 5155 Collective on Mat 5156 5157 Input Parameters: 5158 + A - the matrix to test 5159 - B - the matrix to test against, this can equal the first parameter 5160 5161 Output Parameters: 5162 . flg - the result 5163 5164 Notes: 5165 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 5166 has a running time of the order of the number of nonzeros; the parallel 5167 test involves parallel copies of the block-offdiagonal parts of the matrix. 5168 5169 Level: intermediate 5170 5171 .seealso: `MatTranspose()`, `MatIsSymmetric()`, `MatIsHermitian()` 5172 @*/ 5173 PetscErrorCode MatIsTranspose(Mat A, Mat B, PetscReal tol, PetscBool *flg) { 5174 PetscErrorCode (*f)(Mat, Mat, PetscReal, PetscBool *), (*g)(Mat, Mat, PetscReal, PetscBool *); 5175 5176 PetscFunctionBegin; 5177 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 5178 PetscValidHeaderSpecific(B, MAT_CLASSID, 2); 5179 PetscValidBoolPointer(flg, 4); 5180 PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatIsTranspose_C", &f)); 5181 PetscCall(PetscObjectQueryFunction((PetscObject)B, "MatIsTranspose_C", &g)); 5182 *flg = PETSC_FALSE; 5183 if (f && g) { 5184 PetscCheck(f == g, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_NOTSAMETYPE, "Matrices do not have the same comparator for symmetry test"); 5185 PetscCall((*f)(A, B, tol, flg)); 5186 } else { 5187 MatType mattype; 5188 5189 PetscCall(MatGetType(f ? B : A, &mattype)); 5190 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Matrix of type %s does not support checking for transpose", mattype); 5191 } 5192 PetscFunctionReturn(0); 5193 } 5194 5195 /*@ 5196 MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate. 5197 5198 Collective on Mat 5199 5200 Input Parameters: 5201 + mat - the matrix to transpose and complex conjugate 5202 - reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX 5203 5204 Output Parameter: 5205 . B - the Hermitian 5206 5207 Level: intermediate 5208 5209 .seealso: `MatTranspose()`, `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse` 5210 @*/ 5211 PetscErrorCode MatHermitianTranspose(Mat mat, MatReuse reuse, Mat *B) { 5212 PetscFunctionBegin; 5213 PetscCall(MatTranspose(mat, reuse, B)); 5214 #if defined(PETSC_USE_COMPLEX) 5215 PetscCall(MatConjugate(*B)); 5216 #endif 5217 PetscFunctionReturn(0); 5218 } 5219 5220 /*@ 5221 MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose, 5222 5223 Collective on Mat 5224 5225 Input Parameters: 5226 + A - the matrix to test 5227 - B - the matrix to test against, this can equal the first parameter 5228 5229 Output Parameters: 5230 . flg - the result 5231 5232 Notes: 5233 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 5234 has a running time of the order of the number of nonzeros; the parallel 5235 test involves parallel copies of the block-offdiagonal parts of the matrix. 5236 5237 Level: intermediate 5238 5239 .seealso: `MatTranspose()`, `MatIsSymmetric()`, `MatIsHermitian()`, `MatIsTranspose()` 5240 @*/ 5241 PetscErrorCode MatIsHermitianTranspose(Mat A, Mat B, PetscReal tol, PetscBool *flg) { 5242 PetscErrorCode (*f)(Mat, Mat, PetscReal, PetscBool *), (*g)(Mat, Mat, PetscReal, PetscBool *); 5243 5244 PetscFunctionBegin; 5245 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 5246 PetscValidHeaderSpecific(B, MAT_CLASSID, 2); 5247 PetscValidBoolPointer(flg, 4); 5248 PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatIsHermitianTranspose_C", &f)); 5249 PetscCall(PetscObjectQueryFunction((PetscObject)B, "MatIsHermitianTranspose_C", &g)); 5250 if (f && g) { 5251 PetscCheck(f != g, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_NOTSAMETYPE, "Matrices do not have the same comparator for Hermitian test"); 5252 PetscCall((*f)(A, B, tol, flg)); 5253 } 5254 PetscFunctionReturn(0); 5255 } 5256 5257 /*@ 5258 MatPermute - Creates a new matrix with rows and columns permuted from the 5259 original. 5260 5261 Collective on Mat 5262 5263 Input Parameters: 5264 + mat - the matrix to permute 5265 . row - row permutation, each processor supplies only the permutation for its rows 5266 - col - column permutation, each processor supplies only the permutation for its columns 5267 5268 Output Parameters: 5269 . B - the permuted matrix 5270 5271 Level: advanced 5272 5273 Note: 5274 The index sets map from row/col of permuted matrix to row/col of original matrix. 5275 The index sets should be on the same communicator as Mat and have the same local sizes. 5276 5277 Developer Note: 5278 If you want to implement MatPermute for a matrix type, and your approach doesn't 5279 exploit the fact that row and col are permutations, consider implementing the 5280 more general MatCreateSubMatrix() instead. 5281 5282 .seealso: `MatGetOrdering()`, `ISAllGather()` 5283 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 Mat 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 @*/ 5323 PetscErrorCode MatEqual(Mat A, Mat B, PetscBool *flg) { 5324 PetscFunctionBegin; 5325 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 5326 PetscValidHeaderSpecific(B, MAT_CLASSID, 2); 5327 PetscValidType(A, 1); 5328 PetscValidType(B, 2); 5329 PetscValidBoolPointer(flg, 3); 5330 PetscCheckSameComm(A, 1, B, 2); 5331 MatCheckPreallocated(A, 1); 5332 MatCheckPreallocated(B, 2); 5333 PetscCheck(A->assembled, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 5334 PetscCheck(B->assembled, PetscObjectComm((PetscObject)B), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 5335 PetscCheck(A->rmap->N == B->rmap->N && A->cmap->N == B->cmap->N, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_SIZ, "Mat A,Mat B: global dim %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT, A->rmap->N, B->rmap->N, A->cmap->N, 5336 B->cmap->N); 5337 if (A->ops->equal && A->ops->equal == B->ops->equal) { 5338 PetscUseTypeMethod(A, equal, B, flg); 5339 } else { 5340 PetscCall(MatMultEqual(A, B, 10, flg)); 5341 } 5342 PetscFunctionReturn(0); 5343 } 5344 5345 /*@ 5346 MatDiagonalScale - Scales a matrix on the left and right by diagonal 5347 matrices that are stored as vectors. Either of the two scaling 5348 matrices can be NULL. 5349 5350 Collective on Mat 5351 5352 Input Parameters: 5353 + mat - the matrix to be scaled 5354 . l - the left scaling vector (or NULL) 5355 - r - the right scaling vector (or NULL) 5356 5357 Notes: 5358 MatDiagonalScale() computes A = LAR, where 5359 L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector) 5360 The L scales the rows of the matrix, the R scales the columns of the matrix. 5361 5362 Level: intermediate 5363 5364 .seealso: `MatScale()`, `MatShift()`, `MatDiagonalSet()` 5365 @*/ 5366 PetscErrorCode MatDiagonalScale(Mat mat, Vec l, Vec r) { 5367 PetscFunctionBegin; 5368 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5369 PetscValidType(mat, 1); 5370 if (l) { 5371 PetscValidHeaderSpecific(l, VEC_CLASSID, 2); 5372 PetscCheckSameComm(mat, 1, l, 2); 5373 } 5374 if (r) { 5375 PetscValidHeaderSpecific(r, VEC_CLASSID, 3); 5376 PetscCheckSameComm(mat, 1, r, 3); 5377 } 5378 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 5379 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 5380 MatCheckPreallocated(mat, 1); 5381 if (!l && !r) PetscFunctionReturn(0); 5382 5383 PetscCall(PetscLogEventBegin(MAT_Scale, mat, 0, 0, 0)); 5384 PetscUseTypeMethod(mat, diagonalscale, l, r); 5385 PetscCall(PetscLogEventEnd(MAT_Scale, mat, 0, 0, 0)); 5386 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5387 if (l != r) mat->symmetric = PETSC_BOOL3_FALSE; 5388 PetscFunctionReturn(0); 5389 } 5390 5391 /*@ 5392 MatScale - Scales all elements of a matrix by a given number. 5393 5394 Logically Collective on Mat 5395 5396 Input Parameters: 5397 + mat - the matrix to be scaled 5398 - a - the scaling value 5399 5400 Output Parameter: 5401 . mat - the scaled matrix 5402 5403 Level: intermediate 5404 5405 .seealso: `MatDiagonalScale()` 5406 @*/ 5407 PetscErrorCode MatScale(Mat mat, PetscScalar a) { 5408 PetscFunctionBegin; 5409 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5410 PetscValidType(mat, 1); 5411 PetscCheck(a == (PetscScalar)1.0 || mat->ops->scale, PETSC_COMM_SELF, PETSC_ERR_SUP, "Mat type %s", ((PetscObject)mat)->type_name); 5412 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 5413 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 5414 PetscValidLogicalCollectiveScalar(mat, a, 2); 5415 MatCheckPreallocated(mat, 1); 5416 5417 PetscCall(PetscLogEventBegin(MAT_Scale, mat, 0, 0, 0)); 5418 if (a != (PetscScalar)1.0) { 5419 PetscUseTypeMethod(mat, scale, a); 5420 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5421 } 5422 PetscCall(PetscLogEventEnd(MAT_Scale, mat, 0, 0, 0)); 5423 PetscFunctionReturn(0); 5424 } 5425 5426 /*@ 5427 MatNorm - Calculates various norms of a matrix. 5428 5429 Collective on Mat 5430 5431 Input Parameters: 5432 + mat - the matrix 5433 - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY 5434 5435 Output Parameter: 5436 . nrm - the resulting norm 5437 5438 Level: intermediate 5439 5440 @*/ 5441 PetscErrorCode MatNorm(Mat mat, NormType type, PetscReal *nrm) { 5442 PetscFunctionBegin; 5443 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5444 PetscValidType(mat, 1); 5445 PetscValidRealPointer(nrm, 3); 5446 5447 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 5448 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 5449 MatCheckPreallocated(mat, 1); 5450 5451 PetscUseTypeMethod(mat, norm, type, nrm); 5452 PetscFunctionReturn(0); 5453 } 5454 5455 /* 5456 This variable is used to prevent counting of MatAssemblyBegin() that 5457 are called from within a MatAssemblyEnd(). 5458 */ 5459 static PetscInt MatAssemblyEnd_InUse = 0; 5460 /*@ 5461 MatAssemblyBegin - Begins assembling the matrix. This routine should 5462 be called after completing all calls to MatSetValues(). 5463 5464 Collective on Mat 5465 5466 Input Parameters: 5467 + mat - the matrix 5468 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5469 5470 Notes: 5471 MatSetValues() generally caches the values. The matrix is ready to 5472 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5473 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5474 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5475 using the matrix. 5476 5477 ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the 5478 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 5479 a global collective operation requring all processes that share the matrix. 5480 5481 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5482 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5483 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5484 5485 Level: beginner 5486 5487 .seealso: `MatAssemblyEnd()`, `MatSetValues()`, `MatAssembled()` 5488 @*/ 5489 PetscErrorCode MatAssemblyBegin(Mat mat, MatAssemblyType type) { 5490 PetscFunctionBegin; 5491 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5492 PetscValidType(mat, 1); 5493 MatCheckPreallocated(mat, 1); 5494 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix.\nDid you forget to call MatSetUnfactored()?"); 5495 if (mat->assembled) { 5496 mat->was_assembled = PETSC_TRUE; 5497 mat->assembled = PETSC_FALSE; 5498 } 5499 5500 if (!MatAssemblyEnd_InUse) { 5501 PetscCall(PetscLogEventBegin(MAT_AssemblyBegin, mat, 0, 0, 0)); 5502 PetscTryTypeMethod(mat, assemblybegin, type); 5503 PetscCall(PetscLogEventEnd(MAT_AssemblyBegin, mat, 0, 0, 0)); 5504 } else PetscTryTypeMethod(mat, assemblybegin, type); 5505 PetscFunctionReturn(0); 5506 } 5507 5508 /*@ 5509 MatAssembled - Indicates if a matrix has been assembled and is ready for 5510 use; for example, in matrix-vector product. 5511 5512 Not Collective 5513 5514 Input Parameter: 5515 . mat - the matrix 5516 5517 Output Parameter: 5518 . assembled - PETSC_TRUE or PETSC_FALSE 5519 5520 Level: advanced 5521 5522 .seealso: `MatAssemblyEnd()`, `MatSetValues()`, `MatAssemblyBegin()` 5523 @*/ 5524 PetscErrorCode MatAssembled(Mat mat, PetscBool *assembled) { 5525 PetscFunctionBegin; 5526 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5527 PetscValidBoolPointer(assembled, 2); 5528 *assembled = mat->assembled; 5529 PetscFunctionReturn(0); 5530 } 5531 5532 /*@ 5533 MatAssemblyEnd - Completes assembling the matrix. This routine should 5534 be called after MatAssemblyBegin(). 5535 5536 Collective on Mat 5537 5538 Input Parameters: 5539 + mat - the matrix 5540 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5541 5542 Options Database Keys: 5543 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly() 5544 . -mat_view ::ascii_info_detail - Prints more detailed info 5545 . -mat_view - Prints matrix in ASCII format 5546 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 5547 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 5548 . -display <name> - Sets display name (default is host) 5549 . -draw_pause <sec> - Sets number of seconds to pause after display 5550 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab) 5551 . -viewer_socket_machine <machine> - Machine to use for socket 5552 . -viewer_socket_port <port> - Port number to use for socket 5553 - -mat_view binary:filename[:append] - Save matrix to file in binary format 5554 5555 Notes: 5556 MatSetValues() generally caches the values. The matrix is ready to 5557 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5558 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5559 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5560 using the matrix. 5561 5562 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5563 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5564 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5565 5566 Level: beginner 5567 5568 .seealso: `MatAssemblyBegin()`, `MatSetValues()`, `PetscDrawOpenX()`, `PetscDrawCreate()`, `MatView()`, `MatAssembled()`, `PetscViewerSocketOpen()` 5569 @*/ 5570 PetscErrorCode MatAssemblyEnd(Mat mat, MatAssemblyType type) { 5571 static PetscInt inassm = 0; 5572 PetscBool flg = PETSC_FALSE; 5573 5574 PetscFunctionBegin; 5575 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5576 PetscValidType(mat, 1); 5577 5578 inassm++; 5579 MatAssemblyEnd_InUse++; 5580 if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */ 5581 PetscCall(PetscLogEventBegin(MAT_AssemblyEnd, mat, 0, 0, 0)); 5582 PetscTryTypeMethod(mat, assemblyend, type); 5583 PetscCall(PetscLogEventEnd(MAT_AssemblyEnd, mat, 0, 0, 0)); 5584 } else PetscTryTypeMethod(mat, assemblyend, type); 5585 5586 /* Flush assembly is not a true assembly */ 5587 if (type != MAT_FLUSH_ASSEMBLY) { 5588 if (mat->num_ass) { 5589 if (!mat->symmetry_eternal) { 5590 mat->symmetric = PETSC_BOOL3_UNKNOWN; 5591 mat->hermitian = PETSC_BOOL3_UNKNOWN; 5592 } 5593 if (!mat->structural_symmetry_eternal && mat->ass_nonzerostate != mat->nonzerostate) { mat->structurally_symmetric = PETSC_BOOL3_UNKNOWN; } 5594 if (!mat->spd_eternal) mat->spd = PETSC_BOOL3_UNKNOWN; 5595 } 5596 mat->num_ass++; 5597 mat->assembled = PETSC_TRUE; 5598 mat->ass_nonzerostate = mat->nonzerostate; 5599 } 5600 5601 mat->insertmode = NOT_SET_VALUES; 5602 MatAssemblyEnd_InUse--; 5603 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5604 if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) { 5605 PetscCall(MatViewFromOptions(mat, NULL, "-mat_view")); 5606 5607 if (mat->checksymmetryonassembly) { 5608 PetscCall(MatIsSymmetric(mat, mat->checksymmetrytol, &flg)); 5609 if (flg) { 5610 PetscCall(PetscPrintf(PetscObjectComm((PetscObject)mat), "Matrix is symmetric (tolerance %g)\n", (double)mat->checksymmetrytol)); 5611 } else { 5612 PetscCall(PetscPrintf(PetscObjectComm((PetscObject)mat), "Matrix is not symmetric (tolerance %g)\n", (double)mat->checksymmetrytol)); 5613 } 5614 } 5615 if (mat->nullsp && mat->checknullspaceonassembly) PetscCall(MatNullSpaceTest(mat->nullsp, mat, NULL)); 5616 } 5617 inassm--; 5618 PetscFunctionReturn(0); 5619 } 5620 5621 /*@ 5622 MatSetOption - Sets a parameter option for a matrix. Some options 5623 may be specific to certain storage formats. Some options 5624 determine how values will be inserted (or added). Sorted, 5625 row-oriented input will generally assemble the fastest. The default 5626 is row-oriented. 5627 5628 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5629 5630 Input Parameters: 5631 + mat - the matrix 5632 . option - the option, one of those listed below (and possibly others), 5633 - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5634 5635 Options Describing Matrix Structure: 5636 + MAT_SPD - symmetric positive definite 5637 . MAT_SYMMETRIC - symmetric in terms of both structure and value 5638 . MAT_HERMITIAN - transpose is the complex conjugation 5639 . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure 5640 . MAT_SYMMETRY_ETERNAL - indicates the symmetry (or Hermitian structure) or its absence will persist through any changes to the matrix 5641 . MAT_STRUCTURAL_SYMMETRY_ETERNAL - indicates the structural symmetry or its absence will persist through any changes to the matrix 5642 - MAT_SPD_ETERNAL - indicates the value of MAT_SPD (true or false) will persist through any changes to the matrix 5643 5644 These are not really options of the matrix, they are knowledge about the structure of the matrix that users may provide so that they 5645 do not need to be computed (usually at a high cost) 5646 5647 Options For Use with MatSetValues(): 5648 Insert a logically dense subblock, which can be 5649 . MAT_ROW_ORIENTED - row-oriented (default) 5650 5651 Note these options reflect the data you pass in with MatSetValues(); it has 5652 nothing to do with how the data is stored internally in the matrix 5653 data structure. 5654 5655 When (re)assembling a matrix, we can restrict the input for 5656 efficiency/debugging purposes. These options include 5657 + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow) 5658 . MAT_FORCE_DIAGONAL_ENTRIES - forces diagonal entries to be allocated 5659 . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries 5660 . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry 5661 . MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly 5662 . MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if 5663 any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves 5664 performance for very large process counts. 5665 - MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset 5666 of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly 5667 functions, instead sending only neighbor messages. 5668 5669 Notes: 5670 Except for MAT_UNUSED_NONZERO_LOCATION_ERR and MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg! 5671 5672 Some options are relevant only for particular matrix types and 5673 are thus ignored by others. Other options are not supported by 5674 certain matrix types and will generate an error message if set. 5675 5676 If using a Fortran 77 module to compute a matrix, one may need to 5677 use the column-oriented option (or convert to the row-oriented 5678 format). 5679 5680 MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion 5681 that would generate a new entry in the nonzero structure is instead 5682 ignored. Thus, if memory has not alredy been allocated for this particular 5683 data, then the insertion is ignored. For dense matrices, in which 5684 the entire array is allocated, no entries are ever ignored. 5685 Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5686 5687 MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5688 that would generate a new entry in the nonzero structure instead produces 5689 an error. (Currently supported for AIJ and BAIJ formats only.) If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5690 5691 MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5692 that would generate a new entry that has not been preallocated will 5693 instead produce an error. (Currently supported for AIJ and BAIJ formats 5694 only.) This is a useful flag when debugging matrix memory preallocation. 5695 If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5696 5697 MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for 5698 other processors should be dropped, rather than stashed. 5699 This is useful if you know that the "owning" processor is also 5700 always generating the correct matrix entries, so that PETSc need 5701 not transfer duplicate entries generated on another processor. 5702 5703 MAT_USE_HASH_TABLE indicates that a hash table be used to improve the 5704 searches during matrix assembly. When this flag is set, the hash table 5705 is created during the first Matrix Assembly. This hash table is 5706 used the next time through, during MatSetVaules()/MatSetVaulesBlocked() 5707 to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag 5708 should be used with MAT_USE_HASH_TABLE flag. This option is currently 5709 supported by MATMPIBAIJ format only. 5710 5711 MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries 5712 are kept in the nonzero structure 5713 5714 MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating 5715 a zero location in the matrix 5716 5717 MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types 5718 5719 MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the 5720 zero row routines and thus improves performance for very large process counts. 5721 5722 MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular 5723 part of the matrix (since they should match the upper triangular part). 5724 5725 MAT_SORTED_FULL - each process provides exactly its local rows; all column indices for a given row are passed in a 5726 single call to MatSetValues(), preallocation is perfect, row oriented, INSERT_VALUES is used. Common 5727 with finite difference schemes with non-periodic boundary conditions. 5728 5729 Developer Note: 5730 MAT_SYMMETRY_ETERNAL, MAT_STRUCTURAL_SYMMETRY_ETERNAL, and MAT_SPD_ETERNAL are used by MatAssemblyEnd() and in other 5731 places where otherwise the value of MAT_SYMMETRIC, MAT_STRUCTURAL_SYMMETRIC or MAT_SPD would need to be changed back 5732 to PETSC_BOOL3_UNKNOWN because the matrix values had changed so the code cannot be certain that the related property had 5733 not changed. 5734 5735 Level: intermediate 5736 5737 .seealso: `MatOption`, `Mat`, `MatGetOption()` 5738 5739 @*/ 5740 PetscErrorCode MatSetOption(Mat mat, MatOption op, PetscBool flg) { 5741 PetscFunctionBegin; 5742 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5743 if (op > 0) { 5744 PetscValidLogicalCollectiveEnum(mat, op, 2); 5745 PetscValidLogicalCollectiveBool(mat, flg, 3); 5746 } 5747 5748 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); 5749 5750 switch (op) { 5751 case MAT_FORCE_DIAGONAL_ENTRIES: mat->force_diagonals = flg; PetscFunctionReturn(0); 5752 case MAT_NO_OFF_PROC_ENTRIES: mat->nooffprocentries = flg; PetscFunctionReturn(0); 5753 case MAT_SUBSET_OFF_PROC_ENTRIES: 5754 mat->assembly_subset = flg; 5755 if (!mat->assembly_subset) { /* See the same logic in VecAssembly wrt VEC_SUBSET_OFF_PROC_ENTRIES */ 5756 #if !defined(PETSC_HAVE_MPIUNI) 5757 PetscCall(MatStashScatterDestroy_BTS(&mat->stash)); 5758 #endif 5759 mat->stash.first_assembly_done = PETSC_FALSE; 5760 } 5761 PetscFunctionReturn(0); 5762 case MAT_NO_OFF_PROC_ZERO_ROWS: mat->nooffproczerorows = flg; PetscFunctionReturn(0); 5763 case MAT_SPD: 5764 if (flg) { 5765 mat->spd = PETSC_BOOL3_TRUE; 5766 mat->symmetric = PETSC_BOOL3_TRUE; 5767 mat->structurally_symmetric = PETSC_BOOL3_TRUE; 5768 } else { 5769 mat->spd = PETSC_BOOL3_FALSE; 5770 } 5771 break; 5772 case MAT_SYMMETRIC: 5773 mat->symmetric = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5774 if (flg) mat->structurally_symmetric = PETSC_BOOL3_TRUE; 5775 #if !defined(PETSC_USE_COMPLEX) 5776 mat->hermitian = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5777 #endif 5778 break; 5779 case MAT_HERMITIAN: 5780 mat->hermitian = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5781 if (flg) mat->structurally_symmetric = PETSC_BOOL3_TRUE; 5782 #if !defined(PETSC_USE_COMPLEX) 5783 mat->symmetric = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5784 #endif 5785 break; 5786 case MAT_STRUCTURALLY_SYMMETRIC: mat->structurally_symmetric = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; break; 5787 case MAT_SYMMETRY_ETERNAL: 5788 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"); 5789 mat->symmetry_eternal = flg; 5790 if (flg) mat->structural_symmetry_eternal = PETSC_TRUE; 5791 break; 5792 case MAT_STRUCTURAL_SYMMETRY_ETERNAL: 5793 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"); 5794 mat->structural_symmetry_eternal = flg; 5795 break; 5796 case MAT_SPD_ETERNAL: 5797 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"); 5798 mat->spd_eternal = flg; 5799 if (flg) { 5800 mat->structural_symmetry_eternal = PETSC_TRUE; 5801 mat->symmetry_eternal = PETSC_TRUE; 5802 } 5803 break; 5804 case MAT_STRUCTURE_ONLY: mat->structure_only = flg; break; 5805 case MAT_SORTED_FULL: mat->sortedfull = flg; break; 5806 default: break; 5807 } 5808 PetscTryTypeMethod(mat, setoption, op, flg); 5809 PetscFunctionReturn(0); 5810 } 5811 5812 /*@ 5813 MatGetOption - Gets a parameter option that has been set for a matrix. 5814 5815 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5816 5817 Input Parameters: 5818 + mat - the matrix 5819 - option - the option, this only responds to certain options, check the code for which ones 5820 5821 Output Parameter: 5822 . flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5823 5824 Notes: 5825 Can only be called after MatSetSizes() and MatSetType() have been set. 5826 5827 Certain option values may be unknown, for those use the routines `MatIsSymmetric()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, or 5828 `MatIsSymmetricKnown()`, `MatIsHermitianKnown()`, `MatIsStructurallySymmetricKnown()` 5829 5830 Level: intermediate 5831 5832 .seealso: `MatOption`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, 5833 `MatIsSymmetricKnown()`, `MatIsHermitianKnown()`, `MatIsStructurallySymmetricKnown()` 5834 5835 @*/ 5836 PetscErrorCode MatGetOption(Mat mat, MatOption op, PetscBool *flg) { 5837 PetscFunctionBegin; 5838 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5839 PetscValidType(mat, 1); 5840 5841 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); 5842 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()"); 5843 5844 switch (op) { 5845 case MAT_NO_OFF_PROC_ENTRIES: *flg = mat->nooffprocentries; break; 5846 case MAT_NO_OFF_PROC_ZERO_ROWS: *flg = mat->nooffproczerorows; break; 5847 case MAT_SYMMETRIC: SETERRQ(PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Use MatIsSymmetric() or MatIsSymmetricKnown()"); break; 5848 case MAT_HERMITIAN: SETERRQ(PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Use MatIsHermitian() or MatIsHermitianKnown()"); break; 5849 case MAT_STRUCTURALLY_SYMMETRIC: SETERRQ(PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Use MatIsStructurallySymmetric() or MatIsStructurallySymmetricKnown()"); break; 5850 case MAT_SPD: SETERRQ(PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Use MatIsSPDKnown()"); break; 5851 case MAT_SYMMETRY_ETERNAL: *flg = mat->symmetry_eternal; break; 5852 case MAT_STRUCTURAL_SYMMETRY_ETERNAL: *flg = mat->symmetry_eternal; break; 5853 default: break; 5854 } 5855 PetscFunctionReturn(0); 5856 } 5857 5858 /*@ 5859 MatZeroEntries - Zeros all entries of a matrix. For sparse matrices 5860 this routine retains the old nonzero structure. 5861 5862 Logically Collective on Mat 5863 5864 Input Parameters: 5865 . mat - the matrix 5866 5867 Level: intermediate 5868 5869 Notes: 5870 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. 5871 See the Performance chapter of the users manual for information on preallocating matrices. 5872 5873 .seealso: `MatZeroRows()` 5874 @*/ 5875 PetscErrorCode MatZeroEntries(Mat mat) { 5876 PetscFunctionBegin; 5877 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5878 PetscValidType(mat, 1); 5879 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 5880 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"); 5881 MatCheckPreallocated(mat, 1); 5882 5883 PetscCall(PetscLogEventBegin(MAT_ZeroEntries, mat, 0, 0, 0)); 5884 PetscUseTypeMethod(mat, zeroentries); 5885 PetscCall(PetscLogEventEnd(MAT_ZeroEntries, mat, 0, 0, 0)); 5886 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5887 PetscFunctionReturn(0); 5888 } 5889 5890 /*@ 5891 MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal) 5892 of a set of rows and columns of a matrix. 5893 5894 Collective on Mat 5895 5896 Input Parameters: 5897 + mat - the matrix 5898 . numRows - the number of rows to remove 5899 . rows - the global row indices 5900 . diag - value put in the diagonal of the eliminated rows 5901 . x - optional vector of solutions for zeroed rows (other entries in vector are not used), these must be set before this call 5902 - b - optional vector of right hand side, that will be adjusted by provided solution 5903 5904 Notes: 5905 This routine, along with `MatZeroRows()`, is typically used to eliminate known Dirichlet boundary conditions from a linear system. 5906 5907 For each zeroed row, the value of the corresponding b is set to diag times the value of the corresponding x. 5908 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 5909 5910 If the resulting linear system is to be solved with KSP then one can (but does not have to) call `KSPSetInitialGuessNonzero()` to allow the 5911 Krylov method to take advantage of the known solution on the zeroed rows. 5912 5913 For the parallel case, all processes that share the matrix (i.e., 5914 those in the communicator used for matrix creation) MUST call this 5915 routine, regardless of whether any rows being zeroed are owned by 5916 them. 5917 5918 Unlike `MatZeroRows()` this does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5919 5920 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5921 list only rows local to itself). 5922 5923 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 5924 5925 Level: intermediate 5926 5927 .seealso: `MatZeroRowsIS()`, `MatZeroRows()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 5928 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 5929 @*/ 5930 PetscErrorCode MatZeroRowsColumns(Mat mat, PetscInt numRows, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) { 5931 PetscFunctionBegin; 5932 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5933 PetscValidType(mat, 1); 5934 if (numRows) PetscValidIntPointer(rows, 3); 5935 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 5936 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 5937 MatCheckPreallocated(mat, 1); 5938 5939 PetscUseTypeMethod(mat, zerorowscolumns, numRows, rows, diag, x, b); 5940 PetscCall(MatViewFromOptions(mat, NULL, "-mat_view")); 5941 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5942 PetscFunctionReturn(0); 5943 } 5944 5945 /*@ 5946 MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal) 5947 of a set of rows and columns of a matrix. 5948 5949 Collective on Mat 5950 5951 Input Parameters: 5952 + mat - the matrix 5953 . is - the rows to zero 5954 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5955 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5956 - b - optional vector of right hand side, that will be adjusted by provided solution 5957 5958 Note: 5959 See `MatZeroRowsColumns()` for details on how this routine operates. 5960 5961 Level: intermediate 5962 5963 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 5964 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRows()`, `MatZeroRowsColumnsStencil()` 5965 @*/ 5966 PetscErrorCode MatZeroRowsColumnsIS(Mat mat, IS is, PetscScalar diag, Vec x, Vec b) { 5967 PetscInt numRows; 5968 const PetscInt *rows; 5969 5970 PetscFunctionBegin; 5971 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 5972 PetscValidHeaderSpecific(is, IS_CLASSID, 2); 5973 PetscValidType(mat, 1); 5974 PetscValidType(is, 2); 5975 PetscCall(ISGetLocalSize(is, &numRows)); 5976 PetscCall(ISGetIndices(is, &rows)); 5977 PetscCall(MatZeroRowsColumns(mat, numRows, rows, diag, x, b)); 5978 PetscCall(ISRestoreIndices(is, &rows)); 5979 PetscFunctionReturn(0); 5980 } 5981 5982 /*@ 5983 MatZeroRows - Zeros all entries (except possibly the main diagonal) 5984 of a set of rows of a matrix. 5985 5986 Collective on Mat 5987 5988 Input Parameters: 5989 + mat - the matrix 5990 . numRows - the number of rows to remove 5991 . rows - the global row indices 5992 . diag - value put in the diagonal of the eliminated rows 5993 . x - optional vector of solutions for zeroed rows (other entries in vector are not used), these must be set before this call 5994 - b - optional vector of right hand side, that will be adjusted by provided solution 5995 5996 Notes: 5997 This routine, along with `MatZeroRowsColumns()`, is typically used to eliminate known Dirichlet boundary conditions from a linear system. 5998 5999 For each zeroed row, the value of the corresponding b is set to diag times the value of the corresponding x. 6000 6001 If the resulting linear system is to be solved with KSP then one can (but does not have to) call `KSPSetInitialGuessNonzero()` to allow the 6002 Krylov method to take advantage of the known solution on the zeroed rows. 6003 6004 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) 6005 from the matrix. 6006 6007 Unlike `MatZeroRowsColumns()` for the AIJ and BAIJ matrix formats this removes the old nonzero structure, from the eliminated rows of the matrix 6008 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 6009 formats this does not alter the nonzero structure. 6010 6011 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6012 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6013 merely zeroed. 6014 6015 The user can set a value in the diagonal entry (or for the AIJ and 6016 row formats can optionally remove the main diagonal entry from the 6017 nonzero structure as well, by passing 0.0 as the final argument). 6018 6019 For the parallel case, all processes that share the matrix (i.e., 6020 those in the communicator used for matrix creation) MUST call this 6021 routine, regardless of whether any rows being zeroed are owned by 6022 them. 6023 6024 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6025 list only rows local to itself). 6026 6027 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6028 owns that are to be zeroed. This saves a global synchronization in the implementation. 6029 6030 Level: intermediate 6031 6032 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6033 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()`, `PCREDISTRIBUTE` 6034 @*/ 6035 PetscErrorCode MatZeroRows(Mat mat, PetscInt numRows, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) { 6036 PetscFunctionBegin; 6037 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6038 PetscValidType(mat, 1); 6039 if (numRows) PetscValidIntPointer(rows, 3); 6040 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 6041 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 6042 MatCheckPreallocated(mat, 1); 6043 6044 PetscUseTypeMethod(mat, zerorows, numRows, rows, diag, x, b); 6045 PetscCall(MatViewFromOptions(mat, NULL, "-mat_view")); 6046 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6047 PetscFunctionReturn(0); 6048 } 6049 6050 /*@ 6051 MatZeroRowsIS - Zeros all entries (except possibly the main diagonal) 6052 of a set of rows of a matrix. 6053 6054 Collective on Mat 6055 6056 Input Parameters: 6057 + mat - the matrix 6058 . is - index set of rows to remove (if NULL then no row is removed) 6059 . diag - value put in all diagonals of eliminated rows 6060 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6061 - b - optional vector of right hand side, that will be adjusted by provided solution 6062 6063 Note: 6064 See `MatZeroRows()` for details on how this routine operates. 6065 6066 Level: intermediate 6067 6068 .seealso: `MatZeroRows()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6069 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6070 @*/ 6071 PetscErrorCode MatZeroRowsIS(Mat mat, IS is, PetscScalar diag, Vec x, Vec b) { 6072 PetscInt numRows = 0; 6073 const PetscInt *rows = NULL; 6074 6075 PetscFunctionBegin; 6076 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6077 PetscValidType(mat, 1); 6078 if (is) { 6079 PetscValidHeaderSpecific(is, IS_CLASSID, 2); 6080 PetscCall(ISGetLocalSize(is, &numRows)); 6081 PetscCall(ISGetIndices(is, &rows)); 6082 } 6083 PetscCall(MatZeroRows(mat, numRows, rows, diag, x, b)); 6084 if (is) PetscCall(ISRestoreIndices(is, &rows)); 6085 PetscFunctionReturn(0); 6086 } 6087 6088 /*@ 6089 MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal) 6090 of a set of rows of a matrix. These rows must be local to the process. 6091 6092 Collective on Mat 6093 6094 Input Parameters: 6095 + mat - the matrix 6096 . numRows - the number of rows to remove 6097 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 6098 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6099 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6100 - b - optional vector of right hand side, that will be adjusted by provided solution 6101 6102 Notes: 6103 See `MatZeroRows()` for details on how this routine operates. 6104 6105 The grid coordinates are across the entire grid, not just the local portion 6106 6107 In Fortran idxm and idxn should be declared as 6108 $ MatStencil idxm(4,m) 6109 and the values inserted using 6110 $ idxm(MatStencil_i,1) = i 6111 $ idxm(MatStencil_j,1) = j 6112 $ idxm(MatStencil_k,1) = k 6113 $ idxm(MatStencil_c,1) = c 6114 etc 6115 6116 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6117 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6118 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6119 DM_BOUNDARY_PERIODIC boundary type. 6120 6121 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 6122 a single value per point) you can skip filling those indices. 6123 6124 Level: intermediate 6125 6126 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsl()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6127 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6128 @*/ 6129 PetscErrorCode MatZeroRowsStencil(Mat mat, PetscInt numRows, const MatStencil rows[], PetscScalar diag, Vec x, Vec b) { 6130 PetscInt dim = mat->stencil.dim; 6131 PetscInt sdim = dim - (1 - (PetscInt)mat->stencil.noc); 6132 PetscInt *dims = mat->stencil.dims + 1; 6133 PetscInt *starts = mat->stencil.starts; 6134 PetscInt *dxm = (PetscInt *)rows; 6135 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6136 6137 PetscFunctionBegin; 6138 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6139 PetscValidType(mat, 1); 6140 if (numRows) PetscValidPointer(rows, 3); 6141 6142 PetscCall(PetscMalloc1(numRows, &jdxm)); 6143 for (i = 0; i < numRows; ++i) { 6144 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6145 for (j = 0; j < 3 - sdim; ++j) dxm++; 6146 /* Local index in X dir */ 6147 tmp = *dxm++ - starts[0]; 6148 /* Loop over remaining dimensions */ 6149 for (j = 0; j < dim - 1; ++j) { 6150 /* If nonlocal, set index to be negative */ 6151 if ((*dxm++ - starts[j + 1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6152 /* Update local index */ 6153 else tmp = tmp * dims[j] + *(dxm - 1) - starts[j + 1]; 6154 } 6155 /* Skip component slot if necessary */ 6156 if (mat->stencil.noc) dxm++; 6157 /* Local row number */ 6158 if (tmp >= 0) { jdxm[numNewRows++] = tmp; } 6159 } 6160 PetscCall(MatZeroRowsLocal(mat, numNewRows, jdxm, diag, x, b)); 6161 PetscCall(PetscFree(jdxm)); 6162 PetscFunctionReturn(0); 6163 } 6164 6165 /*@ 6166 MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal) 6167 of a set of rows and columns of a matrix. 6168 6169 Collective on Mat 6170 6171 Input Parameters: 6172 + mat - the matrix 6173 . numRows - the number of rows/columns to remove 6174 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 6175 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6176 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6177 - b - optional vector of right hand side, that will be adjusted by provided solution 6178 6179 Notes: 6180 See `MatZeroRowsColumns()` for details on how this routine operates. 6181 6182 The grid coordinates are across the entire grid, not just the local portion 6183 6184 In Fortran idxm and idxn should be declared as 6185 $ MatStencil idxm(4,m) 6186 and the values inserted using 6187 $ idxm(MatStencil_i,1) = i 6188 $ idxm(MatStencil_j,1) = j 6189 $ idxm(MatStencil_k,1) = k 6190 $ idxm(MatStencil_c,1) = c 6191 etc 6192 6193 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6194 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6195 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6196 DM_BOUNDARY_PERIODIC boundary type. 6197 6198 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 6199 a single value per point) you can skip filling those indices. 6200 6201 Level: intermediate 6202 6203 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6204 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRows()` 6205 @*/ 6206 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat, PetscInt numRows, const MatStencil rows[], PetscScalar diag, Vec x, Vec b) { 6207 PetscInt dim = mat->stencil.dim; 6208 PetscInt sdim = dim - (1 - (PetscInt)mat->stencil.noc); 6209 PetscInt *dims = mat->stencil.dims + 1; 6210 PetscInt *starts = mat->stencil.starts; 6211 PetscInt *dxm = (PetscInt *)rows; 6212 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6213 6214 PetscFunctionBegin; 6215 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6216 PetscValidType(mat, 1); 6217 if (numRows) PetscValidPointer(rows, 3); 6218 6219 PetscCall(PetscMalloc1(numRows, &jdxm)); 6220 for (i = 0; i < numRows; ++i) { 6221 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6222 for (j = 0; j < 3 - sdim; ++j) dxm++; 6223 /* Local index in X dir */ 6224 tmp = *dxm++ - starts[0]; 6225 /* Loop over remaining dimensions */ 6226 for (j = 0; j < dim - 1; ++j) { 6227 /* If nonlocal, set index to be negative */ 6228 if ((*dxm++ - starts[j + 1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6229 /* Update local index */ 6230 else tmp = tmp * dims[j] + *(dxm - 1) - starts[j + 1]; 6231 } 6232 /* Skip component slot if necessary */ 6233 if (mat->stencil.noc) dxm++; 6234 /* Local row number */ 6235 if (tmp >= 0) { jdxm[numNewRows++] = tmp; } 6236 } 6237 PetscCall(MatZeroRowsColumnsLocal(mat, numNewRows, jdxm, diag, x, b)); 6238 PetscCall(PetscFree(jdxm)); 6239 PetscFunctionReturn(0); 6240 } 6241 6242 /*@C 6243 MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal) 6244 of a set of rows of a matrix; using local numbering of rows. 6245 6246 Collective on Mat 6247 6248 Input Parameters: 6249 + mat - the matrix 6250 . numRows - the number of rows to remove 6251 . rows - the local row indices 6252 . diag - value put in all diagonals of eliminated rows 6253 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6254 - b - optional vector of right hand side, that will be adjusted by provided solution 6255 6256 Notes: 6257 Before calling `MatZeroRowsLocal()`, the user must first set the 6258 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6259 6260 See `MatZeroRows()` for details on how this routine operates. 6261 6262 Level: intermediate 6263 6264 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRows()`, `MatSetOption()`, 6265 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6266 @*/ 6267 PetscErrorCode MatZeroRowsLocal(Mat mat, PetscInt numRows, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) { 6268 PetscFunctionBegin; 6269 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6270 PetscValidType(mat, 1); 6271 if (numRows) PetscValidIntPointer(rows, 3); 6272 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 6273 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 6274 MatCheckPreallocated(mat, 1); 6275 6276 if (mat->ops->zerorowslocal) { 6277 PetscUseTypeMethod(mat, zerorowslocal, numRows, rows, diag, x, b); 6278 } else { 6279 IS is, newis; 6280 const PetscInt *newRows; 6281 6282 PetscCheck(mat->rmap->mapping, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Need to provide local to global mapping to matrix first"); 6283 PetscCall(ISCreateGeneral(PETSC_COMM_SELF, numRows, rows, PETSC_COPY_VALUES, &is)); 6284 PetscCall(ISLocalToGlobalMappingApplyIS(mat->rmap->mapping, is, &newis)); 6285 PetscCall(ISGetIndices(newis, &newRows)); 6286 PetscUseTypeMethod(mat, zerorows, numRows, newRows, diag, x, b); 6287 PetscCall(ISRestoreIndices(newis, &newRows)); 6288 PetscCall(ISDestroy(&newis)); 6289 PetscCall(ISDestroy(&is)); 6290 } 6291 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6292 PetscFunctionReturn(0); 6293 } 6294 6295 /*@ 6296 MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal) 6297 of a set of rows of a matrix; using local numbering of rows. 6298 6299 Collective on Mat 6300 6301 Input Parameters: 6302 + mat - the matrix 6303 . is - index set of rows to remove 6304 . diag - value put in all diagonals of eliminated rows 6305 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6306 - b - optional vector of right hand side, that will be adjusted by provided solution 6307 6308 Notes: 6309 Before calling `MatZeroRowsLocalIS()`, the user must first set the 6310 local-to-global mapping by calling `MatSetLocalToGlobalMapping()`. 6311 6312 See `MatZeroRows()` for details on how this routine operates. 6313 6314 Level: intermediate 6315 6316 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRows()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6317 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6318 @*/ 6319 PetscErrorCode MatZeroRowsLocalIS(Mat mat, IS is, PetscScalar diag, Vec x, Vec b) { 6320 PetscInt numRows; 6321 const PetscInt *rows; 6322 6323 PetscFunctionBegin; 6324 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6325 PetscValidType(mat, 1); 6326 PetscValidHeaderSpecific(is, IS_CLASSID, 2); 6327 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 6328 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 6329 MatCheckPreallocated(mat, 1); 6330 6331 PetscCall(ISGetLocalSize(is, &numRows)); 6332 PetscCall(ISGetIndices(is, &rows)); 6333 PetscCall(MatZeroRowsLocal(mat, numRows, rows, diag, x, b)); 6334 PetscCall(ISRestoreIndices(is, &rows)); 6335 PetscFunctionReturn(0); 6336 } 6337 6338 /*@ 6339 MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal) 6340 of a set of rows and columns of a matrix; using local numbering of rows. 6341 6342 Collective on Mat 6343 6344 Input Parameters: 6345 + mat - the matrix 6346 . numRows - the number of rows to remove 6347 . rows - the global row indices 6348 . diag - value put in all diagonals of eliminated rows 6349 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6350 - b - optional vector of right hand side, that will be adjusted by provided solution 6351 6352 Notes: 6353 Before calling MatZeroRowsColumnsLocal(), the user must first set the 6354 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6355 6356 See `MatZeroRowsColumns()` for details on how this routine operates. 6357 6358 Level: intermediate 6359 6360 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6361 `MatZeroRows()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6362 @*/ 6363 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat, PetscInt numRows, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) { 6364 IS is, newis; 6365 const PetscInt *newRows; 6366 6367 PetscFunctionBegin; 6368 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6369 PetscValidType(mat, 1); 6370 if (numRows) PetscValidIntPointer(rows, 3); 6371 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 6372 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 6373 MatCheckPreallocated(mat, 1); 6374 6375 PetscCheck(mat->cmap->mapping, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Need to provide local to global mapping to matrix first"); 6376 PetscCall(ISCreateGeneral(PETSC_COMM_SELF, numRows, rows, PETSC_COPY_VALUES, &is)); 6377 PetscCall(ISLocalToGlobalMappingApplyIS(mat->cmap->mapping, is, &newis)); 6378 PetscCall(ISGetIndices(newis, &newRows)); 6379 PetscUseTypeMethod(mat, zerorowscolumns, numRows, newRows, diag, x, b); 6380 PetscCall(ISRestoreIndices(newis, &newRows)); 6381 PetscCall(ISDestroy(&newis)); 6382 PetscCall(ISDestroy(&is)); 6383 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6384 PetscFunctionReturn(0); 6385 } 6386 6387 /*@ 6388 MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal) 6389 of a set of rows and columns of a matrix; using local numbering of rows. 6390 6391 Collective on Mat 6392 6393 Input Parameters: 6394 + mat - the matrix 6395 . is - index set of rows to remove 6396 . diag - value put in all diagonals of eliminated rows 6397 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6398 - b - optional vector of right hand side, that will be adjusted by provided solution 6399 6400 Notes: 6401 Before calling `MatZeroRowsColumnsLocalIS()`, the user must first set the 6402 local-to-global mapping by calling `MatSetLocalToGlobalMapping()`. 6403 6404 See `MatZeroRowsColumns()` for details on how this routine operates. 6405 6406 Level: intermediate 6407 6408 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6409 `MatZeroRowsColumnsLocal()`, `MatZeroRows()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6410 @*/ 6411 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat, IS is, PetscScalar diag, Vec x, Vec b) { 6412 PetscInt numRows; 6413 const PetscInt *rows; 6414 6415 PetscFunctionBegin; 6416 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6417 PetscValidType(mat, 1); 6418 PetscValidHeaderSpecific(is, IS_CLASSID, 2); 6419 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 6420 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 6421 MatCheckPreallocated(mat, 1); 6422 6423 PetscCall(ISGetLocalSize(is, &numRows)); 6424 PetscCall(ISGetIndices(is, &rows)); 6425 PetscCall(MatZeroRowsColumnsLocal(mat, numRows, rows, diag, x, b)); 6426 PetscCall(ISRestoreIndices(is, &rows)); 6427 PetscFunctionReturn(0); 6428 } 6429 6430 /*@C 6431 MatGetSize - Returns the numbers of rows and columns in a matrix. 6432 6433 Not Collective 6434 6435 Input Parameter: 6436 . mat - the matrix 6437 6438 Output Parameters: 6439 + m - the number of global rows 6440 - n - the number of global columns 6441 6442 Note: both output parameters can be NULL on input. 6443 6444 Level: beginner 6445 6446 .seealso: `MatGetLocalSize()` 6447 @*/ 6448 PetscErrorCode MatGetSize(Mat mat, PetscInt *m, PetscInt *n) { 6449 PetscFunctionBegin; 6450 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6451 if (m) *m = mat->rmap->N; 6452 if (n) *n = mat->cmap->N; 6453 PetscFunctionReturn(0); 6454 } 6455 6456 /*@C 6457 MatGetLocalSize - For most matrix formats, excluding `MATELEMENTAL` and `MATSCALAPACK`, Returns the number of local rows and local columns 6458 of a matrix. For all matrices this is the local size of the left and right vectors as returned by MatCreateVecs(). 6459 6460 Not Collective 6461 6462 Input Parameter: 6463 . mat - the matrix 6464 6465 Output Parameters: 6466 + m - the number of local rows, use `NULL` to not obtain this value 6467 - n - the number of local columns, use `NULL` to not obtain this value 6468 6469 Level: beginner 6470 6471 .seealso: `MatGetSize()` 6472 @*/ 6473 PetscErrorCode MatGetLocalSize(Mat mat, PetscInt *m, PetscInt *n) { 6474 PetscFunctionBegin; 6475 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6476 if (m) PetscValidIntPointer(m, 2); 6477 if (n) PetscValidIntPointer(n, 3); 6478 if (m) *m = mat->rmap->n; 6479 if (n) *n = mat->cmap->n; 6480 PetscFunctionReturn(0); 6481 } 6482 6483 /*@C 6484 MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies this matrix by that are owned by 6485 this processor. (The columns of the "diagonal block" for most sparse matrix formats). See :any:`<sec_matlayout>` for details on matrix layouts. 6486 6487 Not Collective, unless matrix has not been allocated, then collective on Mat 6488 6489 Input Parameter: 6490 . mat - the matrix 6491 6492 Output Parameters: 6493 + m - the global index of the first local column, use `NULL` to not obtain this value 6494 - n - one more than the global index of the last local column, use `NULL` to not obtain this value 6495 6496 Level: developer 6497 6498 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRanges()`, `MatGetOwnershipRangesColumn()`, `PetscLayout` 6499 6500 @*/ 6501 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat, PetscInt *m, PetscInt *n) { 6502 PetscFunctionBegin; 6503 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6504 PetscValidType(mat, 1); 6505 if (m) PetscValidIntPointer(m, 2); 6506 if (n) PetscValidIntPointer(n, 3); 6507 MatCheckPreallocated(mat, 1); 6508 if (m) *m = mat->cmap->rstart; 6509 if (n) *n = mat->cmap->rend; 6510 PetscFunctionReturn(0); 6511 } 6512 6513 /*@C 6514 MatGetOwnershipRange - For matrices that own values by row, excludes `MATELEMENTAL` and `MATSCALAPACK`, returns the range of matrix rows owned by 6515 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 6516 vector product with this matrix. See :any:`<sec_matlayout>` for details on matrix layouts 6517 6518 Not Collective 6519 6520 Input Parameter: 6521 . mat - the matrix 6522 6523 Output Parameters: 6524 + m - the global index of the first local row, use `NULL` to not obtain this value 6525 - n - one more than the global index of the last local row, use `NULL` to not obtain this value 6526 6527 Note: 6528 This function requires that the matrix be preallocated. If you have not preallocated, consider using 6529 `PetscSplitOwnership`(`MPI_Comm` comm, `PetscInt` *n, `PetscInt` *N) 6530 and then `MPI_Scan()` to calculate prefix sums of the local sizes. 6531 6532 Level: beginner 6533 6534 .seealso: `MatGetOwnershipRanges()`, `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRangesColumn()`, `PetscSplitOwnership()`, `PetscSplitOwnershipBlock()`, 6535 `PetscLayout` 6536 6537 @*/ 6538 PetscErrorCode MatGetOwnershipRange(Mat mat, PetscInt *m, PetscInt *n) { 6539 PetscFunctionBegin; 6540 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6541 PetscValidType(mat, 1); 6542 if (m) PetscValidIntPointer(m, 2); 6543 if (n) PetscValidIntPointer(n, 3); 6544 MatCheckPreallocated(mat, 1); 6545 if (m) *m = mat->rmap->rstart; 6546 if (n) *n = mat->rmap->rend; 6547 PetscFunctionReturn(0); 6548 } 6549 6550 /*@C 6551 MatGetOwnershipRanges - For matrices that own values by row, excludes `MATELEMENTAL` and `MATSCALAPACK`, returns the range of matrix rows owned by 6552 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 6553 vector product with this matrix. See :any:`<sec_matlayout>` for details on matrix layouts 6554 6555 Not Collective, unless matrix has not been allocated, then collective on Mat 6556 6557 Input Parameters: 6558 . mat - the matrix 6559 6560 Output Parameters: 6561 . ranges - start of each processors portion plus one more than the total length at the end 6562 6563 Level: beginner 6564 6565 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRangesColumn()`, `PetscLayout` 6566 6567 @*/ 6568 PetscErrorCode MatGetOwnershipRanges(Mat mat, const PetscInt **ranges) { 6569 PetscFunctionBegin; 6570 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6571 PetscValidType(mat, 1); 6572 MatCheckPreallocated(mat, 1); 6573 PetscCall(PetscLayoutGetRanges(mat->rmap, ranges)); 6574 PetscFunctionReturn(0); 6575 } 6576 6577 /*@C 6578 MatGetOwnershipRangesColumn - Returns the ranges of matrix columns associated with rows of a vector one multiplies this vector by that are owned by 6579 each processor. (The columns of the "diagonal blocks", for most sparse matrix formats). See :any:`<sec_matlayout>` for details on matrix layouts. 6580 6581 Not Collective, unless matrix has not been allocated, then collective on Mat 6582 6583 Input Parameters: 6584 . mat - the matrix 6585 6586 Output Parameters: 6587 . ranges - start of each processors portion plus one more then the total length at the end 6588 6589 Level: beginner 6590 6591 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRanges()` 6592 6593 @*/ 6594 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat, const PetscInt **ranges) { 6595 PetscFunctionBegin; 6596 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6597 PetscValidType(mat, 1); 6598 MatCheckPreallocated(mat, 1); 6599 PetscCall(PetscLayoutGetRanges(mat->cmap, ranges)); 6600 PetscFunctionReturn(0); 6601 } 6602 6603 /*@C 6604 MatGetOwnershipIS - Get row and column ownership of a matrices' values as index sets. For most matrices, excluding `MATELEMENTAL` and `MATSCALAPACK`, this 6605 corresponds to values returned by `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`. For `MATELEMENTAL` and `MATSCALAPACK` the ownership 6606 is more complicated. See :any:`<sec_matlayout>` for details on matrix layouts. 6607 6608 Not Collective 6609 6610 Input Parameter: 6611 . A - matrix 6612 6613 Output Parameters: 6614 + rows - rows in which this process owns elements, , use `NULL` to not obtain this value 6615 - cols - columns in which this process owns elements, use `NULL` to not obtain this value 6616 6617 Level: intermediate 6618 6619 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`, `MatSetValues()`, ``MATELEMENTAL``, ``MATSCALAPACK`` 6620 @*/ 6621 PetscErrorCode MatGetOwnershipIS(Mat A, IS *rows, IS *cols) { 6622 PetscErrorCode (*f)(Mat, IS *, IS *); 6623 6624 PetscFunctionBegin; 6625 MatCheckPreallocated(A, 1); 6626 PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatGetOwnershipIS_C", &f)); 6627 if (f) { 6628 PetscCall((*f)(A, rows, cols)); 6629 } else { /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */ 6630 if (rows) PetscCall(ISCreateStride(PETSC_COMM_SELF, A->rmap->n, A->rmap->rstart, 1, rows)); 6631 if (cols) PetscCall(ISCreateStride(PETSC_COMM_SELF, A->cmap->N, 0, 1, cols)); 6632 } 6633 PetscFunctionReturn(0); 6634 } 6635 6636 /*@C 6637 MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix. 6638 Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric() 6639 to complete the factorization. 6640 6641 Collective on Mat 6642 6643 Input Parameters: 6644 + mat - the matrix 6645 . row - row permutation 6646 . column - column permutation 6647 - info - structure containing 6648 $ levels - number of levels of fill. 6649 $ expected fill - as ratio of original fill. 6650 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 6651 missing diagonal entries) 6652 6653 Output Parameters: 6654 . fact - new matrix that has been symbolically factored 6655 6656 Notes: 6657 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 6658 6659 Most users should employ the simplified KSP interface for linear solvers 6660 instead of working directly with matrix algebra routines such as this. 6661 See, e.g., KSPCreate(). 6662 6663 Level: developer 6664 6665 .seealso: `MatLUFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()` 6666 `MatGetOrdering()`, `MatFactorInfo` 6667 6668 Note: this uses the definition of level of fill as in Y. Saad, 2003 6669 6670 Developer Note: fortran interface is not autogenerated as the f90 6671 interface definition cannot be generated correctly [due to MatFactorInfo] 6672 6673 References: 6674 . * - Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6675 @*/ 6676 PetscErrorCode MatILUFactorSymbolic(Mat fact, Mat mat, IS row, IS col, const MatFactorInfo *info) { 6677 PetscFunctionBegin; 6678 PetscValidHeaderSpecific(mat, MAT_CLASSID, 2); 6679 PetscValidType(mat, 2); 6680 if (row) PetscValidHeaderSpecific(row, IS_CLASSID, 3); 6681 if (col) PetscValidHeaderSpecific(col, IS_CLASSID, 4); 6682 PetscValidPointer(info, 5); 6683 PetscValidPointer(fact, 1); 6684 PetscCheck(info->levels >= 0, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_OUTOFRANGE, "Levels of fill negative %" PetscInt_FMT, (PetscInt)info->levels); 6685 PetscCheck(info->fill >= 1.0, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_OUTOFRANGE, "Expected fill less than 1.0 %g", (double)info->fill); 6686 if (!fact->ops->ilufactorsymbolic) { 6687 MatSolverType stype; 6688 PetscCall(MatFactorGetSolverType(fact, &stype)); 6689 SETERRQ(PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Matrix type %s symbolic ILU using solver type %s", ((PetscObject)mat)->type_name, stype); 6690 } 6691 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 6692 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 6693 MatCheckPreallocated(mat, 2); 6694 6695 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_ILUFactorSymbolic, mat, row, col, 0)); 6696 PetscCall((fact->ops->ilufactorsymbolic)(fact, mat, row, col, info)); 6697 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_ILUFactorSymbolic, mat, row, col, 0)); 6698 PetscFunctionReturn(0); 6699 } 6700 6701 /*@C 6702 MatICCFactorSymbolic - Performs symbolic incomplete 6703 Cholesky factorization for a symmetric matrix. Use 6704 MatCholeskyFactorNumeric() to complete the factorization. 6705 6706 Collective on Mat 6707 6708 Input Parameters: 6709 + mat - the matrix 6710 . perm - row and column permutation 6711 - info - structure containing 6712 $ levels - number of levels of fill. 6713 $ expected fill - as ratio of original fill. 6714 6715 Output Parameter: 6716 . fact - the factored matrix 6717 6718 Notes: 6719 Most users should employ the KSP interface for linear solvers 6720 instead of working directly with matrix algebra routines such as this. 6721 See, e.g., KSPCreate(). 6722 6723 Level: developer 6724 6725 .seealso: `MatCholeskyFactorNumeric()`, `MatCholeskyFactor()`, `MatFactorInfo` 6726 6727 Note: this uses the definition of level of fill as in Y. Saad, 2003 6728 6729 Developer Note: fortran interface is not autogenerated as the f90 6730 interface definition cannot be generated correctly [due to MatFactorInfo] 6731 6732 References: 6733 . * - Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6734 @*/ 6735 PetscErrorCode MatICCFactorSymbolic(Mat fact, Mat mat, IS perm, const MatFactorInfo *info) { 6736 PetscFunctionBegin; 6737 PetscValidHeaderSpecific(mat, MAT_CLASSID, 2); 6738 PetscValidType(mat, 2); 6739 if (perm) PetscValidHeaderSpecific(perm, IS_CLASSID, 3); 6740 PetscValidPointer(info, 4); 6741 PetscValidPointer(fact, 1); 6742 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 6743 PetscCheck(info->levels >= 0, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_OUTOFRANGE, "Levels negative %" PetscInt_FMT, (PetscInt)info->levels); 6744 PetscCheck(info->fill >= 1.0, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_OUTOFRANGE, "Expected fill less than 1.0 %g", (double)info->fill); 6745 if (!(fact)->ops->iccfactorsymbolic) { 6746 MatSolverType stype; 6747 PetscCall(MatFactorGetSolverType(fact, &stype)); 6748 SETERRQ(PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Matrix type %s symbolic ICC using solver type %s", ((PetscObject)mat)->type_name, stype); 6749 } 6750 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 6751 MatCheckPreallocated(mat, 2); 6752 6753 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_ICCFactorSymbolic, mat, perm, 0, 0)); 6754 PetscCall((fact->ops->iccfactorsymbolic)(fact, mat, perm, info)); 6755 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_ICCFactorSymbolic, mat, perm, 0, 0)); 6756 PetscFunctionReturn(0); 6757 } 6758 6759 /*@C 6760 MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat 6761 points to an array of valid matrices, they may be reused to store the new 6762 submatrices. 6763 6764 Collective on Mat 6765 6766 Input Parameters: 6767 + mat - the matrix 6768 . n - the number of submatrixes to be extracted (on this processor, may be zero) 6769 . irow, icol - index sets of rows and columns to extract 6770 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6771 6772 Output Parameter: 6773 . submat - the array of submatrices 6774 6775 Notes: 6776 MatCreateSubMatrices() can extract ONLY sequential submatrices 6777 (from both sequential and parallel matrices). Use MatCreateSubMatrix() 6778 to extract a parallel submatrix. 6779 6780 Some matrix types place restrictions on the row and column 6781 indices, such as that they be sorted or that they be equal to each other. 6782 6783 The index sets may not have duplicate entries. 6784 6785 When extracting submatrices from a parallel matrix, each processor can 6786 form a different submatrix by setting the rows and columns of its 6787 individual index sets according to the local submatrix desired. 6788 6789 When finished using the submatrices, the user should destroy 6790 them with MatDestroySubMatrices(). 6791 6792 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 6793 original matrix has not changed from that last call to MatCreateSubMatrices(). 6794 6795 This routine creates the matrices in submat; you should NOT create them before 6796 calling it. It also allocates the array of matrix pointers submat. 6797 6798 For BAIJ matrices the index sets must respect the block structure, that is if they 6799 request one row/column in a block, they must request all rows/columns that are in 6800 that block. For example, if the block size is 2 you cannot request just row 0 and 6801 column 0. 6802 6803 Fortran Note: 6804 The Fortran interface is slightly different from that given below; it 6805 requires one to pass in as submat a Mat (integer) array of size at least n+1. 6806 6807 Level: advanced 6808 6809 .seealso: `MatDestroySubMatrices()`, `MatCreateSubMatrix()`, `MatGetRow()`, `MatGetDiagonal()`, `MatReuse` 6810 @*/ 6811 PetscErrorCode MatCreateSubMatrices(Mat mat, PetscInt n, const IS irow[], const IS icol[], MatReuse scall, Mat *submat[]) { 6812 PetscInt i; 6813 PetscBool eq; 6814 6815 PetscFunctionBegin; 6816 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6817 PetscValidType(mat, 1); 6818 if (n) { 6819 PetscValidPointer(irow, 3); 6820 for (i = 0; i < n; i++) PetscValidHeaderSpecific(irow[i], IS_CLASSID, 3); 6821 PetscValidPointer(icol, 4); 6822 for (i = 0; i < n; i++) PetscValidHeaderSpecific(icol[i], IS_CLASSID, 4); 6823 } 6824 PetscValidPointer(submat, 6); 6825 if (n && scall == MAT_REUSE_MATRIX) { 6826 PetscValidPointer(*submat, 6); 6827 for (i = 0; i < n; i++) PetscValidHeaderSpecific((*submat)[i], MAT_CLASSID, 6); 6828 } 6829 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 6830 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 6831 MatCheckPreallocated(mat, 1); 6832 PetscCall(PetscLogEventBegin(MAT_CreateSubMats, mat, 0, 0, 0)); 6833 PetscUseTypeMethod(mat, createsubmatrices, n, irow, icol, scall, submat); 6834 PetscCall(PetscLogEventEnd(MAT_CreateSubMats, mat, 0, 0, 0)); 6835 for (i = 0; i < n; i++) { 6836 (*submat)[i]->factortype = MAT_FACTOR_NONE; /* in case in place factorization was previously done on submatrix */ 6837 PetscCall(ISEqualUnsorted(irow[i], icol[i], &eq)); 6838 if (eq) PetscCall(MatPropagateSymmetryOptions(mat, (*submat)[i])); 6839 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 6840 if (mat->boundtocpu && mat->bindingpropagates) { 6841 PetscCall(MatBindToCPU((*submat)[i], PETSC_TRUE)); 6842 PetscCall(MatSetBindingPropagates((*submat)[i], PETSC_TRUE)); 6843 } 6844 #endif 6845 } 6846 PetscFunctionReturn(0); 6847 } 6848 6849 /*@C 6850 MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms). 6851 6852 Collective on Mat 6853 6854 Input Parameters: 6855 + mat - the matrix 6856 . n - the number of submatrixes to be extracted 6857 . irow, icol - index sets of rows and columns to extract 6858 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6859 6860 Output Parameter: 6861 . submat - the array of submatrices 6862 6863 Level: advanced 6864 6865 .seealso: `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRow()`, `MatGetDiagonal()`, `MatReuse` 6866 @*/ 6867 PetscErrorCode MatCreateSubMatricesMPI(Mat mat, PetscInt n, const IS irow[], const IS icol[], MatReuse scall, Mat *submat[]) { 6868 PetscInt i; 6869 PetscBool eq; 6870 6871 PetscFunctionBegin; 6872 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6873 PetscValidType(mat, 1); 6874 if (n) { 6875 PetscValidPointer(irow, 3); 6876 PetscValidHeaderSpecific(*irow, IS_CLASSID, 3); 6877 PetscValidPointer(icol, 4); 6878 PetscValidHeaderSpecific(*icol, IS_CLASSID, 4); 6879 } 6880 PetscValidPointer(submat, 6); 6881 if (n && scall == MAT_REUSE_MATRIX) { 6882 PetscValidPointer(*submat, 6); 6883 PetscValidHeaderSpecific(**submat, MAT_CLASSID, 6); 6884 } 6885 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 6886 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 6887 MatCheckPreallocated(mat, 1); 6888 6889 PetscCall(PetscLogEventBegin(MAT_CreateSubMats, mat, 0, 0, 0)); 6890 PetscUseTypeMethod(mat, createsubmatricesmpi, n, irow, icol, scall, submat); 6891 PetscCall(PetscLogEventEnd(MAT_CreateSubMats, mat, 0, 0, 0)); 6892 for (i = 0; i < n; i++) { 6893 PetscCall(ISEqualUnsorted(irow[i], icol[i], &eq)); 6894 if (eq) PetscCall(MatPropagateSymmetryOptions(mat, (*submat)[i])); 6895 } 6896 PetscFunctionReturn(0); 6897 } 6898 6899 /*@C 6900 MatDestroyMatrices - Destroys an array of matrices. 6901 6902 Collective on Mat 6903 6904 Input Parameters: 6905 + n - the number of local matrices 6906 - mat - the matrices (note that this is a pointer to the array of matrices) 6907 6908 Level: advanced 6909 6910 Notes: 6911 Frees not only the matrices, but also the array that contains the matrices 6912 In Fortran will not free the array. 6913 6914 .seealso: `MatCreateSubMatrices()` `MatDestroySubMatrices()` 6915 @*/ 6916 PetscErrorCode MatDestroyMatrices(PetscInt n, Mat *mat[]) { 6917 PetscInt i; 6918 6919 PetscFunctionBegin; 6920 if (!*mat) PetscFunctionReturn(0); 6921 PetscCheck(n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Trying to destroy negative number of matrices %" PetscInt_FMT, n); 6922 PetscValidPointer(mat, 2); 6923 6924 for (i = 0; i < n; i++) PetscCall(MatDestroy(&(*mat)[i])); 6925 6926 /* memory is allocated even if n = 0 */ 6927 PetscCall(PetscFree(*mat)); 6928 PetscFunctionReturn(0); 6929 } 6930 6931 /*@C 6932 MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices(). 6933 6934 Collective on Mat 6935 6936 Input Parameters: 6937 + n - the number of local matrices 6938 - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling 6939 sequence of MatCreateSubMatrices()) 6940 6941 Level: advanced 6942 6943 Notes: 6944 Frees not only the matrices, but also the array that contains the matrices 6945 In Fortran will not free the array. 6946 6947 .seealso: `MatCreateSubMatrices()` 6948 @*/ 6949 PetscErrorCode MatDestroySubMatrices(PetscInt n, Mat *mat[]) { 6950 Mat mat0; 6951 6952 PetscFunctionBegin; 6953 if (!*mat) PetscFunctionReturn(0); 6954 /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */ 6955 PetscCheck(n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Trying to destroy negative number of matrices %" PetscInt_FMT, n); 6956 PetscValidPointer(mat, 2); 6957 6958 mat0 = (*mat)[0]; 6959 if (mat0 && mat0->ops->destroysubmatrices) { 6960 PetscCall((mat0->ops->destroysubmatrices)(n, mat)); 6961 } else { 6962 PetscCall(MatDestroyMatrices(n, mat)); 6963 } 6964 PetscFunctionReturn(0); 6965 } 6966 6967 /*@C 6968 MatGetSeqNonzeroStructure - Extracts the nonzero structure from a matrix and stores it, in its entirety, on each process 6969 6970 Collective on Mat 6971 6972 Input Parameters: 6973 . mat - the matrix 6974 6975 Output Parameter: 6976 . matstruct - the sequential matrix with the nonzero structure of mat 6977 6978 Level: intermediate 6979 6980 .seealso: `MatDestroySeqNonzeroStructure()`, `MatCreateSubMatrices()`, `MatDestroyMatrices()` 6981 @*/ 6982 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat, Mat *matstruct) { 6983 PetscFunctionBegin; 6984 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 6985 PetscValidPointer(matstruct, 2); 6986 6987 PetscValidType(mat, 1); 6988 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 6989 MatCheckPreallocated(mat, 1); 6990 6991 PetscCall(PetscLogEventBegin(MAT_GetSeqNonzeroStructure, mat, 0, 0, 0)); 6992 PetscUseTypeMethod(mat, getseqnonzerostructure, matstruct); 6993 PetscCall(PetscLogEventEnd(MAT_GetSeqNonzeroStructure, mat, 0, 0, 0)); 6994 PetscFunctionReturn(0); 6995 } 6996 6997 /*@C 6998 MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure(). 6999 7000 Collective on Mat 7001 7002 Input Parameters: 7003 . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling 7004 sequence of MatGetSequentialNonzeroStructure()) 7005 7006 Level: advanced 7007 7008 Notes: 7009 Frees not only the matrices, but also the array that contains the matrices 7010 7011 .seealso: `MatGetSeqNonzeroStructure()` 7012 @*/ 7013 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat) { 7014 PetscFunctionBegin; 7015 PetscValidPointer(mat, 1); 7016 PetscCall(MatDestroy(mat)); 7017 PetscFunctionReturn(0); 7018 } 7019 7020 /*@ 7021 MatIncreaseOverlap - Given a set of submatrices indicated by index sets, 7022 replaces the index sets by larger ones that represent submatrices with 7023 additional overlap. 7024 7025 Collective on Mat 7026 7027 Input Parameters: 7028 + mat - the matrix 7029 . n - the number of index sets 7030 . is - the array of index sets (these index sets will changed during the call) 7031 - ov - the additional overlap requested 7032 7033 Options Database: 7034 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7035 7036 Level: developer 7037 7038 Developer Note: 7039 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. 7040 7041 .seealso: `MatCreateSubMatrices()` 7042 @*/ 7043 PetscErrorCode MatIncreaseOverlap(Mat mat, PetscInt n, IS is[], PetscInt ov) { 7044 PetscInt i, bs, cbs; 7045 7046 PetscFunctionBegin; 7047 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7048 PetscValidType(mat, 1); 7049 PetscValidLogicalCollectiveInt(mat, n, 2); 7050 PetscCheck(n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Must have one or more domains, you have %" PetscInt_FMT, n); 7051 if (n) { 7052 PetscValidPointer(is, 3); 7053 for (i = 0; i < n; i++) PetscValidHeaderSpecific(is[i], IS_CLASSID, 3); 7054 } 7055 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 7056 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 7057 MatCheckPreallocated(mat, 1); 7058 7059 if (!ov || !n) PetscFunctionReturn(0); 7060 PetscCall(PetscLogEventBegin(MAT_IncreaseOverlap, mat, 0, 0, 0)); 7061 PetscUseTypeMethod(mat, increaseoverlap, n, is, ov); 7062 PetscCall(PetscLogEventEnd(MAT_IncreaseOverlap, mat, 0, 0, 0)); 7063 PetscCall(MatGetBlockSizes(mat, &bs, &cbs)); 7064 if (bs == cbs) { 7065 for (i = 0; i < n; i++) PetscCall(ISSetBlockSize(is[i], bs)); 7066 } 7067 PetscFunctionReturn(0); 7068 } 7069 7070 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat, IS *, PetscInt); 7071 7072 /*@ 7073 MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across 7074 a sub communicator, replaces the index sets by larger ones that represent submatrices with 7075 additional overlap. 7076 7077 Collective on Mat 7078 7079 Input Parameters: 7080 + mat - the matrix 7081 . n - the number of index sets 7082 . is - the array of index sets (these index sets will changed during the call) 7083 - ov - the additional overlap requested 7084 7085 Options Database: 7086 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7087 7088 Level: developer 7089 7090 .seealso: `MatCreateSubMatrices()` 7091 @*/ 7092 PetscErrorCode MatIncreaseOverlapSplit(Mat mat, PetscInt n, IS is[], PetscInt ov) { 7093 PetscInt i; 7094 7095 PetscFunctionBegin; 7096 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7097 PetscValidType(mat, 1); 7098 PetscCheck(n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Must have one or more domains, you have %" PetscInt_FMT, n); 7099 if (n) { 7100 PetscValidPointer(is, 3); 7101 PetscValidHeaderSpecific(*is, IS_CLASSID, 3); 7102 } 7103 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 7104 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 7105 MatCheckPreallocated(mat, 1); 7106 if (!ov) PetscFunctionReturn(0); 7107 PetscCall(PetscLogEventBegin(MAT_IncreaseOverlap, mat, 0, 0, 0)); 7108 for (i = 0; i < n; i++) PetscCall(MatIncreaseOverlapSplit_Single(mat, &is[i], ov)); 7109 PetscCall(PetscLogEventEnd(MAT_IncreaseOverlap, mat, 0, 0, 0)); 7110 PetscFunctionReturn(0); 7111 } 7112 7113 /*@ 7114 MatGetBlockSize - Returns the matrix block size. 7115 7116 Not Collective 7117 7118 Input Parameter: 7119 . mat - the matrix 7120 7121 Output Parameter: 7122 . bs - block size 7123 7124 Notes: 7125 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7126 7127 If the block size has not been set yet this routine returns 1. 7128 7129 Level: intermediate 7130 7131 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSizes()` 7132 @*/ 7133 PetscErrorCode MatGetBlockSize(Mat mat, PetscInt *bs) { 7134 PetscFunctionBegin; 7135 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7136 PetscValidIntPointer(bs, 2); 7137 *bs = PetscAbs(mat->rmap->bs); 7138 PetscFunctionReturn(0); 7139 } 7140 7141 /*@ 7142 MatGetBlockSizes - Returns the matrix block row and column sizes. 7143 7144 Not Collective 7145 7146 Input Parameter: 7147 . mat - the matrix 7148 7149 Output Parameters: 7150 + rbs - row block size 7151 - cbs - column block size 7152 7153 Notes: 7154 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7155 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7156 7157 If a block size has not been set yet this routine returns 1. 7158 7159 Level: intermediate 7160 7161 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSize()`, `MatSetBlockSizes()` 7162 @*/ 7163 PetscErrorCode MatGetBlockSizes(Mat mat, PetscInt *rbs, PetscInt *cbs) { 7164 PetscFunctionBegin; 7165 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7166 if (rbs) PetscValidIntPointer(rbs, 2); 7167 if (cbs) PetscValidIntPointer(cbs, 3); 7168 if (rbs) *rbs = PetscAbs(mat->rmap->bs); 7169 if (cbs) *cbs = PetscAbs(mat->cmap->bs); 7170 PetscFunctionReturn(0); 7171 } 7172 7173 /*@ 7174 MatSetBlockSize - Sets the matrix block size. 7175 7176 Logically Collective on Mat 7177 7178 Input Parameters: 7179 + mat - the matrix 7180 - bs - block size 7181 7182 Notes: 7183 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7184 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7185 7186 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size 7187 is compatible with the matrix local sizes. 7188 7189 Level: intermediate 7190 7191 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`, `MatGetBlockSizes()` 7192 @*/ 7193 PetscErrorCode MatSetBlockSize(Mat mat, PetscInt bs) { 7194 PetscFunctionBegin; 7195 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7196 PetscValidLogicalCollectiveInt(mat, bs, 2); 7197 PetscCall(MatSetBlockSizes(mat, bs, bs)); 7198 PetscFunctionReturn(0); 7199 } 7200 7201 typedef struct { 7202 PetscInt n; 7203 IS *is; 7204 Mat *mat; 7205 PetscObjectState nonzerostate; 7206 Mat C; 7207 } EnvelopeData; 7208 7209 static PetscErrorCode EnvelopeDataDestroy(EnvelopeData *edata) { 7210 for (PetscInt i = 0; i < edata->n; i++) PetscCall(ISDestroy(&edata->is[i])); 7211 PetscCall(PetscFree(edata->is)); 7212 PetscCall(PetscFree(edata)); 7213 return 0; 7214 } 7215 7216 /* 7217 MatComputeVariableBlockEnvelope - Given a matrix whose nonzeros are in blocks along the diagonal this computes and stores 7218 the sizes of these blocks in the matrix. An individual block may lie over several processes. 7219 7220 Collective on mat 7221 7222 Input Parameter: 7223 . mat - the matrix 7224 7225 Notes: 7226 There can be zeros within the blocks 7227 7228 The blocks can overlap between processes, including laying on more than two processes 7229 7230 */ 7231 static PetscErrorCode MatComputeVariableBlockEnvelope(Mat mat) { 7232 PetscInt n, *sizes, *starts, i = 0, env = 0, tbs = 0, lblocks = 0, rstart, II, ln = 0, cnt = 0, cstart, cend; 7233 PetscInt *diag, *odiag, sc; 7234 VecScatter scatter; 7235 PetscScalar *seqv; 7236 const PetscScalar *parv; 7237 const PetscInt *ia, *ja; 7238 PetscBool set, flag, done; 7239 Mat AA = mat, A; 7240 MPI_Comm comm; 7241 PetscMPIInt rank, size, tag; 7242 MPI_Status status; 7243 PetscContainer container; 7244 EnvelopeData *edata; 7245 Vec seq, par; 7246 IS isglobal; 7247 7248 PetscFunctionBegin; 7249 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7250 PetscCall(MatIsSymmetricKnown(mat, &set, &flag)); 7251 if (!set || !flag) { 7252 /* TOO: only needs nonzero structure of transpose */ 7253 PetscCall(MatTranspose(mat, MAT_INITIAL_MATRIX, &AA)); 7254 PetscCall(MatAXPY(AA, 1.0, mat, DIFFERENT_NONZERO_PATTERN)); 7255 } 7256 PetscCall(MatAIJGetLocalMat(AA, &A)); 7257 PetscCall(MatGetRowIJ(A, 0, PETSC_FALSE, PETSC_FALSE, &n, &ia, &ja, &done)); 7258 PetscCheck(done, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Unable to get IJ structure from matrix"); 7259 7260 PetscCall(MatGetLocalSize(mat, &n, NULL)); 7261 PetscCall(PetscObjectGetNewTag((PetscObject)mat, &tag)); 7262 PetscCall(PetscObjectGetComm((PetscObject)mat, &comm)); 7263 PetscCallMPI(MPI_Comm_size(comm, &size)); 7264 PetscCallMPI(MPI_Comm_rank(comm, &rank)); 7265 7266 PetscCall(PetscMalloc2(n, &sizes, n, &starts)); 7267 7268 if (rank > 0) { 7269 PetscCallMPI(MPI_Recv(&env, 1, MPIU_INT, rank - 1, tag, comm, &status)); 7270 PetscCallMPI(MPI_Recv(&tbs, 1, MPIU_INT, rank - 1, tag, comm, &status)); 7271 } 7272 PetscCall(MatGetOwnershipRange(mat, &rstart, NULL)); 7273 for (i = 0; i < n; i++) { 7274 env = PetscMax(env, ja[ia[i + 1] - 1]); 7275 II = rstart + i; 7276 if (env == II) { 7277 starts[lblocks] = tbs; 7278 sizes[lblocks++] = 1 + II - tbs; 7279 tbs = 1 + II; 7280 } 7281 } 7282 if (rank < size - 1) { 7283 PetscCallMPI(MPI_Send(&env, 1, MPIU_INT, rank + 1, tag, comm)); 7284 PetscCallMPI(MPI_Send(&tbs, 1, MPIU_INT, rank + 1, tag, comm)); 7285 } 7286 7287 PetscCall(MatRestoreRowIJ(A, 0, PETSC_FALSE, PETSC_FALSE, &n, &ia, &ja, &done)); 7288 if (!set || !flag) PetscCall(MatDestroy(&AA)); 7289 PetscCall(MatDestroy(&A)); 7290 7291 PetscCall(PetscNew(&edata)); 7292 PetscCall(MatGetNonzeroState(mat, &edata->nonzerostate)); 7293 edata->n = lblocks; 7294 /* create IS needed for extracting blocks from the original matrix */ 7295 PetscCall(PetscMalloc1(lblocks, &edata->is)); 7296 for (PetscInt i = 0; i < lblocks; i++) PetscCall(ISCreateStride(PETSC_COMM_SELF, sizes[i], starts[i], 1, &edata->is[i])); 7297 7298 /* Create the resulting inverse matrix structure with preallocation information */ 7299 PetscCall(MatCreate(PetscObjectComm((PetscObject)mat), &edata->C)); 7300 PetscCall(MatSetSizes(edata->C, mat->rmap->n, mat->cmap->n, mat->rmap->N, mat->cmap->N)); 7301 PetscCall(MatSetBlockSizesFromMats(edata->C, mat, mat)); 7302 PetscCall(MatSetType(edata->C, MATAIJ)); 7303 7304 /* Communicate the start and end of each row, from each block to the correct rank */ 7305 /* TODO: Use PetscSF instead of VecScatter */ 7306 for (PetscInt i = 0; i < lblocks; i++) ln += sizes[i]; 7307 PetscCall(VecCreateSeq(PETSC_COMM_SELF, 2 * ln, &seq)); 7308 PetscCall(VecGetArrayWrite(seq, &seqv)); 7309 for (PetscInt i = 0; i < lblocks; i++) { 7310 for (PetscInt j = 0; j < sizes[i]; j++) { 7311 seqv[cnt] = starts[i]; 7312 seqv[cnt + 1] = starts[i] + sizes[i]; 7313 cnt += 2; 7314 } 7315 } 7316 PetscCall(VecRestoreArrayWrite(seq, &seqv)); 7317 PetscCallMPI(MPI_Scan(&cnt, &sc, 1, MPIU_INT, MPI_SUM, PetscObjectComm((PetscObject)mat))); 7318 sc -= cnt; 7319 PetscCall(VecCreateMPI(PetscObjectComm((PetscObject)mat), 2 * mat->rmap->n, 2 * mat->rmap->N, &par)); 7320 PetscCall(ISCreateStride(PETSC_COMM_SELF, cnt, sc, 1, &isglobal)); 7321 PetscCall(VecScatterCreate(seq, NULL, par, isglobal, &scatter)); 7322 PetscCall(ISDestroy(&isglobal)); 7323 PetscCall(VecScatterBegin(scatter, seq, par, INSERT_VALUES, SCATTER_FORWARD)); 7324 PetscCall(VecScatterEnd(scatter, seq, par, INSERT_VALUES, SCATTER_FORWARD)); 7325 PetscCall(VecScatterDestroy(&scatter)); 7326 PetscCall(VecDestroy(&seq)); 7327 PetscCall(MatGetOwnershipRangeColumn(mat, &cstart, &cend)); 7328 PetscCall(PetscMalloc2(mat->rmap->n, &diag, mat->rmap->n, &odiag)); 7329 PetscCall(VecGetArrayRead(par, &parv)); 7330 cnt = 0; 7331 PetscCall(MatGetSize(mat, NULL, &n)); 7332 for (PetscInt i = 0; i < mat->rmap->n; i++) { 7333 PetscInt start, end, d = 0, od = 0; 7334 7335 start = (PetscInt)PetscRealPart(parv[cnt]); 7336 end = (PetscInt)PetscRealPart(parv[cnt + 1]); 7337 cnt += 2; 7338 7339 if (start < cstart) { 7340 od += cstart - start + n - cend; 7341 d += cend - cstart; 7342 } else if (start < cend) { 7343 od += n - cend; 7344 d += cend - start; 7345 } else od += n - start; 7346 if (end <= cstart) { 7347 od -= cstart - end + n - cend; 7348 d -= cend - cstart; 7349 } else if (end < cend) { 7350 od -= n - cend; 7351 d -= cend - end; 7352 } else od -= n - end; 7353 7354 odiag[i] = od; 7355 diag[i] = d; 7356 } 7357 PetscCall(VecRestoreArrayRead(par, &parv)); 7358 PetscCall(VecDestroy(&par)); 7359 PetscCall(MatXAIJSetPreallocation(edata->C, mat->rmap->bs, diag, odiag, NULL, NULL)); 7360 PetscCall(PetscFree2(diag, odiag)); 7361 PetscCall(PetscFree2(sizes, starts)); 7362 7363 PetscCall(PetscContainerCreate(PETSC_COMM_SELF, &container)); 7364 PetscCall(PetscContainerSetPointer(container, edata)); 7365 PetscCall(PetscContainerSetUserDestroy(container, (PetscErrorCode(*)(void *))EnvelopeDataDestroy)); 7366 PetscCall(PetscObjectCompose((PetscObject)mat, "EnvelopeData", (PetscObject)container)); 7367 PetscCall(PetscObjectDereference((PetscObject)container)); 7368 PetscFunctionReturn(0); 7369 } 7370 7371 /*@ 7372 MatInvertVariableBlockEnvelope - set matrix C to be the inverted block diagonal of matrix A 7373 7374 Collective on Mat 7375 7376 Input Parameters: 7377 . A - the matrix 7378 7379 Output Parameters: 7380 . C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set. 7381 7382 Notes: 7383 For efficiency the matrix A should have all the nonzero entries clustered in smallish blocks along the diagonal. 7384 7385 Level: advanced 7386 7387 .seealso: MatInvertBlockDiagonal(), MatComputeBlockDiagonal() 7388 @*/ 7389 PetscErrorCode MatInvertVariableBlockEnvelope(Mat A, MatReuse reuse, Mat *C) { 7390 PetscContainer container; 7391 EnvelopeData *edata; 7392 PetscObjectState nonzerostate; 7393 7394 PetscFunctionBegin; 7395 PetscCall(PetscObjectQuery((PetscObject)A, "EnvelopeData", (PetscObject *)&container)); 7396 if (!container) { 7397 PetscCall(MatComputeVariableBlockEnvelope(A)); 7398 PetscCall(PetscObjectQuery((PetscObject)A, "EnvelopeData", (PetscObject *)&container)); 7399 } 7400 PetscCall(PetscContainerGetPointer(container, (void **)&edata)); 7401 PetscCall(MatGetNonzeroState(A, &nonzerostate)); 7402 PetscCheck(nonzerostate <= edata->nonzerostate, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Cannot handle changes to matrix nonzero structure"); 7403 PetscCheck(reuse != MAT_REUSE_MATRIX || *C == edata->C, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "C matrix must be the same as previously output"); 7404 7405 PetscCall(MatCreateSubMatrices(A, edata->n, edata->is, edata->is, MAT_INITIAL_MATRIX, &edata->mat)); 7406 *C = edata->C; 7407 7408 for (PetscInt i = 0; i < edata->n; i++) { 7409 Mat D; 7410 PetscScalar *dvalues; 7411 7412 PetscCall(MatConvert(edata->mat[i], MATSEQDENSE, MAT_INITIAL_MATRIX, &D)); 7413 PetscCall(MatSetOption(*C, MAT_ROW_ORIENTED, PETSC_FALSE)); 7414 PetscCall(MatSeqDenseInvert(D)); 7415 PetscCall(MatDenseGetArray(D, &dvalues)); 7416 PetscCall(MatSetValuesIS(*C, edata->is[i], edata->is[i], dvalues, INSERT_VALUES)); 7417 PetscCall(MatDestroy(&D)); 7418 } 7419 PetscCall(MatDestroySubMatrices(edata->n, &edata->mat)); 7420 PetscCall(MatAssemblyBegin(*C, MAT_FINAL_ASSEMBLY)); 7421 PetscCall(MatAssemblyEnd(*C, MAT_FINAL_ASSEMBLY)); 7422 PetscFunctionReturn(0); 7423 } 7424 7425 /*@ 7426 MatSetVariableBlockSizes - Sets diagonal point-blocks of the matrix that need not be of the same size 7427 7428 Logically Collective on Mat 7429 7430 Input Parameters: 7431 + mat - the matrix 7432 . nblocks - the number of blocks on this process, each block can only exist on a single process 7433 - bsizes - the block sizes 7434 7435 Notes: 7436 Currently used by PCVPBJACOBI for AIJ matrices 7437 7438 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. 7439 7440 Level: intermediate 7441 7442 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`, `MatGetBlockSizes()`, `MatGetVariableBlockSizes()`, `MatComputeVariableBlockEnvelope()`, `PCVPBJACOBI` 7443 @*/ 7444 PetscErrorCode MatSetVariableBlockSizes(Mat mat, PetscInt nblocks, PetscInt *bsizes) { 7445 PetscInt i, ncnt = 0, nlocal; 7446 7447 PetscFunctionBegin; 7448 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7449 PetscCheck(nblocks >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Number of local blocks must be great than or equal to zero"); 7450 PetscCall(MatGetLocalSize(mat, &nlocal, NULL)); 7451 for (i = 0; i < nblocks; i++) ncnt += bsizes[i]; 7452 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); 7453 PetscCall(PetscFree(mat->bsizes)); 7454 mat->nblocks = nblocks; 7455 PetscCall(PetscMalloc1(nblocks, &mat->bsizes)); 7456 PetscCall(PetscArraycpy(mat->bsizes, bsizes, nblocks)); 7457 PetscFunctionReturn(0); 7458 } 7459 7460 /*@C 7461 MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size 7462 7463 Logically Collective on Mat 7464 7465 Input Parameter: 7466 . mat - the matrix 7467 7468 Output Parameters: 7469 + nblocks - the number of blocks on this process 7470 - bsizes - the block sizes 7471 7472 Notes: Currently not supported from Fortran 7473 7474 Level: intermediate 7475 7476 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`, `MatGetBlockSizes()`, `MatSetVariableBlockSizes()`, `MatComputeVariableBlockEnvelope()` 7477 @*/ 7478 PetscErrorCode MatGetVariableBlockSizes(Mat mat, PetscInt *nblocks, const PetscInt **bsizes) { 7479 PetscFunctionBegin; 7480 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7481 *nblocks = mat->nblocks; 7482 *bsizes = mat->bsizes; 7483 PetscFunctionReturn(0); 7484 } 7485 7486 /*@ 7487 MatSetBlockSizes - Sets the matrix block row and column sizes. 7488 7489 Logically Collective on Mat 7490 7491 Input Parameters: 7492 + mat - the matrix 7493 . rbs - row block size 7494 - cbs - column block size 7495 7496 Notes: 7497 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7498 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7499 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7500 7501 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes 7502 are compatible with the matrix local sizes. 7503 7504 The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs(). 7505 7506 Level: intermediate 7507 7508 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSize()`, `MatGetBlockSizes()` 7509 @*/ 7510 PetscErrorCode MatSetBlockSizes(Mat mat, PetscInt rbs, PetscInt cbs) { 7511 PetscFunctionBegin; 7512 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7513 PetscValidLogicalCollectiveInt(mat, rbs, 2); 7514 PetscValidLogicalCollectiveInt(mat, cbs, 3); 7515 PetscTryTypeMethod(mat, setblocksizes, rbs, cbs); 7516 if (mat->rmap->refcnt) { 7517 ISLocalToGlobalMapping l2g = NULL; 7518 PetscLayout nmap = NULL; 7519 7520 PetscCall(PetscLayoutDuplicate(mat->rmap, &nmap)); 7521 if (mat->rmap->mapping) PetscCall(ISLocalToGlobalMappingDuplicate(mat->rmap->mapping, &l2g)); 7522 PetscCall(PetscLayoutDestroy(&mat->rmap)); 7523 mat->rmap = nmap; 7524 mat->rmap->mapping = l2g; 7525 } 7526 if (mat->cmap->refcnt) { 7527 ISLocalToGlobalMapping l2g = NULL; 7528 PetscLayout nmap = NULL; 7529 7530 PetscCall(PetscLayoutDuplicate(mat->cmap, &nmap)); 7531 if (mat->cmap->mapping) PetscCall(ISLocalToGlobalMappingDuplicate(mat->cmap->mapping, &l2g)); 7532 PetscCall(PetscLayoutDestroy(&mat->cmap)); 7533 mat->cmap = nmap; 7534 mat->cmap->mapping = l2g; 7535 } 7536 PetscCall(PetscLayoutSetBlockSize(mat->rmap, rbs)); 7537 PetscCall(PetscLayoutSetBlockSize(mat->cmap, cbs)); 7538 PetscFunctionReturn(0); 7539 } 7540 7541 /*@ 7542 MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices 7543 7544 Logically Collective on Mat 7545 7546 Input Parameters: 7547 + mat - the matrix 7548 . fromRow - matrix from which to copy row block size 7549 - fromCol - matrix from which to copy column block size (can be same as fromRow) 7550 7551 Level: developer 7552 7553 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()` 7554 @*/ 7555 PetscErrorCode MatSetBlockSizesFromMats(Mat mat, Mat fromRow, Mat fromCol) { 7556 PetscFunctionBegin; 7557 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7558 PetscValidHeaderSpecific(fromRow, MAT_CLASSID, 2); 7559 PetscValidHeaderSpecific(fromCol, MAT_CLASSID, 3); 7560 if (fromRow->rmap->bs > 0) PetscCall(PetscLayoutSetBlockSize(mat->rmap, fromRow->rmap->bs)); 7561 if (fromCol->cmap->bs > 0) PetscCall(PetscLayoutSetBlockSize(mat->cmap, fromCol->cmap->bs)); 7562 PetscFunctionReturn(0); 7563 } 7564 7565 /*@ 7566 MatResidual - Default routine to calculate the residual. 7567 7568 Collective on Mat 7569 7570 Input Parameters: 7571 + mat - the matrix 7572 . b - the right-hand-side 7573 - x - the approximate solution 7574 7575 Output Parameter: 7576 . r - location to store the residual 7577 7578 Level: developer 7579 7580 .seealso: `PCMGSetResidual()` 7581 @*/ 7582 PetscErrorCode MatResidual(Mat mat, Vec b, Vec x, Vec r) { 7583 PetscFunctionBegin; 7584 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7585 PetscValidHeaderSpecific(b, VEC_CLASSID, 2); 7586 PetscValidHeaderSpecific(x, VEC_CLASSID, 3); 7587 PetscValidHeaderSpecific(r, VEC_CLASSID, 4); 7588 PetscValidType(mat, 1); 7589 MatCheckPreallocated(mat, 1); 7590 PetscCall(PetscLogEventBegin(MAT_Residual, mat, 0, 0, 0)); 7591 if (!mat->ops->residual) { 7592 PetscCall(MatMult(mat, x, r)); 7593 PetscCall(VecAYPX(r, -1.0, b)); 7594 } else { 7595 PetscUseTypeMethod(mat, residual, b, x, r); 7596 } 7597 PetscCall(PetscLogEventEnd(MAT_Residual, mat, 0, 0, 0)); 7598 PetscFunctionReturn(0); 7599 } 7600 7601 /*@C 7602 MatGetRowIJ - Returns the compressed row storage i and j indices for the local rows of a sparse matrix 7603 7604 Collective on Mat 7605 7606 Input Parameters: 7607 + mat - the matrix 7608 . shift - 0 or 1 indicating we want the indices starting at 0 or 1 7609 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized 7610 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7611 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7612 always used. 7613 7614 Output Parameters: 7615 + n - number of local rows in the (possibly compressed) matrix 7616 . ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix 7617 . ja - the column indices 7618 - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers 7619 are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set 7620 7621 Level: developer 7622 7623 Notes: 7624 You CANNOT change any of the ia[] or ja[] values. 7625 7626 Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values. 7627 7628 Fortran Notes: 7629 In Fortran use 7630 $ 7631 $ PetscInt ia(1), ja(1) 7632 $ PetscOffset iia, jja 7633 $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr) 7634 $ ! Access the ith and jth entries via ia(iia + i) and ja(jja + j) 7635 7636 or 7637 $ 7638 $ PetscInt, pointer :: ia(:),ja(:) 7639 $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr) 7640 $ ! Access the ith and jth entries via ia(i) and ja(j) 7641 7642 .seealso: `MatGetColumnIJ()`, `MatRestoreRowIJ()`, `MatSeqAIJGetArray()` 7643 @*/ 7644 PetscErrorCode MatGetRowIJ(Mat mat, PetscInt shift, PetscBool symmetric, PetscBool inodecompressed, PetscInt *n, const PetscInt *ia[], const PetscInt *ja[], PetscBool *done) { 7645 PetscFunctionBegin; 7646 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7647 PetscValidType(mat, 1); 7648 if (n) PetscValidIntPointer(n, 5); 7649 if (ia) PetscValidPointer(ia, 6); 7650 if (ja) PetscValidPointer(ja, 7); 7651 if (done) PetscValidBoolPointer(done, 8); 7652 MatCheckPreallocated(mat, 1); 7653 if (!mat->ops->getrowij && done) *done = PETSC_FALSE; 7654 else { 7655 if (done) *done = PETSC_TRUE; 7656 PetscCall(PetscLogEventBegin(MAT_GetRowIJ, mat, 0, 0, 0)); 7657 PetscUseTypeMethod(mat, getrowij, shift, symmetric, inodecompressed, n, ia, ja, done); 7658 PetscCall(PetscLogEventEnd(MAT_GetRowIJ, mat, 0, 0, 0)); 7659 } 7660 PetscFunctionReturn(0); 7661 } 7662 7663 /*@C 7664 MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices. 7665 7666 Collective on Mat 7667 7668 Input Parameters: 7669 + mat - the matrix 7670 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7671 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7672 symmetrized 7673 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7674 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7675 always used. 7676 . n - number of columns in the (possibly compressed) matrix 7677 . ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix 7678 - ja - the row indices 7679 7680 Output Parameters: 7681 . done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned 7682 7683 Level: developer 7684 7685 .seealso: `MatGetRowIJ()`, `MatRestoreColumnIJ()` 7686 @*/ 7687 PetscErrorCode MatGetColumnIJ(Mat mat, PetscInt shift, PetscBool symmetric, PetscBool inodecompressed, PetscInt *n, const PetscInt *ia[], const PetscInt *ja[], PetscBool *done) { 7688 PetscFunctionBegin; 7689 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7690 PetscValidType(mat, 1); 7691 PetscValidIntPointer(n, 5); 7692 if (ia) PetscValidPointer(ia, 6); 7693 if (ja) PetscValidPointer(ja, 7); 7694 PetscValidBoolPointer(done, 8); 7695 MatCheckPreallocated(mat, 1); 7696 if (!mat->ops->getcolumnij) *done = PETSC_FALSE; 7697 else { 7698 *done = PETSC_TRUE; 7699 PetscUseTypeMethod(mat, getcolumnij, shift, symmetric, inodecompressed, n, ia, ja, done); 7700 } 7701 PetscFunctionReturn(0); 7702 } 7703 7704 /*@C 7705 MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with 7706 MatGetRowIJ(). 7707 7708 Collective on Mat 7709 7710 Input Parameters: 7711 + mat - the matrix 7712 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7713 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7714 symmetrized 7715 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7716 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7717 always used. 7718 . n - size of (possibly compressed) matrix 7719 . ia - the row pointers 7720 - ja - the column indices 7721 7722 Output Parameters: 7723 . done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7724 7725 Note: 7726 This routine zeros out n, ia, and ja. This is to prevent accidental 7727 us of the array after it has been restored. If you pass NULL, it will 7728 not zero the pointers. Use of ia or ja after MatRestoreRowIJ() is invalid. 7729 7730 Level: developer 7731 7732 .seealso: `MatGetRowIJ()`, `MatRestoreColumnIJ()` 7733 @*/ 7734 PetscErrorCode MatRestoreRowIJ(Mat mat, PetscInt shift, PetscBool symmetric, PetscBool inodecompressed, PetscInt *n, const PetscInt *ia[], const PetscInt *ja[], PetscBool *done) { 7735 PetscFunctionBegin; 7736 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7737 PetscValidType(mat, 1); 7738 if (ia) PetscValidPointer(ia, 6); 7739 if (ja) PetscValidPointer(ja, 7); 7740 if (done) PetscValidBoolPointer(done, 8); 7741 MatCheckPreallocated(mat, 1); 7742 7743 if (!mat->ops->restorerowij && done) *done = PETSC_FALSE; 7744 else { 7745 if (done) *done = PETSC_TRUE; 7746 PetscUseTypeMethod(mat, restorerowij, shift, symmetric, inodecompressed, n, ia, ja, done); 7747 if (n) *n = 0; 7748 if (ia) *ia = NULL; 7749 if (ja) *ja = NULL; 7750 } 7751 PetscFunctionReturn(0); 7752 } 7753 7754 /*@C 7755 MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with 7756 MatGetColumnIJ(). 7757 7758 Collective on Mat 7759 7760 Input Parameters: 7761 + mat - the matrix 7762 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7763 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7764 symmetrized 7765 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7766 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7767 always used. 7768 7769 Output Parameters: 7770 + n - size of (possibly compressed) matrix 7771 . ia - the column pointers 7772 . ja - the row indices 7773 - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7774 7775 Level: developer 7776 7777 .seealso: `MatGetColumnIJ()`, `MatRestoreRowIJ()` 7778 @*/ 7779 PetscErrorCode MatRestoreColumnIJ(Mat mat, PetscInt shift, PetscBool symmetric, PetscBool inodecompressed, PetscInt *n, const PetscInt *ia[], const PetscInt *ja[], PetscBool *done) { 7780 PetscFunctionBegin; 7781 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7782 PetscValidType(mat, 1); 7783 if (ia) PetscValidPointer(ia, 6); 7784 if (ja) PetscValidPointer(ja, 7); 7785 PetscValidBoolPointer(done, 8); 7786 MatCheckPreallocated(mat, 1); 7787 7788 if (!mat->ops->restorecolumnij) *done = PETSC_FALSE; 7789 else { 7790 *done = PETSC_TRUE; 7791 PetscUseTypeMethod(mat, restorecolumnij, shift, symmetric, inodecompressed, n, ia, ja, done); 7792 if (n) *n = 0; 7793 if (ia) *ia = NULL; 7794 if (ja) *ja = NULL; 7795 } 7796 PetscFunctionReturn(0); 7797 } 7798 7799 /*@C 7800 MatColoringPatch -Used inside matrix coloring routines that 7801 use MatGetRowIJ() and/or MatGetColumnIJ(). 7802 7803 Collective on Mat 7804 7805 Input Parameters: 7806 + mat - the matrix 7807 . ncolors - max color value 7808 . n - number of entries in colorarray 7809 - colorarray - array indicating color for each column 7810 7811 Output Parameters: 7812 . iscoloring - coloring generated using colorarray information 7813 7814 Level: developer 7815 7816 .seealso: `MatGetRowIJ()`, `MatGetColumnIJ()` 7817 7818 @*/ 7819 PetscErrorCode MatColoringPatch(Mat mat, PetscInt ncolors, PetscInt n, ISColoringValue colorarray[], ISColoring *iscoloring) { 7820 PetscFunctionBegin; 7821 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7822 PetscValidType(mat, 1); 7823 PetscValidIntPointer(colorarray, 4); 7824 PetscValidPointer(iscoloring, 5); 7825 MatCheckPreallocated(mat, 1); 7826 7827 if (!mat->ops->coloringpatch) { 7828 PetscCall(ISColoringCreate(PetscObjectComm((PetscObject)mat), ncolors, n, colorarray, PETSC_OWN_POINTER, iscoloring)); 7829 } else { 7830 PetscUseTypeMethod(mat, coloringpatch, ncolors, n, colorarray, iscoloring); 7831 } 7832 PetscFunctionReturn(0); 7833 } 7834 7835 /*@ 7836 MatSetUnfactored - Resets a factored matrix to be treated as unfactored. 7837 7838 Logically Collective on Mat 7839 7840 Input Parameter: 7841 . mat - the factored matrix to be reset 7842 7843 Notes: 7844 This routine should be used only with factored matrices formed by in-place 7845 factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE 7846 format). This option can save memory, for example, when solving nonlinear 7847 systems with a matrix-free Newton-Krylov method and a matrix-based, in-place 7848 ILU(0) preconditioner. 7849 7850 Note that one can specify in-place ILU(0) factorization by calling 7851 .vb 7852 PCType(pc,PCILU); 7853 PCFactorSeUseInPlace(pc); 7854 .ve 7855 or by using the options -pc_type ilu -pc_factor_in_place 7856 7857 In-place factorization ILU(0) can also be used as a local 7858 solver for the blocks within the block Jacobi or additive Schwarz 7859 methods (runtime option: -sub_pc_factor_in_place). See Users-Manual: ch_pc 7860 for details on setting local solver options. 7861 7862 Most users should employ the simplified KSP interface for linear solvers 7863 instead of working directly with matrix algebra routines such as this. 7864 See, e.g., KSPCreate(). 7865 7866 Level: developer 7867 7868 .seealso: `PCFactorSetUseInPlace()`, `PCFactorGetUseInPlace()` 7869 7870 @*/ 7871 PetscErrorCode MatSetUnfactored(Mat mat) { 7872 PetscFunctionBegin; 7873 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 7874 PetscValidType(mat, 1); 7875 MatCheckPreallocated(mat, 1); 7876 mat->factortype = MAT_FACTOR_NONE; 7877 if (!mat->ops->setunfactored) PetscFunctionReturn(0); 7878 PetscUseTypeMethod(mat, setunfactored); 7879 PetscFunctionReturn(0); 7880 } 7881 7882 /*MC 7883 MatDenseGetArrayF90 - Accesses a matrix array from Fortran90. 7884 7885 Synopsis: 7886 MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7887 7888 Not collective 7889 7890 Input Parameter: 7891 . x - matrix 7892 7893 Output Parameters: 7894 + xx_v - the Fortran90 pointer to the array 7895 - ierr - error code 7896 7897 Example of Usage: 7898 .vb 7899 PetscScalar, pointer xx_v(:,:) 7900 .... 7901 call MatDenseGetArrayF90(x,xx_v,ierr) 7902 a = xx_v(3) 7903 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7904 .ve 7905 7906 Level: advanced 7907 7908 .seealso: `MatDenseRestoreArrayF90()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatSeqAIJGetArrayF90()` 7909 7910 M*/ 7911 7912 /*MC 7913 MatDenseRestoreArrayF90 - Restores a matrix array that has been 7914 accessed with MatDenseGetArrayF90(). 7915 7916 Synopsis: 7917 MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7918 7919 Not collective 7920 7921 Input Parameters: 7922 + x - matrix 7923 - xx_v - the Fortran90 pointer to the array 7924 7925 Output Parameter: 7926 . ierr - error code 7927 7928 Example of Usage: 7929 .vb 7930 PetscScalar, pointer xx_v(:,:) 7931 .... 7932 call MatDenseGetArrayF90(x,xx_v,ierr) 7933 a = xx_v(3) 7934 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7935 .ve 7936 7937 Level: advanced 7938 7939 .seealso: `MatDenseGetArrayF90()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatSeqAIJRestoreArrayF90()` 7940 7941 M*/ 7942 7943 /*MC 7944 MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90. 7945 7946 Synopsis: 7947 MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7948 7949 Not collective 7950 7951 Input Parameter: 7952 . x - matrix 7953 7954 Output Parameters: 7955 + xx_v - the Fortran90 pointer to the array 7956 - ierr - error code 7957 7958 Example of Usage: 7959 .vb 7960 PetscScalar, pointer xx_v(:) 7961 .... 7962 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 7963 a = xx_v(3) 7964 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 7965 .ve 7966 7967 Level: advanced 7968 7969 .seealso: `MatSeqAIJRestoreArrayF90()`, `MatSeqAIJGetArray()`, `MatSeqAIJRestoreArray()`, `MatDenseGetArrayF90()` 7970 7971 M*/ 7972 7973 /*MC 7974 MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been 7975 accessed with MatSeqAIJGetArrayF90(). 7976 7977 Synopsis: 7978 MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7979 7980 Not collective 7981 7982 Input Parameters: 7983 + x - matrix 7984 - xx_v - the Fortran90 pointer to the array 7985 7986 Output Parameter: 7987 . ierr - error code 7988 7989 Example of Usage: 7990 .vb 7991 PetscScalar, pointer xx_v(:) 7992 .... 7993 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 7994 a = xx_v(3) 7995 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 7996 .ve 7997 7998 Level: advanced 7999 8000 .seealso: `MatSeqAIJGetArrayF90()`, `MatSeqAIJGetArray()`, `MatSeqAIJRestoreArray()`, `MatDenseRestoreArrayF90()` 8001 8002 M*/ 8003 8004 /*@ 8005 MatCreateSubMatrix - Gets a single submatrix on the same number of processors 8006 as the original matrix. 8007 8008 Collective on Mat 8009 8010 Input Parameters: 8011 + mat - the original matrix 8012 . isrow - parallel IS containing the rows this processor should obtain 8013 . 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. 8014 - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 8015 8016 Output Parameter: 8017 . newmat - the new submatrix, of the same type as the old 8018 8019 Level: advanced 8020 8021 Notes: 8022 The submatrix will be able to be multiplied with vectors using the same layout as iscol. 8023 8024 Some matrix types place restrictions on the row and column indices, such 8025 as that they be sorted or that they be equal to each other. 8026 8027 The index sets may not have duplicate entries. 8028 8029 The first time this is called you should use a cll of MAT_INITIAL_MATRIX, 8030 the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls 8031 to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX 8032 will reuse the matrix generated the first time. You should call MatDestroy() on newmat when 8033 you are finished using it. 8034 8035 The communicator of the newly obtained matrix is ALWAYS the same as the communicator of 8036 the input matrix. 8037 8038 If iscol is NULL then all columns are obtained (not supported in Fortran). 8039 8040 Example usage: 8041 Consider the following 8x8 matrix with 34 non-zero values, that is 8042 assembled across 3 processors. Let's assume that proc0 owns 3 rows, 8043 proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown 8044 as follows: 8045 8046 .vb 8047 1 2 0 | 0 3 0 | 0 4 8048 Proc0 0 5 6 | 7 0 0 | 8 0 8049 9 0 10 | 11 0 0 | 12 0 8050 ------------------------------------- 8051 13 0 14 | 15 16 17 | 0 0 8052 Proc1 0 18 0 | 19 20 21 | 0 0 8053 0 0 0 | 22 23 0 | 24 0 8054 ------------------------------------- 8055 Proc2 25 26 27 | 0 0 28 | 29 0 8056 30 0 0 | 31 32 33 | 0 34 8057 .ve 8058 8059 Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is 8060 8061 .vb 8062 2 0 | 0 3 0 | 0 8063 Proc0 5 6 | 7 0 0 | 8 8064 ------------------------------- 8065 Proc1 18 0 | 19 20 21 | 0 8066 ------------------------------- 8067 Proc2 26 27 | 0 0 28 | 29 8068 0 0 | 31 32 33 | 0 8069 .ve 8070 8071 .seealso: `MatCreateSubMatrices()`, `MatCreateSubMatricesMPI()`, `MatCreateSubMatrixVirtual()`, `MatSubMatrixVirtualUpdate()` 8072 @*/ 8073 PetscErrorCode MatCreateSubMatrix(Mat mat, IS isrow, IS iscol, MatReuse cll, Mat *newmat) { 8074 PetscMPIInt size; 8075 Mat *local; 8076 IS iscoltmp; 8077 PetscBool flg; 8078 8079 PetscFunctionBegin; 8080 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8081 PetscValidHeaderSpecific(isrow, IS_CLASSID, 2); 8082 if (iscol) PetscValidHeaderSpecific(iscol, IS_CLASSID, 3); 8083 PetscValidPointer(newmat, 5); 8084 if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat, MAT_CLASSID, 5); 8085 PetscValidType(mat, 1); 8086 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 8087 PetscCheck(cll != MAT_IGNORE_MATRIX, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Cannot use MAT_IGNORE_MATRIX"); 8088 8089 MatCheckPreallocated(mat, 1); 8090 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size)); 8091 8092 if (!iscol || isrow == iscol) { 8093 PetscBool stride; 8094 PetscMPIInt grabentirematrix = 0, grab; 8095 PetscCall(PetscObjectTypeCompare((PetscObject)isrow, ISSTRIDE, &stride)); 8096 if (stride) { 8097 PetscInt first, step, n, rstart, rend; 8098 PetscCall(ISStrideGetInfo(isrow, &first, &step)); 8099 if (step == 1) { 8100 PetscCall(MatGetOwnershipRange(mat, &rstart, &rend)); 8101 if (rstart == first) { 8102 PetscCall(ISGetLocalSize(isrow, &n)); 8103 if (n == rend - rstart) { grabentirematrix = 1; } 8104 } 8105 } 8106 } 8107 PetscCall(MPIU_Allreduce(&grabentirematrix, &grab, 1, MPI_INT, MPI_MIN, PetscObjectComm((PetscObject)mat))); 8108 if (grab) { 8109 PetscCall(PetscInfo(mat, "Getting entire matrix as submatrix\n")); 8110 if (cll == MAT_INITIAL_MATRIX) { 8111 *newmat = mat; 8112 PetscCall(PetscObjectReference((PetscObject)mat)); 8113 } 8114 PetscFunctionReturn(0); 8115 } 8116 } 8117 8118 if (!iscol) { 8119 PetscCall(ISCreateStride(PetscObjectComm((PetscObject)mat), mat->cmap->n, mat->cmap->rstart, 1, &iscoltmp)); 8120 } else { 8121 iscoltmp = iscol; 8122 } 8123 8124 /* if original matrix is on just one processor then use submatrix generated */ 8125 if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) { 8126 PetscCall(MatCreateSubMatrices(mat, 1, &isrow, &iscoltmp, MAT_REUSE_MATRIX, &newmat)); 8127 goto setproperties; 8128 } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) { 8129 PetscCall(MatCreateSubMatrices(mat, 1, &isrow, &iscoltmp, MAT_INITIAL_MATRIX, &local)); 8130 *newmat = *local; 8131 PetscCall(PetscFree(local)); 8132 goto setproperties; 8133 } else if (!mat->ops->createsubmatrix) { 8134 /* Create a new matrix type that implements the operation using the full matrix */ 8135 PetscCall(PetscLogEventBegin(MAT_CreateSubMat, mat, 0, 0, 0)); 8136 switch (cll) { 8137 case MAT_INITIAL_MATRIX: PetscCall(MatCreateSubMatrixVirtual(mat, isrow, iscoltmp, newmat)); break; 8138 case MAT_REUSE_MATRIX: PetscCall(MatSubMatrixVirtualUpdate(*newmat, mat, isrow, iscoltmp)); break; 8139 default: SETERRQ(PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_OUTOFRANGE, "Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX"); 8140 } 8141 PetscCall(PetscLogEventEnd(MAT_CreateSubMat, mat, 0, 0, 0)); 8142 goto setproperties; 8143 } 8144 8145 PetscCall(PetscLogEventBegin(MAT_CreateSubMat, mat, 0, 0, 0)); 8146 PetscUseTypeMethod(mat, createsubmatrix, isrow, iscoltmp, cll, newmat); 8147 PetscCall(PetscLogEventEnd(MAT_CreateSubMat, mat, 0, 0, 0)); 8148 8149 setproperties: 8150 PetscCall(ISEqualUnsorted(isrow, iscoltmp, &flg)); 8151 if (flg) PetscCall(MatPropagateSymmetryOptions(mat, *newmat)); 8152 if (!iscol) PetscCall(ISDestroy(&iscoltmp)); 8153 if (*newmat && cll == MAT_INITIAL_MATRIX) PetscCall(PetscObjectStateIncrease((PetscObject)*newmat)); 8154 PetscFunctionReturn(0); 8155 } 8156 8157 /*@ 8158 MatPropagateSymmetryOptions - Propagates symmetry options set on a matrix to another matrix 8159 8160 Not Collective 8161 8162 Input Parameters: 8163 + A - the matrix we wish to propagate options from 8164 - B - the matrix we wish to propagate options to 8165 8166 Level: beginner 8167 8168 Notes: 8169 Propagates the options associated to `MAT_SYMMETRY_ETERNAL`, `MAT_STRUCTURALLY_SYMMETRIC`, `MAT_HERMITIAN`, `MAT_SPD`, `MAT_SYMMETRIC`, and `MAT_STRUCTURAL_SYMMETRY_ETERNAL` 8170 8171 .seealso: `MatSetOption()`, `MatIsSymmetricKnown()`, `MatIsSPDKnown()`, `MatIsHermitianKnown()`, MatIsStructurallySymmetricKnown()` 8172 @*/ 8173 PetscErrorCode MatPropagateSymmetryOptions(Mat A, Mat B) { 8174 PetscFunctionBegin; 8175 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8176 PetscValidHeaderSpecific(B, MAT_CLASSID, 2); 8177 B->symmetry_eternal = A->symmetry_eternal; 8178 B->structural_symmetry_eternal = A->structural_symmetry_eternal; 8179 B->symmetric = A->symmetric; 8180 B->structurally_symmetric = A->structurally_symmetric; 8181 B->spd = A->spd; 8182 B->hermitian = A->hermitian; 8183 PetscFunctionReturn(0); 8184 } 8185 8186 /*@ 8187 MatStashSetInitialSize - sets the sizes of the matrix stash, that is 8188 used during the assembly process to store values that belong to 8189 other processors. 8190 8191 Not Collective 8192 8193 Input Parameters: 8194 + mat - the matrix 8195 . size - the initial size of the stash. 8196 - bsize - the initial size of the block-stash(if used). 8197 8198 Options Database Keys: 8199 + -matstash_initial_size <size> or <size0,size1,...sizep-1> 8200 - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1> 8201 8202 Level: intermediate 8203 8204 Notes: 8205 The block-stash is used for values set with MatSetValuesBlocked() while 8206 the stash is used for values set with MatSetValues() 8207 8208 Run with the option -info and look for output of the form 8209 MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs. 8210 to determine the appropriate value, MM, to use for size and 8211 MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs. 8212 to determine the value, BMM to use for bsize 8213 8214 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `Mat`, `MatStashGetInfo()` 8215 8216 @*/ 8217 PetscErrorCode MatStashSetInitialSize(Mat mat, PetscInt size, PetscInt bsize) { 8218 PetscFunctionBegin; 8219 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8220 PetscValidType(mat, 1); 8221 PetscCall(MatStashSetInitialSize_Private(&mat->stash, size)); 8222 PetscCall(MatStashSetInitialSize_Private(&mat->bstash, bsize)); 8223 PetscFunctionReturn(0); 8224 } 8225 8226 /*@ 8227 MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 8228 the matrix 8229 8230 Neighbor-wise Collective on Mat 8231 8232 Input Parameters: 8233 + mat - the matrix 8234 . x,y - the vectors 8235 - w - where the result is stored 8236 8237 Level: intermediate 8238 8239 Notes: 8240 w may be the same vector as y. 8241 8242 This allows one to use either the restriction or interpolation (its transpose) 8243 matrix to do the interpolation 8244 8245 .seealso: `MatMultAdd()`, `MatMultTransposeAdd()`, `MatRestrict()` 8246 8247 @*/ 8248 PetscErrorCode MatInterpolateAdd(Mat A, Vec x, Vec y, Vec w) { 8249 PetscInt M, N, Ny; 8250 8251 PetscFunctionBegin; 8252 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8253 PetscValidHeaderSpecific(x, VEC_CLASSID, 2); 8254 PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 8255 PetscValidHeaderSpecific(w, VEC_CLASSID, 4); 8256 PetscCall(MatGetSize(A, &M, &N)); 8257 PetscCall(VecGetSize(y, &Ny)); 8258 if (M == Ny) { 8259 PetscCall(MatMultAdd(A, x, y, w)); 8260 } else { 8261 PetscCall(MatMultTransposeAdd(A, x, y, w)); 8262 } 8263 PetscFunctionReturn(0); 8264 } 8265 8266 /*@ 8267 MatInterpolate - y = A*x or A'*x depending on the shape of 8268 the matrix 8269 8270 Neighbor-wise Collective on Mat 8271 8272 Input Parameters: 8273 + mat - the matrix 8274 - x,y - the vectors 8275 8276 Level: intermediate 8277 8278 Notes: 8279 This allows one to use either the restriction or interpolation (its transpose) 8280 matrix to do the interpolation 8281 8282 .seealso: `MatMultAdd()`, `MatMultTransposeAdd()`, `MatRestrict()` 8283 8284 @*/ 8285 PetscErrorCode MatInterpolate(Mat A, Vec x, Vec y) { 8286 PetscInt M, N, Ny; 8287 8288 PetscFunctionBegin; 8289 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8290 PetscValidHeaderSpecific(x, VEC_CLASSID, 2); 8291 PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 8292 PetscCall(MatGetSize(A, &M, &N)); 8293 PetscCall(VecGetSize(y, &Ny)); 8294 if (M == Ny) { 8295 PetscCall(MatMult(A, x, y)); 8296 } else { 8297 PetscCall(MatMultTranspose(A, x, y)); 8298 } 8299 PetscFunctionReturn(0); 8300 } 8301 8302 /*@ 8303 MatRestrict - y = A*x or A'*x 8304 8305 Neighbor-wise Collective on Mat 8306 8307 Input Parameters: 8308 + mat - the matrix 8309 - x,y - the vectors 8310 8311 Level: intermediate 8312 8313 Notes: 8314 This allows one to use either the restriction or interpolation (its transpose) 8315 matrix to do the restriction 8316 8317 .seealso: `MatMultAdd()`, `MatMultTransposeAdd()`, `MatInterpolate()` 8318 8319 @*/ 8320 PetscErrorCode MatRestrict(Mat A, Vec x, Vec y) { 8321 PetscInt M, N, Ny; 8322 8323 PetscFunctionBegin; 8324 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8325 PetscValidHeaderSpecific(x, VEC_CLASSID, 2); 8326 PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 8327 PetscCall(MatGetSize(A, &M, &N)); 8328 PetscCall(VecGetSize(y, &Ny)); 8329 if (M == Ny) { 8330 PetscCall(MatMult(A, x, y)); 8331 } else { 8332 PetscCall(MatMultTranspose(A, x, y)); 8333 } 8334 PetscFunctionReturn(0); 8335 } 8336 8337 /*@ 8338 MatMatInterpolateAdd - Y = W + A*X or W + A'*X 8339 8340 Neighbor-wise Collective on Mat 8341 8342 Input Parameters: 8343 + mat - the matrix 8344 - w, x - the input dense matrices 8345 8346 Output Parameters: 8347 . y - the output dense matrix 8348 8349 Level: intermediate 8350 8351 Notes: 8352 This allows one to use either the restriction or interpolation (its transpose) 8353 matrix to do the interpolation. y matrix can be reused if already created with the proper sizes, 8354 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8355 8356 .seealso: `MatInterpolateAdd()`, `MatMatInterpolate()`, `MatMatRestrict()` 8357 8358 @*/ 8359 PetscErrorCode MatMatInterpolateAdd(Mat A, Mat x, Mat w, Mat *y) { 8360 PetscInt M, N, Mx, Nx, Mo, My = 0, Ny = 0; 8361 PetscBool trans = PETSC_TRUE; 8362 MatReuse reuse = MAT_INITIAL_MATRIX; 8363 8364 PetscFunctionBegin; 8365 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8366 PetscValidHeaderSpecific(x, MAT_CLASSID, 2); 8367 PetscValidType(x, 2); 8368 if (w) PetscValidHeaderSpecific(w, MAT_CLASSID, 3); 8369 if (*y) PetscValidHeaderSpecific(*y, MAT_CLASSID, 4); 8370 PetscCall(MatGetSize(A, &M, &N)); 8371 PetscCall(MatGetSize(x, &Mx, &Nx)); 8372 if (N == Mx) trans = PETSC_FALSE; 8373 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); 8374 Mo = trans ? N : M; 8375 if (*y) { 8376 PetscCall(MatGetSize(*y, &My, &Ny)); 8377 if (Mo == My && Nx == Ny) { 8378 reuse = MAT_REUSE_MATRIX; 8379 } else { 8380 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); 8381 PetscCall(MatDestroy(y)); 8382 } 8383 } 8384 8385 if (w && *y == w) { /* this is to minimize changes in PCMG */ 8386 PetscBool flg; 8387 8388 PetscCall(PetscObjectQuery((PetscObject)*y, "__MatMatIntAdd_w", (PetscObject *)&w)); 8389 if (w) { 8390 PetscInt My, Ny, Mw, Nw; 8391 8392 PetscCall(PetscObjectTypeCompare((PetscObject)*y, ((PetscObject)w)->type_name, &flg)); 8393 PetscCall(MatGetSize(*y, &My, &Ny)); 8394 PetscCall(MatGetSize(w, &Mw, &Nw)); 8395 if (!flg || My != Mw || Ny != Nw) w = NULL; 8396 } 8397 if (!w) { 8398 PetscCall(MatDuplicate(*y, MAT_COPY_VALUES, &w)); 8399 PetscCall(PetscObjectCompose((PetscObject)*y, "__MatMatIntAdd_w", (PetscObject)w)); 8400 PetscCall(PetscLogObjectParent((PetscObject)*y, (PetscObject)w)); 8401 PetscCall(PetscObjectDereference((PetscObject)w)); 8402 } else { 8403 PetscCall(MatCopy(*y, w, UNKNOWN_NONZERO_PATTERN)); 8404 } 8405 } 8406 if (!trans) { 8407 PetscCall(MatMatMult(A, x, reuse, PETSC_DEFAULT, y)); 8408 } else { 8409 PetscCall(MatTransposeMatMult(A, x, reuse, PETSC_DEFAULT, y)); 8410 } 8411 if (w) PetscCall(MatAXPY(*y, 1.0, w, UNKNOWN_NONZERO_PATTERN)); 8412 PetscFunctionReturn(0); 8413 } 8414 8415 /*@ 8416 MatMatInterpolate - Y = A*X or A'*X 8417 8418 Neighbor-wise Collective on Mat 8419 8420 Input Parameters: 8421 + mat - the matrix 8422 - x - the input dense matrix 8423 8424 Output Parameters: 8425 . y - the output dense matrix 8426 8427 Level: intermediate 8428 8429 Notes: 8430 This allows one to use either the restriction or interpolation (its transpose) 8431 matrix to do the interpolation. y matrix can be reused if already created with the proper sizes, 8432 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8433 8434 .seealso: `MatInterpolate()`, `MatRestrict()`, `MatMatRestrict()` 8435 8436 @*/ 8437 PetscErrorCode MatMatInterpolate(Mat A, Mat x, Mat *y) { 8438 PetscFunctionBegin; 8439 PetscCall(MatMatInterpolateAdd(A, x, NULL, y)); 8440 PetscFunctionReturn(0); 8441 } 8442 8443 /*@ 8444 MatMatRestrict - Y = A*X or A'*X 8445 8446 Neighbor-wise Collective on Mat 8447 8448 Input Parameters: 8449 + mat - the matrix 8450 - x - the input dense matrix 8451 8452 Output Parameters: 8453 . y - the output dense matrix 8454 8455 Level: intermediate 8456 8457 Notes: 8458 This allows one to use either the restriction or interpolation (its transpose) 8459 matrix to do the restriction. y matrix can be reused if already created with the proper sizes, 8460 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8461 8462 .seealso: `MatRestrict()`, `MatInterpolate()`, `MatMatInterpolate()` 8463 @*/ 8464 PetscErrorCode MatMatRestrict(Mat A, Mat x, Mat *y) { 8465 PetscFunctionBegin; 8466 PetscCall(MatMatInterpolateAdd(A, x, NULL, y)); 8467 PetscFunctionReturn(0); 8468 } 8469 8470 /*@ 8471 MatGetNullSpace - retrieves the null space of a matrix. 8472 8473 Logically Collective on Mat 8474 8475 Input Parameters: 8476 + mat - the matrix 8477 - nullsp - the null space object 8478 8479 Level: developer 8480 8481 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatSetNullSpace()` 8482 @*/ 8483 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp) { 8484 PetscFunctionBegin; 8485 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8486 PetscValidPointer(nullsp, 2); 8487 *nullsp = (mat->symmetric == PETSC_BOOL3_TRUE && !mat->nullsp) ? mat->transnullsp : mat->nullsp; 8488 PetscFunctionReturn(0); 8489 } 8490 8491 /*@ 8492 MatSetNullSpace - attaches a null space to a matrix. 8493 8494 Logically Collective on Mat 8495 8496 Input Parameters: 8497 + mat - the matrix 8498 - nullsp - the null space object 8499 8500 Level: advanced 8501 8502 Notes: 8503 This null space is used by the KSP linear solvers to solve singular systems. 8504 8505 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 8506 8507 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 8508 to zero but the linear system will still be solved in a least squares sense. 8509 8510 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8511 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). 8512 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 8513 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 8514 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). 8515 This \hat{b} can be obtained by calling MatNullSpaceRemove() with the null space of the transpose of the matrix. 8516 8517 If the matrix is known to be symmetric because it is an SBAIJ matrix or one as called MatSetOption(mat,MAT_SYMMETRIC or MAT_SYMMETRY_ETERNAL,PETSC_TRUE); this 8518 routine also automatically calls MatSetTransposeNullSpace(). 8519 8520 The user should call `MatNullSpaceDestroy()`. 8521 8522 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatGetNullSpace()`, `MatSetTransposeNullSpace()`, `MatGetTransposeNullSpace()`, `MatNullSpaceRemove()`, 8523 `KSPSetPCSide()` 8524 @*/ 8525 PetscErrorCode MatSetNullSpace(Mat mat, MatNullSpace nullsp) { 8526 PetscFunctionBegin; 8527 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8528 if (nullsp) PetscValidHeaderSpecific(nullsp, MAT_NULLSPACE_CLASSID, 2); 8529 if (nullsp) PetscCall(PetscObjectReference((PetscObject)nullsp)); 8530 PetscCall(MatNullSpaceDestroy(&mat->nullsp)); 8531 mat->nullsp = nullsp; 8532 if (mat->symmetric == PETSC_BOOL3_TRUE) PetscCall(MatSetTransposeNullSpace(mat, nullsp)); 8533 PetscFunctionReturn(0); 8534 } 8535 8536 /*@ 8537 MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix. 8538 8539 Logically Collective on Mat 8540 8541 Input Parameters: 8542 + mat - the matrix 8543 - nullsp - the null space object 8544 8545 Level: developer 8546 8547 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatSetTransposeNullSpace()`, `MatSetNullSpace()`, `MatGetNullSpace()` 8548 @*/ 8549 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp) { 8550 PetscFunctionBegin; 8551 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8552 PetscValidType(mat, 1); 8553 PetscValidPointer(nullsp, 2); 8554 *nullsp = (mat->symmetric == PETSC_BOOL3_TRUE && !mat->transnullsp) ? mat->nullsp : mat->transnullsp; 8555 PetscFunctionReturn(0); 8556 } 8557 8558 /*@ 8559 MatSetTransposeNullSpace - attaches the null space of a transpose of a matrix to the matrix 8560 8561 Logically Collective on Mat 8562 8563 Input Parameters: 8564 + mat - the matrix 8565 - nullsp - the null space object 8566 8567 Level: advanced 8568 8569 Notes: 8570 This allows solving singular linear systems defined by the transpose of the matrix using KSP solvers with left preconditioning. 8571 8572 See MatSetNullSpace() 8573 8574 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatGetNullSpace()`, `MatSetNullSpace()`, `MatGetTransposeNullSpace()`, `MatNullSpaceRemove()`, `KSPSetPCSide()` 8575 @*/ 8576 PetscErrorCode MatSetTransposeNullSpace(Mat mat, MatNullSpace nullsp) { 8577 PetscFunctionBegin; 8578 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8579 if (nullsp) PetscValidHeaderSpecific(nullsp, MAT_NULLSPACE_CLASSID, 2); 8580 if (nullsp) PetscCall(PetscObjectReference((PetscObject)nullsp)); 8581 PetscCall(MatNullSpaceDestroy(&mat->transnullsp)); 8582 mat->transnullsp = nullsp; 8583 PetscFunctionReturn(0); 8584 } 8585 8586 /*@ 8587 MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions 8588 This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix. 8589 8590 Logically Collective on Mat 8591 8592 Input Parameters: 8593 + mat - the matrix 8594 - nullsp - the null space object 8595 8596 Level: advanced 8597 8598 Notes: 8599 Overwrites any previous near null space that may have been attached 8600 8601 You can remove the null space by calling this routine with an nullsp of NULL 8602 8603 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNullSpace()`, `MatNullSpaceCreateRigidBody()`, `MatGetNearNullSpace()` 8604 @*/ 8605 PetscErrorCode MatSetNearNullSpace(Mat mat, MatNullSpace nullsp) { 8606 PetscFunctionBegin; 8607 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8608 PetscValidType(mat, 1); 8609 if (nullsp) PetscValidHeaderSpecific(nullsp, MAT_NULLSPACE_CLASSID, 2); 8610 MatCheckPreallocated(mat, 1); 8611 if (nullsp) PetscCall(PetscObjectReference((PetscObject)nullsp)); 8612 PetscCall(MatNullSpaceDestroy(&mat->nearnullsp)); 8613 mat->nearnullsp = nullsp; 8614 PetscFunctionReturn(0); 8615 } 8616 8617 /*@ 8618 MatGetNearNullSpace - Get null space attached with MatSetNearNullSpace() 8619 8620 Not Collective 8621 8622 Input Parameter: 8623 . mat - the matrix 8624 8625 Output Parameter: 8626 . nullsp - the null space object, NULL if not set 8627 8628 Level: developer 8629 8630 .seealso: `MatSetNearNullSpace()`, `MatGetNullSpace()`, `MatNullSpaceCreate()` 8631 @*/ 8632 PetscErrorCode MatGetNearNullSpace(Mat mat, MatNullSpace *nullsp) { 8633 PetscFunctionBegin; 8634 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8635 PetscValidType(mat, 1); 8636 PetscValidPointer(nullsp, 2); 8637 MatCheckPreallocated(mat, 1); 8638 *nullsp = mat->nearnullsp; 8639 PetscFunctionReturn(0); 8640 } 8641 8642 /*@C 8643 MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix. 8644 8645 Collective on Mat 8646 8647 Input Parameters: 8648 + mat - the matrix 8649 . row - row/column permutation 8650 . fill - expected fill factor >= 1.0 8651 - level - level of fill, for ICC(k) 8652 8653 Notes: 8654 Probably really in-place only when level of fill is zero, otherwise allocates 8655 new space to store factored matrix and deletes previous memory. 8656 8657 Most users should employ the simplified KSP interface for linear solvers 8658 instead of working directly with matrix algebra routines such as this. 8659 See, e.g., KSPCreate(). 8660 8661 Level: developer 8662 8663 .seealso: `MatICCFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()` 8664 8665 Developer Note: fortran interface is not autogenerated as the f90 8666 interface definition cannot be generated correctly [due to MatFactorInfo] 8667 8668 @*/ 8669 PetscErrorCode MatICCFactor(Mat mat, IS row, const MatFactorInfo *info) { 8670 PetscFunctionBegin; 8671 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8672 PetscValidType(mat, 1); 8673 if (row) PetscValidHeaderSpecific(row, IS_CLASSID, 2); 8674 PetscValidPointer(info, 3); 8675 PetscCheck(mat->rmap->N == mat->cmap->N, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONG, "matrix must be square"); 8676 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 8677 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 8678 MatCheckPreallocated(mat, 1); 8679 PetscUseTypeMethod(mat, iccfactor, row, info); 8680 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 8681 PetscFunctionReturn(0); 8682 } 8683 8684 /*@ 8685 MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 8686 ghosted ones. 8687 8688 Not Collective 8689 8690 Input Parameters: 8691 + mat - the matrix 8692 - diag - the diagonal values, including ghost ones 8693 8694 Level: developer 8695 8696 Notes: 8697 Works only for MPIAIJ and MPIBAIJ matrices 8698 8699 .seealso: `MatDiagonalScale()` 8700 @*/ 8701 PetscErrorCode MatDiagonalScaleLocal(Mat mat, Vec diag) { 8702 PetscMPIInt size; 8703 8704 PetscFunctionBegin; 8705 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8706 PetscValidHeaderSpecific(diag, VEC_CLASSID, 2); 8707 PetscValidType(mat, 1); 8708 8709 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Matrix must be already assembled"); 8710 PetscCall(PetscLogEventBegin(MAT_Scale, mat, 0, 0, 0)); 8711 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size)); 8712 if (size == 1) { 8713 PetscInt n, m; 8714 PetscCall(VecGetSize(diag, &n)); 8715 PetscCall(MatGetSize(mat, NULL, &m)); 8716 if (m == n) { 8717 PetscCall(MatDiagonalScale(mat, NULL, diag)); 8718 } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Only supported for sequential matrices when no ghost points/periodic conditions"); 8719 } else { 8720 PetscUseMethod(mat, "MatDiagonalScaleLocal_C", (Mat, Vec), (mat, diag)); 8721 } 8722 PetscCall(PetscLogEventEnd(MAT_Scale, mat, 0, 0, 0)); 8723 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 8724 PetscFunctionReturn(0); 8725 } 8726 8727 /*@ 8728 MatGetInertia - Gets the inertia from a factored matrix 8729 8730 Collective on Mat 8731 8732 Input Parameter: 8733 . mat - the matrix 8734 8735 Output Parameters: 8736 + nneg - number of negative eigenvalues 8737 . nzero - number of zero eigenvalues 8738 - npos - number of positive eigenvalues 8739 8740 Level: advanced 8741 8742 Notes: 8743 Matrix must have been factored by MatCholeskyFactor() 8744 8745 @*/ 8746 PetscErrorCode MatGetInertia(Mat mat, PetscInt *nneg, PetscInt *nzero, PetscInt *npos) { 8747 PetscFunctionBegin; 8748 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8749 PetscValidType(mat, 1); 8750 PetscCheck(mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Unfactored matrix"); 8751 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Numeric factor mat is not assembled"); 8752 PetscUseTypeMethod(mat, getinertia, nneg, nzero, npos); 8753 PetscFunctionReturn(0); 8754 } 8755 8756 /* ----------------------------------------------------------------*/ 8757 /*@C 8758 MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors 8759 8760 Neighbor-wise Collective on Mats 8761 8762 Input Parameters: 8763 + mat - the factored matrix 8764 - b - the right-hand-side vectors 8765 8766 Output Parameter: 8767 . x - the result vectors 8768 8769 Notes: 8770 The vectors b and x cannot be the same. I.e., one cannot 8771 call MatSolves(A,x,x). 8772 8773 Notes: 8774 Most users should employ the simplified KSP interface for linear solvers 8775 instead of working directly with matrix algebra routines such as this. 8776 See, e.g., KSPCreate(). 8777 8778 Level: developer 8779 8780 .seealso: `MatSolveAdd()`, `MatSolveTranspose()`, `MatSolveTransposeAdd()`, `MatSolve()` 8781 @*/ 8782 PetscErrorCode MatSolves(Mat mat, Vecs b, Vecs x) { 8783 PetscFunctionBegin; 8784 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 8785 PetscValidType(mat, 1); 8786 PetscCheck(x != b, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_IDN, "x and b must be different vectors"); 8787 PetscCheck(mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Unfactored matrix"); 8788 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 8789 8790 MatCheckPreallocated(mat, 1); 8791 PetscCall(PetscLogEventBegin(MAT_Solves, mat, 0, 0, 0)); 8792 PetscUseTypeMethod(mat, solves, b, x); 8793 PetscCall(PetscLogEventEnd(MAT_Solves, mat, 0, 0, 0)); 8794 PetscFunctionReturn(0); 8795 } 8796 8797 /*@ 8798 MatIsSymmetric - Test whether a matrix is symmetric 8799 8800 Collective on Mat 8801 8802 Input Parameters: 8803 + A - the matrix to test 8804 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose) 8805 8806 Output Parameters: 8807 . flg - the result 8808 8809 Notes: 8810 For real numbers MatIsSymmetric() and MatIsHermitian() return identical results 8811 8812 If the matrix does not yet know if it is symmetric or not this can be an expensive operation, also available `MatIsSymmetricKnown()` 8813 8814 Level: intermediate 8815 8816 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetricKnown()` 8817 @*/ 8818 PetscErrorCode MatIsSymmetric(Mat A, PetscReal tol, PetscBool *flg) { 8819 PetscFunctionBegin; 8820 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8821 PetscValidBoolPointer(flg, 3); 8822 8823 if (A->symmetric == PETSC_BOOL3_TRUE) *flg = PETSC_TRUE; 8824 else if (A->symmetric == PETSC_BOOL3_FALSE) *flg = PETSC_FALSE; 8825 else { 8826 if (!A->ops->issymmetric) { 8827 MatType mattype; 8828 PetscCall(MatGetType(A, &mattype)); 8829 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Matrix of type %s does not support checking for symmetric", mattype); 8830 } 8831 PetscUseTypeMethod(A, issymmetric, tol, flg); 8832 if (!tol) PetscCall(MatSetOption(A, MAT_SYMMETRIC, *flg)); 8833 } 8834 PetscFunctionReturn(0); 8835 } 8836 8837 /*@ 8838 MatIsHermitian - Test whether a matrix is Hermitian 8839 8840 Collective on Mat 8841 8842 Input Parameters: 8843 + A - the matrix to test 8844 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian) 8845 8846 Output Parameters: 8847 . flg - the result 8848 8849 Level: intermediate 8850 8851 Notes: 8852 For real numbers MatIsSymmetric() and MatIsHermitian() return identical results 8853 8854 If the matrix does not yet know if it is hermitian or not this can be an expensive operation, also available `MatIsHermitianKnown()` 8855 8856 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitianKnown()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, 8857 `MatIsSymmetricKnown()`, `MatIsSymmetric()` 8858 @*/ 8859 PetscErrorCode MatIsHermitian(Mat A, PetscReal tol, PetscBool *flg) { 8860 PetscFunctionBegin; 8861 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8862 PetscValidBoolPointer(flg, 3); 8863 8864 if (A->hermitian == PETSC_BOOL3_TRUE) *flg = PETSC_TRUE; 8865 else if (A->hermitian == PETSC_BOOL3_FALSE) *flg = PETSC_FALSE; 8866 else { 8867 if (!A->ops->ishermitian) { 8868 MatType mattype; 8869 PetscCall(MatGetType(A, &mattype)); 8870 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Matrix of type %s does not support checking for hermitian", mattype); 8871 } 8872 PetscUseTypeMethod(A, ishermitian, tol, flg); 8873 if (!tol) PetscCall(MatSetOption(A, MAT_HERMITIAN, *flg)); 8874 } 8875 PetscFunctionReturn(0); 8876 } 8877 8878 /*@ 8879 MatIsSymmetricKnown - Checks if a matrix knows if it is symmetric or not and its symmetric state 8880 8881 Not Collective 8882 8883 Input Parameter: 8884 . A - the matrix to check 8885 8886 Output Parameters: 8887 + set - PETSC_TRUE if the matrix knows its symmetry state (this tells you if the next flag is valid) 8888 - flg - the result (only valid if set is PETSC_TRUE) 8889 8890 Level: advanced 8891 8892 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric() 8893 if you want it explicitly checked 8894 8895 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitianKnown()` 8896 @*/ 8897 PetscErrorCode MatIsSymmetricKnown(Mat A, PetscBool *set, PetscBool *flg) { 8898 PetscFunctionBegin; 8899 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8900 PetscValidBoolPointer(set, 2); 8901 PetscValidBoolPointer(flg, 3); 8902 if (A->symmetric != PETSC_BOOL3_UNKNOWN) { 8903 *set = PETSC_TRUE; 8904 *flg = PetscBool3ToBool(A->symmetric); 8905 } else { 8906 *set = PETSC_FALSE; 8907 } 8908 PetscFunctionReturn(0); 8909 } 8910 8911 /*@ 8912 MatIsSPDKnown - Checks if a matrix knows if it is symmetric positive definite or not and its symmetric positive definite state 8913 8914 Not Collective 8915 8916 Input Parameter: 8917 . A - the matrix to check 8918 8919 Output Parameters: 8920 + set - PETSC_TRUE if the matrix knows its symmetric positive definite state (this tells you if the next flag is valid) 8921 - flg - the result (only valid if set is PETSC_TRUE) 8922 8923 Level: advanced 8924 8925 Note: 8926 Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). 8927 8928 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitianKnown()` 8929 @*/ 8930 PetscErrorCode MatIsSPDKnown(Mat A, PetscBool *set, PetscBool *flg) { 8931 PetscFunctionBegin; 8932 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8933 PetscValidBoolPointer(set, 2); 8934 PetscValidBoolPointer(flg, 3); 8935 if (A->spd != PETSC_BOOL3_UNKNOWN) { 8936 *set = PETSC_TRUE; 8937 *flg = PetscBool3ToBool(A->spd); 8938 } else { 8939 *set = PETSC_FALSE; 8940 } 8941 PetscFunctionReturn(0); 8942 } 8943 8944 /*@ 8945 MatIsHermitianKnown - Checks if a matrix knows if it is Hermitian or not and its Hermitian state 8946 8947 Not Collective 8948 8949 Input Parameter: 8950 . A - the matrix to check 8951 8952 Output Parameters: 8953 + set - PETSC_TRUE if the matrix knows its Hermitian state (this tells you if the next flag is valid) 8954 - flg - the result (only valid if set is PETSC_TRUE) 8955 8956 Level: advanced 8957 8958 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian() 8959 if you want it explicitly checked 8960 8961 .seealso: `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 Level: intermediate 8992 8993 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsSymmetric()`, `MatSetOption()`, `MatIsStructurallySymmetricKnown()` 8994 @*/ 8995 PetscErrorCode MatIsStructurallySymmetric(Mat A, PetscBool *flg) { 8996 PetscFunctionBegin; 8997 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8998 PetscValidBoolPointer(flg, 2); 8999 if (A->structurally_symmetric != PETSC_BOOL3_UNKNOWN) { 9000 *flg = PetscBool3ToBool(A->structurally_symmetric); 9001 } else { 9002 PetscUseTypeMethod(A, isstructurallysymmetric, flg); 9003 PetscCall(MatSetOption(A, MAT_STRUCTURALLY_SYMMETRIC, *flg)); 9004 } 9005 PetscFunctionReturn(0); 9006 } 9007 9008 /*@ 9009 MatIsStructurallySymmetricKnown - Checks if a matrix knows if it is structurally symmetric or not and its structurally symmetric state 9010 9011 Not Collective 9012 9013 Input Parameter: 9014 . A - the matrix to check 9015 9016 Output Parameters: 9017 + set - PETSC_TRUE if the matrix knows its structurally symmetric state (this tells you if the next flag is valid) 9018 - flg - the result (only valid if set is PETSC_TRUE) 9019 9020 Level: advanced 9021 9022 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitianKnown()` 9023 @*/ 9024 PetscErrorCode MatIsStructurallySymmetricKnown(Mat A, PetscBool *set, PetscBool *flg) { 9025 PetscFunctionBegin; 9026 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 9027 PetscValidBoolPointer(set, 2); 9028 PetscValidBoolPointer(flg, 3); 9029 if (A->structurally_symmetric != PETSC_BOOL3_UNKNOWN) { 9030 *set = PETSC_TRUE; 9031 *flg = PetscBool3ToBool(A->structurally_symmetric); 9032 } else { 9033 *set = PETSC_FALSE; 9034 } 9035 PetscFunctionReturn(0); 9036 } 9037 9038 /*@ 9039 MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need 9040 to be communicated to other processors during the MatAssemblyBegin/End() process 9041 9042 Not collective 9043 9044 Input Parameter: 9045 . vec - the vector 9046 9047 Output Parameters: 9048 + nstash - the size of the stash 9049 . reallocs - the number of additional mallocs incurred. 9050 . bnstash - the size of the block stash 9051 - breallocs - the number of additional mallocs incurred.in the block stash 9052 9053 Level: advanced 9054 9055 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `Mat`, `MatStashSetInitialSize()` 9056 9057 @*/ 9058 PetscErrorCode MatStashGetInfo(Mat mat, PetscInt *nstash, PetscInt *reallocs, PetscInt *bnstash, PetscInt *breallocs) { 9059 PetscFunctionBegin; 9060 PetscCall(MatStashGetInfo_Private(&mat->stash, nstash, reallocs)); 9061 PetscCall(MatStashGetInfo_Private(&mat->bstash, bnstash, breallocs)); 9062 PetscFunctionReturn(0); 9063 } 9064 9065 /*@C 9066 MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same 9067 parallel layout 9068 9069 Collective on Mat 9070 9071 Input Parameter: 9072 . mat - the matrix 9073 9074 Output Parameters: 9075 + right - (optional) vector that the matrix can be multiplied against 9076 - left - (optional) vector that the matrix vector product can be stored in 9077 9078 Notes: 9079 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(). 9080 9081 Notes: 9082 These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed 9083 9084 Level: advanced 9085 9086 .seealso: `MatCreate()`, `VecDestroy()` 9087 @*/ 9088 PetscErrorCode MatCreateVecs(Mat mat, Vec *right, Vec *left) { 9089 PetscFunctionBegin; 9090 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 9091 PetscValidType(mat, 1); 9092 if (mat->ops->getvecs) { 9093 PetscUseTypeMethod(mat, getvecs, right, left); 9094 } else { 9095 PetscInt rbs, cbs; 9096 PetscCall(MatGetBlockSizes(mat, &rbs, &cbs)); 9097 if (right) { 9098 PetscCheck(mat->cmap->n >= 0, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "PetscLayout for columns not yet setup"); 9099 PetscCall(VecCreate(PetscObjectComm((PetscObject)mat), right)); 9100 PetscCall(VecSetSizes(*right, mat->cmap->n, PETSC_DETERMINE)); 9101 PetscCall(VecSetBlockSize(*right, cbs)); 9102 PetscCall(VecSetType(*right, mat->defaultvectype)); 9103 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 9104 if (mat->boundtocpu && mat->bindingpropagates) { 9105 PetscCall(VecSetBindingPropagates(*right, PETSC_TRUE)); 9106 PetscCall(VecBindToCPU(*right, PETSC_TRUE)); 9107 } 9108 #endif 9109 PetscCall(PetscLayoutReference(mat->cmap, &(*right)->map)); 9110 } 9111 if (left) { 9112 PetscCheck(mat->rmap->n >= 0, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "PetscLayout for rows not yet setup"); 9113 PetscCall(VecCreate(PetscObjectComm((PetscObject)mat), left)); 9114 PetscCall(VecSetSizes(*left, mat->rmap->n, PETSC_DETERMINE)); 9115 PetscCall(VecSetBlockSize(*left, rbs)); 9116 PetscCall(VecSetType(*left, mat->defaultvectype)); 9117 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 9118 if (mat->boundtocpu && mat->bindingpropagates) { 9119 PetscCall(VecSetBindingPropagates(*left, PETSC_TRUE)); 9120 PetscCall(VecBindToCPU(*left, PETSC_TRUE)); 9121 } 9122 #endif 9123 PetscCall(PetscLayoutReference(mat->rmap, &(*left)->map)); 9124 } 9125 } 9126 PetscFunctionReturn(0); 9127 } 9128 9129 /*@C 9130 MatFactorInfoInitialize - Initializes a MatFactorInfo data structure 9131 with default values. 9132 9133 Not Collective 9134 9135 Input Parameters: 9136 . info - the MatFactorInfo data structure 9137 9138 Notes: 9139 The solvers are generally used through the KSP and PC objects, for example 9140 PCLU, PCILU, PCCHOLESKY, PCICC 9141 9142 Level: developer 9143 9144 .seealso: `MatFactorInfo` 9145 9146 Developer Note: fortran interface is not autogenerated as the f90 9147 interface definition cannot be generated correctly [due to MatFactorInfo] 9148 9149 @*/ 9150 9151 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info) { 9152 PetscFunctionBegin; 9153 PetscCall(PetscMemzero(info, sizeof(MatFactorInfo))); 9154 PetscFunctionReturn(0); 9155 } 9156 9157 /*@ 9158 MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed 9159 9160 Collective on Mat 9161 9162 Input Parameters: 9163 + mat - the factored matrix 9164 - is - the index set defining the Schur indices (0-based) 9165 9166 Notes: 9167 Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system. 9168 9169 You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call. 9170 9171 Level: developer 9172 9173 .seealso: `MatGetFactor()`, `MatFactorGetSchurComplement()`, `MatFactorRestoreSchurComplement()`, `MatFactorCreateSchurComplement()`, `MatFactorSolveSchurComplement()`, 9174 `MatFactorSolveSchurComplementTranspose()`, `MatFactorSolveSchurComplement()` 9175 9176 @*/ 9177 PetscErrorCode MatFactorSetSchurIS(Mat mat, IS is) { 9178 PetscErrorCode (*f)(Mat, IS); 9179 9180 PetscFunctionBegin; 9181 PetscValidType(mat, 1); 9182 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 9183 PetscValidType(is, 2); 9184 PetscValidHeaderSpecific(is, IS_CLASSID, 2); 9185 PetscCheckSameComm(mat, 1, is, 2); 9186 PetscCheck(mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Only for factored matrix"); 9187 PetscCall(PetscObjectQueryFunction((PetscObject)mat, "MatFactorSetSchurIS_C", &f)); 9188 PetscCheck(f, PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "The selected MatSolverType does not support Schur complement computation. You should use MATSOLVERMUMPS or MATSOLVERMKL_PARDISO"); 9189 PetscCall(MatDestroy(&mat->schur)); 9190 PetscCall((*f)(mat, is)); 9191 PetscCheck(mat->schur, PetscObjectComm((PetscObject)mat), PETSC_ERR_PLIB, "Schur complement has not been created"); 9192 PetscFunctionReturn(0); 9193 } 9194 9195 /*@ 9196 MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step 9197 9198 Logically Collective on Mat 9199 9200 Input Parameters: 9201 + F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface 9202 . S - location where to return the Schur complement, can be NULL 9203 - status - the status of the Schur complement matrix, can be NULL 9204 9205 Notes: 9206 You must call MatFactorSetSchurIS() before calling this routine. 9207 9208 The routine provides a copy of the Schur matrix stored within the solver data structures. 9209 The caller must destroy the object when it is no longer needed. 9210 If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse. 9211 9212 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) 9213 9214 Developer Notes: 9215 The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc 9216 matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix. 9217 9218 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 9219 9220 Level: advanced 9221 9222 References: 9223 9224 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorGetSchurComplement()`, `MatFactorSchurStatus` 9225 @*/ 9226 PetscErrorCode MatFactorCreateSchurComplement(Mat F, Mat *S, MatFactorSchurStatus *status) { 9227 PetscFunctionBegin; 9228 PetscValidHeaderSpecific(F, MAT_CLASSID, 1); 9229 if (S) PetscValidPointer(S, 2); 9230 if (status) PetscValidPointer(status, 3); 9231 if (S) { 9232 PetscErrorCode (*f)(Mat, Mat *); 9233 9234 PetscCall(PetscObjectQueryFunction((PetscObject)F, "MatFactorCreateSchurComplement_C", &f)); 9235 if (f) { 9236 PetscCall((*f)(F, S)); 9237 } else { 9238 PetscCall(MatDuplicate(F->schur, MAT_COPY_VALUES, S)); 9239 } 9240 } 9241 if (status) *status = F->schur_status; 9242 PetscFunctionReturn(0); 9243 } 9244 9245 /*@ 9246 MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix 9247 9248 Logically Collective on Mat 9249 9250 Input Parameters: 9251 + F - the factored matrix obtained by calling MatGetFactor() 9252 . *S - location where to return the Schur complement, can be NULL 9253 - status - the status of the Schur complement matrix, can be NULL 9254 9255 Notes: 9256 You must call MatFactorSetSchurIS() before calling this routine. 9257 9258 Schur complement mode is currently implemented for sequential matrices. 9259 The routine returns a the Schur Complement stored within the data strutures of the solver. 9260 If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement. 9261 The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed. 9262 9263 Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix 9264 9265 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 9266 9267 Level: advanced 9268 9269 References: 9270 9271 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorRestoreSchurComplement()`, `MatFactorCreateSchurComplement()`, `MatFactorSchurStatus` 9272 @*/ 9273 PetscErrorCode MatFactorGetSchurComplement(Mat F, Mat *S, MatFactorSchurStatus *status) { 9274 PetscFunctionBegin; 9275 PetscValidHeaderSpecific(F, MAT_CLASSID, 1); 9276 if (S) PetscValidPointer(S, 2); 9277 if (status) PetscValidPointer(status, 3); 9278 if (S) *S = F->schur; 9279 if (status) *status = F->schur_status; 9280 PetscFunctionReturn(0); 9281 } 9282 9283 /*@ 9284 MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement 9285 9286 Logically Collective on Mat 9287 9288 Input Parameters: 9289 + F - the factored matrix obtained by calling MatGetFactor() 9290 . *S - location where the Schur complement is stored 9291 - status - the status of the Schur complement matrix (see MatFactorSchurStatus) 9292 9293 Notes: 9294 9295 Level: advanced 9296 9297 References: 9298 9299 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorRestoreSchurComplement()`, `MatFactorCreateSchurComplement()`, `MatFactorSchurStatus` 9300 @*/ 9301 PetscErrorCode MatFactorRestoreSchurComplement(Mat F, Mat *S, MatFactorSchurStatus status) { 9302 PetscFunctionBegin; 9303 PetscValidHeaderSpecific(F, MAT_CLASSID, 1); 9304 if (S) { 9305 PetscValidHeaderSpecific(*S, MAT_CLASSID, 2); 9306 *S = NULL; 9307 } 9308 F->schur_status = status; 9309 PetscCall(MatFactorUpdateSchurStatus_Private(F)); 9310 PetscFunctionReturn(0); 9311 } 9312 9313 /*@ 9314 MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step 9315 9316 Logically Collective on Mat 9317 9318 Input Parameters: 9319 + F - the factored matrix obtained by calling MatGetFactor() 9320 . rhs - location where the right hand side of the Schur complement system is stored 9321 - sol - location where the solution of the Schur complement system has to be returned 9322 9323 Notes: 9324 The sizes of the vectors should match the size of the Schur complement 9325 9326 Must be called after MatFactorSetSchurIS() 9327 9328 Level: advanced 9329 9330 References: 9331 9332 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorSolveSchurComplement()` 9333 @*/ 9334 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol) { 9335 PetscFunctionBegin; 9336 PetscValidType(F, 1); 9337 PetscValidType(rhs, 2); 9338 PetscValidType(sol, 3); 9339 PetscValidHeaderSpecific(F, MAT_CLASSID, 1); 9340 PetscValidHeaderSpecific(rhs, VEC_CLASSID, 2); 9341 PetscValidHeaderSpecific(sol, VEC_CLASSID, 3); 9342 PetscCheckSameComm(F, 1, rhs, 2); 9343 PetscCheckSameComm(F, 1, sol, 3); 9344 PetscCall(MatFactorFactorizeSchurComplement(F)); 9345 switch (F->schur_status) { 9346 case MAT_FACTOR_SCHUR_FACTORED: PetscCall(MatSolveTranspose(F->schur, rhs, sol)); break; 9347 case MAT_FACTOR_SCHUR_INVERTED: PetscCall(MatMultTranspose(F->schur, rhs, sol)); break; 9348 default: SETERRQ(PetscObjectComm((PetscObject)F), PETSC_ERR_SUP, "Unhandled MatFactorSchurStatus %d", F->schur_status); 9349 } 9350 PetscFunctionReturn(0); 9351 } 9352 9353 /*@ 9354 MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step 9355 9356 Logically Collective on Mat 9357 9358 Input Parameters: 9359 + F - the factored matrix obtained by calling MatGetFactor() 9360 . rhs - location where the right hand side of the Schur complement system is stored 9361 - sol - location where the solution of the Schur complement system has to be returned 9362 9363 Notes: 9364 The sizes of the vectors should match the size of the Schur complement 9365 9366 Must be called after MatFactorSetSchurIS() 9367 9368 Level: advanced 9369 9370 References: 9371 9372 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorSolveSchurComplementTranspose()` 9373 @*/ 9374 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol) { 9375 PetscFunctionBegin; 9376 PetscValidType(F, 1); 9377 PetscValidType(rhs, 2); 9378 PetscValidType(sol, 3); 9379 PetscValidHeaderSpecific(F, MAT_CLASSID, 1); 9380 PetscValidHeaderSpecific(rhs, VEC_CLASSID, 2); 9381 PetscValidHeaderSpecific(sol, VEC_CLASSID, 3); 9382 PetscCheckSameComm(F, 1, rhs, 2); 9383 PetscCheckSameComm(F, 1, sol, 3); 9384 PetscCall(MatFactorFactorizeSchurComplement(F)); 9385 switch (F->schur_status) { 9386 case MAT_FACTOR_SCHUR_FACTORED: PetscCall(MatSolve(F->schur, rhs, sol)); break; 9387 case MAT_FACTOR_SCHUR_INVERTED: PetscCall(MatMult(F->schur, rhs, sol)); break; 9388 default: SETERRQ(PetscObjectComm((PetscObject)F), PETSC_ERR_SUP, "Unhandled MatFactorSchurStatus %d", F->schur_status); 9389 } 9390 PetscFunctionReturn(0); 9391 } 9392 9393 /*@ 9394 MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step 9395 9396 Logically Collective on Mat 9397 9398 Input Parameters: 9399 . F - the factored matrix obtained by calling MatGetFactor() 9400 9401 Notes: 9402 Must be called after MatFactorSetSchurIS(). 9403 9404 Call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it. 9405 9406 Level: advanced 9407 9408 References: 9409 9410 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorGetSchurComplement()`, `MatFactorCreateSchurComplement()` 9411 @*/ 9412 PetscErrorCode MatFactorInvertSchurComplement(Mat F) { 9413 PetscFunctionBegin; 9414 PetscValidType(F, 1); 9415 PetscValidHeaderSpecific(F, MAT_CLASSID, 1); 9416 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0); 9417 PetscCall(MatFactorFactorizeSchurComplement(F)); 9418 PetscCall(MatFactorInvertSchurComplement_Private(F)); 9419 F->schur_status = MAT_FACTOR_SCHUR_INVERTED; 9420 PetscFunctionReturn(0); 9421 } 9422 9423 /*@ 9424 MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step 9425 9426 Logically Collective on Mat 9427 9428 Input Parameters: 9429 . F - the factored matrix obtained by calling MatGetFactor() 9430 9431 Notes: 9432 Must be called after MatFactorSetSchurIS(). 9433 9434 Level: advanced 9435 9436 References: 9437 9438 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorInvertSchurComplement()` 9439 @*/ 9440 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F) { 9441 PetscFunctionBegin; 9442 PetscValidType(F, 1); 9443 PetscValidHeaderSpecific(F, MAT_CLASSID, 1); 9444 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0); 9445 PetscCall(MatFactorFactorizeSchurComplement_Private(F)); 9446 F->schur_status = MAT_FACTOR_SCHUR_FACTORED; 9447 PetscFunctionReturn(0); 9448 } 9449 9450 /*@ 9451 MatPtAP - Creates the matrix product C = P^T * A * P 9452 9453 Neighbor-wise Collective on Mat 9454 9455 Input Parameters: 9456 + A - the matrix 9457 . P - the projection matrix 9458 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9459 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate 9460 if the result is a dense matrix this is irrelevant 9461 9462 Output Parameters: 9463 . C - the product matrix 9464 9465 Notes: 9466 C will be created and must be destroyed by the user with MatDestroy(). 9467 9468 For matrix types without special implementation the function fallbacks to MatMatMult() followed by MatTransposeMatMult(). 9469 9470 Level: intermediate 9471 9472 .seealso: `MatMatMult()`, `MatRARt()` 9473 @*/ 9474 PetscErrorCode MatPtAP(Mat A, Mat P, MatReuse scall, PetscReal fill, Mat *C) { 9475 PetscFunctionBegin; 9476 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*C, 5); 9477 PetscCheck(scall != MAT_INPLACE_MATRIX, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Inplace product not supported"); 9478 9479 if (scall == MAT_INITIAL_MATRIX) { 9480 PetscCall(MatProductCreate(A, P, NULL, C)); 9481 PetscCall(MatProductSetType(*C, MATPRODUCT_PtAP)); 9482 PetscCall(MatProductSetAlgorithm(*C, "default")); 9483 PetscCall(MatProductSetFill(*C, fill)); 9484 9485 (*C)->product->api_user = PETSC_TRUE; 9486 PetscCall(MatProductSetFromOptions(*C)); 9487 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); 9488 PetscCall(MatProductSymbolic(*C)); 9489 } else { /* scall == MAT_REUSE_MATRIX */ 9490 PetscCall(MatProductReplaceMats(A, P, NULL, *C)); 9491 } 9492 9493 PetscCall(MatProductNumeric(*C)); 9494 (*C)->symmetric = A->symmetric; 9495 (*C)->spd = A->spd; 9496 PetscFunctionReturn(0); 9497 } 9498 9499 /*@ 9500 MatRARt - Creates the matrix product C = R * A * R^T 9501 9502 Neighbor-wise Collective on Mat 9503 9504 Input Parameters: 9505 + A - the matrix 9506 . R - the projection matrix 9507 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9508 - fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate 9509 if the result is a dense matrix this is irrelevant 9510 9511 Output Parameters: 9512 . C - the product matrix 9513 9514 Notes: 9515 C will be created and must be destroyed by the user with MatDestroy(). 9516 9517 This routine is currently only implemented for pairs of AIJ matrices and classes 9518 which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes, 9519 parallel MatRARt is implemented via explicit transpose of R, which could be very expensive. 9520 We recommend using MatPtAP(). 9521 9522 Level: intermediate 9523 9524 .seealso: `MatMatMult()`, `MatPtAP()` 9525 @*/ 9526 PetscErrorCode MatRARt(Mat A, Mat R, MatReuse scall, PetscReal fill, Mat *C) { 9527 PetscFunctionBegin; 9528 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*C, 5); 9529 PetscCheck(scall != MAT_INPLACE_MATRIX, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Inplace product not supported"); 9530 9531 if (scall == MAT_INITIAL_MATRIX) { 9532 PetscCall(MatProductCreate(A, R, NULL, C)); 9533 PetscCall(MatProductSetType(*C, MATPRODUCT_RARt)); 9534 PetscCall(MatProductSetAlgorithm(*C, "default")); 9535 PetscCall(MatProductSetFill(*C, fill)); 9536 9537 (*C)->product->api_user = PETSC_TRUE; 9538 PetscCall(MatProductSetFromOptions(*C)); 9539 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); 9540 PetscCall(MatProductSymbolic(*C)); 9541 } else { /* scall == MAT_REUSE_MATRIX */ 9542 PetscCall(MatProductReplaceMats(A, R, NULL, *C)); 9543 } 9544 9545 PetscCall(MatProductNumeric(*C)); 9546 if (A->symmetric == PETSC_BOOL3_TRUE) PetscCall(MatSetOption(*C, MAT_SYMMETRIC, PETSC_TRUE)); 9547 PetscFunctionReturn(0); 9548 } 9549 9550 static PetscErrorCode MatProduct_Private(Mat A, Mat B, MatReuse scall, PetscReal fill, MatProductType ptype, Mat *C) { 9551 PetscFunctionBegin; 9552 PetscCheck(scall != MAT_INPLACE_MATRIX, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Inplace product not supported"); 9553 9554 if (scall == MAT_INITIAL_MATRIX) { 9555 PetscCall(PetscInfo(A, "Calling MatProduct API with MAT_INITIAL_MATRIX and product type %s\n", MatProductTypes[ptype])); 9556 PetscCall(MatProductCreate(A, B, NULL, C)); 9557 PetscCall(MatProductSetType(*C, ptype)); 9558 PetscCall(MatProductSetAlgorithm(*C, MATPRODUCTALGORITHMDEFAULT)); 9559 PetscCall(MatProductSetFill(*C, fill)); 9560 9561 (*C)->product->api_user = PETSC_TRUE; 9562 PetscCall(MatProductSetFromOptions(*C)); 9563 PetscCall(MatProductSymbolic(*C)); 9564 } else { /* scall == MAT_REUSE_MATRIX */ 9565 Mat_Product *product = (*C)->product; 9566 PetscBool isdense; 9567 9568 PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)(*C), &isdense, MATSEQDENSE, MATMPIDENSE, "")); 9569 if (isdense && product && product->type != ptype) { 9570 PetscCall(MatProductClear(*C)); 9571 product = NULL; 9572 } 9573 PetscCall(PetscInfo(A, "Calling MatProduct API with MAT_REUSE_MATRIX %s product present and product type %s\n", product ? "with" : "without", MatProductTypes[ptype])); 9574 if (!product) { /* user provide the dense matrix *C without calling MatProductCreate() or reusing it from previous calls */ 9575 if (isdense) { 9576 PetscCall(MatProductCreate_Private(A, B, NULL, *C)); 9577 product = (*C)->product; 9578 product->fill = fill; 9579 product->api_user = PETSC_TRUE; 9580 product->clear = PETSC_TRUE; 9581 9582 PetscCall(MatProductSetType(*C, ptype)); 9583 PetscCall(MatProductSetFromOptions(*C)); 9584 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); 9585 PetscCall(MatProductSymbolic(*C)); 9586 } else SETERRQ(PetscObjectComm((PetscObject)(*C)), PETSC_ERR_SUP, "Call MatProductCreate() first"); 9587 } else { /* user may change input matrices A or B when REUSE */ 9588 PetscCall(MatProductReplaceMats(A, B, NULL, *C)); 9589 } 9590 } 9591 PetscCall(MatProductNumeric(*C)); 9592 PetscFunctionReturn(0); 9593 } 9594 9595 /*@ 9596 MatMatMult - Performs Matrix-Matrix Multiplication C=A*B. 9597 9598 Neighbor-wise Collective on Mat 9599 9600 Input Parameters: 9601 + A - the left matrix 9602 . B - the right matrix 9603 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9604 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate 9605 if the result is a dense matrix this is irrelevant 9606 9607 Output Parameters: 9608 . C - the product matrix 9609 9610 Notes: 9611 Unless scall is MAT_REUSE_MATRIX C will be created. 9612 9613 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 9614 call to this function with MAT_INITIAL_MATRIX. 9615 9616 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value actually needed. 9617 9618 If you have many matrices with the same non-zero structure to multiply, you should use MatProductCreate()/MatProductSymbolic()/MatProductReplaceMats(), and call MatProductNumeric() repeatedly. 9619 9620 In the special case where matrix B (and hence C) are dense you can create the correctly sized matrix C yourself and then call this routine with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse. 9621 9622 Example of Usage: 9623 .vb 9624 MatProductCreate(A,B,NULL,&C); 9625 MatProductSetType(C,MATPRODUCT_AB); 9626 MatProductSymbolic(C); 9627 MatProductNumeric(C); // compute C=A * B 9628 MatProductReplaceMats(A1,B1,NULL,C); // compute C=A1 * B1 9629 MatProductNumeric(C); 9630 MatProductReplaceMats(A2,NULL,NULL,C); // compute C=A2 * B1 9631 MatProductNumeric(C); 9632 .ve 9633 9634 Level: intermediate 9635 9636 .seealso: `MatTransposeMatMult()`, `MatMatTransposeMult()`, `MatPtAP()`, `MatProductCreate()`, `MatProductSymbolic()`, `MatProductReplaceMats()`, `MatProductNumeric()` 9637 @*/ 9638 PetscErrorCode MatMatMult(Mat A, Mat B, MatReuse scall, PetscReal fill, Mat *C) { 9639 PetscFunctionBegin; 9640 PetscCall(MatProduct_Private(A, B, scall, fill, MATPRODUCT_AB, C)); 9641 PetscFunctionReturn(0); 9642 } 9643 9644 /*@ 9645 MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T. 9646 9647 Neighbor-wise Collective on Mat 9648 9649 Input Parameters: 9650 + A - the left matrix 9651 . B - the right matrix 9652 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9653 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9654 9655 Output Parameters: 9656 . C - the product matrix 9657 9658 Notes: 9659 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9660 9661 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9662 9663 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9664 actually needed. 9665 9666 This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class, 9667 and for pairs of MPIDense matrices. 9668 9669 Options Database Keys: 9670 . -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorithms for MPIDense matrices: the 9671 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity; 9672 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity. 9673 9674 Level: intermediate 9675 9676 .seealso: `MatMatMult()`, `MatTransposeMatMult()` `MatPtAP()` 9677 @*/ 9678 PetscErrorCode MatMatTransposeMult(Mat A, Mat B, MatReuse scall, PetscReal fill, Mat *C) { 9679 PetscFunctionBegin; 9680 PetscCall(MatProduct_Private(A, B, scall, fill, MATPRODUCT_ABt, C)); 9681 if (A == B) PetscCall(MatSetOption(*C, MAT_SYMMETRIC, PETSC_TRUE)); 9682 PetscFunctionReturn(0); 9683 } 9684 9685 /*@ 9686 MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B. 9687 9688 Neighbor-wise Collective on Mat 9689 9690 Input Parameters: 9691 + A - the left matrix 9692 . B - the right matrix 9693 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9694 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9695 9696 Output Parameters: 9697 . C - the product matrix 9698 9699 Notes: 9700 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9701 9702 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call. 9703 9704 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9705 actually needed. 9706 9707 This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes 9708 which inherit from SeqAIJ. C will be of the same type as the input matrices. 9709 9710 Level: intermediate 9711 9712 .seealso: `MatMatMult()`, `MatMatTransposeMult()`, `MatPtAP()` 9713 @*/ 9714 PetscErrorCode MatTransposeMatMult(Mat A, Mat B, MatReuse scall, PetscReal fill, Mat *C) { 9715 PetscFunctionBegin; 9716 PetscCall(MatProduct_Private(A, B, scall, fill, MATPRODUCT_AtB, C)); 9717 PetscFunctionReturn(0); 9718 } 9719 9720 /*@ 9721 MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C. 9722 9723 Neighbor-wise Collective on Mat 9724 9725 Input Parameters: 9726 + A - the left matrix 9727 . B - the middle matrix 9728 . C - the right matrix 9729 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9730 - 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 9731 if the result is a dense matrix this is irrelevant 9732 9733 Output Parameters: 9734 . D - the product matrix 9735 9736 Notes: 9737 Unless scall is MAT_REUSE_MATRIX D will be created. 9738 9739 MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call 9740 9741 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9742 actually needed. 9743 9744 If you have many matrices with the same non-zero structure to multiply, you 9745 should use MAT_REUSE_MATRIX in all calls but the first 9746 9747 Level: intermediate 9748 9749 .seealso: `MatMatMult`, `MatPtAP()`, `MatMatTransposeMult()`, `MatTransposeMatMult()` 9750 @*/ 9751 PetscErrorCode MatMatMatMult(Mat A, Mat B, Mat C, MatReuse scall, PetscReal fill, Mat *D) { 9752 PetscFunctionBegin; 9753 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*D, 6); 9754 PetscCheck(scall != MAT_INPLACE_MATRIX, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Inplace product not supported"); 9755 9756 if (scall == MAT_INITIAL_MATRIX) { 9757 PetscCall(MatProductCreate(A, B, C, D)); 9758 PetscCall(MatProductSetType(*D, MATPRODUCT_ABC)); 9759 PetscCall(MatProductSetAlgorithm(*D, "default")); 9760 PetscCall(MatProductSetFill(*D, fill)); 9761 9762 (*D)->product->api_user = PETSC_TRUE; 9763 PetscCall(MatProductSetFromOptions(*D)); 9764 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, 9765 ((PetscObject)C)->type_name); 9766 PetscCall(MatProductSymbolic(*D)); 9767 } else { /* user may change input matrices when REUSE */ 9768 PetscCall(MatProductReplaceMats(A, B, C, *D)); 9769 } 9770 PetscCall(MatProductNumeric(*D)); 9771 PetscFunctionReturn(0); 9772 } 9773 9774 /*@ 9775 MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators. 9776 9777 Collective on Mat 9778 9779 Input Parameters: 9780 + mat - the matrix 9781 . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices) 9782 . subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used) 9783 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9784 9785 Output Parameter: 9786 . matredundant - redundant matrix 9787 9788 Notes: 9789 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 9790 original matrix has not changed from that last call to MatCreateRedundantMatrix(). 9791 9792 This routine creates the duplicated matrices in the subcommunicators; you should NOT create them before 9793 calling it. 9794 9795 Level: advanced 9796 9797 .seealso: `MatDestroy()` 9798 @*/ 9799 PetscErrorCode MatCreateRedundantMatrix(Mat mat, PetscInt nsubcomm, MPI_Comm subcomm, MatReuse reuse, Mat *matredundant) { 9800 MPI_Comm comm; 9801 PetscMPIInt size; 9802 PetscInt mloc_sub, nloc_sub, rstart, rend, M = mat->rmap->N, N = mat->cmap->N, bs = mat->rmap->bs; 9803 Mat_Redundant *redund = NULL; 9804 PetscSubcomm psubcomm = NULL; 9805 MPI_Comm subcomm_in = subcomm; 9806 Mat *matseq; 9807 IS isrow, iscol; 9808 PetscBool newsubcomm = PETSC_FALSE; 9809 9810 PetscFunctionBegin; 9811 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 9812 if (nsubcomm && reuse == MAT_REUSE_MATRIX) { 9813 PetscValidPointer(*matredundant, 5); 9814 PetscValidHeaderSpecific(*matredundant, MAT_CLASSID, 5); 9815 } 9816 9817 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size)); 9818 if (size == 1 || nsubcomm == 1) { 9819 if (reuse == MAT_INITIAL_MATRIX) { 9820 PetscCall(MatDuplicate(mat, MAT_COPY_VALUES, matredundant)); 9821 } else { 9822 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"); 9823 PetscCall(MatCopy(mat, *matredundant, SAME_NONZERO_PATTERN)); 9824 } 9825 PetscFunctionReturn(0); 9826 } 9827 9828 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 9829 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 9830 MatCheckPreallocated(mat, 1); 9831 9832 PetscCall(PetscLogEventBegin(MAT_RedundantMat, mat, 0, 0, 0)); 9833 if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */ 9834 /* create psubcomm, then get subcomm */ 9835 PetscCall(PetscObjectGetComm((PetscObject)mat, &comm)); 9836 PetscCallMPI(MPI_Comm_size(comm, &size)); 9837 PetscCheck(nsubcomm >= 1 && nsubcomm <= size, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "nsubcomm must between 1 and %d", size); 9838 9839 PetscCall(PetscSubcommCreate(comm, &psubcomm)); 9840 PetscCall(PetscSubcommSetNumber(psubcomm, nsubcomm)); 9841 PetscCall(PetscSubcommSetType(psubcomm, PETSC_SUBCOMM_CONTIGUOUS)); 9842 PetscCall(PetscSubcommSetFromOptions(psubcomm)); 9843 PetscCall(PetscCommDuplicate(PetscSubcommChild(psubcomm), &subcomm, NULL)); 9844 newsubcomm = PETSC_TRUE; 9845 PetscCall(PetscSubcommDestroy(&psubcomm)); 9846 } 9847 9848 /* get isrow, iscol and a local sequential matrix matseq[0] */ 9849 if (reuse == MAT_INITIAL_MATRIX) { 9850 mloc_sub = PETSC_DECIDE; 9851 nloc_sub = PETSC_DECIDE; 9852 if (bs < 1) { 9853 PetscCall(PetscSplitOwnership(subcomm, &mloc_sub, &M)); 9854 PetscCall(PetscSplitOwnership(subcomm, &nloc_sub, &N)); 9855 } else { 9856 PetscCall(PetscSplitOwnershipBlock(subcomm, bs, &mloc_sub, &M)); 9857 PetscCall(PetscSplitOwnershipBlock(subcomm, bs, &nloc_sub, &N)); 9858 } 9859 PetscCallMPI(MPI_Scan(&mloc_sub, &rend, 1, MPIU_INT, MPI_SUM, subcomm)); 9860 rstart = rend - mloc_sub; 9861 PetscCall(ISCreateStride(PETSC_COMM_SELF, mloc_sub, rstart, 1, &isrow)); 9862 PetscCall(ISCreateStride(PETSC_COMM_SELF, N, 0, 1, &iscol)); 9863 } else { /* reuse == MAT_REUSE_MATRIX */ 9864 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"); 9865 /* retrieve subcomm */ 9866 PetscCall(PetscObjectGetComm((PetscObject)(*matredundant), &subcomm)); 9867 redund = (*matredundant)->redundant; 9868 isrow = redund->isrow; 9869 iscol = redund->iscol; 9870 matseq = redund->matseq; 9871 } 9872 PetscCall(MatCreateSubMatrices(mat, 1, &isrow, &iscol, reuse, &matseq)); 9873 9874 /* get matredundant over subcomm */ 9875 if (reuse == MAT_INITIAL_MATRIX) { 9876 PetscCall(MatCreateMPIMatConcatenateSeqMat(subcomm, matseq[0], nloc_sub, reuse, matredundant)); 9877 9878 /* create a supporting struct and attach it to C for reuse */ 9879 PetscCall(PetscNewLog(*matredundant, &redund)); 9880 (*matredundant)->redundant = redund; 9881 redund->isrow = isrow; 9882 redund->iscol = iscol; 9883 redund->matseq = matseq; 9884 if (newsubcomm) { 9885 redund->subcomm = subcomm; 9886 } else { 9887 redund->subcomm = MPI_COMM_NULL; 9888 } 9889 } else { 9890 PetscCall(MatCreateMPIMatConcatenateSeqMat(subcomm, matseq[0], PETSC_DECIDE, reuse, matredundant)); 9891 } 9892 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 9893 if (matseq[0]->boundtocpu && matseq[0]->bindingpropagates) { 9894 PetscCall(MatBindToCPU(*matredundant, PETSC_TRUE)); 9895 PetscCall(MatSetBindingPropagates(*matredundant, PETSC_TRUE)); 9896 } 9897 #endif 9898 PetscCall(PetscLogEventEnd(MAT_RedundantMat, mat, 0, 0, 0)); 9899 PetscFunctionReturn(0); 9900 } 9901 9902 /*@C 9903 MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from 9904 a given 'mat' object. Each submatrix can span multiple procs. 9905 9906 Collective on Mat 9907 9908 Input Parameters: 9909 + mat - the matrix 9910 . subcomm - the subcommunicator obtained by com_split(comm) 9911 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9912 9913 Output Parameter: 9914 . subMat - 'parallel submatrices each spans a given subcomm 9915 9916 Notes: 9917 The submatrix partition across processors is dictated by 'subComm' a 9918 communicator obtained by MPI_comm_split(). The subComm 9919 is not restriced to be grouped with consecutive original ranks. 9920 9921 Due the MPI_Comm_split() usage, the parallel layout of the submatrices 9922 map directly to the layout of the original matrix [wrt the local 9923 row,col partitioning]. So the original 'DiagonalMat' naturally maps 9924 into the 'DiagonalMat' of the subMat, hence it is used directly from 9925 the subMat. However the offDiagMat looses some columns - and this is 9926 reconstructed with MatSetValues() 9927 9928 Level: advanced 9929 9930 .seealso: `MatCreateSubMatrices()` 9931 @*/ 9932 PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall, Mat *subMat) { 9933 PetscMPIInt commsize, subCommSize; 9934 9935 PetscFunctionBegin; 9936 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat), &commsize)); 9937 PetscCallMPI(MPI_Comm_size(subComm, &subCommSize)); 9938 PetscCheck(subCommSize <= commsize, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_OUTOFRANGE, "CommSize %d < SubCommZize %d", commsize, subCommSize); 9939 9940 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"); 9941 PetscCall(PetscLogEventBegin(MAT_GetMultiProcBlock, mat, 0, 0, 0)); 9942 PetscUseTypeMethod(mat, getmultiprocblock, subComm, scall, subMat); 9943 PetscCall(PetscLogEventEnd(MAT_GetMultiProcBlock, mat, 0, 0, 0)); 9944 PetscFunctionReturn(0); 9945 } 9946 9947 /*@ 9948 MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering 9949 9950 Not Collective 9951 9952 Input Parameters: 9953 + mat - matrix to extract local submatrix from 9954 . isrow - local row indices for submatrix 9955 - iscol - local column indices for submatrix 9956 9957 Output Parameter: 9958 . submat - the submatrix 9959 9960 Level: intermediate 9961 9962 Notes: 9963 The submat should be returned with MatRestoreLocalSubMatrix(). 9964 9965 Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be 9966 the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's. 9967 9968 The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then 9969 MatSetValuesBlockedLocal() will also be implemented. 9970 9971 The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that 9972 matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided. 9973 9974 .seealso: `MatRestoreLocalSubMatrix()`, `MatCreateLocalRef()`, `MatSetLocalToGlobalMapping()` 9975 @*/ 9976 PetscErrorCode MatGetLocalSubMatrix(Mat mat, IS isrow, IS iscol, Mat *submat) { 9977 PetscFunctionBegin; 9978 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 9979 PetscValidHeaderSpecific(isrow, IS_CLASSID, 2); 9980 PetscValidHeaderSpecific(iscol, IS_CLASSID, 3); 9981 PetscCheckSameComm(isrow, 2, iscol, 3); 9982 PetscValidPointer(submat, 4); 9983 PetscCheck(mat->rmap->mapping, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Matrix must have local to global mapping provided before this call"); 9984 9985 if (mat->ops->getlocalsubmatrix) { 9986 PetscUseTypeMethod(mat, getlocalsubmatrix, isrow, iscol, submat); 9987 } else { 9988 PetscCall(MatCreateLocalRef(mat, isrow, iscol, submat)); 9989 } 9990 PetscFunctionReturn(0); 9991 } 9992 9993 /*@ 9994 MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering 9995 9996 Not Collective 9997 9998 Input Parameters: 9999 + mat - matrix to extract local submatrix from 10000 . isrow - local row indices for submatrix 10001 . iscol - local column indices for submatrix 10002 - submat - the submatrix 10003 10004 Level: intermediate 10005 10006 .seealso: `MatGetLocalSubMatrix()` 10007 @*/ 10008 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat, IS isrow, IS iscol, Mat *submat) { 10009 PetscFunctionBegin; 10010 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 10011 PetscValidHeaderSpecific(isrow, IS_CLASSID, 2); 10012 PetscValidHeaderSpecific(iscol, IS_CLASSID, 3); 10013 PetscCheckSameComm(isrow, 2, iscol, 3); 10014 PetscValidPointer(submat, 4); 10015 if (*submat) { PetscValidHeaderSpecific(*submat, MAT_CLASSID, 4); } 10016 10017 if (mat->ops->restorelocalsubmatrix) { 10018 PetscUseTypeMethod(mat, restorelocalsubmatrix, isrow, iscol, submat); 10019 } else { 10020 PetscCall(MatDestroy(submat)); 10021 } 10022 *submat = NULL; 10023 PetscFunctionReturn(0); 10024 } 10025 10026 /* --------------------------------------------------------*/ 10027 /*@ 10028 MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix 10029 10030 Collective on Mat 10031 10032 Input Parameter: 10033 . mat - the matrix 10034 10035 Output Parameter: 10036 . is - if any rows have zero diagonals this contains the list of them 10037 10038 Level: developer 10039 10040 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 10041 @*/ 10042 PetscErrorCode MatFindZeroDiagonals(Mat mat, IS *is) { 10043 PetscFunctionBegin; 10044 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 10045 PetscValidType(mat, 1); 10046 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 10047 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 10048 10049 if (!mat->ops->findzerodiagonals) { 10050 Vec diag; 10051 const PetscScalar *a; 10052 PetscInt *rows; 10053 PetscInt rStart, rEnd, r, nrow = 0; 10054 10055 PetscCall(MatCreateVecs(mat, &diag, NULL)); 10056 PetscCall(MatGetDiagonal(mat, diag)); 10057 PetscCall(MatGetOwnershipRange(mat, &rStart, &rEnd)); 10058 PetscCall(VecGetArrayRead(diag, &a)); 10059 for (r = 0; r < rEnd - rStart; ++r) 10060 if (a[r] == 0.0) ++nrow; 10061 PetscCall(PetscMalloc1(nrow, &rows)); 10062 nrow = 0; 10063 for (r = 0; r < rEnd - rStart; ++r) 10064 if (a[r] == 0.0) rows[nrow++] = r + rStart; 10065 PetscCall(VecRestoreArrayRead(diag, &a)); 10066 PetscCall(VecDestroy(&diag)); 10067 PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)mat), nrow, rows, PETSC_OWN_POINTER, is)); 10068 } else { 10069 PetscUseTypeMethod(mat, findzerodiagonals, is); 10070 } 10071 PetscFunctionReturn(0); 10072 } 10073 10074 /*@ 10075 MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size) 10076 10077 Collective on Mat 10078 10079 Input Parameter: 10080 . mat - the matrix 10081 10082 Output Parameter: 10083 . is - contains the list of rows with off block diagonal entries 10084 10085 Level: developer 10086 10087 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 10088 @*/ 10089 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat, IS *is) { 10090 PetscFunctionBegin; 10091 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 10092 PetscValidType(mat, 1); 10093 PetscCheck(mat->assembled, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 10094 PetscCheck(!mat->factortype, PetscObjectComm((PetscObject)mat), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 10095 10096 PetscUseTypeMethod(mat, findoffblockdiagonalentries, is); 10097 PetscFunctionReturn(0); 10098 } 10099 10100 /*@C 10101 MatInvertBlockDiagonal - Inverts the block diagonal entries. 10102 10103 Collective on Mat 10104 10105 Input Parameters: 10106 . mat - the matrix 10107 10108 Output Parameters: 10109 . values - the block inverses in column major order (FORTRAN-like) 10110 10111 Note: 10112 The size of the blocks is determined by the block size of the matrix. 10113 10114 Fortran Note: 10115 This routine is not available from Fortran. 10116 10117 Level: advanced 10118 10119 .seealso: `MatInvertVariableBlockEnvelope()`, `MatInvertBlockDiagonalMat()` 10120 @*/ 10121 PetscErrorCode MatInvertBlockDiagonal(Mat mat, const PetscScalar **values) { 10122 PetscFunctionBegin; 10123 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 10124 PetscCheck(mat->assembled, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 10125 PetscCheck(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 10126 PetscUseTypeMethod(mat, invertblockdiagonal, values); 10127 PetscFunctionReturn(0); 10128 } 10129 10130 /*@C 10131 MatInvertVariableBlockDiagonal - Inverts the point block diagonal entries. 10132 10133 Collective on Mat 10134 10135 Input Parameters: 10136 + mat - the matrix 10137 . nblocks - the number of blocks on the process, set with MatSetVariableBlockSizes() 10138 - bsizes - the size of each block on the process, set with MatSetVariableBlockSizes() 10139 10140 Output Parameters: 10141 . values - the block inverses in column major order (FORTRAN-like) 10142 10143 Note: 10144 This routine is not available from Fortran. 10145 10146 Level: advanced 10147 10148 .seealso: `MatInvertBlockDiagonal()`, `MatSetVariableBlockSizes()`, `MatInvertVariableBlockEnvelope()` 10149 @*/ 10150 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat, PetscInt nblocks, const PetscInt *bsizes, PetscScalar *values) { 10151 PetscFunctionBegin; 10152 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 10153 PetscCheck(mat->assembled, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 10154 PetscCheck(!mat->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 10155 PetscUseTypeMethod(mat, invertvariableblockdiagonal, nblocks, bsizes, values); 10156 PetscFunctionReturn(0); 10157 } 10158 10159 /*@ 10160 MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A 10161 10162 Collective on Mat 10163 10164 Input Parameters: 10165 . A - the matrix 10166 10167 Output Parameters: 10168 . C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set. 10169 10170 Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C 10171 10172 Level: advanced 10173 10174 .seealso: `MatInvertBlockDiagonal()` 10175 @*/ 10176 PetscErrorCode MatInvertBlockDiagonalMat(Mat A, Mat C) { 10177 const PetscScalar *vals; 10178 PetscInt *dnnz; 10179 PetscInt m, rstart, rend, bs, i, j; 10180 10181 PetscFunctionBegin; 10182 PetscCall(MatInvertBlockDiagonal(A, &vals)); 10183 PetscCall(MatGetBlockSize(A, &bs)); 10184 PetscCall(MatGetLocalSize(A, &m, NULL)); 10185 PetscCall(MatSetLayouts(C, A->rmap, A->cmap)); 10186 PetscCall(PetscMalloc1(m / bs, &dnnz)); 10187 for (j = 0; j < m / bs; j++) dnnz[j] = 1; 10188 PetscCall(MatXAIJSetPreallocation(C, bs, dnnz, NULL, NULL, NULL)); 10189 PetscCall(PetscFree(dnnz)); 10190 PetscCall(MatGetOwnershipRange(C, &rstart, &rend)); 10191 PetscCall(MatSetOption(C, MAT_ROW_ORIENTED, PETSC_FALSE)); 10192 for (i = rstart / bs; i < rend / bs; i++) PetscCall(MatSetValuesBlocked(C, 1, &i, 1, &i, &vals[(i - rstart / bs) * bs * bs], INSERT_VALUES)); 10193 PetscCall(MatAssemblyBegin(C, MAT_FINAL_ASSEMBLY)); 10194 PetscCall(MatAssemblyEnd(C, MAT_FINAL_ASSEMBLY)); 10195 PetscCall(MatSetOption(C, MAT_ROW_ORIENTED, PETSC_TRUE)); 10196 PetscFunctionReturn(0); 10197 } 10198 10199 /*@C 10200 MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created 10201 via MatTransposeColoringCreate(). 10202 10203 Collective on MatTransposeColoring 10204 10205 Input Parameter: 10206 . c - coloring context 10207 10208 Level: intermediate 10209 10210 .seealso: `MatTransposeColoringCreate()` 10211 @*/ 10212 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c) { 10213 MatTransposeColoring matcolor = *c; 10214 10215 PetscFunctionBegin; 10216 if (!matcolor) PetscFunctionReturn(0); 10217 if (--((PetscObject)matcolor)->refct > 0) { 10218 matcolor = NULL; 10219 PetscFunctionReturn(0); 10220 } 10221 10222 PetscCall(PetscFree3(matcolor->ncolumns, matcolor->nrows, matcolor->colorforrow)); 10223 PetscCall(PetscFree(matcolor->rows)); 10224 PetscCall(PetscFree(matcolor->den2sp)); 10225 PetscCall(PetscFree(matcolor->colorforcol)); 10226 PetscCall(PetscFree(matcolor->columns)); 10227 if (matcolor->brows > 0) PetscCall(PetscFree(matcolor->lstart)); 10228 PetscCall(PetscHeaderDestroy(c)); 10229 PetscFunctionReturn(0); 10230 } 10231 10232 /*@C 10233 MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which 10234 a MatTransposeColoring context has been created, computes a dense B^T by Apply 10235 MatTransposeColoring to sparse B. 10236 10237 Collective on MatTransposeColoring 10238 10239 Input Parameters: 10240 + B - sparse matrix B 10241 . Btdense - symbolic dense matrix B^T 10242 - coloring - coloring context created with MatTransposeColoringCreate() 10243 10244 Output Parameter: 10245 . Btdense - dense matrix B^T 10246 10247 Level: advanced 10248 10249 Notes: 10250 These are used internally for some implementations of MatRARt() 10251 10252 .seealso: `MatTransposeColoringCreate()`, `MatTransposeColoringDestroy()`, `MatTransColoringApplyDenToSp()` 10253 10254 @*/ 10255 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring, Mat B, Mat Btdense) { 10256 PetscFunctionBegin; 10257 PetscValidHeaderSpecific(B, MAT_CLASSID, 2); 10258 PetscValidHeaderSpecific(Btdense, MAT_CLASSID, 3); 10259 PetscValidHeaderSpecific(coloring, MAT_TRANSPOSECOLORING_CLASSID, 1); 10260 10261 PetscCall((B->ops->transcoloringapplysptoden)(coloring, B, Btdense)); 10262 PetscFunctionReturn(0); 10263 } 10264 10265 /*@C 10266 MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which 10267 a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense 10268 in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix 10269 Csp from Cden. 10270 10271 Collective on MatTransposeColoring 10272 10273 Input Parameters: 10274 + coloring - coloring context created with MatTransposeColoringCreate() 10275 - Cden - matrix product of a sparse matrix and a dense matrix Btdense 10276 10277 Output Parameter: 10278 . Csp - sparse matrix 10279 10280 Level: advanced 10281 10282 Notes: 10283 These are used internally for some implementations of MatRARt() 10284 10285 .seealso: `MatTransposeColoringCreate()`, `MatTransposeColoringDestroy()`, `MatTransColoringApplySpToDen()` 10286 10287 @*/ 10288 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring, Mat Cden, Mat Csp) { 10289 PetscFunctionBegin; 10290 PetscValidHeaderSpecific(matcoloring, MAT_TRANSPOSECOLORING_CLASSID, 1); 10291 PetscValidHeaderSpecific(Cden, MAT_CLASSID, 2); 10292 PetscValidHeaderSpecific(Csp, MAT_CLASSID, 3); 10293 10294 PetscCall((Csp->ops->transcoloringapplydentosp)(matcoloring, Cden, Csp)); 10295 PetscCall(MatAssemblyBegin(Csp, MAT_FINAL_ASSEMBLY)); 10296 PetscCall(MatAssemblyEnd(Csp, MAT_FINAL_ASSEMBLY)); 10297 PetscFunctionReturn(0); 10298 } 10299 10300 /*@C 10301 MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T. 10302 10303 Collective on Mat 10304 10305 Input Parameters: 10306 + mat - the matrix product C 10307 - iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring() 10308 10309 Output Parameter: 10310 . color - the new coloring context 10311 10312 Level: intermediate 10313 10314 .seealso: `MatTransposeColoringDestroy()`, `MatTransColoringApplySpToDen()`, 10315 `MatTransColoringApplyDenToSp()` 10316 @*/ 10317 PetscErrorCode MatTransposeColoringCreate(Mat mat, ISColoring iscoloring, MatTransposeColoring *color) { 10318 MatTransposeColoring c; 10319 MPI_Comm comm; 10320 10321 PetscFunctionBegin; 10322 PetscCall(PetscLogEventBegin(MAT_TransposeColoringCreate, mat, 0, 0, 0)); 10323 PetscCall(PetscObjectGetComm((PetscObject)mat, &comm)); 10324 PetscCall(PetscHeaderCreate(c, MAT_TRANSPOSECOLORING_CLASSID, "MatTransposeColoring", "Matrix product C=A*B^T via coloring", "Mat", comm, MatTransposeColoringDestroy, NULL)); 10325 10326 c->ctype = iscoloring->ctype; 10327 if (mat->ops->transposecoloringcreate) { 10328 PetscUseTypeMethod(mat, transposecoloringcreate, iscoloring, c); 10329 } else SETERRQ(PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Code not yet written for matrix type %s", ((PetscObject)mat)->type_name); 10330 10331 *color = c; 10332 PetscCall(PetscLogEventEnd(MAT_TransposeColoringCreate, mat, 0, 0, 0)); 10333 PetscFunctionReturn(0); 10334 } 10335 10336 /*@ 10337 MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the 10338 matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the 10339 same, otherwise it will be larger 10340 10341 Not Collective 10342 10343 Input Parameter: 10344 . A - the matrix 10345 10346 Output Parameter: 10347 . state - the current state 10348 10349 Notes: 10350 You can only compare states from two different calls to the SAME matrix, you cannot compare calls between 10351 different matrices 10352 10353 Level: intermediate 10354 10355 .seealso: `PetscObjectStateGet()` 10356 @*/ 10357 PetscErrorCode MatGetNonzeroState(Mat mat, PetscObjectState *state) { 10358 PetscFunctionBegin; 10359 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 10360 *state = mat->nonzerostate; 10361 PetscFunctionReturn(0); 10362 } 10363 10364 /*@ 10365 MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential 10366 matrices from each processor 10367 10368 Collective 10369 10370 Input Parameters: 10371 + comm - the communicators the parallel matrix will live on 10372 . seqmat - the input sequential matrices 10373 . n - number of local columns (or PETSC_DECIDE) 10374 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10375 10376 Output Parameter: 10377 . mpimat - the parallel matrix generated 10378 10379 Level: advanced 10380 10381 Notes: 10382 The number of columns of the matrix in EACH processor MUST be the same. 10383 10384 @*/ 10385 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm, Mat seqmat, PetscInt n, MatReuse reuse, Mat *mpimat) { 10386 PetscMPIInt size; 10387 10388 PetscFunctionBegin; 10389 PetscCallMPI(MPI_Comm_size(comm, &size)); 10390 if (size == 1) { 10391 if (reuse == MAT_INITIAL_MATRIX) { 10392 PetscCall(MatDuplicate(seqmat, MAT_COPY_VALUES, mpimat)); 10393 } else { 10394 PetscCall(MatCopy(seqmat, *mpimat, SAME_NONZERO_PATTERN)); 10395 } 10396 PetscFunctionReturn(0); 10397 } 10398 10399 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"); 10400 10401 PetscCall(PetscLogEventBegin(MAT_Merge, seqmat, 0, 0, 0)); 10402 PetscCall((*seqmat->ops->creatempimatconcatenateseqmat)(comm, seqmat, n, reuse, mpimat)); 10403 PetscCall(PetscLogEventEnd(MAT_Merge, seqmat, 0, 0, 0)); 10404 PetscFunctionReturn(0); 10405 } 10406 10407 /*@ 10408 MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent 10409 ranks' ownership ranges. 10410 10411 Collective on A 10412 10413 Input Parameters: 10414 + A - the matrix to create subdomains from 10415 - N - requested number of subdomains 10416 10417 Output Parameters: 10418 + n - number of subdomains resulting on this rank 10419 - iss - IS list with indices of subdomains on this rank 10420 10421 Level: advanced 10422 10423 Notes: 10424 number of subdomains must be smaller than the communicator size 10425 @*/ 10426 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A, PetscInt N, PetscInt *n, IS *iss[]) { 10427 MPI_Comm comm, subcomm; 10428 PetscMPIInt size, rank, color; 10429 PetscInt rstart, rend, k; 10430 10431 PetscFunctionBegin; 10432 PetscCall(PetscObjectGetComm((PetscObject)A, &comm)); 10433 PetscCallMPI(MPI_Comm_size(comm, &size)); 10434 PetscCallMPI(MPI_Comm_rank(comm, &rank)); 10435 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); 10436 *n = 1; 10437 k = ((PetscInt)size) / N + ((PetscInt)size % N > 0); /* There are up to k ranks to a color */ 10438 color = rank / k; 10439 PetscCallMPI(MPI_Comm_split(comm, color, rank, &subcomm)); 10440 PetscCall(PetscMalloc1(1, iss)); 10441 PetscCall(MatGetOwnershipRange(A, &rstart, &rend)); 10442 PetscCall(ISCreateStride(subcomm, rend - rstart, rstart, 1, iss[0])); 10443 PetscCallMPI(MPI_Comm_free(&subcomm)); 10444 PetscFunctionReturn(0); 10445 } 10446 10447 /*@ 10448 MatGalerkin - Constructs the coarse grid problem via Galerkin projection. 10449 10450 If the interpolation and restriction operators are the same, uses MatPtAP. 10451 If they are not the same, use MatMatMatMult. 10452 10453 Once the coarse grid problem is constructed, correct for interpolation operators 10454 that are not of full rank, which can legitimately happen in the case of non-nested 10455 geometric multigrid. 10456 10457 Input Parameters: 10458 + restrct - restriction operator 10459 . dA - fine grid matrix 10460 . interpolate - interpolation operator 10461 . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10462 - fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate 10463 10464 Output Parameters: 10465 . A - the Galerkin coarse matrix 10466 10467 Options Database Key: 10468 . -pc_mg_galerkin <both,pmat,mat,none> - for what matrices the Galerkin process should be used 10469 10470 Level: developer 10471 10472 .seealso: `MatPtAP()`, `MatMatMatMult()` 10473 @*/ 10474 PetscErrorCode MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A) { 10475 IS zerorows; 10476 Vec diag; 10477 10478 PetscFunctionBegin; 10479 PetscCheck(reuse != MAT_INPLACE_MATRIX, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Inplace product not supported"); 10480 /* Construct the coarse grid matrix */ 10481 if (interpolate == restrct) { 10482 PetscCall(MatPtAP(dA, interpolate, reuse, fill, A)); 10483 } else { 10484 PetscCall(MatMatMatMult(restrct, dA, interpolate, reuse, fill, A)); 10485 } 10486 10487 /* If the interpolation matrix is not of full rank, A will have zero rows. 10488 This can legitimately happen in the case of non-nested geometric multigrid. 10489 In that event, we set the rows of the matrix to the rows of the identity, 10490 ignoring the equations (as the RHS will also be zero). */ 10491 10492 PetscCall(MatFindZeroRows(*A, &zerorows)); 10493 10494 if (zerorows != NULL) { /* if there are any zero rows */ 10495 PetscCall(MatCreateVecs(*A, &diag, NULL)); 10496 PetscCall(MatGetDiagonal(*A, diag)); 10497 PetscCall(VecISSet(diag, zerorows, 1.0)); 10498 PetscCall(MatDiagonalSet(*A, diag, INSERT_VALUES)); 10499 PetscCall(VecDestroy(&diag)); 10500 PetscCall(ISDestroy(&zerorows)); 10501 } 10502 PetscFunctionReturn(0); 10503 } 10504 10505 /*@C 10506 MatSetOperation - Allows user to set a matrix operation for any matrix type 10507 10508 Logically Collective on Mat 10509 10510 Input Parameters: 10511 + mat - the matrix 10512 . op - the name of the operation 10513 - f - the function that provides the operation 10514 10515 Level: developer 10516 10517 Usage: 10518 $ extern PetscErrorCode usermult(Mat,Vec,Vec); 10519 $ PetscCall(MatCreateXXX(comm,...&A); 10520 $ PetscCall(MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult); 10521 10522 Notes: 10523 See the file include/petscmat.h for a complete list of matrix 10524 operations, which all have the form MATOP_<OPERATION>, where 10525 <OPERATION> is the name (in all capital letters) of the 10526 user interface routine (e.g., MatMult() -> MATOP_MULT). 10527 10528 All user-provided functions (except for MATOP_DESTROY) should have the same calling 10529 sequence as the usual matrix interface routines, since they 10530 are intended to be accessed via the usual matrix interface 10531 routines, e.g., 10532 $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 10533 10534 In particular each function MUST return an error code of 0 on success and 10535 nonzero on failure. 10536 10537 This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type. 10538 10539 .seealso: `MatGetOperation()`, `MatCreateShell()`, `MatShellSetContext()`, `MatShellSetOperation()` 10540 @*/ 10541 PetscErrorCode MatSetOperation(Mat mat, MatOperation op, void (*f)(void)) { 10542 PetscFunctionBegin; 10543 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 10544 if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) { mat->ops->viewnative = mat->ops->view; } 10545 (((void (**)(void))mat->ops)[op]) = f; 10546 PetscFunctionReturn(0); 10547 } 10548 10549 /*@C 10550 MatGetOperation - Gets a matrix operation for any matrix type. 10551 10552 Not Collective 10553 10554 Input Parameters: 10555 + mat - the matrix 10556 - op - the name of the operation 10557 10558 Output Parameter: 10559 . f - the function that provides the operation 10560 10561 Level: developer 10562 10563 Usage: 10564 $ PetscErrorCode (*usermult)(Mat,Vec,Vec); 10565 $ MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult); 10566 10567 Notes: 10568 See the file include/petscmat.h for a complete list of matrix 10569 operations, which all have the form MATOP_<OPERATION>, where 10570 <OPERATION> is the name (in all capital letters) of the 10571 user interface routine (e.g., MatMult() -> MATOP_MULT). 10572 10573 This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type. 10574 10575 .seealso: `MatSetOperation()`, `MatCreateShell()`, `MatShellGetContext()`, `MatShellGetOperation()` 10576 @*/ 10577 PetscErrorCode MatGetOperation(Mat mat, MatOperation op, void (**f)(void)) { 10578 PetscFunctionBegin; 10579 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 10580 *f = (((void (**)(void))mat->ops)[op]); 10581 PetscFunctionReturn(0); 10582 } 10583 10584 /*@ 10585 MatHasOperation - Determines whether the given matrix supports the particular 10586 operation. 10587 10588 Not Collective 10589 10590 Input Parameters: 10591 + mat - the matrix 10592 - op - the operation, for example, MATOP_GET_DIAGONAL 10593 10594 Output Parameter: 10595 . has - either PETSC_TRUE or PETSC_FALSE 10596 10597 Level: advanced 10598 10599 Notes: 10600 See the file include/petscmat.h for a complete list of matrix 10601 operations, which all have the form MATOP_<OPERATION>, where 10602 <OPERATION> is the name (in all capital letters) of the 10603 user-level routine. E.g., MatNorm() -> MATOP_NORM. 10604 10605 .seealso: `MatCreateShell()` 10606 @*/ 10607 PetscErrorCode MatHasOperation(Mat mat, MatOperation op, PetscBool *has) { 10608 PetscFunctionBegin; 10609 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 10610 PetscValidBoolPointer(has, 3); 10611 if (mat->ops->hasoperation) { 10612 PetscUseTypeMethod(mat, hasoperation, op, has); 10613 } else { 10614 if (((void **)mat->ops)[op]) *has = PETSC_TRUE; 10615 else { 10616 *has = PETSC_FALSE; 10617 if (op == MATOP_CREATE_SUBMATRIX) { 10618 PetscMPIInt size; 10619 10620 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size)); 10621 if (size == 1) PetscCall(MatHasOperation(mat, MATOP_CREATE_SUBMATRICES, has)); 10622 } 10623 } 10624 } 10625 PetscFunctionReturn(0); 10626 } 10627 10628 /*@ 10629 MatHasCongruentLayouts - Determines whether the rows and columns layouts 10630 of the matrix are congruent 10631 10632 Collective on mat 10633 10634 Input Parameters: 10635 . mat - the matrix 10636 10637 Output Parameter: 10638 . cong - either PETSC_TRUE or PETSC_FALSE 10639 10640 Level: beginner 10641 10642 Notes: 10643 10644 .seealso: `MatCreate()`, `MatSetSizes()` 10645 @*/ 10646 PetscErrorCode MatHasCongruentLayouts(Mat mat, PetscBool *cong) { 10647 PetscFunctionBegin; 10648 PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 10649 PetscValidType(mat, 1); 10650 PetscValidBoolPointer(cong, 2); 10651 if (!mat->rmap || !mat->cmap) { 10652 *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE; 10653 PetscFunctionReturn(0); 10654 } 10655 if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */ 10656 PetscCall(PetscLayoutSetUp(mat->rmap)); 10657 PetscCall(PetscLayoutSetUp(mat->cmap)); 10658 PetscCall(PetscLayoutCompare(mat->rmap, mat->cmap, cong)); 10659 if (*cong) mat->congruentlayouts = 1; 10660 else mat->congruentlayouts = 0; 10661 } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE; 10662 PetscFunctionReturn(0); 10663 } 10664 10665 PetscErrorCode MatSetInf(Mat A) { 10666 PetscFunctionBegin; 10667 PetscUseTypeMethod(A, setinf); 10668 PetscFunctionReturn(0); 10669 } 10670 10671 /*C 10672 MatCreateGraph - create a scalar matrix, for use in graph algorithms 10673 10674 Collective on mat 10675 10676 Input Parameters: 10677 + A - the matrix 10678 - sym - PETSC_TRUE indicates that the graph will be symmetrized 10679 . scale - PETSC_TRUE indicates that the graph will be scaled with the diagonal 10680 10681 Output Parameter: 10682 . graph - the resulting graph 10683 10684 Level: advanced 10685 10686 Notes: 10687 10688 .seealso: `MatCreate()`, `MatFilter()` 10689 */ 10690 PETSC_EXTERN PetscErrorCode MatCreateGraph(Mat A, PetscBool sym, PetscBool scale, Mat *graph) { 10691 PetscFunctionBegin; 10692 PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 10693 PetscValidType(A, 1); 10694 PetscValidPointer(graph, 3); 10695 PetscUseTypeMethod(A, creategraph, sym, scale, graph); 10696 PetscFunctionReturn(0); 10697 } 10698 10699 /*C 10700 MatFilter - filters a Mat values with an absolut value equal to or below a give threshold 10701 10702 Collective on mat 10703 10704 Input Parameter: 10705 . value - filter value - < 0: does nothing; == 0: removes only 0.0 entries; otherwise: removes entries <= value 10706 10707 Input/Output Parameter: 10708 . A - the Mat to filter in place 10709 10710 Level: developer 10711 10712 Note: 10713 This is called before graph coarsers are called in GAMG 10714 10715 .seealso: `MatCreate()`, `MatCreateGraph()` 10716 */ 10717 PETSC_EXTERN PetscErrorCode MatFilter(Mat G, PetscReal value, Mat *F) { 10718 PetscFunctionBegin; 10719 PetscValidHeaderSpecific(G, MAT_CLASSID, 1); 10720 PetscValidType(G, 1); 10721 PetscValidPointer(F, 3); 10722 if (value >= 0.0) PetscCall((G->ops->filter)(G, value, F)); 10723 PetscFunctionReturn(0); 10724 } 10725