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