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 { 74 PetscRandom randObj = NULL; 75 76 PetscFunctionBegin; 77 PetscValidHeaderSpecific(x,MAT_CLASSID,1); 78 if (rctx) PetscValidHeaderSpecific(rctx,PETSC_RANDOM_CLASSID,2); 79 PetscValidType(x,1); 80 MatCheckPreallocated(x,1); 81 82 PetscCheck(x->ops->setrandom,PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Mat type %s",((PetscObject)x)->type_name); 83 84 if (!rctx) { 85 MPI_Comm comm; 86 PetscCall(PetscObjectGetComm((PetscObject)x,&comm)); 87 PetscCall(PetscRandomCreate(comm,&randObj)); 88 PetscCall(PetscRandomSetFromOptions(randObj)); 89 rctx = randObj; 90 } 91 PetscCall(PetscLogEventBegin(MAT_SetRandom,x,rctx,0,0)); 92 PetscCall((*x->ops->setrandom)(x,rctx)); 93 PetscCall(PetscLogEventEnd(MAT_SetRandom,x,rctx,0,0)); 94 95 PetscCall(MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY)); 96 PetscCall(MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY)); 97 PetscCall(PetscRandomDestroy(&randObj)); 98 PetscFunctionReturn(0); 99 } 100 101 /*@ 102 MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in 103 104 Logically Collective on Mat 105 106 Input Parameter: 107 . mat - the factored matrix 108 109 Output Parameters: 110 + pivot - the pivot value computed 111 - row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes 112 the share the matrix 113 114 Level: advanced 115 116 Notes: 117 This routine does not work for factorizations done with external packages. 118 119 This routine should only be called if `MatGetFactorError()` returns a value of `MAT_FACTOR_NUMERIC_ZEROPIVOT` 120 121 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 122 123 .seealso: `MatZeroEntries()`, `MatFactor()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()`, `MatFactorClearError()`, `MatFactorGetErrorZeroPivot()` 124 @*/ 125 PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row) 126 { 127 PetscFunctionBegin; 128 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 129 PetscValidRealPointer(pivot,2); 130 PetscValidIntPointer(row,3); 131 *pivot = mat->factorerror_zeropivot_value; 132 *row = mat->factorerror_zeropivot_row; 133 PetscFunctionReturn(0); 134 } 135 136 /*@ 137 MatFactorGetError - gets the error code from a factorization 138 139 Logically Collective on Mat 140 141 Input Parameters: 142 . mat - the factored matrix 143 144 Output Parameter: 145 . err - the error code 146 147 Level: advanced 148 149 Notes: 150 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 151 152 .seealso: `MatZeroEntries()`, `MatFactor()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()`, `MatFactorClearError()`, `MatFactorGetErrorZeroPivot()`, 153 `MatErrorCode` 154 @*/ 155 PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err) 156 { 157 PetscFunctionBegin; 158 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 159 PetscValidPointer(err,2); 160 *err = mat->factorerrortype; 161 PetscFunctionReturn(0); 162 } 163 164 /*@ 165 MatFactorClearError - clears the error code in a factorization 166 167 Logically Collective on Mat 168 169 Input Parameter: 170 . mat - the factored matrix 171 172 Level: developer 173 174 Notes: 175 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 176 177 .seealso: `MatZeroEntries()`, `MatFactor()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()`, `MatFactorGetError()`, `MatFactorGetErrorZeroPivot()`, 178 `MatGetErrorCode()`, `MatErrorCode` 179 @*/ 180 PetscErrorCode MatFactorClearError(Mat mat) 181 { 182 PetscFunctionBegin; 183 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 184 mat->factorerrortype = MAT_FACTOR_NOERROR; 185 mat->factorerror_zeropivot_value = 0.0; 186 mat->factorerror_zeropivot_row = 0; 187 PetscFunctionReturn(0); 188 } 189 190 PETSC_INTERN PetscErrorCode MatFindNonzeroRowsOrCols_Basic(Mat mat,PetscBool cols,PetscReal tol,IS *nonzero) 191 { 192 Vec r,l; 193 const PetscScalar *al; 194 PetscInt i,nz,gnz,N,n; 195 196 PetscFunctionBegin; 197 PetscCall(MatCreateVecs(mat,&r,&l)); 198 if (!cols) { /* nonzero rows */ 199 PetscCall(MatGetSize(mat,&N,NULL)); 200 PetscCall(MatGetLocalSize(mat,&n,NULL)); 201 PetscCall(VecSet(l,0.0)); 202 PetscCall(VecSetRandom(r,NULL)); 203 PetscCall(MatMult(mat,r,l)); 204 PetscCall(VecGetArrayRead(l,&al)); 205 } else { /* nonzero columns */ 206 PetscCall(MatGetSize(mat,NULL,&N)); 207 PetscCall(MatGetLocalSize(mat,NULL,&n)); 208 PetscCall(VecSet(r,0.0)); 209 PetscCall(VecSetRandom(l,NULL)); 210 PetscCall(MatMultTranspose(mat,l,r)); 211 PetscCall(VecGetArrayRead(r,&al)); 212 } 213 if (tol <= 0.0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++; } 214 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nz++; } 215 PetscCall(MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat))); 216 if (gnz != N) { 217 PetscInt *nzr; 218 PetscCall(PetscMalloc1(nz,&nzr)); 219 if (nz) { 220 if (tol < 0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; } 221 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nzr[nz++] = i; } 222 } 223 PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,nonzero)); 224 } else *nonzero = NULL; 225 if (!cols) { /* nonzero rows */ 226 PetscCall(VecRestoreArrayRead(l,&al)); 227 } else { 228 PetscCall(VecRestoreArrayRead(r,&al)); 229 } 230 PetscCall(VecDestroy(&l)); 231 PetscCall(VecDestroy(&r)); 232 PetscFunctionReturn(0); 233 } 234 235 /*@ 236 MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix 237 238 Input Parameter: 239 . A - the matrix 240 241 Output Parameter: 242 . keptrows - the rows that are not completely zero 243 244 Notes: 245 keptrows is set to NULL if all rows are nonzero. 246 247 Level: intermediate 248 249 @*/ 250 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows) 251 { 252 PetscFunctionBegin; 253 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 254 PetscValidType(mat,1); 255 PetscValidPointer(keptrows,2); 256 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 257 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 258 if (mat->ops->findnonzerorows) { 259 PetscCall((*mat->ops->findnonzerorows)(mat,keptrows)); 260 } else { 261 PetscCall(MatFindNonzeroRowsOrCols_Basic(mat,PETSC_FALSE,0.0,keptrows)); 262 } 263 PetscFunctionReturn(0); 264 } 265 266 /*@ 267 MatFindZeroRows - Locate all rows that are completely zero in the matrix 268 269 Input Parameter: 270 . A - the matrix 271 272 Output Parameter: 273 . zerorows - the rows that are completely zero 274 275 Notes: 276 zerorows is set to NULL if no rows are zero. 277 278 Level: intermediate 279 280 @*/ 281 PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows) 282 { 283 IS keptrows; 284 PetscInt m, n; 285 286 PetscFunctionBegin; 287 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 288 PetscValidType(mat,1); 289 PetscValidPointer(zerorows,2); 290 PetscCall(MatFindNonzeroRows(mat, &keptrows)); 291 /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows. 292 In keeping with this convention, we set zerorows to NULL if there are no zero 293 rows. */ 294 if (keptrows == NULL) { 295 *zerorows = NULL; 296 } else { 297 PetscCall(MatGetOwnershipRange(mat,&m,&n)); 298 PetscCall(ISComplement(keptrows,m,n,zerorows)); 299 PetscCall(ISDestroy(&keptrows)); 300 } 301 PetscFunctionReturn(0); 302 } 303 304 /*@ 305 MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling 306 307 Not Collective 308 309 Input Parameters: 310 . A - the matrix 311 312 Output Parameters: 313 . a - the diagonal part (which is a SEQUENTIAL matrix) 314 315 Notes: 316 See the manual page for `MatCreateAIJ()` for more information on the "diagonal part" of the matrix. 317 318 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. 319 320 Level: advanced 321 322 .seelaso: `MatCreateAIJ()` 323 @*/ 324 PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a) 325 { 326 PetscFunctionBegin; 327 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 328 PetscValidType(A,1); 329 PetscValidPointer(a,2); 330 PetscCheck(!A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 331 if (A->ops->getdiagonalblock) { 332 PetscCall((*A->ops->getdiagonalblock)(A,a)); 333 } else { 334 PetscMPIInt size; 335 336 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)A),&size)); 337 PetscCheck(size == 1,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not for parallel matrix type %s",((PetscObject)A)->type_name); 338 *a = A; 339 } 340 PetscFunctionReturn(0); 341 } 342 343 /*@ 344 MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries. 345 346 Collective on Mat 347 348 Input Parameters: 349 . mat - the matrix 350 351 Output Parameter: 352 . trace - the sum of the diagonal entries 353 354 Level: advanced 355 356 @*/ 357 PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace) 358 { 359 Vec diag; 360 361 PetscFunctionBegin; 362 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 363 PetscValidScalarPointer(trace,2); 364 PetscCall(MatCreateVecs(mat,&diag,NULL)); 365 PetscCall(MatGetDiagonal(mat,diag)); 366 PetscCall(VecSum(diag,trace)); 367 PetscCall(VecDestroy(&diag)); 368 PetscFunctionReturn(0); 369 } 370 371 /*@ 372 MatRealPart - Zeros out the imaginary part of the matrix 373 374 Logically Collective on Mat 375 376 Input Parameters: 377 . mat - the matrix 378 379 Level: advanced 380 381 .seealso: `MatImaginaryPart()` 382 @*/ 383 PetscErrorCode MatRealPart(Mat mat) 384 { 385 PetscFunctionBegin; 386 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 387 PetscValidType(mat,1); 388 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 389 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 390 PetscCheck(mat->ops->realpart,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 391 MatCheckPreallocated(mat,1); 392 PetscCall((*mat->ops->realpart)(mat)); 393 PetscFunctionReturn(0); 394 } 395 396 /*@C 397 MatGetGhosts - Get the global indices of all ghost nodes defined by the sparse matrix 398 399 Collective on Mat 400 401 Input Parameter: 402 . mat - the matrix 403 404 Output Parameters: 405 + nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block) 406 - ghosts - the global indices of the ghost points 407 408 Notes: 409 the nghosts and ghosts are suitable to pass into `VecCreateGhost()` 410 411 Level: advanced 412 413 @*/ 414 PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[]) 415 { 416 PetscFunctionBegin; 417 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 418 PetscValidType(mat,1); 419 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 420 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 421 if (mat->ops->getghosts) { 422 PetscCall((*mat->ops->getghosts)(mat,nghosts,ghosts)); 423 } else { 424 if (nghosts) *nghosts = 0; 425 if (ghosts) *ghosts = NULL; 426 } 427 PetscFunctionReturn(0); 428 } 429 430 /*@ 431 MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part 432 433 Logically Collective on Mat 434 435 Input Parameters: 436 . mat - the matrix 437 438 Level: advanced 439 440 .seealso: `MatRealPart()` 441 @*/ 442 PetscErrorCode MatImaginaryPart(Mat mat) 443 { 444 PetscFunctionBegin; 445 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 446 PetscValidType(mat,1); 447 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 448 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 449 PetscCheck(mat->ops->imaginarypart,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 450 MatCheckPreallocated(mat,1); 451 PetscCall((*mat->ops->imaginarypart)(mat)); 452 PetscFunctionReturn(0); 453 } 454 455 /*@ 456 MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices) 457 458 Not Collective 459 460 Input Parameter: 461 . mat - the matrix 462 463 Output Parameters: 464 + missing - is any diagonal missing 465 - dd - first diagonal entry that is missing (optional) on this process 466 467 Level: advanced 468 469 .seealso: `MatRealPart()` 470 @*/ 471 PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd) 472 { 473 PetscFunctionBegin; 474 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 475 PetscValidType(mat,1); 476 PetscValidBoolPointer(missing,2); 477 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix %s",((PetscObject)mat)->type_name); 478 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 479 PetscCheck(mat->ops->missingdiagonal,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 480 PetscCall((*mat->ops->missingdiagonal)(mat,missing,dd)); 481 PetscFunctionReturn(0); 482 } 483 484 /*@C 485 MatGetRow - Gets a row of a matrix. You MUST call `MatRestoreRow()` 486 for each row that you get to ensure that your application does 487 not bleed memory. 488 489 Not Collective 490 491 Input Parameters: 492 + mat - the matrix 493 - row - the row to get 494 495 Output Parameters: 496 + ncols - if not NULL, the number of nonzeros in the row 497 . cols - if not NULL, the column numbers 498 - vals - if not NULL, the values 499 500 Notes: 501 This routine is provided for people who need to have direct access 502 to the structure of a matrix. We hope that we provide enough 503 high-level matrix routines that few users will need it. 504 505 `MatGetRow()` always returns 0-based column indices, regardless of 506 whether the internal representation is 0-based (default) or 1-based. 507 508 For better efficiency, set cols and/or vals to NULL if you do 509 not wish to extract these quantities. 510 511 The user can only examine the values extracted with `MatGetRow()`; 512 the values cannot be altered. To change the matrix entries, one 513 must use `MatSetValues()`. 514 515 You can only have one call to `MatGetRow()` outstanding for a particular 516 matrix at a time, per processor. `MatGetRow()` can only obtain rows 517 associated with the given processor, it cannot get rows from the 518 other processors; for that we suggest using `MatCreateSubMatrices()`, then 519 MatGetRow() on the submatrix. The row index passed to `MatGetRow()` 520 is in the global number of rows. 521 522 Use `MatGetRowIJ()` and `MatRestoreRowIJ()` to access all the local indices of the sparse matrix. 523 524 Use `MatSeqAIJGetArray()` and similar functions to access the numerical values for certain matrix types directly. 525 526 Fortran Notes: 527 The calling sequence from Fortran is 528 .vb 529 MatGetRow(matrix,row,ncols,cols,values,ierr) 530 Mat matrix (input) 531 integer row (input) 532 integer ncols (output) 533 integer cols(maxcols) (output) 534 double precision (or double complex) values(maxcols) output 535 .ve 536 where maxcols >= maximum nonzeros in any row of the matrix. 537 538 Caution: 539 Do not try to change the contents of the output arrays (cols and vals). 540 In some cases, this may corrupt the matrix. 541 542 Level: advanced 543 544 .seealso: `MatRestoreRow()`, `MatSetValues()`, `MatGetValues()`, `MatCreateSubMatrices()`, `MatGetDiagonal()`, `MatGetRowIJ()`, `MatRestoreRowIJ()` 545 @*/ 546 PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 547 { 548 PetscInt incols; 549 550 PetscFunctionBegin; 551 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 552 PetscValidType(mat,1); 553 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 554 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 555 PetscCheck(mat->ops->getrow,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 556 MatCheckPreallocated(mat,1); 557 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); 558 PetscCall(PetscLogEventBegin(MAT_GetRow,mat,0,0,0)); 559 PetscCall((*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals)); 560 if (ncols) *ncols = incols; 561 PetscCall(PetscLogEventEnd(MAT_GetRow,mat,0,0,0)); 562 PetscFunctionReturn(0); 563 } 564 565 /*@ 566 MatConjugate - replaces the matrix values with their complex conjugates 567 568 Logically Collective on Mat 569 570 Input Parameters: 571 . mat - the matrix 572 573 Level: advanced 574 575 .seealso: `VecConjugate()`, `MatTranspose()` 576 @*/ 577 PetscErrorCode MatConjugate(Mat mat) 578 { 579 PetscFunctionBegin; 580 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 581 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 582 if (PetscDefined(USE_COMPLEX) && mat->hermitian != PETSC_BOOL3_TRUE) { 583 PetscCheck(mat->ops->conjugate,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not provided for matrix type %s, send email to petsc-maint@mcs.anl.gov",((PetscObject)mat)->type_name); 584 PetscCall((*mat->ops->conjugate)(mat)); 585 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 586 } 587 PetscFunctionReturn(0); 588 } 589 590 /*@C 591 MatRestoreRow - Frees any temporary space allocated by `MatGetRow()`. 592 593 Not Collective 594 595 Input Parameters: 596 + mat - the matrix 597 . row - the row to get 598 . ncols, cols - the number of nonzeros and their columns 599 - vals - if nonzero the column values 600 601 Notes: 602 This routine should be called after you have finished examining the entries. 603 604 This routine zeros out ncols, cols, and vals. This is to prevent accidental 605 us of the array after it has been restored. If you pass NULL, it will 606 not zero the pointers. Use of cols or vals after `MatRestoreRow()` is invalid. 607 608 Fortran Notes: 609 The calling sequence from Fortran is 610 .vb 611 MatRestoreRow(matrix,row,ncols,cols,values,ierr) 612 Mat matrix (input) 613 integer row (input) 614 integer ncols (output) 615 integer cols(maxcols) (output) 616 double precision (or double complex) values(maxcols) output 617 .ve 618 Where maxcols >= maximum nonzeros in any row of the matrix. 619 620 In Fortran `MatRestoreRow()` MUST be called after `MatGetRow()` 621 before another call to `MatGetRow()` can be made. 622 623 Level: advanced 624 625 .seealso: `MatGetRow()` 626 @*/ 627 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 628 { 629 PetscFunctionBegin; 630 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 631 if (ncols) PetscValidIntPointer(ncols,3); 632 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 633 if (!mat->ops->restorerow) PetscFunctionReturn(0); 634 PetscCall((*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals)); 635 if (ncols) *ncols = 0; 636 if (cols) *cols = NULL; 637 if (vals) *vals = NULL; 638 PetscFunctionReturn(0); 639 } 640 641 /*@ 642 MatGetRowUpperTriangular - Sets a flag to enable calls to `MatGetRow()` for matrix in `MATSBAIJ` format. 643 You should call `MatRestoreRowUpperTriangular()` after calling` MatGetRow()` and `MatRestoreRow()` to disable the flag. 644 645 Not Collective 646 647 Input Parameters: 648 . mat - the matrix 649 650 Notes: 651 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. 652 653 Level: advanced 654 655 .seealso: `MatRestoreRowUpperTriangular()` 656 @*/ 657 PetscErrorCode MatGetRowUpperTriangular(Mat mat) 658 { 659 PetscFunctionBegin; 660 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 661 PetscValidType(mat,1); 662 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 663 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 664 MatCheckPreallocated(mat,1); 665 if (!mat->ops->getrowuppertriangular) PetscFunctionReturn(0); 666 PetscCall((*mat->ops->getrowuppertriangular)(mat)); 667 PetscFunctionReturn(0); 668 } 669 670 /*@ 671 MatRestoreRowUpperTriangular - Disable calls to `MatGetRow()` for matrix in `MATSBAIJ` format. 672 673 Not Collective 674 675 Input Parameters: 676 . mat - the matrix 677 678 Notes: 679 This routine should be called after you have finished calls to `MatGetRow()` and `MatRestoreRow()`. 680 681 Level: advanced 682 683 .seealso: `MatGetRowUpperTriangular()` 684 @*/ 685 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat) 686 { 687 PetscFunctionBegin; 688 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 689 PetscValidType(mat,1); 690 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 691 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 692 MatCheckPreallocated(mat,1); 693 if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0); 694 PetscCall((*mat->ops->restorerowuppertriangular)(mat)); 695 PetscFunctionReturn(0); 696 } 697 698 /*@C 699 MatSetOptionsPrefix - Sets the prefix used for searching for all 700 Mat options in the database. 701 702 Logically Collective on Mat 703 704 Input Parameters: 705 + A - the Mat context 706 - prefix - the prefix to prepend to all option names 707 708 Notes: 709 A hyphen (-) must NOT be given at the beginning of the prefix name. 710 The first character of all runtime options is AUTOMATICALLY the hyphen. 711 712 This is NOT used for options for the factorization of the matrix. Normally the 713 prefix is automatically passed in from the PC calling the factorization. To set 714 it directly use `MatSetOptionsPrefixFactor()` 715 716 Level: advanced 717 718 .seealso: `MatSetFromOptions()`, `MatSetOptionsPrefixFactor()` 719 @*/ 720 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[]) 721 { 722 PetscFunctionBegin; 723 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 724 PetscCall(PetscObjectSetOptionsPrefix((PetscObject)A,prefix)); 725 PetscFunctionReturn(0); 726 } 727 728 /*@C 729 MatSetOptionsPrefixFactor - Sets the prefix used for searching for all Mat factor options in the database for 730 for matrices created with `MatGetFactor()` 731 732 Logically Collective on Mat 733 734 Input Parameters: 735 + A - the Mat context 736 - prefix - the prefix to prepend to all option names for the factored matrix 737 738 Notes: 739 A hyphen (-) must NOT be given at the beginning of the prefix name. 740 The first character of all runtime options is AUTOMATICALLY the hyphen. 741 742 Normally the prefix is automatically passed in from the PC calling the factorization. To set 743 it directly when not using `KSP`/`PC` use `MatSetOptionsPrefixFactor()` 744 745 Level: developer 746 747 .seealso: `MatSetFromOptions()`, `MatSetOptionsPrefix()`, `MatAppendOptionsPrefixFactor()` 748 @*/ 749 PetscErrorCode MatSetOptionsPrefixFactor(Mat A,const char prefix[]) 750 { 751 PetscFunctionBegin; 752 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 753 if (prefix) { 754 PetscValidCharPointer(prefix,2); 755 PetscCheck(prefix[0] != '-',PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Options prefix should not begin with a hyphen"); 756 if (prefix != A->factorprefix) { 757 PetscCall(PetscFree(A->factorprefix)); 758 PetscCall(PetscStrallocpy(prefix,&A->factorprefix)); 759 } 760 } else PetscCall(PetscFree(A->factorprefix)); 761 PetscFunctionReturn(0); 762 } 763 764 /*@C 765 MatAppendOptionsPrefixFactor - Appends to the prefix used for searching for all Mat factor options in the database for 766 for matrices created with `MatGetFactor()` 767 768 Logically Collective on Mat 769 770 Input Parameters: 771 + A - the Mat context 772 - prefix - the prefix to prepend to all option names for the factored matrix 773 774 Notes: 775 A hyphen (-) must NOT be given at the beginning of the prefix name. 776 The first character of all runtime options is AUTOMATICALLY the hyphen. 777 778 Normally the prefix is automatically passed in from the PC calling the factorization. To set 779 it directly when not using `KSP`/`PC` use `MatAppendOptionsPrefixFactor()` 780 781 Level: developer 782 .seealso: `PetscOptionsCreate()`, `PetscOptionsDestroy()`, `PetscObjectSetOptionsPrefix()`, `PetscObjectPrependOptionsPrefix()`, 783 `PetscObjectGetOptionsPrefix()`, `TSAppendOptionsPrefix()`, `SNESAppendOptionsPrefix()`, `KSPAppendOptionsPrefix()`, `MatSetOptionsPrefixFactor()`, 784 `MatSetOptionsPrefix()` 785 @*/ 786 PetscErrorCode MatAppendOptionsPrefixFactor(Mat A,const char prefix[]) 787 { 788 char *buf = A->factorprefix; 789 size_t len1,len2; 790 791 PetscFunctionBegin; 792 PetscValidHeader(A,1); 793 if (!prefix) PetscFunctionReturn(0); 794 if (!buf) { 795 PetscCall(MatSetOptionsPrefixFactor(A,prefix)); 796 PetscFunctionReturn(0); 797 } 798 PetscCheck(prefix[0] != '-',PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Options prefix should not begin with a hyphen"); 799 800 PetscCall(PetscStrlen(prefix,&len1)); 801 PetscCall(PetscStrlen(buf,&len2)); 802 PetscCall(PetscMalloc1(1+len1+len2,&A->factorprefix)); 803 PetscCall(PetscStrcpy(A->factorprefix,buf)); 804 PetscCall(PetscStrcat(A->factorprefix,prefix)); 805 PetscCall(PetscFree(buf)); 806 PetscFunctionReturn(0); 807 } 808 809 /*@C 810 MatAppendOptionsPrefix - Appends to the prefix used for searching for all 811 Mat options in the database. 812 813 Logically Collective on Mat 814 815 Input Parameters: 816 + A - the Mat context 817 - prefix - the prefix to prepend to all option names 818 819 Notes: 820 A hyphen (-) must NOT be given at the beginning of the prefix name. 821 The first character of all runtime options is AUTOMATICALLY the hyphen. 822 823 Level: advanced 824 825 .seealso: `MatGetOptionsPrefix()` 826 @*/ 827 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[]) 828 { 829 PetscFunctionBegin; 830 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 831 PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)A,prefix)); 832 PetscFunctionReturn(0); 833 } 834 835 /*@C 836 MatGetOptionsPrefix - Gets the prefix used for searching for all 837 Mat options in the database. 838 839 Not Collective 840 841 Input Parameter: 842 . A - the Mat context 843 844 Output Parameter: 845 . prefix - pointer to the prefix string used 846 847 Notes: 848 On the fortran side, the user should pass in a string 'prefix' of 849 sufficient length to hold the prefix. 850 851 Level: advanced 852 853 .seealso: `MatAppendOptionsPrefix()` 854 @*/ 855 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[]) 856 { 857 PetscFunctionBegin; 858 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 859 PetscValidPointer(prefix,2); 860 PetscCall(PetscObjectGetOptionsPrefix((PetscObject)A,prefix)); 861 PetscFunctionReturn(0); 862 } 863 864 /*@ 865 MatResetPreallocation - Reset mat to use the original nonzero pattern provided by users. 866 867 Collective on Mat 868 869 Input Parameters: 870 . A - the Mat context 871 872 Notes: 873 The allocated memory will be shrunk after calling `MatAssemblyBegin()` and `MatAssemblyEnd()` with `MAT_FINAL_ASSEMBLY`. 874 875 Users can reset the preallocation to access the original memory. 876 877 Currently only supported for `MATMPIAIJ` and `MATSEQAIJ` matrices. 878 879 Level: beginner 880 881 .seealso: `MatSeqAIJSetPreallocation()`, `MatMPIAIJSetPreallocation()`, `MatXAIJSetPreallocation()` 882 @*/ 883 PetscErrorCode MatResetPreallocation(Mat A) 884 { 885 PetscFunctionBegin; 886 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 887 PetscValidType(A,1); 888 PetscUseMethod(A,"MatResetPreallocation_C",(Mat),(A)); 889 PetscFunctionReturn(0); 890 } 891 892 /*@ 893 MatSetUp - Sets up the internal matrix data structures for later use. 894 895 Collective on Mat 896 897 Input Parameters: 898 . A - the Mat context 899 900 Notes: 901 If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used. 902 903 If a suitable preallocation routine is used, this function does not need to be called. 904 905 See the Performance chapter of the PETSc users manual for how to preallocate matrices 906 907 Level: beginner 908 909 .seealso: `MatCreate()`, `MatDestroy()` 910 @*/ 911 PetscErrorCode MatSetUp(Mat A) 912 { 913 PetscFunctionBegin; 914 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 915 if (!((PetscObject)A)->type_name) { 916 PetscMPIInt size; 917 918 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)A), &size)); 919 PetscCall(MatSetType(A, size == 1 ? MATSEQAIJ : MATMPIAIJ)); 920 } 921 if (!A->preallocated && A->ops->setup) { 922 PetscCall(PetscInfo(A,"Warning not preallocating matrix storage\n")); 923 PetscCall((*A->ops->setup)(A)); 924 } 925 PetscCall(PetscLayoutSetUp(A->rmap)); 926 PetscCall(PetscLayoutSetUp(A->cmap)); 927 A->preallocated = PETSC_TRUE; 928 PetscFunctionReturn(0); 929 } 930 931 #if defined(PETSC_HAVE_SAWS) 932 #include <petscviewersaws.h> 933 #endif 934 935 /*@C 936 MatViewFromOptions - View from Options 937 938 Collective on Mat 939 940 Input Parameters: 941 + A - the Mat context 942 . obj - Optional object 943 - name - command line option 944 945 Level: intermediate 946 .seealso: `Mat`, `MatView`, `PetscObjectViewFromOptions()`, `MatCreate()` 947 @*/ 948 PetscErrorCode MatViewFromOptions(Mat A,PetscObject obj,const char name[]) 949 { 950 PetscFunctionBegin; 951 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 952 PetscCall(PetscObjectViewFromOptions((PetscObject)A,obj,name)); 953 PetscFunctionReturn(0); 954 } 955 956 /*@C 957 MatView - Visualizes a matrix object. 958 959 Collective on Mat 960 961 Input Parameters: 962 + mat - the matrix 963 - viewer - visualization context 964 965 Notes: 966 The available visualization contexts include 967 + `PETSC_VIEWER_STDOUT_SELF` - for sequential matrices 968 . `PETSC_VIEWER_STDOUT_WORLD` - for parallel matrices created on `PETSC_COMM_WORLD` 969 . `PETSC_VIEWER_STDOUT_`(comm) - for matrices created on MPI communicator comm 970 - `PETSC_VIEWER_DRAW_WORLD` - graphical display of nonzero structure 971 972 The user can open alternative visualization contexts with 973 + `PetscViewerASCIIOpen()` - Outputs matrix to a specified file 974 . `PetscViewerBinaryOpen()` - Outputs matrix in binary to a 975 specified file; corresponding input uses MatLoad() 976 . `PetscViewerDrawOpen()` - Outputs nonzero matrix structure to 977 an X window display 978 - `PetscViewerSocketOpen()` - Outputs matrix to Socket viewer. 979 Currently only the sequential dense and AIJ 980 matrix types support the Socket viewer. 981 982 The user can call `PetscViewerPushFormat()` to specify the output 983 format of ASCII printed objects (when using `PETSC_VIEWER_STDOUT_SELF`, 984 `PETSC_VIEWER_STDOUT_WORLD` and `PetscViewerASCIIOpen()`). Available formats include 985 + `PETSC_VIEWER_DEFAULT` - default, prints matrix contents 986 . `PETSC_VIEWER_ASCII_MATLAB` - prints matrix contents in Matlab format 987 . `PETSC_VIEWER_ASCII_DENSE` - prints entire matrix including zeros 988 . `PETSC_VIEWER_ASCII_COMMON` - prints matrix contents, using a sparse 989 format common among all matrix types 990 . `PETSC_VIEWER_ASCII_IMPL` - prints matrix contents, using an implementation-specific 991 format (which is in many cases the same as the default) 992 . `PETSC_VIEWER_ASCII_INFO` - prints basic information about the matrix 993 size and structure (not the matrix entries) 994 - `PETSC_VIEWER_ASCII_INFO_DETAIL` - prints more detailed information about 995 the matrix structure 996 997 Options Database Keys: 998 + -mat_view ::ascii_info - Prints info on matrix at conclusion of `MatAssemblyEnd()` 999 . -mat_view ::ascii_info_detail - Prints more detailed info 1000 . -mat_view - Prints matrix in ASCII format 1001 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 1002 . -mat_view draw - PetscDraws nonzero structure of matrix, using `MatView()` and `PetscDrawOpenX()`. 1003 . -display <name> - Sets display name (default is host) 1004 . -draw_pause <sec> - Sets number of seconds to pause after display 1005 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details) 1006 . -viewer_socket_machine <machine> - 1007 . -viewer_socket_port <port> - 1008 . -mat_view binary - save matrix to file in binary format 1009 - -viewer_binary_filename <name> - 1010 1011 Level: beginner 1012 1013 Notes: 1014 The ASCII viewers are only recommended for small matrices on at most a moderate number of processes, 1015 the program will seemingly hang and take hours for larger matrices, for larger matrices one should use the binary format. 1016 1017 In the debugger you can do "call MatView(mat,0)" to display the matrix. (The same holds for any PETSc object viewer). 1018 1019 See the manual page for `MatLoad()` for the exact format of the binary file when the binary 1020 viewer is used. 1021 1022 See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary 1023 viewer is used and lib/petsc/bin/PetscBinaryIO.py for loading them into Python. 1024 1025 One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure, 1026 and then use the following mouse functions. 1027 .vb 1028 left mouse: zoom in 1029 middle mouse: zoom out 1030 right mouse: continue with the simulation 1031 .ve 1032 1033 .seealso: `PetscViewerPushFormat()`, `PetscViewerASCIIOpen()`, `PetscViewerDrawOpen()`, 1034 `PetscViewerSocketOpen()`, `PetscViewerBinaryOpen()`, `MatLoad()` 1035 @*/ 1036 PetscErrorCode MatView(Mat mat,PetscViewer viewer) 1037 { 1038 PetscInt rows,cols,rbs,cbs; 1039 PetscBool isascii,isstring,issaws; 1040 PetscViewerFormat format; 1041 PetscMPIInt size; 1042 1043 PetscFunctionBegin; 1044 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1045 PetscValidType(mat,1); 1046 if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer)); 1047 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1048 PetscCheckSameComm(mat,1,viewer,2); 1049 MatCheckPreallocated(mat,1); 1050 1051 PetscCall(PetscViewerGetFormat(viewer,&format)); 1052 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 1053 if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0); 1054 1055 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring)); 1056 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii)); 1057 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws)); 1058 if ((!isascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) { 1059 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detail"); 1060 } 1061 1062 PetscCall(PetscLogEventBegin(MAT_View,mat,viewer,0,0)); 1063 if (isascii) { 1064 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix"); 1065 PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer)); 1066 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1067 MatNullSpace nullsp,transnullsp; 1068 1069 PetscCall(PetscViewerASCIIPushTab(viewer)); 1070 PetscCall(MatGetSize(mat,&rows,&cols)); 1071 PetscCall(MatGetBlockSizes(mat,&rbs,&cbs)); 1072 if (rbs != 1 || cbs != 1) { 1073 if (rbs != cbs) PetscCall(PetscViewerASCIIPrintf(viewer,"rows=%" PetscInt_FMT ", cols=%" PetscInt_FMT ", rbs=%" PetscInt_FMT ", cbs=%" PetscInt_FMT "\n",rows,cols,rbs,cbs)); 1074 else PetscCall(PetscViewerASCIIPrintf(viewer,"rows=%" PetscInt_FMT ", cols=%" PetscInt_FMT ", bs=%" PetscInt_FMT "\n",rows,cols,rbs)); 1075 } else PetscCall(PetscViewerASCIIPrintf(viewer,"rows=%" PetscInt_FMT ", cols=%" PetscInt_FMT "\n",rows,cols)); 1076 if (mat->factortype) { 1077 MatSolverType solver; 1078 PetscCall(MatFactorGetSolverType(mat,&solver)); 1079 PetscCall(PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver)); 1080 } 1081 if (mat->ops->getinfo) { 1082 MatInfo info; 1083 PetscCall(MatGetInfo(mat,MAT_GLOBAL_SUM,&info)); 1084 PetscCall(PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated)); 1085 if (!mat->factortype) PetscCall(PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls=%" PetscInt_FMT "\n",(PetscInt)info.mallocs)); 1086 } 1087 PetscCall(MatGetNullSpace(mat,&nullsp)); 1088 PetscCall(MatGetTransposeNullSpace(mat,&transnullsp)); 1089 if (nullsp) PetscCall(PetscViewerASCIIPrintf(viewer," has attached null space\n")); 1090 if (transnullsp && transnullsp != nullsp) PetscCall(PetscViewerASCIIPrintf(viewer," has attached transposed null space\n")); 1091 PetscCall(MatGetNearNullSpace(mat,&nullsp)); 1092 if (nullsp) PetscCall(PetscViewerASCIIPrintf(viewer," has attached near null space\n")); 1093 PetscCall(PetscViewerASCIIPushTab(viewer)); 1094 PetscCall(MatProductView(mat,viewer)); 1095 PetscCall(PetscViewerASCIIPopTab(viewer)); 1096 } 1097 } else if (issaws) { 1098 #if defined(PETSC_HAVE_SAWS) 1099 PetscMPIInt rank; 1100 1101 PetscCall(PetscObjectName((PetscObject)mat)); 1102 PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD,&rank)); 1103 if (!((PetscObject)mat)->amsmem && rank == 0) { 1104 PetscCall(PetscObjectViewSAWs((PetscObject)mat,viewer)); 1105 } 1106 #endif 1107 } else if (isstring) { 1108 const char *type; 1109 PetscCall(MatGetType(mat,&type)); 1110 PetscCall(PetscViewerStringSPrintf(viewer," MatType: %-7.7s",type)); 1111 if (mat->ops->view) PetscCall((*mat->ops->view)(mat,viewer)); 1112 } 1113 if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) { 1114 PetscCall(PetscViewerASCIIPushTab(viewer)); 1115 PetscCall((*mat->ops->viewnative)(mat,viewer)); 1116 PetscCall(PetscViewerASCIIPopTab(viewer)); 1117 } else if (mat->ops->view) { 1118 PetscCall(PetscViewerASCIIPushTab(viewer)); 1119 PetscCall((*mat->ops->view)(mat,viewer)); 1120 PetscCall(PetscViewerASCIIPopTab(viewer)); 1121 } 1122 if (isascii) { 1123 PetscCall(PetscViewerGetFormat(viewer,&format)); 1124 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1125 PetscCall(PetscViewerASCIIPopTab(viewer)); 1126 } 1127 } 1128 PetscCall(PetscLogEventEnd(MAT_View,mat,viewer,0,0)); 1129 PetscFunctionReturn(0); 1130 } 1131 1132 #if defined(PETSC_USE_DEBUG) 1133 #include <../src/sys/totalview/tv_data_display.h> 1134 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat) 1135 { 1136 TV_add_row("Local rows", "int", &mat->rmap->n); 1137 TV_add_row("Local columns", "int", &mat->cmap->n); 1138 TV_add_row("Global rows", "int", &mat->rmap->N); 1139 TV_add_row("Global columns", "int", &mat->cmap->N); 1140 TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name); 1141 return TV_format_OK; 1142 } 1143 #endif 1144 1145 /*@C 1146 MatLoad - Loads a matrix that has been stored in binary/HDF5 format 1147 with `MatView()`. The matrix format is determined from the options database. 1148 Generates a parallel MPI matrix if the communicator has more than one 1149 processor. The default matrix type is AIJ. 1150 1151 Collective on PetscViewer 1152 1153 Input Parameters: 1154 + mat - the newly loaded matrix, this needs to have been created with `MatCreate()` 1155 or some related function before a call to `MatLoad()` 1156 - viewer - binary/HDF5 file viewer 1157 1158 Options Database Keys: 1159 Used with block matrix formats (`MATSEQBAIJ`, ...) to specify 1160 block size 1161 . -matload_block_size <bs> - set block size 1162 1163 Level: beginner 1164 1165 Notes: 1166 If the Mat type has not yet been given then `MATAIJ` is used, call `MatSetFromOptions()` on the 1167 Mat before calling this routine if you wish to set it from the options database. 1168 1169 `MatLoad()` automatically loads into the options database any options 1170 given in the file filename.info where filename is the name of the file 1171 that was passed to the `PetscViewerBinaryOpen()`. The options in the info 1172 file will be ignored if you use the -viewer_binary_skip_info option. 1173 1174 If the type or size of mat is not set before a call to `MatLoad()`, PETSc 1175 sets the default matrix type AIJ and sets the local and global sizes. 1176 If type and/or size is already set, then the same are used. 1177 1178 In parallel, each processor can load a subset of rows (or the 1179 entire matrix). This routine is especially useful when a large 1180 matrix is stored on disk and only part of it is desired on each 1181 processor. For example, a parallel solver may access only some of 1182 the rows from each processor. The algorithm used here reads 1183 relatively small blocks of data rather than reading the entire 1184 matrix and then subsetting it. 1185 1186 Viewer's `PetscViewerType` must be either `PETSCVIEWERBINARY` or `PETSCVIEWERHDF5`. 1187 Such viewer can be created using `PetscViewerBinaryOpen()` or `PetscViewerHDF5Open()`, 1188 or the sequence like 1189 .vb 1190 `PetscViewer` v; 1191 `PetscViewerCreate`(`PETSC_COMM_WORLD`,&v); 1192 `PetscViewerSetType`(v,`PETSCVIEWERBINARY`); 1193 `PetscViewerSetFromOptions`(v); 1194 `PetscViewerFileSetMode`(v,`FILE_MODE_READ`); 1195 `PetscViewerFileSetName`(v,"datafile"); 1196 .ve 1197 The optional `PetscViewerSetFromOptions()` call allows overriding `PetscViewerSetType()` using the option 1198 $ -viewer_type {binary,hdf5} 1199 1200 See the example src/ksp/ksp/tutorials/ex27.c with the first approach, 1201 and src/mat/tutorials/ex10.c with the second approach. 1202 1203 Notes about the PETSc binary format: 1204 In case of `PETSCVIEWERBINARY`, a native PETSc binary format is used. Each of the blocks 1205 is read onto rank 0 and then shipped to its destination rank, one after another. 1206 Multiple objects, both matrices and vectors, can be stored within the same file. 1207 Their PetscObject name is ignored; they are loaded in the order of their storage. 1208 1209 Most users should not need to know the details of the binary storage 1210 format, since `MatLoad()` and `MatView()` completely hide these details. 1211 But for anyone who's interested, the standard binary matrix storage 1212 format is 1213 1214 $ PetscInt MAT_FILE_CLASSID 1215 $ PetscInt number of rows 1216 $ PetscInt number of columns 1217 $ PetscInt total number of nonzeros 1218 $ PetscInt *number nonzeros in each row 1219 $ PetscInt *column indices of all nonzeros (starting index is zero) 1220 $ PetscScalar *values of all nonzeros 1221 1222 PETSc automatically does the byte swapping for 1223 machines that store the bytes reversed, e.g. DEC alpha, freebsd, 1224 Linux, Microsoft Windows and the Intel Paragon; thus if you write your own binary 1225 read/write routines you have to swap the bytes; see `PetscBinaryRead()` 1226 and `PetscBinaryWrite()` to see how this may be done. 1227 1228 Notes about the HDF5 (MATLAB MAT-File Version 7.3) format: 1229 In case of `PETSCVIEWERHDF5`, a parallel HDF5 reader is used. 1230 Each processor's chunk is loaded independently by its owning rank. 1231 Multiple objects, both matrices and vectors, can be stored within the same file. 1232 They are looked up by their PetscObject name. 1233 1234 As the MATLAB MAT-File Version 7.3 format is also a HDF5 flavor, we decided to use 1235 by default the same structure and naming of the AIJ arrays and column count 1236 within the HDF5 file. This means that a MAT file saved with -v7.3 flag, e.g. 1237 $ save example.mat A b -v7.3 1238 can be directly read by this routine (see Reference 1 for details). 1239 Note that depending on your MATLAB version, this format might be a default, 1240 otherwise you can set it as default in Preferences. 1241 1242 Unless -nocompression flag is used to save the file in MATLAB, 1243 PETSc must be configured with ZLIB package. 1244 1245 See also examples src/mat/tutorials/ex10.c and src/ksp/ksp/tutorials/ex27.c 1246 1247 Current HDF5 (MAT-File) limitations: 1248 This reader currently supports only real `MATSEQAIJ`, `MATMPIAIJ`, `MATSEQDENSE` and `MATMPIDENSE` matrices. 1249 1250 Corresponding `MatView()` is not yet implemented. 1251 1252 The loaded matrix is actually a transpose of the original one in MATLAB, 1253 unless you push `PETSC_VIEWER_HDF5_MAT` format (see examples above). 1254 With this format, matrix is automatically transposed by PETSc, 1255 unless the matrix is marked as SPD or symmetric 1256 (see `MatSetOption()`, `MAT_SPD`, `MAT_SYMMETRIC`). 1257 1258 References: 1259 . * - MATLAB(R) Documentation, manual page of save(), https://www.mathworks.com/help/matlab/ref/save.html#btox10b-1-version 1260 1261 .seealso: `PetscViewerBinaryOpen()`, `PetscViewerSetType()`, `MatView()`, `VecLoad()` 1262 1263 @*/ 1264 PetscErrorCode MatLoad(Mat mat,PetscViewer viewer) 1265 { 1266 PetscBool flg; 1267 1268 PetscFunctionBegin; 1269 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1270 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1271 1272 if (!((PetscObject)mat)->type_name) PetscCall(MatSetType(mat,MATAIJ)); 1273 1274 flg = PETSC_FALSE; 1275 PetscCall(PetscOptionsGetBool(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matload_symmetric",&flg,NULL)); 1276 if (flg) { 1277 PetscCall(MatSetOption(mat,MAT_SYMMETRIC,PETSC_TRUE)); 1278 PetscCall(MatSetOption(mat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE)); 1279 } 1280 flg = PETSC_FALSE; 1281 PetscCall(PetscOptionsGetBool(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matload_spd",&flg,NULL)); 1282 if (flg) PetscCall(MatSetOption(mat,MAT_SPD,PETSC_TRUE)); 1283 1284 PetscCheck(mat->ops->load,PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type %s",((PetscObject)mat)->type_name); 1285 PetscCall(PetscLogEventBegin(MAT_Load,mat,viewer,0,0)); 1286 PetscCall((*mat->ops->load)(mat,viewer)); 1287 PetscCall(PetscLogEventEnd(MAT_Load,mat,viewer,0,0)); 1288 PetscFunctionReturn(0); 1289 } 1290 1291 static PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant) 1292 { 1293 Mat_Redundant *redund = *redundant; 1294 1295 PetscFunctionBegin; 1296 if (redund) { 1297 if (redund->matseq) { /* via MatCreateSubMatrices() */ 1298 PetscCall(ISDestroy(&redund->isrow)); 1299 PetscCall(ISDestroy(&redund->iscol)); 1300 PetscCall(MatDestroySubMatrices(1,&redund->matseq)); 1301 } else { 1302 PetscCall(PetscFree2(redund->send_rank,redund->recv_rank)); 1303 PetscCall(PetscFree(redund->sbuf_j)); 1304 PetscCall(PetscFree(redund->sbuf_a)); 1305 for (PetscInt i=0; i<redund->nrecvs; i++) { 1306 PetscCall(PetscFree(redund->rbuf_j[i])); 1307 PetscCall(PetscFree(redund->rbuf_a[i])); 1308 } 1309 PetscCall(PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a)); 1310 } 1311 1312 if (redund->subcomm) PetscCall(PetscCommDestroy(&redund->subcomm)); 1313 PetscCall(PetscFree(redund)); 1314 } 1315 PetscFunctionReturn(0); 1316 } 1317 1318 /*@C 1319 MatDestroy - Frees space taken by a matrix. 1320 1321 Collective on Mat 1322 1323 Input Parameter: 1324 . A - the matrix 1325 1326 Level: beginner 1327 1328 Developer Notes: 1329 Some special arrays of matrices are not destroyed in this routine but instead by the routines called by 1330 `MatDestroySubMatrices()`. Thus one must be sure that any changes here must also be made in those routines. 1331 MatHeaderMerge() and MatHeaderReplace() also manipulate the data in the `Mat` object and likely need changes 1332 if changes are needed here. 1333 @*/ 1334 PetscErrorCode MatDestroy(Mat *A) 1335 { 1336 PetscFunctionBegin; 1337 if (!*A) PetscFunctionReturn(0); 1338 PetscValidHeaderSpecific(*A,MAT_CLASSID,1); 1339 if (--((PetscObject)(*A))->refct > 0) {*A = NULL; PetscFunctionReturn(0);} 1340 1341 /* if memory was published with SAWs then destroy it */ 1342 PetscCall(PetscObjectSAWsViewOff((PetscObject)*A)); 1343 if ((*A)->ops->destroy) PetscCall((*(*A)->ops->destroy)(*A)); 1344 1345 PetscCall(PetscFree((*A)->factorprefix)); 1346 PetscCall(PetscFree((*A)->defaultvectype)); 1347 PetscCall(PetscFree((*A)->bsizes)); 1348 PetscCall(PetscFree((*A)->solvertype)); 1349 for (PetscInt i=0; i<MAT_FACTOR_NUM_TYPES; i++) PetscCall(PetscFree((*A)->preferredordering[i])); 1350 if ((*A)->redundant && (*A)->redundant->matseq[0] == *A) (*A)->redundant->matseq[0] = NULL; 1351 PetscCall(MatDestroy_Redundant(&(*A)->redundant)); 1352 PetscCall(MatProductClear(*A)); 1353 PetscCall(MatNullSpaceDestroy(&(*A)->nullsp)); 1354 PetscCall(MatNullSpaceDestroy(&(*A)->transnullsp)); 1355 PetscCall(MatNullSpaceDestroy(&(*A)->nearnullsp)); 1356 PetscCall(MatDestroy(&(*A)->schur)); 1357 PetscCall(PetscLayoutDestroy(&(*A)->rmap)); 1358 PetscCall(PetscLayoutDestroy(&(*A)->cmap)); 1359 PetscCall(PetscHeaderDestroy(A)); 1360 PetscFunctionReturn(0); 1361 } 1362 1363 /*@C 1364 MatSetValues - Inserts or adds a block of values into a matrix. 1365 These values may be cached, so `MatAssemblyBegin()` and `MatAssemblyEnd()` 1366 MUST be called after all calls to `MatSetValues()` have been completed. 1367 1368 Not Collective 1369 1370 Input Parameters: 1371 + mat - the matrix 1372 . v - a logically two-dimensional array of values 1373 . m, idxm - the number of rows and their global indices 1374 . n, idxn - the number of columns and their global indices 1375 - addv - either `ADD_VALUES` or `INSERT_VALUES`, where 1376 `ADD_VALUES` adds values to any existing entries, and 1377 `INSERT_VALUES` replaces existing entries with new values 1378 1379 Notes: 1380 If you create the matrix yourself (that is not with a call to `DMCreateMatrix()`) then you MUST call MatXXXXSetPreallocation() or 1381 `MatSetUp()` before using this routine 1382 1383 By default the values, v, are row-oriented. See `MatSetOption()` for other options. 1384 1385 Calls to `MatSetValues()` with the `INSERT_VALUES` and `ADD_VALUES` 1386 options cannot be mixed without intervening calls to the assembly 1387 routines. 1388 1389 `MatSetValues()` uses 0-based row and column numbers in Fortran 1390 as well as in C. 1391 1392 Negative indices may be passed in idxm and idxn, these rows and columns are 1393 simply ignored. This allows easily inserting element stiffness matrices 1394 with homogeneous Dirchlet boundary conditions that you don't want represented 1395 in the matrix. 1396 1397 Efficiency Alert: 1398 The routine `MatSetValuesBlocked()` may offer much better efficiency 1399 for users of block sparse formats (`MATSEQBAIJ` and `MATMPIBAIJ`). 1400 1401 Level: beginner 1402 1403 Developer Notes: 1404 This is labeled with C so does not automatically generate Fortran stubs and interfaces 1405 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 1406 1407 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 1408 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES` 1409 @*/ 1410 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1411 { 1412 PetscFunctionBeginHot; 1413 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1414 PetscValidType(mat,1); 1415 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1416 PetscValidIntPointer(idxm,3); 1417 PetscValidIntPointer(idxn,5); 1418 MatCheckPreallocated(mat,1); 1419 1420 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 1421 else PetscCheck(mat->insertmode == addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1422 1423 if (PetscDefined(USE_DEBUG)) { 1424 PetscInt i,j; 1425 1426 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1427 PetscCheck(mat->ops->setvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1428 1429 for (i=0; i<m; i++) { 1430 for (j=0; j<n; j++) { 1431 if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j])) 1432 #if defined(PETSC_USE_COMPLEX) 1433 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]); 1434 #else 1435 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]); 1436 #endif 1437 } 1438 } 1439 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); 1440 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); 1441 } 1442 1443 if (mat->assembled) { 1444 mat->was_assembled = PETSC_TRUE; 1445 mat->assembled = PETSC_FALSE; 1446 } 1447 PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 1448 PetscCall((*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv)); 1449 PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 1450 PetscFunctionReturn(0); 1451 } 1452 1453 /*@C 1454 MatSetValuesIS - Inserts or adds a block of values into a matrix using IS to indicate the rows and columns 1455 These values may be cached, so `MatAssemblyBegin()` and `MatAssemblyEnd()` 1456 MUST be called after all calls to `MatSetValues()` have been completed. 1457 1458 Not Collective 1459 1460 Input Parameters: 1461 + mat - the matrix 1462 . v - a logically two-dimensional array of values 1463 . ism - the rows to provide 1464 . isn - the columns to provide 1465 - addv - either `ADD_VALUES` or `INSERT_VALUES`, where 1466 `ADD_VALUES` adds values to any existing entries, and 1467 `INSERT_VALUES` replaces existing entries with new values 1468 1469 Notes: 1470 If you create the matrix yourself (that is not with a call to `DMCreateMatrix()`) then you MUST call MatXXXXSetPreallocation() or 1471 `MatSetUp()` before using this routine 1472 1473 By default the values, v, are row-oriented. See `MatSetOption()` for other options. 1474 1475 Calls to `MatSetValues()` with the `INSERT_VALUES` and `ADD_VALUES` 1476 options cannot be mixed without intervening calls to the assembly 1477 routines. 1478 1479 MatSetValues() uses 0-based row and column numbers in Fortran 1480 as well as in C. 1481 1482 Negative indices may be passed in ism and isn, these rows and columns are 1483 simply ignored. This allows easily inserting element stiffness matrices 1484 with homogeneous Dirchlet boundary conditions that you don't want represented 1485 in the matrix. 1486 1487 Efficiency Alert: 1488 The routine `MatSetValuesBlocked()` may offer much better efficiency 1489 for users of block sparse formats (`MATSEQBAIJ` and `MATMPIBAIJ`). 1490 1491 Level: beginner 1492 1493 Developer Notes: 1494 This is labeled with C so does not automatically generate Fortran stubs and interfaces 1495 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 1496 1497 This is currently not optimized for any particular IS type 1498 1499 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 1500 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()` 1501 @*/ 1502 PetscErrorCode MatSetValuesIS(Mat mat,IS ism,IS isn,const PetscScalar v[],InsertMode addv) 1503 { 1504 PetscInt m,n; 1505 const PetscInt *rows,*cols; 1506 1507 PetscFunctionBeginHot; 1508 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1509 PetscCall(ISGetIndices(ism,&rows)); 1510 PetscCall(ISGetIndices(isn,&cols)); 1511 PetscCall(ISGetLocalSize(ism,&m)); 1512 PetscCall(ISGetLocalSize(isn,&n)); 1513 PetscCall(MatSetValues(mat,m,rows,n,cols,v,addv)); 1514 PetscCall(ISRestoreIndices(ism,&rows)); 1515 PetscCall(ISRestoreIndices(isn,&cols)); 1516 PetscFunctionReturn(0); 1517 } 1518 1519 /*@ 1520 MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero 1521 values into a matrix 1522 1523 Not Collective 1524 1525 Input Parameters: 1526 + mat - the matrix 1527 . row - the (block) row to set 1528 - v - a logically two-dimensional array of values 1529 1530 Notes: 1531 By the values, v, are column-oriented (for the block version) and sorted 1532 1533 All the nonzeros in the row must be provided 1534 1535 The matrix must have previously had its column indices set 1536 1537 The row must belong to this process 1538 1539 Level: intermediate 1540 1541 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 1542 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()`, `MatSetValuesRow()`, `MatSetLocalToGlobalMapping()` 1543 @*/ 1544 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[]) 1545 { 1546 PetscInt globalrow; 1547 1548 PetscFunctionBegin; 1549 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1550 PetscValidType(mat,1); 1551 PetscValidScalarPointer(v,3); 1552 PetscCall(ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow)); 1553 PetscCall(MatSetValuesRow(mat,globalrow,v)); 1554 PetscFunctionReturn(0); 1555 } 1556 1557 /*@ 1558 MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero 1559 values into a matrix 1560 1561 Not Collective 1562 1563 Input Parameters: 1564 + mat - the matrix 1565 . row - the (block) row to set 1566 - 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 1567 1568 Notes: 1569 The values, v, are column-oriented for the block version. 1570 1571 All the nonzeros in the row must be provided 1572 1573 THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually `MatSetValues()` is used. 1574 1575 The row must belong to this process 1576 1577 Level: advanced 1578 1579 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 1580 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()` 1581 @*/ 1582 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[]) 1583 { 1584 PetscFunctionBeginHot; 1585 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1586 PetscValidType(mat,1); 1587 MatCheckPreallocated(mat,1); 1588 PetscValidScalarPointer(v,3); 1589 PetscCheck(mat->insertmode != ADD_VALUES,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values"); 1590 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1591 mat->insertmode = INSERT_VALUES; 1592 1593 if (mat->assembled) { 1594 mat->was_assembled = PETSC_TRUE; 1595 mat->assembled = PETSC_FALSE; 1596 } 1597 PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 1598 PetscCheck(mat->ops->setvaluesrow,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1599 PetscCall((*mat->ops->setvaluesrow)(mat,row,v)); 1600 PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 1601 PetscFunctionReturn(0); 1602 } 1603 1604 /*@ 1605 MatSetValuesStencil - Inserts or adds a block of values into a matrix. 1606 Using structured grid indexing 1607 1608 Not Collective 1609 1610 Input Parameters: 1611 + mat - the matrix 1612 . m - number of rows being entered 1613 . idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered 1614 . n - number of columns being entered 1615 . idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered 1616 . v - a logically two-dimensional array of values 1617 - addv - either ADD_VALUES or INSERT_VALUES, where 1618 ADD_VALUES adds values to any existing entries, and 1619 INSERT_VALUES replaces existing entries with new values 1620 1621 Notes: 1622 By default the values, v, are row-oriented. See `MatSetOption()` for other options. 1623 1624 Calls to `MatSetValuesStencil()` with the `INSERT_VALUES` and `ADD_VALUES` 1625 options cannot be mixed without intervening calls to the assembly 1626 routines. 1627 1628 The grid coordinates are across the entire grid, not just the local portion 1629 1630 `MatSetValuesStencil()` uses 0-based row and column numbers in Fortran 1631 as well as in C. 1632 1633 For setting/accessing vector values via array coordinates you can use the `DMDAVecGetArray()` routine 1634 1635 In order to use this routine you must either obtain the matrix with `DMCreateMatrix()` 1636 or call `MatSetLocalToGlobalMapping()` and `MatSetStencil()` first. 1637 1638 The columns and rows in the stencil passed in MUST be contained within the 1639 ghost region of the given process as set with DMDACreateXXX() or `MatSetStencil()`. For example, 1640 if you create a `DMDA` with an overlap of one grid level and on a particular process its first 1641 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1642 first i index you can use in your column and row indices in `MatSetStencil()` is 5. 1643 1644 In Fortran idxm and idxn should be declared as 1645 $ MatStencil idxm(4,m),idxn(4,n) 1646 and the values inserted using 1647 $ idxm(MatStencil_i,1) = i 1648 $ idxm(MatStencil_j,1) = j 1649 $ idxm(MatStencil_k,1) = k 1650 $ idxm(MatStencil_c,1) = c 1651 etc 1652 1653 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 1654 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 1655 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 1656 `DM_BOUNDARY_PERIODIC` boundary type. 1657 1658 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 1659 a single value per point) you can skip filling those indices. 1660 1661 Inspired by the structured grid interface to the HYPRE package 1662 (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods) 1663 1664 Efficiency Alert: 1665 The routine `MatSetValuesBlockedStencil()` may offer much better efficiency 1666 for users of block sparse formats (`MATSEQBAIJ` and `MATMPIBAIJ`). 1667 1668 Level: beginner 1669 1670 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()` 1671 `MatSetValues()`, `MatSetValuesBlockedStencil()`, `MatSetStencil()`, `DMCreateMatrix()`, `DMDAVecGetArray()`, `MatStencil` 1672 @*/ 1673 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1674 { 1675 PetscInt buf[8192],*bufm=NULL,*bufn=NULL,*jdxm,*jdxn; 1676 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1677 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1678 1679 PetscFunctionBegin; 1680 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1681 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1682 PetscValidType(mat,1); 1683 PetscValidPointer(idxm,3); 1684 PetscValidPointer(idxn,5); 1685 1686 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1687 jdxm = buf; jdxn = buf+m; 1688 } else { 1689 PetscCall(PetscMalloc2(m,&bufm,n,&bufn)); 1690 jdxm = bufm; jdxn = bufn; 1691 } 1692 for (i=0; i<m; i++) { 1693 for (j=0; j<3-sdim; j++) dxm++; 1694 tmp = *dxm++ - starts[0]; 1695 for (j=0; j<dim-1; j++) { 1696 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1697 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1698 } 1699 if (mat->stencil.noc) dxm++; 1700 jdxm[i] = tmp; 1701 } 1702 for (i=0; i<n; i++) { 1703 for (j=0; j<3-sdim; j++) dxn++; 1704 tmp = *dxn++ - starts[0]; 1705 for (j=0; j<dim-1; j++) { 1706 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1707 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1708 } 1709 if (mat->stencil.noc) dxn++; 1710 jdxn[i] = tmp; 1711 } 1712 PetscCall(MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv)); 1713 PetscCall(PetscFree2(bufm,bufn)); 1714 PetscFunctionReturn(0); 1715 } 1716 1717 /*@ 1718 MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix. 1719 Using structured grid indexing 1720 1721 Not Collective 1722 1723 Input Parameters: 1724 + mat - the matrix 1725 . m - number of rows being entered 1726 . idxm - grid coordinates for matrix rows being entered 1727 . n - number of columns being entered 1728 . idxn - grid coordinates for matrix columns being entered 1729 . v - a logically two-dimensional array of values 1730 - addv - either ADD_VALUES or INSERT_VALUES, where 1731 ADD_VALUES adds values to any existing entries, and 1732 INSERT_VALUES replaces existing entries with new values 1733 1734 Notes: 1735 By default the values, v, are row-oriented and unsorted. 1736 See MatSetOption() for other options. 1737 1738 Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES 1739 options cannot be mixed without intervening calls to the assembly 1740 routines. 1741 1742 The grid coordinates are across the entire grid, not just the local portion 1743 1744 MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran 1745 as well as in C. 1746 1747 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine 1748 1749 In order to use this routine you must either obtain the matrix with DMCreateMatrix() 1750 or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first. 1751 1752 The columns and rows in the stencil passed in MUST be contained within the 1753 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example, 1754 if you create a DMDA with an overlap of one grid level and on a particular process its first 1755 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1756 first i index you can use in your column and row indices in MatSetStencil() is 5. 1757 1758 In Fortran idxm and idxn should be declared as 1759 $ MatStencil idxm(4,m),idxn(4,n) 1760 and the values inserted using 1761 $ idxm(MatStencil_i,1) = i 1762 $ idxm(MatStencil_j,1) = j 1763 $ idxm(MatStencil_k,1) = k 1764 etc 1765 1766 Negative indices may be passed in idxm and idxn, these rows and columns are 1767 simply ignored. This allows easily inserting element stiffness matrices 1768 with homogeneous Dirchlet boundary conditions that you don't want represented 1769 in the matrix. 1770 1771 Inspired by the structured grid interface to the HYPRE package 1772 (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods) 1773 1774 Level: beginner 1775 1776 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()` 1777 `MatSetValues()`, `MatSetValuesStencil()`, `MatSetStencil()`, `DMCreateMatrix()`, `DMDAVecGetArray()`, `MatStencil`, 1778 `MatSetBlockSize()`, `MatSetLocalToGlobalMapping()` 1779 @*/ 1780 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1781 { 1782 PetscInt buf[8192],*bufm=NULL,*bufn=NULL,*jdxm,*jdxn; 1783 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1784 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1785 1786 PetscFunctionBegin; 1787 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1788 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1789 PetscValidType(mat,1); 1790 PetscValidPointer(idxm,3); 1791 PetscValidPointer(idxn,5); 1792 PetscValidScalarPointer(v,6); 1793 1794 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1795 jdxm = buf; jdxn = buf+m; 1796 } else { 1797 PetscCall(PetscMalloc2(m,&bufm,n,&bufn)); 1798 jdxm = bufm; jdxn = bufn; 1799 } 1800 for (i=0; i<m; i++) { 1801 for (j=0; j<3-sdim; j++) dxm++; 1802 tmp = *dxm++ - starts[0]; 1803 for (j=0; j<sdim-1; j++) { 1804 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1805 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1806 } 1807 dxm++; 1808 jdxm[i] = tmp; 1809 } 1810 for (i=0; i<n; i++) { 1811 for (j=0; j<3-sdim; j++) dxn++; 1812 tmp = *dxn++ - starts[0]; 1813 for (j=0; j<sdim-1; j++) { 1814 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1815 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1816 } 1817 dxn++; 1818 jdxn[i] = tmp; 1819 } 1820 PetscCall(MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv)); 1821 PetscCall(PetscFree2(bufm,bufn)); 1822 PetscFunctionReturn(0); 1823 } 1824 1825 /*@ 1826 MatSetStencil - Sets the grid information for setting values into a matrix via 1827 MatSetValuesStencil() 1828 1829 Not Collective 1830 1831 Input Parameters: 1832 + mat - the matrix 1833 . dim - dimension of the grid 1, 2, or 3 1834 . dims - number of grid points in x, y, and z direction, including ghost points on your processor 1835 . starts - starting point of ghost nodes on your processor in x, y, and z direction 1836 - dof - number of degrees of freedom per node 1837 1838 Inspired by the structured grid interface to the HYPRE package 1839 (www.llnl.gov/CASC/hyper) 1840 1841 For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the 1842 user. 1843 1844 Level: beginner 1845 1846 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()` 1847 `MatSetValues()`, `MatSetValuesBlockedStencil()`, `MatSetValuesStencil()` 1848 @*/ 1849 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof) 1850 { 1851 PetscFunctionBegin; 1852 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1853 PetscValidIntPointer(dims,3); 1854 PetscValidIntPointer(starts,4); 1855 1856 mat->stencil.dim = dim + (dof > 1); 1857 for (PetscInt i=0; i<dim; i++) { 1858 mat->stencil.dims[i] = dims[dim-i-1]; /* copy the values in backwards */ 1859 mat->stencil.starts[i] = starts[dim-i-1]; 1860 } 1861 mat->stencil.dims[dim] = dof; 1862 mat->stencil.starts[dim] = 0; 1863 mat->stencil.noc = (PetscBool)(dof == 1); 1864 PetscFunctionReturn(0); 1865 } 1866 1867 /*@C 1868 MatSetValuesBlocked - Inserts or adds a block of values into a matrix. 1869 1870 Not Collective 1871 1872 Input Parameters: 1873 + mat - the matrix 1874 . v - a logically two-dimensional array of values 1875 . m, idxm - the number of block rows and their global block indices 1876 . n, idxn - the number of block columns and their global block indices 1877 - addv - either ADD_VALUES or INSERT_VALUES, where 1878 ADD_VALUES adds values to any existing entries, and 1879 INSERT_VALUES replaces existing entries with new values 1880 1881 Notes: 1882 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call 1883 MatXXXXSetPreallocation() or MatSetUp() before using this routine. 1884 1885 The m and n count the NUMBER of blocks in the row direction and column direction, 1886 NOT the total number of rows/columns; for example, if the block size is 2 and 1887 you are passing in values for rows 2,3,4,5 then m would be 2 (not 4). 1888 The values in idxm would be 1 2; that is the first index for each block divided by 1889 the block size. 1890 1891 Note that you must call MatSetBlockSize() when constructing this matrix (before 1892 preallocating it). 1893 1894 By default the values, v, are row-oriented, so the layout of 1895 v is the same as for MatSetValues(). See MatSetOption() for other options. 1896 1897 Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES 1898 options cannot be mixed without intervening calls to the assembly 1899 routines. 1900 1901 MatSetValuesBlocked() uses 0-based row and column numbers in Fortran 1902 as well as in C. 1903 1904 Negative indices may be passed in idxm and idxn, these rows and columns are 1905 simply ignored. This allows easily inserting element stiffness matrices 1906 with homogeneous Dirchlet boundary conditions that you don't want represented 1907 in the matrix. 1908 1909 Each time an entry is set within a sparse matrix via MatSetValues(), 1910 internal searching must be done to determine where to place the 1911 data in the matrix storage space. By instead inserting blocks of 1912 entries via MatSetValuesBlocked(), the overhead of matrix assembly is 1913 reduced. 1914 1915 Example: 1916 $ Suppose m=n=2 and block size(bs) = 2 The array is 1917 $ 1918 $ 1 2 | 3 4 1919 $ 5 6 | 7 8 1920 $ - - - | - - - 1921 $ 9 10 | 11 12 1922 $ 13 14 | 15 16 1923 $ 1924 $ v[] should be passed in like 1925 $ v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] 1926 $ 1927 $ If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then 1928 $ v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16] 1929 1930 Level: intermediate 1931 1932 .seealso: `MatSetBlockSize()`, `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetValuesBlockedLocal()` 1933 @*/ 1934 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1935 { 1936 PetscFunctionBeginHot; 1937 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1938 PetscValidType(mat,1); 1939 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1940 PetscValidIntPointer(idxm,3); 1941 PetscValidIntPointer(idxn,5); 1942 MatCheckPreallocated(mat,1); 1943 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 1944 else PetscCheck(mat->insertmode == addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1945 if (PetscDefined(USE_DEBUG)) { 1946 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1947 PetscCheck(mat->ops->setvaluesblocked || mat->ops->setvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1948 } 1949 if (PetscDefined(USE_DEBUG)) { 1950 PetscInt rbs,cbs,M,N,i; 1951 PetscCall(MatGetBlockSizes(mat,&rbs,&cbs)); 1952 PetscCall(MatGetSize(mat,&M,&N)); 1953 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); 1954 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); 1955 } 1956 if (mat->assembled) { 1957 mat->was_assembled = PETSC_TRUE; 1958 mat->assembled = PETSC_FALSE; 1959 } 1960 PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 1961 if (mat->ops->setvaluesblocked) { 1962 PetscCall((*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv)); 1963 } else { 1964 PetscInt buf[8192],*bufr=NULL,*bufc=NULL,*iidxm,*iidxn; 1965 PetscInt i,j,bs,cbs; 1966 1967 PetscCall(MatGetBlockSizes(mat,&bs,&cbs)); 1968 if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1969 iidxm = buf; 1970 iidxn = buf + m*bs; 1971 } else { 1972 PetscCall(PetscMalloc2(m*bs,&bufr,n*cbs,&bufc)); 1973 iidxm = bufr; 1974 iidxn = bufc; 1975 } 1976 for (i=0; i<m; i++) { 1977 for (j=0; j<bs; j++) { 1978 iidxm[i*bs+j] = bs*idxm[i] + j; 1979 } 1980 } 1981 if (m != n || bs != cbs || idxm != idxn) { 1982 for (i=0; i<n; i++) { 1983 for (j=0; j<cbs; j++) { 1984 iidxn[i*cbs+j] = cbs*idxn[i] + j; 1985 } 1986 } 1987 } else iidxn = iidxm; 1988 PetscCall(MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv)); 1989 PetscCall(PetscFree2(bufr,bufc)); 1990 } 1991 PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 1992 PetscFunctionReturn(0); 1993 } 1994 1995 /*@C 1996 MatGetValues - Gets a block of values from a matrix. 1997 1998 Not Collective; can only return values that are owned by the give process 1999 2000 Input Parameters: 2001 + mat - the matrix 2002 . v - a logically two-dimensional array for storing the values 2003 . m, idxm - the number of rows and their global indices 2004 - n, idxn - the number of columns and their global indices 2005 2006 Notes: 2007 The user must allocate space (m*n PetscScalars) for the values, v. 2008 The values, v, are then returned in a row-oriented format, 2009 analogous to that used by default in MatSetValues(). 2010 2011 MatGetValues() uses 0-based row and column numbers in 2012 Fortran as well as in C. 2013 2014 MatGetValues() requires that the matrix has been assembled 2015 with MatAssemblyBegin()/MatAssemblyEnd(). Thus, calls to 2016 MatSetValues() and MatGetValues() CANNOT be made in succession 2017 without intermediate matrix assembly. 2018 2019 Negative row or column indices will be ignored and those locations in v[] will be 2020 left unchanged. 2021 2022 For the standard row-based matrix formats, idxm[] can only contain rows owned by the requesting MPI rank. 2023 That is, rows with global index greater than or equal to rstart and less than rend where rstart and rend are obtainable 2024 from MatGetOwnershipRange(mat,&rstart,&rend). 2025 2026 Level: advanced 2027 2028 .seealso: `MatGetRow()`, `MatCreateSubMatrices()`, `MatSetValues()`, `MatGetOwnershipRange()`, `MatGetValuesLocal()`, `MatGetValue()` 2029 @*/ 2030 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[]) 2031 { 2032 PetscFunctionBegin; 2033 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2034 PetscValidType(mat,1); 2035 if (!m || !n) PetscFunctionReturn(0); 2036 PetscValidIntPointer(idxm,3); 2037 PetscValidIntPointer(idxn,5); 2038 PetscValidScalarPointer(v,6); 2039 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2040 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2041 PetscCheck(mat->ops->getvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2042 MatCheckPreallocated(mat,1); 2043 2044 PetscCall(PetscLogEventBegin(MAT_GetValues,mat,0,0,0)); 2045 PetscCall((*mat->ops->getvalues)(mat,m,idxm,n,idxn,v)); 2046 PetscCall(PetscLogEventEnd(MAT_GetValues,mat,0,0,0)); 2047 PetscFunctionReturn(0); 2048 } 2049 2050 /*@C 2051 MatGetValuesLocal - retrieves values from certain locations in a matrix using the local numbering of the indices 2052 defined previously by MatSetLocalToGlobalMapping() 2053 2054 Not Collective 2055 2056 Input Parameters: 2057 + mat - the matrix 2058 . nrow, irow - number of rows and their local indices 2059 - ncol, icol - number of columns and their local indices 2060 2061 Output Parameter: 2062 . y - a logically two-dimensional array of values 2063 2064 Notes: 2065 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine. 2066 2067 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, 2068 are greater than or equal to rstart and less than rend where rstart and rend are obtainable from MatGetOwnershipRange(mat,&rstart,&rend). One can 2069 determine if the resulting global row associated with the local row r is owned by the requesting MPI rank by applying the ISLocalToGlobalMapping set 2070 with MatSetLocalToGlobalMapping(). 2071 2072 Developer Notes: 2073 This is labelled with C so does not automatically generate Fortran stubs and interfaces 2074 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2075 2076 Level: advanced 2077 2078 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetLocalToGlobalMapping()`, 2079 `MatSetValuesLocal()`, `MatGetValues()` 2080 @*/ 2081 PetscErrorCode MatGetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],PetscScalar y[]) 2082 { 2083 PetscFunctionBeginHot; 2084 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2085 PetscValidType(mat,1); 2086 MatCheckPreallocated(mat,1); 2087 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to retrieve */ 2088 PetscValidIntPointer(irow,3); 2089 PetscValidIntPointer(icol,5); 2090 if (PetscDefined(USE_DEBUG)) { 2091 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2092 PetscCheck(mat->ops->getvalueslocal || mat->ops->getvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2093 } 2094 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2095 PetscCall(PetscLogEventBegin(MAT_GetValues,mat,0,0,0)); 2096 if (mat->ops->getvalueslocal) { 2097 PetscCall((*mat->ops->getvalueslocal)(mat,nrow,irow,ncol,icol,y)); 2098 } else { 2099 PetscInt buf[8192],*bufr=NULL,*bufc=NULL,*irowm,*icolm; 2100 if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2101 irowm = buf; icolm = buf+nrow; 2102 } else { 2103 PetscCall(PetscMalloc2(nrow,&bufr,ncol,&bufc)); 2104 irowm = bufr; icolm = bufc; 2105 } 2106 PetscCheck(mat->rmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MatGetValuesLocal() cannot proceed without local-to-global row mapping (See MatSetLocalToGlobalMapping())."); 2107 PetscCheck(mat->cmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MatGetValuesLocal() cannot proceed without local-to-global column mapping (See MatSetLocalToGlobalMapping())."); 2108 PetscCall(ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm)); 2109 PetscCall(ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm)); 2110 PetscCall(MatGetValues(mat,nrow,irowm,ncol,icolm,y)); 2111 PetscCall(PetscFree2(bufr,bufc)); 2112 } 2113 PetscCall(PetscLogEventEnd(MAT_GetValues,mat,0,0,0)); 2114 PetscFunctionReturn(0); 2115 } 2116 2117 /*@ 2118 MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and 2119 the same size. Currently, this can only be called once and creates the given matrix. 2120 2121 Not Collective 2122 2123 Input Parameters: 2124 + mat - the matrix 2125 . nb - the number of blocks 2126 . bs - the number of rows (and columns) in each block 2127 . rows - a concatenation of the rows for each block 2128 - v - a concatenation of logically two-dimensional arrays of values 2129 2130 Notes: 2131 In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix. 2132 2133 Level: advanced 2134 2135 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 2136 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()` 2137 @*/ 2138 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[]) 2139 { 2140 PetscFunctionBegin; 2141 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2142 PetscValidType(mat,1); 2143 PetscValidIntPointer(rows,4); 2144 PetscValidScalarPointer(v,5); 2145 PetscAssert(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2146 2147 PetscCall(PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0)); 2148 if (mat->ops->setvaluesbatch) { 2149 PetscCall((*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v)); 2150 } else { 2151 for (PetscInt b = 0; b < nb; ++b) PetscCall(MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES)); 2152 } 2153 PetscCall(PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0)); 2154 PetscFunctionReturn(0); 2155 } 2156 2157 /*@ 2158 MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by 2159 the routine MatSetValuesLocal() to allow users to insert matrix entries 2160 using a local (per-processor) numbering. 2161 2162 Not Collective 2163 2164 Input Parameters: 2165 + x - the matrix 2166 . rmapping - row mapping created with ISLocalToGlobalMappingCreate() or ISLocalToGlobalMappingCreateIS() 2167 - cmapping - column mapping 2168 2169 Level: intermediate 2170 2171 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetValuesLocal()`, `MatGetValuesLocal()` 2172 @*/ 2173 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 2174 { 2175 PetscFunctionBegin; 2176 PetscValidHeaderSpecific(x,MAT_CLASSID,1); 2177 PetscValidType(x,1); 2178 if (rmapping) PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2); 2179 if (cmapping) PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3); 2180 if (x->ops->setlocaltoglobalmapping) { 2181 PetscCall((*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping)); 2182 } else { 2183 PetscCall(PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping)); 2184 PetscCall(PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping)); 2185 } 2186 PetscFunctionReturn(0); 2187 } 2188 2189 /*@ 2190 MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping() 2191 2192 Not Collective 2193 2194 Input Parameter: 2195 . A - the matrix 2196 2197 Output Parameters: 2198 + rmapping - row mapping 2199 - cmapping - column mapping 2200 2201 Level: advanced 2202 2203 .seealso: `MatSetValuesLocal()` 2204 @*/ 2205 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping) 2206 { 2207 PetscFunctionBegin; 2208 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2209 PetscValidType(A,1); 2210 if (rmapping) { 2211 PetscValidPointer(rmapping,2); 2212 *rmapping = A->rmap->mapping; 2213 } 2214 if (cmapping) { 2215 PetscValidPointer(cmapping,3); 2216 *cmapping = A->cmap->mapping; 2217 } 2218 PetscFunctionReturn(0); 2219 } 2220 2221 /*@ 2222 MatSetLayouts - Sets the PetscLayout objects for rows and columns of a matrix 2223 2224 Logically Collective on A 2225 2226 Input Parameters: 2227 + A - the matrix 2228 . rmap - row layout 2229 - cmap - column layout 2230 2231 Level: advanced 2232 2233 .seealso: `MatCreateVecs()`, `MatGetLocalToGlobalMapping()`, `MatGetLayouts()` 2234 @*/ 2235 PetscErrorCode MatSetLayouts(Mat A,PetscLayout rmap,PetscLayout cmap) 2236 { 2237 PetscFunctionBegin; 2238 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2239 PetscCall(PetscLayoutReference(rmap,&A->rmap)); 2240 PetscCall(PetscLayoutReference(cmap,&A->cmap)); 2241 PetscFunctionReturn(0); 2242 } 2243 2244 /*@ 2245 MatGetLayouts - Gets the PetscLayout objects for rows and columns 2246 2247 Not Collective 2248 2249 Input Parameter: 2250 . A - the matrix 2251 2252 Output Parameters: 2253 + rmap - row layout 2254 - cmap - column layout 2255 2256 Level: advanced 2257 2258 .seealso: `MatCreateVecs()`, `MatGetLocalToGlobalMapping()`, `MatSetLayouts()` 2259 @*/ 2260 PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap) 2261 { 2262 PetscFunctionBegin; 2263 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2264 PetscValidType(A,1); 2265 if (rmap) { 2266 PetscValidPointer(rmap,2); 2267 *rmap = A->rmap; 2268 } 2269 if (cmap) { 2270 PetscValidPointer(cmap,3); 2271 *cmap = A->cmap; 2272 } 2273 PetscFunctionReturn(0); 2274 } 2275 2276 /*@C 2277 MatSetValuesLocal - Inserts or adds values into certain locations of a matrix, 2278 using a local numbering of the nodes. 2279 2280 Not Collective 2281 2282 Input Parameters: 2283 + mat - the matrix 2284 . nrow, irow - number of rows and their local indices 2285 . ncol, icol - number of columns and their local indices 2286 . y - a logically two-dimensional array of values 2287 - addv - either INSERT_VALUES or ADD_VALUES, where 2288 ADD_VALUES adds values to any existing entries, and 2289 INSERT_VALUES replaces existing entries with new values 2290 2291 Notes: 2292 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2293 MatSetUp() before using this routine 2294 2295 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine 2296 2297 Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES 2298 options cannot be mixed without intervening calls to the assembly 2299 routines. 2300 2301 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2302 MUST be called after all calls to MatSetValuesLocal() have been completed. 2303 2304 Level: intermediate 2305 2306 Developer Notes: 2307 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2308 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2309 2310 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetLocalToGlobalMapping()`, 2311 `MatSetValueLocal()`, `MatGetValuesLocal()` 2312 @*/ 2313 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2314 { 2315 PetscFunctionBeginHot; 2316 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2317 PetscValidType(mat,1); 2318 MatCheckPreallocated(mat,1); 2319 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2320 PetscValidIntPointer(irow,3); 2321 PetscValidIntPointer(icol,5); 2322 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 2323 else PetscCheck(mat->insertmode == addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2324 if (PetscDefined(USE_DEBUG)) { 2325 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2326 PetscCheck(mat->ops->setvalueslocal || mat->ops->setvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2327 } 2328 2329 if (mat->assembled) { 2330 mat->was_assembled = PETSC_TRUE; 2331 mat->assembled = PETSC_FALSE; 2332 } 2333 PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 2334 if (mat->ops->setvalueslocal) { 2335 PetscCall((*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv)); 2336 } else { 2337 PetscInt buf[8192],*bufr=NULL,*bufc=NULL; 2338 const PetscInt *irowm,*icolm; 2339 2340 if ((!mat->rmap->mapping && !mat->cmap->mapping) || (nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2341 bufr = buf; 2342 bufc = buf + nrow; 2343 irowm = bufr; 2344 icolm = bufc; 2345 } else { 2346 PetscCall(PetscMalloc2(nrow,&bufr,ncol,&bufc)); 2347 irowm = bufr; 2348 icolm = bufc; 2349 } 2350 if (mat->rmap->mapping) PetscCall(ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,bufr)); 2351 else irowm = irow; 2352 if (mat->cmap->mapping) { 2353 if (mat->cmap->mapping != mat->rmap->mapping || ncol != nrow || icol != irow) { 2354 PetscCall(ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,bufc)); 2355 } else icolm = irowm; 2356 } else icolm = icol; 2357 PetscCall(MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv)); 2358 if (bufr != buf) PetscCall(PetscFree2(bufr,bufc)); 2359 } 2360 PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 2361 PetscFunctionReturn(0); 2362 } 2363 2364 /*@C 2365 MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix, 2366 using a local ordering of the nodes a block at a time. 2367 2368 Not Collective 2369 2370 Input Parameters: 2371 + x - the matrix 2372 . nrow, irow - number of rows and their local indices 2373 . ncol, icol - number of columns and their local indices 2374 . y - a logically two-dimensional array of values 2375 - addv - either INSERT_VALUES or ADD_VALUES, where 2376 ADD_VALUES adds values to any existing entries, and 2377 INSERT_VALUES replaces existing entries with new values 2378 2379 Notes: 2380 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2381 MatSetUp() before using this routine 2382 2383 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping() 2384 before using this routineBefore calling MatSetValuesLocal(), the user must first set the 2385 2386 Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES 2387 options cannot be mixed without intervening calls to the assembly 2388 routines. 2389 2390 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2391 MUST be called after all calls to MatSetValuesBlockedLocal() have been completed. 2392 2393 Level: intermediate 2394 2395 Developer Notes: 2396 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2397 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2398 2399 .seealso: `MatSetBlockSize()`, `MatSetLocalToGlobalMapping()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, 2400 `MatSetValuesLocal()`, `MatSetValuesBlocked()` 2401 @*/ 2402 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2403 { 2404 PetscFunctionBeginHot; 2405 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2406 PetscValidType(mat,1); 2407 MatCheckPreallocated(mat,1); 2408 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2409 PetscValidIntPointer(irow,3); 2410 PetscValidIntPointer(icol,5); 2411 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 2412 else PetscCheck(mat->insertmode == addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2413 if (PetscDefined(USE_DEBUG)) { 2414 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2415 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); 2416 } 2417 2418 if (mat->assembled) { 2419 mat->was_assembled = PETSC_TRUE; 2420 mat->assembled = PETSC_FALSE; 2421 } 2422 if (PetscUnlikelyDebug(mat->rmap->mapping)) { /* Condition on the mapping existing, because MatSetValuesBlockedLocal_IS does not require it to be set. */ 2423 PetscInt irbs, rbs; 2424 PetscCall(MatGetBlockSizes(mat, &rbs, NULL)); 2425 PetscCall(ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&irbs)); 2426 PetscCheck(rbs == irbs,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different row block sizes! mat %" PetscInt_FMT ", row l2g map %" PetscInt_FMT,rbs,irbs); 2427 } 2428 if (PetscUnlikelyDebug(mat->cmap->mapping)) { 2429 PetscInt icbs, cbs; 2430 PetscCall(MatGetBlockSizes(mat,NULL,&cbs)); 2431 PetscCall(ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&icbs)); 2432 PetscCheck(cbs == icbs,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different col block sizes! mat %" PetscInt_FMT ", col l2g map %" PetscInt_FMT,cbs,icbs); 2433 } 2434 PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 2435 if (mat->ops->setvaluesblockedlocal) { 2436 PetscCall((*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv)); 2437 } else { 2438 PetscInt buf[8192],*bufr=NULL,*bufc=NULL; 2439 const PetscInt *irowm,*icolm; 2440 2441 if ((!mat->rmap->mapping && !mat->cmap->mapping) || (nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2442 bufr = buf; 2443 bufc = buf + nrow; 2444 irowm = bufr; 2445 icolm = bufc; 2446 } else { 2447 PetscCall(PetscMalloc2(nrow,&bufr,ncol,&bufc)); 2448 irowm = bufr; 2449 icolm = bufc; 2450 } 2451 if (mat->rmap->mapping) PetscCall(ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,bufr)); 2452 else irowm = irow; 2453 if (mat->cmap->mapping) { 2454 if (mat->cmap->mapping != mat->rmap->mapping || ncol != nrow || icol != irow) { 2455 PetscCall(ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,bufc)); 2456 } else icolm = irowm; 2457 } else icolm = icol; 2458 PetscCall(MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv)); 2459 if (bufr != buf) PetscCall(PetscFree2(bufr,bufc)); 2460 } 2461 PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 2462 PetscFunctionReturn(0); 2463 } 2464 2465 /*@ 2466 MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal 2467 2468 Collective on Mat 2469 2470 Input Parameters: 2471 + mat - the matrix 2472 - x - the vector to be multiplied 2473 2474 Output Parameters: 2475 . y - the result 2476 2477 Notes: 2478 The vectors x and y cannot be the same. I.e., one cannot 2479 call MatMult(A,y,y). 2480 2481 Level: developer 2482 2483 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 2484 @*/ 2485 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y) 2486 { 2487 PetscFunctionBegin; 2488 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2489 PetscValidType(mat,1); 2490 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2491 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2492 2493 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2494 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2495 PetscCheck(x != y,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2496 MatCheckPreallocated(mat,1); 2497 2498 PetscCheck(mat->ops->multdiagonalblock,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a multiply defined",((PetscObject)mat)->type_name); 2499 PetscCall((*mat->ops->multdiagonalblock)(mat,x,y)); 2500 PetscCall(PetscObjectStateIncrease((PetscObject)y)); 2501 PetscFunctionReturn(0); 2502 } 2503 2504 /* --------------------------------------------------------*/ 2505 /*@ 2506 MatMult - Computes the matrix-vector product, y = Ax. 2507 2508 Neighbor-wise Collective on Mat 2509 2510 Input Parameters: 2511 + mat - the matrix 2512 - x - the vector to be multiplied 2513 2514 Output Parameters: 2515 . y - the result 2516 2517 Notes: 2518 The vectors x and y cannot be the same. I.e., one cannot 2519 call MatMult(A,y,y). 2520 2521 Level: beginner 2522 2523 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 2524 @*/ 2525 PetscErrorCode MatMult(Mat mat,Vec x,Vec y) 2526 { 2527 PetscFunctionBegin; 2528 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2529 PetscValidType(mat,1); 2530 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2531 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2532 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2533 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2534 PetscCheck(x != y,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2535 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); 2536 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); 2537 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); 2538 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); 2539 PetscCall(VecSetErrorIfLocked(y,3)); 2540 if (mat->erroriffailure) PetscCall(VecValidValues(x,2,PETSC_TRUE)); 2541 MatCheckPreallocated(mat,1); 2542 2543 PetscCall(VecLockReadPush(x)); 2544 PetscCall(PetscLogEventBegin(MAT_Mult,mat,x,y,0)); 2545 PetscUseTypeMethod(mat,mult,x,y); 2546 PetscCall(PetscLogEventEnd(MAT_Mult,mat,x,y,0)); 2547 if (mat->erroriffailure) PetscCall(VecValidValues(y,3,PETSC_FALSE)); 2548 PetscCall(VecLockReadPop(x)); 2549 PetscFunctionReturn(0); 2550 } 2551 2552 /*@ 2553 MatMultTranspose - Computes matrix transpose times a vector y = A^T * x. 2554 2555 Neighbor-wise Collective on Mat 2556 2557 Input Parameters: 2558 + mat - the matrix 2559 - x - the vector to be multiplied 2560 2561 Output Parameters: 2562 . y - the result 2563 2564 Notes: 2565 The vectors x and y cannot be the same. I.e., one cannot 2566 call MatMultTranspose(A,y,y). 2567 2568 For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple, 2569 use MatMultHermitianTranspose() 2570 2571 Level: beginner 2572 2573 .seealso: `MatMult()`, `MatMultAdd()`, `MatMultTransposeAdd()`, `MatMultHermitianTranspose()`, `MatTranspose()` 2574 @*/ 2575 PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y) 2576 { 2577 PetscErrorCode (*op)(Mat,Vec,Vec) = NULL; 2578 2579 PetscFunctionBegin; 2580 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2581 PetscValidType(mat,1); 2582 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2583 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2584 2585 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2586 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2587 PetscCheck(x != y,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2588 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); 2589 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); 2590 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); 2591 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); 2592 if (mat->erroriffailure) PetscCall(VecValidValues(x,2,PETSC_TRUE)); 2593 MatCheckPreallocated(mat,1); 2594 2595 if (!mat->ops->multtranspose) { 2596 if (mat->symmetric == PETSC_BOOL3_TRUE && mat->ops->mult) op = mat->ops->mult; 2597 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); 2598 } else op = mat->ops->multtranspose; 2599 PetscCall(PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0)); 2600 PetscCall(VecLockReadPush(x)); 2601 PetscCall((*op)(mat,x,y)); 2602 PetscCall(VecLockReadPop(x)); 2603 PetscCall(PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0)); 2604 PetscCall(PetscObjectStateIncrease((PetscObject)y)); 2605 if (mat->erroriffailure) PetscCall(VecValidValues(y,3,PETSC_FALSE)); 2606 PetscFunctionReturn(0); 2607 } 2608 2609 /*@ 2610 MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector. 2611 2612 Neighbor-wise Collective on Mat 2613 2614 Input Parameters: 2615 + mat - the matrix 2616 - x - the vector to be multilplied 2617 2618 Output Parameters: 2619 . y - the result 2620 2621 Notes: 2622 The vectors x and y cannot be the same. I.e., one cannot 2623 call MatMultHermitianTranspose(A,y,y). 2624 2625 Also called the conjugate transpose, complex conjugate transpose, or adjoint. 2626 2627 For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical. 2628 2629 Level: beginner 2630 2631 .seealso: `MatMult()`, `MatMultAdd()`, `MatMultHermitianTransposeAdd()`, `MatMultTranspose()` 2632 @*/ 2633 PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y) 2634 { 2635 PetscFunctionBegin; 2636 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2637 PetscValidType(mat,1); 2638 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2639 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2640 2641 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2642 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2643 PetscCheck(x != y,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2644 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); 2645 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); 2646 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); 2647 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); 2648 MatCheckPreallocated(mat,1); 2649 2650 PetscCall(PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0)); 2651 #if defined(PETSC_USE_COMPLEX) 2652 if (mat->ops->multhermitiantranspose || (mat->hermitian == PETSC_BOOL3_TRUE && mat->ops->mult)) { 2653 PetscCall(VecLockReadPush(x)); 2654 if (mat->ops->multhermitiantranspose) { 2655 PetscCall((*mat->ops->multhermitiantranspose)(mat,x,y)); 2656 } else { 2657 PetscCall((*mat->ops->mult)(mat,x,y)); 2658 } 2659 PetscCall(VecLockReadPop(x)); 2660 } else { 2661 Vec w; 2662 PetscCall(VecDuplicate(x,&w)); 2663 PetscCall(VecCopy(x,w)); 2664 PetscCall(VecConjugate(w)); 2665 PetscCall(MatMultTranspose(mat,w,y)); 2666 PetscCall(VecDestroy(&w)); 2667 PetscCall(VecConjugate(y)); 2668 } 2669 PetscCall(PetscObjectStateIncrease((PetscObject)y)); 2670 #else 2671 PetscCall(MatMultTranspose(mat,x,y)); 2672 #endif 2673 PetscCall(PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0)); 2674 PetscFunctionReturn(0); 2675 } 2676 2677 /*@ 2678 MatMultAdd - Computes v3 = v2 + A * v1. 2679 2680 Neighbor-wise Collective on Mat 2681 2682 Input Parameters: 2683 + mat - the matrix 2684 - v1, v2 - the vectors 2685 2686 Output Parameters: 2687 . v3 - the result 2688 2689 Notes: 2690 The vectors v1 and v3 cannot be the same. I.e., one cannot 2691 call MatMultAdd(A,v1,v2,v1). 2692 2693 Level: beginner 2694 2695 .seealso: `MatMultTranspose()`, `MatMult()`, `MatMultTransposeAdd()` 2696 @*/ 2697 PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2698 { 2699 PetscFunctionBegin; 2700 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2701 PetscValidType(mat,1); 2702 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2703 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2704 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2705 2706 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2707 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2708 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); 2709 /* 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); 2710 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); */ 2711 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); 2712 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); 2713 PetscCheck(v1 != v3,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2714 MatCheckPreallocated(mat,1); 2715 2716 PetscCheck(mat->ops->multadd,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type %s",((PetscObject)mat)->type_name); 2717 PetscCall(PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3)); 2718 PetscCall(VecLockReadPush(v1)); 2719 PetscCall((*mat->ops->multadd)(mat,v1,v2,v3)); 2720 PetscCall(VecLockReadPop(v1)); 2721 PetscCall(PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3)); 2722 PetscCall(PetscObjectStateIncrease((PetscObject)v3)); 2723 PetscFunctionReturn(0); 2724 } 2725 2726 /*@ 2727 MatMultTransposeAdd - Computes v3 = v2 + A' * v1. 2728 2729 Neighbor-wise Collective on Mat 2730 2731 Input Parameters: 2732 + mat - the matrix 2733 - v1, v2 - the vectors 2734 2735 Output Parameters: 2736 . v3 - the result 2737 2738 Notes: 2739 The vectors v1 and v3 cannot be the same. I.e., one cannot 2740 call MatMultTransposeAdd(A,v1,v2,v1). 2741 2742 Level: beginner 2743 2744 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMult()` 2745 @*/ 2746 PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2747 { 2748 PetscErrorCode (*op)(Mat,Vec,Vec,Vec) = (!mat->ops->multtransposeadd && mat->symmetric) ? mat->ops->multadd : mat->ops->multtransposeadd; 2749 2750 PetscFunctionBegin; 2751 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2752 PetscValidType(mat,1); 2753 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2754 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2755 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2756 2757 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2758 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2759 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); 2760 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); 2761 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); 2762 PetscCheck(v1 != v3,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2763 PetscCheck(op,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2764 MatCheckPreallocated(mat,1); 2765 2766 PetscCall(PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3)); 2767 PetscCall(VecLockReadPush(v1)); 2768 PetscCall((*op)(mat,v1,v2,v3)); 2769 PetscCall(VecLockReadPop(v1)); 2770 PetscCall(PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3)); 2771 PetscCall(PetscObjectStateIncrease((PetscObject)v3)); 2772 PetscFunctionReturn(0); 2773 } 2774 2775 /*@ 2776 MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1. 2777 2778 Neighbor-wise Collective on Mat 2779 2780 Input Parameters: 2781 + mat - the matrix 2782 - v1, v2 - the vectors 2783 2784 Output Parameters: 2785 . v3 - the result 2786 2787 Notes: 2788 The vectors v1 and v3 cannot be the same. I.e., one cannot 2789 call MatMultHermitianTransposeAdd(A,v1,v2,v1). 2790 2791 Level: beginner 2792 2793 .seealso: `MatMultHermitianTranspose()`, `MatMultTranspose()`, `MatMultAdd()`, `MatMult()` 2794 @*/ 2795 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2796 { 2797 PetscFunctionBegin; 2798 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2799 PetscValidType(mat,1); 2800 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2801 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2802 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2803 2804 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2805 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2806 PetscCheck(v1 != v3,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2807 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); 2808 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); 2809 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); 2810 MatCheckPreallocated(mat,1); 2811 2812 PetscCall(PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3)); 2813 PetscCall(VecLockReadPush(v1)); 2814 if (mat->ops->multhermitiantransposeadd) { 2815 PetscCall((*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3)); 2816 } else { 2817 Vec w,z; 2818 PetscCall(VecDuplicate(v1,&w)); 2819 PetscCall(VecCopy(v1,w)); 2820 PetscCall(VecConjugate(w)); 2821 PetscCall(VecDuplicate(v3,&z)); 2822 PetscCall(MatMultTranspose(mat,w,z)); 2823 PetscCall(VecDestroy(&w)); 2824 PetscCall(VecConjugate(z)); 2825 if (v2 != v3) { 2826 PetscCall(VecWAXPY(v3,1.0,v2,z)); 2827 } else { 2828 PetscCall(VecAXPY(v3,1.0,z)); 2829 } 2830 PetscCall(VecDestroy(&z)); 2831 } 2832 PetscCall(VecLockReadPop(v1)); 2833 PetscCall(PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3)); 2834 PetscCall(PetscObjectStateIncrease((PetscObject)v3)); 2835 PetscFunctionReturn(0); 2836 } 2837 2838 /*@C 2839 MatGetFactorType - gets the type of factorization it is 2840 2841 Not Collective 2842 2843 Input Parameters: 2844 . mat - the matrix 2845 2846 Output Parameters: 2847 . t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT 2848 2849 Level: intermediate 2850 2851 .seealso: `MatFactorType`, `MatGetFactor()`, `MatSetFactorType()` 2852 @*/ 2853 PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t) 2854 { 2855 PetscFunctionBegin; 2856 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2857 PetscValidType(mat,1); 2858 PetscValidPointer(t,2); 2859 *t = mat->factortype; 2860 PetscFunctionReturn(0); 2861 } 2862 2863 /*@C 2864 MatSetFactorType - sets the type of factorization it is 2865 2866 Logically Collective on Mat 2867 2868 Input Parameters: 2869 + mat - the matrix 2870 - t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT 2871 2872 Level: intermediate 2873 2874 .seealso: `MatFactorType`, `MatGetFactor()`, `MatGetFactorType()` 2875 @*/ 2876 PetscErrorCode MatSetFactorType(Mat mat, MatFactorType t) 2877 { 2878 PetscFunctionBegin; 2879 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2880 PetscValidType(mat,1); 2881 mat->factortype = t; 2882 PetscFunctionReturn(0); 2883 } 2884 2885 /* ------------------------------------------------------------*/ 2886 /*@C 2887 MatGetInfo - Returns information about matrix storage (number of 2888 nonzeros, memory, etc.). 2889 2890 Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag 2891 2892 Input Parameter: 2893 . mat - the matrix 2894 2895 Output Parameters: 2896 + flag - flag indicating the type of parameters to be returned 2897 (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors, 2898 MAT_GLOBAL_SUM - sum over all processors) 2899 - info - matrix information context 2900 2901 Notes: 2902 The MatInfo context contains a variety of matrix data, including 2903 number of nonzeros allocated and used, number of mallocs during 2904 matrix assembly, etc. Additional information for factored matrices 2905 is provided (such as the fill ratio, number of mallocs during 2906 factorization, etc.). Much of this info is printed to PETSC_STDOUT 2907 when using the runtime options 2908 $ -info -mat_view ::ascii_info 2909 2910 Example for C/C++ Users: 2911 See the file ${PETSC_DIR}/include/petscmat.h for a complete list of 2912 data within the MatInfo context. For example, 2913 .vb 2914 MatInfo info; 2915 Mat A; 2916 double mal, nz_a, nz_u; 2917 2918 MatGetInfo(A,MAT_LOCAL,&info); 2919 mal = info.mallocs; 2920 nz_a = info.nz_allocated; 2921 .ve 2922 2923 Example for Fortran Users: 2924 Fortran users should declare info as a double precision 2925 array of dimension MAT_INFO_SIZE, and then extract the parameters 2926 of interest. See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h 2927 a complete list of parameter names. 2928 .vb 2929 double precision info(MAT_INFO_SIZE) 2930 double precision mal, nz_a 2931 Mat A 2932 integer ierr 2933 2934 call MatGetInfo(A,MAT_LOCAL,info,ierr) 2935 mal = info(MAT_INFO_MALLOCS) 2936 nz_a = info(MAT_INFO_NZ_ALLOCATED) 2937 .ve 2938 2939 Level: intermediate 2940 2941 Developer Note: fortran interface is not autogenerated as the f90 2942 interface definition cannot be generated correctly [due to MatInfo] 2943 2944 .seealso: `MatStashGetInfo()` 2945 2946 @*/ 2947 PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info) 2948 { 2949 PetscFunctionBegin; 2950 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2951 PetscValidType(mat,1); 2952 PetscValidPointer(info,3); 2953 PetscCheck(mat->ops->getinfo,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2954 MatCheckPreallocated(mat,1); 2955 PetscCall((*mat->ops->getinfo)(mat,flag,info)); 2956 PetscFunctionReturn(0); 2957 } 2958 2959 /* 2960 This is used by external packages where it is not easy to get the info from the actual 2961 matrix factorization. 2962 */ 2963 PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info) 2964 { 2965 PetscFunctionBegin; 2966 PetscCall(PetscMemzero(info,sizeof(MatInfo))); 2967 PetscFunctionReturn(0); 2968 } 2969 2970 /* ----------------------------------------------------------*/ 2971 2972 /*@C 2973 MatLUFactor - Performs in-place LU factorization of matrix. 2974 2975 Collective on Mat 2976 2977 Input Parameters: 2978 + mat - the matrix 2979 . row - row permutation 2980 . col - column permutation 2981 - info - options for factorization, includes 2982 $ fill - expected fill as ratio of original fill. 2983 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 2984 $ Run with the option -info to determine an optimal value to use 2985 2986 Notes: 2987 Most users should employ the simplified KSP interface for linear solvers 2988 instead of working directly with matrix algebra routines such as this. 2989 See, e.g., KSPCreate(). 2990 2991 This changes the state of the matrix to a factored matrix; it cannot be used 2992 for example with MatSetValues() unless one first calls MatSetUnfactored(). 2993 2994 Level: developer 2995 2996 .seealso: `MatLUFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()`, 2997 `MatGetOrdering()`, `MatSetUnfactored()`, `MatFactorInfo`, `MatGetFactor()` 2998 2999 Developer Note: fortran interface is not autogenerated as the f90 3000 interface definition cannot be generated correctly [due to MatFactorInfo] 3001 3002 @*/ 3003 PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 3004 { 3005 MatFactorInfo tinfo; 3006 3007 PetscFunctionBegin; 3008 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3009 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 3010 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 3011 if (info) PetscValidPointer(info,4); 3012 PetscValidType(mat,1); 3013 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3014 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3015 PetscCheck(mat->ops->lufactor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3016 MatCheckPreallocated(mat,1); 3017 if (!info) { 3018 PetscCall(MatFactorInfoInitialize(&tinfo)); 3019 info = &tinfo; 3020 } 3021 3022 PetscCall(PetscLogEventBegin(MAT_LUFactor,mat,row,col,0)); 3023 PetscCall((*mat->ops->lufactor)(mat,row,col,info)); 3024 PetscCall(PetscLogEventEnd(MAT_LUFactor,mat,row,col,0)); 3025 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 3026 PetscFunctionReturn(0); 3027 } 3028 3029 /*@C 3030 MatILUFactor - Performs in-place ILU factorization of matrix. 3031 3032 Collective on Mat 3033 3034 Input Parameters: 3035 + mat - the matrix 3036 . row - row permutation 3037 . col - column permutation 3038 - info - structure containing 3039 $ levels - number of levels of fill. 3040 $ expected fill - as ratio of original fill. 3041 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 3042 missing diagonal entries) 3043 3044 Notes: 3045 Probably really in-place only when level of fill is zero, otherwise allocates 3046 new space to store factored matrix and deletes previous memory. 3047 3048 Most users should employ the simplified KSP interface for linear solvers 3049 instead of working directly with matrix algebra routines such as this. 3050 See, e.g., KSPCreate(). 3051 3052 Level: developer 3053 3054 .seealso: `MatILUFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()`, `MatFactorInfo` 3055 3056 Developer Note: fortran interface is not autogenerated as the f90 3057 interface definition cannot be generated correctly [due to MatFactorInfo] 3058 3059 @*/ 3060 PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 3061 { 3062 PetscFunctionBegin; 3063 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3064 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 3065 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 3066 PetscValidPointer(info,4); 3067 PetscValidType(mat,1); 3068 PetscCheck(mat->rmap->N == mat->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 3069 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3070 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3071 PetscCheck(mat->ops->ilufactor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3072 MatCheckPreallocated(mat,1); 3073 3074 PetscCall(PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0)); 3075 PetscCall((*mat->ops->ilufactor)(mat,row,col,info)); 3076 PetscCall(PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0)); 3077 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 3078 PetscFunctionReturn(0); 3079 } 3080 3081 /*@C 3082 MatLUFactorSymbolic - Performs symbolic LU factorization of matrix. 3083 Call this routine before calling MatLUFactorNumeric(). 3084 3085 Collective on Mat 3086 3087 Input Parameters: 3088 + fact - the factor matrix obtained with MatGetFactor() 3089 . mat - the matrix 3090 . row, col - row and column permutations 3091 - info - options for factorization, includes 3092 $ fill - expected fill as ratio of original fill. 3093 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3094 $ Run with the option -info to determine an optimal value to use 3095 3096 Notes: 3097 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 3098 3099 Most users should employ the simplified KSP interface for linear solvers 3100 instead of working directly with matrix algebra routines such as this. 3101 See, e.g., KSPCreate(). 3102 3103 Level: developer 3104 3105 .seealso: `MatLUFactor()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()`, `MatFactorInfo`, `MatFactorInfoInitialize()` 3106 3107 Developer Note: fortran interface is not autogenerated as the f90 3108 interface definition cannot be generated correctly [due to MatFactorInfo] 3109 3110 @*/ 3111 PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 3112 { 3113 MatFactorInfo tinfo; 3114 3115 PetscFunctionBegin; 3116 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3117 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,3); 3118 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,4); 3119 if (info) PetscValidPointer(info,5); 3120 PetscValidType(mat,2); 3121 PetscValidPointer(fact,1); 3122 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3123 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3124 if (!(fact)->ops->lufactorsymbolic) { 3125 MatSolverType stype; 3126 PetscCall(MatFactorGetSolverType(fact,&stype)); 3127 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,stype); 3128 } 3129 MatCheckPreallocated(mat,2); 3130 if (!info) { 3131 PetscCall(MatFactorInfoInitialize(&tinfo)); 3132 info = &tinfo; 3133 } 3134 3135 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0)); 3136 PetscCall((fact->ops->lufactorsymbolic)(fact,mat,row,col,info)); 3137 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0)); 3138 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3139 PetscFunctionReturn(0); 3140 } 3141 3142 /*@C 3143 MatLUFactorNumeric - Performs numeric LU factorization of a matrix. 3144 Call this routine after first calling MatLUFactorSymbolic(). 3145 3146 Collective on Mat 3147 3148 Input Parameters: 3149 + fact - the factor matrix obtained with MatGetFactor() 3150 . mat - the matrix 3151 - info - options for factorization 3152 3153 Notes: 3154 See MatLUFactor() for in-place factorization. See 3155 MatCholeskyFactorNumeric() for the symmetric, positive definite case. 3156 3157 Most users should employ the simplified KSP interface for linear solvers 3158 instead of working directly with matrix algebra routines such as this. 3159 See, e.g., KSPCreate(). 3160 3161 Level: developer 3162 3163 .seealso: `MatLUFactorSymbolic()`, `MatLUFactor()`, `MatCholeskyFactor()` 3164 3165 Developer Note: fortran interface is not autogenerated as the f90 3166 interface definition cannot be generated correctly [due to MatFactorInfo] 3167 3168 @*/ 3169 PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3170 { 3171 MatFactorInfo tinfo; 3172 3173 PetscFunctionBegin; 3174 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3175 PetscValidType(mat,2); 3176 PetscValidPointer(fact,1); 3177 PetscValidHeaderSpecific(fact,MAT_CLASSID,1); 3178 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3179 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,mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N); 3180 3181 PetscCheck((fact)->ops->lufactornumeric,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name); 3182 MatCheckPreallocated(mat,2); 3183 if (!info) { 3184 PetscCall(MatFactorInfoInitialize(&tinfo)); 3185 info = &tinfo; 3186 } 3187 3188 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0)); 3189 else PetscCall(PetscLogEventBegin(MAT_LUFactor,mat,fact,0,0)); 3190 PetscCall((fact->ops->lufactornumeric)(fact,mat,info)); 3191 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0)); 3192 else PetscCall(PetscLogEventEnd(MAT_LUFactor,mat,fact,0,0)); 3193 PetscCall(MatViewFromOptions(fact,NULL,"-mat_factor_view")); 3194 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3195 PetscFunctionReturn(0); 3196 } 3197 3198 /*@C 3199 MatCholeskyFactor - Performs in-place Cholesky factorization of a 3200 symmetric matrix. 3201 3202 Collective on Mat 3203 3204 Input Parameters: 3205 + mat - the matrix 3206 . perm - row and column permutations 3207 - f - expected fill as ratio of original fill 3208 3209 Notes: 3210 See MatLUFactor() for the nonsymmetric case. See also 3211 MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric(). 3212 3213 Most users should employ the simplified KSP interface for linear solvers 3214 instead of working directly with matrix algebra routines such as this. 3215 See, e.g., KSPCreate(). 3216 3217 Level: developer 3218 3219 .seealso: `MatLUFactor()`, `MatCholeskyFactorSymbolic()`, `MatCholeskyFactorNumeric()` 3220 `MatGetOrdering()` 3221 3222 Developer Note: fortran interface is not autogenerated as the f90 3223 interface definition cannot be generated correctly [due to MatFactorInfo] 3224 3225 @*/ 3226 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info) 3227 { 3228 MatFactorInfo tinfo; 3229 3230 PetscFunctionBegin; 3231 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3232 PetscValidType(mat,1); 3233 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2); 3234 if (info) PetscValidPointer(info,3); 3235 PetscCheck(mat->rmap->N == mat->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square"); 3236 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3237 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3238 PetscCheck(mat->ops->choleskyfactor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"In-place factorization for Mat type %s is not supported, try out-of-place factorization. See MatCholeskyFactorSymbolic/Numeric",((PetscObject)mat)->type_name); 3239 MatCheckPreallocated(mat,1); 3240 if (!info) { 3241 PetscCall(MatFactorInfoInitialize(&tinfo)); 3242 info = &tinfo; 3243 } 3244 3245 PetscCall(PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0)); 3246 PetscCall((*mat->ops->choleskyfactor)(mat,perm,info)); 3247 PetscCall(PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0)); 3248 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 3249 PetscFunctionReturn(0); 3250 } 3251 3252 /*@C 3253 MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization 3254 of a symmetric matrix. 3255 3256 Collective on Mat 3257 3258 Input Parameters: 3259 + fact - the factor matrix obtained with MatGetFactor() 3260 . mat - the matrix 3261 . perm - row and column permutations 3262 - info - options for factorization, includes 3263 $ fill - expected fill as ratio of original fill. 3264 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3265 $ Run with the option -info to determine an optimal value to use 3266 3267 Notes: 3268 See MatLUFactorSymbolic() for the nonsymmetric case. See also 3269 MatCholeskyFactor() and MatCholeskyFactorNumeric(). 3270 3271 Most users should employ the simplified KSP interface for linear solvers 3272 instead of working directly with matrix algebra routines such as this. 3273 See, e.g., KSPCreate(). 3274 3275 Level: developer 3276 3277 .seealso: `MatLUFactorSymbolic()`, `MatCholeskyFactor()`, `MatCholeskyFactorNumeric()` 3278 `MatGetOrdering()` 3279 3280 Developer Note: fortran interface is not autogenerated as the f90 3281 interface definition cannot be generated correctly [due to MatFactorInfo] 3282 3283 @*/ 3284 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 3285 { 3286 MatFactorInfo tinfo; 3287 3288 PetscFunctionBegin; 3289 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3290 PetscValidType(mat,2); 3291 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,3); 3292 if (info) PetscValidPointer(info,4); 3293 PetscValidPointer(fact,1); 3294 PetscCheck(mat->rmap->N == mat->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square"); 3295 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3296 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3297 if (!(fact)->ops->choleskyfactorsymbolic) { 3298 MatSolverType stype; 3299 PetscCall(MatFactorGetSolverType(fact,&stype)); 3300 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,stype); 3301 } 3302 MatCheckPreallocated(mat,2); 3303 if (!info) { 3304 PetscCall(MatFactorInfoInitialize(&tinfo)); 3305 info = &tinfo; 3306 } 3307 3308 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0)); 3309 PetscCall((fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info)); 3310 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0)); 3311 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3312 PetscFunctionReturn(0); 3313 } 3314 3315 /*@C 3316 MatCholeskyFactorNumeric - Performs numeric Cholesky factorization 3317 of a symmetric matrix. Call this routine after first calling 3318 MatCholeskyFactorSymbolic(). 3319 3320 Collective on Mat 3321 3322 Input Parameters: 3323 + fact - the factor matrix obtained with MatGetFactor() 3324 . mat - the initial matrix 3325 . info - options for factorization 3326 - fact - the symbolic factor of mat 3327 3328 Notes: 3329 Most users should employ the simplified KSP interface for linear solvers 3330 instead of working directly with matrix algebra routines such as this. 3331 See, e.g., KSPCreate(). 3332 3333 Level: developer 3334 3335 .seealso: `MatCholeskyFactorSymbolic()`, `MatCholeskyFactor()`, `MatLUFactorNumeric()` 3336 3337 Developer Note: fortran interface is not autogenerated as the f90 3338 interface definition cannot be generated correctly [due to MatFactorInfo] 3339 3340 @*/ 3341 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3342 { 3343 MatFactorInfo tinfo; 3344 3345 PetscFunctionBegin; 3346 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3347 PetscValidType(mat,2); 3348 PetscValidPointer(fact,1); 3349 PetscValidHeaderSpecific(fact,MAT_CLASSID,1); 3350 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3351 PetscCheck((fact)->ops->choleskyfactornumeric,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name); 3352 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,mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N); 3353 MatCheckPreallocated(mat,2); 3354 if (!info) { 3355 PetscCall(MatFactorInfoInitialize(&tinfo)); 3356 info = &tinfo; 3357 } 3358 3359 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0)); 3360 else PetscCall(PetscLogEventBegin(MAT_CholeskyFactor,mat,fact,0,0)); 3361 PetscCall((fact->ops->choleskyfactornumeric)(fact,mat,info)); 3362 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0)); 3363 else PetscCall(PetscLogEventEnd(MAT_CholeskyFactor,mat,fact,0,0)); 3364 PetscCall(MatViewFromOptions(fact,NULL,"-mat_factor_view")); 3365 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3366 PetscFunctionReturn(0); 3367 } 3368 3369 /*@ 3370 MatQRFactor - Performs in-place QR factorization of matrix. 3371 3372 Collective on Mat 3373 3374 Input Parameters: 3375 + mat - the matrix 3376 . col - column permutation 3377 - info - options for factorization, includes 3378 $ fill - expected fill as ratio of original fill. 3379 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3380 $ Run with the option -info to determine an optimal value to use 3381 3382 Notes: 3383 Most users should employ the simplified KSP interface for linear solvers 3384 instead of working directly with matrix algebra routines such as this. 3385 See, e.g., KSPCreate(). 3386 3387 This changes the state of the matrix to a factored matrix; it cannot be used 3388 for example with MatSetValues() unless one first calls MatSetUnfactored(). 3389 3390 Level: developer 3391 3392 .seealso: `MatQRFactorSymbolic()`, `MatQRFactorNumeric()`, `MatLUFactor()`, 3393 `MatSetUnfactored()`, `MatFactorInfo`, `MatGetFactor()` 3394 3395 Developer Note: fortran interface is not autogenerated as the f90 3396 interface definition cannot be generated correctly [due to MatFactorInfo] 3397 3398 @*/ 3399 PetscErrorCode MatQRFactor(Mat mat, IS col, const MatFactorInfo *info) 3400 { 3401 PetscFunctionBegin; 3402 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3403 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,2); 3404 if (info) PetscValidPointer(info,3); 3405 PetscValidType(mat,1); 3406 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3407 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3408 MatCheckPreallocated(mat,1); 3409 PetscCall(PetscLogEventBegin(MAT_QRFactor,mat,col,0,0)); 3410 PetscUseMethod(mat,"MatQRFactor_C", (Mat,IS,const MatFactorInfo*), (mat, col, info)); 3411 PetscCall(PetscLogEventEnd(MAT_QRFactor,mat,col,0,0)); 3412 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 3413 PetscFunctionReturn(0); 3414 } 3415 3416 /*@ 3417 MatQRFactorSymbolic - Performs symbolic QR factorization of matrix. 3418 Call this routine before calling MatQRFactorNumeric(). 3419 3420 Collective on Mat 3421 3422 Input Parameters: 3423 + fact - the factor matrix obtained with MatGetFactor() 3424 . mat - the matrix 3425 . col - column permutation 3426 - info - options for factorization, includes 3427 $ fill - expected fill as ratio of original fill. 3428 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3429 $ Run with the option -info to determine an optimal value to use 3430 3431 Most users should employ the simplified KSP interface for linear solvers 3432 instead of working directly with matrix algebra routines such as this. 3433 See, e.g., KSPCreate(). 3434 3435 Level: developer 3436 3437 .seealso: `MatQRFactor()`, `MatQRFactorNumeric()`, `MatLUFactor()`, `MatFactorInfo`, `MatFactorInfoInitialize()` 3438 3439 Developer Note: fortran interface is not autogenerated as the f90 3440 interface definition cannot be generated correctly [due to MatFactorInfo] 3441 3442 @*/ 3443 PetscErrorCode MatQRFactorSymbolic(Mat fact,Mat mat,IS col,const MatFactorInfo *info) 3444 { 3445 MatFactorInfo tinfo; 3446 3447 PetscFunctionBegin; 3448 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3449 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 3450 if (info) PetscValidPointer(info,4); 3451 PetscValidType(mat,2); 3452 PetscValidPointer(fact,1); 3453 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3454 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3455 MatCheckPreallocated(mat,2); 3456 if (!info) { 3457 PetscCall(MatFactorInfoInitialize(&tinfo)); 3458 info = &tinfo; 3459 } 3460 3461 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_QRFactorSymbolic,fact,mat,col,0)); 3462 PetscUseMethod(fact,"MatQRFactorSymbolic_C", (Mat,Mat,IS,const MatFactorInfo*), (fact, mat, col, info)); 3463 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_QRFactorSymbolic,fact,mat,col,0)); 3464 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3465 PetscFunctionReturn(0); 3466 } 3467 3468 /*@ 3469 MatQRFactorNumeric - Performs numeric QR factorization of a matrix. 3470 Call this routine after first calling MatQRFactorSymbolic(). 3471 3472 Collective on Mat 3473 3474 Input Parameters: 3475 + fact - the factor matrix obtained with MatGetFactor() 3476 . mat - the matrix 3477 - info - options for factorization 3478 3479 Notes: 3480 See MatQRFactor() for in-place factorization. 3481 3482 Most users should employ the simplified KSP interface for linear solvers 3483 instead of working directly with matrix algebra routines such as this. 3484 See, e.g., KSPCreate(). 3485 3486 Level: developer 3487 3488 .seealso: `MatQRFactorSymbolic()`, `MatLUFactor()` 3489 3490 Developer Note: fortran interface is not autogenerated as the f90 3491 interface definition cannot be generated correctly [due to MatFactorInfo] 3492 3493 @*/ 3494 PetscErrorCode MatQRFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3495 { 3496 MatFactorInfo tinfo; 3497 3498 PetscFunctionBegin; 3499 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3500 PetscValidType(mat,2); 3501 PetscValidPointer(fact,1); 3502 PetscValidHeaderSpecific(fact,MAT_CLASSID,1); 3503 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3504 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,mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N); 3505 3506 MatCheckPreallocated(mat,2); 3507 if (!info) { 3508 PetscCall(MatFactorInfoInitialize(&tinfo)); 3509 info = &tinfo; 3510 } 3511 3512 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_QRFactorNumeric,mat,fact,0,0)); 3513 else PetscCall(PetscLogEventBegin(MAT_QRFactor,mat,fact,0,0)); 3514 PetscUseMethod(fact,"MatQRFactorNumeric_C", (Mat,Mat,const MatFactorInfo*), (fact, mat, info)); 3515 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_QRFactorNumeric,mat,fact,0,0)); 3516 else PetscCall(PetscLogEventEnd(MAT_QRFactor,mat,fact,0,0)); 3517 PetscCall(MatViewFromOptions(fact,NULL,"-mat_factor_view")); 3518 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3519 PetscFunctionReturn(0); 3520 } 3521 3522 /* ----------------------------------------------------------------*/ 3523 /*@ 3524 MatSolve - Solves A x = b, given a factored matrix. 3525 3526 Neighbor-wise Collective on Mat 3527 3528 Input Parameters: 3529 + mat - the factored matrix 3530 - b - the right-hand-side vector 3531 3532 Output Parameter: 3533 . x - the result vector 3534 3535 Notes: 3536 The vectors b and x cannot be the same. I.e., one cannot 3537 call MatSolve(A,x,x). 3538 3539 Notes: 3540 Most users should employ the simplified KSP interface for linear solvers 3541 instead of working directly with matrix algebra routines such as this. 3542 See, e.g., KSPCreate(). 3543 3544 Level: developer 3545 3546 .seealso: `MatSolveAdd()`, `MatSolveTranspose()`, `MatSolveTransposeAdd()` 3547 @*/ 3548 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x) 3549 { 3550 PetscFunctionBegin; 3551 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3552 PetscValidType(mat,1); 3553 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3554 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3555 PetscCheckSameComm(mat,1,b,2); 3556 PetscCheckSameComm(mat,1,x,3); 3557 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3558 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); 3559 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); 3560 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); 3561 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3562 MatCheckPreallocated(mat,1); 3563 3564 PetscCall(PetscLogEventBegin(MAT_Solve,mat,b,x,0)); 3565 if (mat->factorerrortype) { 3566 PetscCall(PetscInfo(mat,"MatFactorError %d\n",mat->factorerrortype)); 3567 PetscCall(VecSetInf(x)); 3568 } else { 3569 PetscCheck(mat->ops->solve,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3570 PetscCall((*mat->ops->solve)(mat,b,x)); 3571 } 3572 PetscCall(PetscLogEventEnd(MAT_Solve,mat,b,x,0)); 3573 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3574 PetscFunctionReturn(0); 3575 } 3576 3577 static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X,PetscBool trans) 3578 { 3579 Vec b,x; 3580 PetscInt N,i; 3581 PetscErrorCode (*f)(Mat,Vec,Vec); 3582 PetscBool Abound,Bneedconv = PETSC_FALSE,Xneedconv = PETSC_FALSE; 3583 3584 PetscFunctionBegin; 3585 if (A->factorerrortype) { 3586 PetscCall(PetscInfo(A,"MatFactorError %d\n",A->factorerrortype)); 3587 PetscCall(MatSetInf(X)); 3588 PetscFunctionReturn(0); 3589 } 3590 f = (!trans || (!A->ops->solvetranspose && A->symmetric)) ? A->ops->solve : A->ops->solvetranspose; 3591 PetscCheck(f,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 3592 PetscCall(MatBoundToCPU(A,&Abound)); 3593 if (!Abound) { 3594 PetscCall(PetscObjectTypeCompareAny((PetscObject)B,&Bneedconv,MATSEQDENSE,MATMPIDENSE,"")); 3595 PetscCall(PetscObjectTypeCompareAny((PetscObject)X,&Xneedconv,MATSEQDENSE,MATMPIDENSE,"")); 3596 } 3597 if (Bneedconv) { 3598 PetscCall(MatConvert(B,MATDENSECUDA,MAT_INPLACE_MATRIX,&B)); 3599 } 3600 if (Xneedconv) { 3601 PetscCall(MatConvert(X,MATDENSECUDA,MAT_INPLACE_MATRIX,&X)); 3602 } 3603 PetscCall(MatGetSize(B,NULL,&N)); 3604 for (i=0; i<N; i++) { 3605 PetscCall(MatDenseGetColumnVecRead(B,i,&b)); 3606 PetscCall(MatDenseGetColumnVecWrite(X,i,&x)); 3607 PetscCall((*f)(A,b,x)); 3608 PetscCall(MatDenseRestoreColumnVecWrite(X,i,&x)); 3609 PetscCall(MatDenseRestoreColumnVecRead(B,i,&b)); 3610 } 3611 if (Bneedconv) { 3612 PetscCall(MatConvert(B,MATDENSE,MAT_INPLACE_MATRIX,&B)); 3613 } 3614 if (Xneedconv) { 3615 PetscCall(MatConvert(X,MATDENSE,MAT_INPLACE_MATRIX,&X)); 3616 } 3617 PetscFunctionReturn(0); 3618 } 3619 3620 /*@ 3621 MatMatSolve - Solves A X = B, given a factored matrix. 3622 3623 Neighbor-wise Collective on Mat 3624 3625 Input Parameters: 3626 + A - the factored matrix 3627 - B - the right-hand-side matrix MATDENSE (or sparse -- when using MUMPS) 3628 3629 Output Parameter: 3630 . X - the result matrix (dense matrix) 3631 3632 Notes: 3633 If B is a MATDENSE matrix then one can call MatMatSolve(A,B,B) except with MKL_CPARDISO; 3634 otherwise, B and X cannot be the same. 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 Level: developer 3643 3644 .seealso: `MatMatSolveTranspose()`, `MatLUFactor()`, `MatCholeskyFactor()` 3645 @*/ 3646 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X) 3647 { 3648 PetscFunctionBegin; 3649 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3650 PetscValidType(A,1); 3651 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3652 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3653 PetscCheckSameComm(A,1,B,2); 3654 PetscCheckSameComm(A,1,X,3); 3655 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); 3656 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); 3657 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"); 3658 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3659 PetscCheck(A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3660 MatCheckPreallocated(A,1); 3661 3662 PetscCall(PetscLogEventBegin(MAT_MatSolve,A,B,X,0)); 3663 if (!A->ops->matsolve) { 3664 PetscCall(PetscInfo(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name)); 3665 PetscCall(MatMatSolve_Basic(A,B,X,PETSC_FALSE)); 3666 } else { 3667 PetscCall((*A->ops->matsolve)(A,B,X)); 3668 } 3669 PetscCall(PetscLogEventEnd(MAT_MatSolve,A,B,X,0)); 3670 PetscCall(PetscObjectStateIncrease((PetscObject)X)); 3671 PetscFunctionReturn(0); 3672 } 3673 3674 /*@ 3675 MatMatSolveTranspose - Solves A^T X = B, given a factored matrix. 3676 3677 Neighbor-wise Collective on Mat 3678 3679 Input Parameters: 3680 + A - the factored matrix 3681 - B - the right-hand-side matrix (dense matrix) 3682 3683 Output Parameter: 3684 . X - the result matrix (dense matrix) 3685 3686 Notes: 3687 The matrices B and X cannot be the same. I.e., one cannot 3688 call MatMatSolveTranspose(A,X,X). 3689 3690 Notes: 3691 Most users should usually employ the simplified KSP interface for linear solvers 3692 instead of working directly with matrix algebra routines such as this. 3693 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3694 at a time. 3695 3696 When using SuperLU_Dist or MUMPS as a parallel solver, PETSc will use their functionality to solve multiple right hand sides simultaneously. 3697 3698 Level: developer 3699 3700 .seealso: `MatMatSolve()`, `MatLUFactor()`, `MatCholeskyFactor()` 3701 @*/ 3702 PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X) 3703 { 3704 PetscFunctionBegin; 3705 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3706 PetscValidType(A,1); 3707 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3708 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3709 PetscCheckSameComm(A,1,B,2); 3710 PetscCheckSameComm(A,1,X,3); 3711 PetscCheck(X != B,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3712 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); 3713 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); 3714 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); 3715 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"); 3716 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3717 PetscCheck(A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3718 MatCheckPreallocated(A,1); 3719 3720 PetscCall(PetscLogEventBegin(MAT_MatSolve,A,B,X,0)); 3721 if (!A->ops->matsolvetranspose) { 3722 PetscCall(PetscInfo(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name)); 3723 PetscCall(MatMatSolve_Basic(A,B,X,PETSC_TRUE)); 3724 } else { 3725 PetscCall((*A->ops->matsolvetranspose)(A,B,X)); 3726 } 3727 PetscCall(PetscLogEventEnd(MAT_MatSolve,A,B,X,0)); 3728 PetscCall(PetscObjectStateIncrease((PetscObject)X)); 3729 PetscFunctionReturn(0); 3730 } 3731 3732 /*@ 3733 MatMatTransposeSolve - Solves A X = B^T, given a factored matrix. 3734 3735 Neighbor-wise Collective on Mat 3736 3737 Input Parameters: 3738 + A - the factored matrix 3739 - Bt - the transpose of right-hand-side matrix 3740 3741 Output Parameter: 3742 . X - the result matrix (dense matrix) 3743 3744 Notes: 3745 Most users should usually employ the simplified KSP interface for linear solvers 3746 instead of working directly with matrix algebra routines such as this. 3747 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3748 at a time. 3749 3750 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(). 3751 3752 Level: developer 3753 3754 .seealso: `MatMatSolve()`, `MatMatSolveTranspose()`, `MatLUFactor()`, `MatCholeskyFactor()` 3755 @*/ 3756 PetscErrorCode MatMatTransposeSolve(Mat A,Mat Bt,Mat X) 3757 { 3758 PetscFunctionBegin; 3759 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3760 PetscValidType(A,1); 3761 PetscValidHeaderSpecific(Bt,MAT_CLASSID,2); 3762 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3763 PetscCheckSameComm(A,1,Bt,2); 3764 PetscCheckSameComm(A,1,X,3); 3765 3766 PetscCheck(X != Bt,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3767 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); 3768 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); 3769 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"); 3770 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3771 PetscCheck(A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3772 MatCheckPreallocated(A,1); 3773 3774 PetscCheck(A->ops->mattransposesolve,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 3775 PetscCall(PetscLogEventBegin(MAT_MatTrSolve,A,Bt,X,0)); 3776 PetscCall((*A->ops->mattransposesolve)(A,Bt,X)); 3777 PetscCall(PetscLogEventEnd(MAT_MatTrSolve,A,Bt,X,0)); 3778 PetscCall(PetscObjectStateIncrease((PetscObject)X)); 3779 PetscFunctionReturn(0); 3780 } 3781 3782 /*@ 3783 MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or 3784 U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U, 3785 3786 Neighbor-wise Collective on Mat 3787 3788 Input Parameters: 3789 + mat - the factored matrix 3790 - b - the right-hand-side vector 3791 3792 Output Parameter: 3793 . x - the result vector 3794 3795 Notes: 3796 MatSolve() should be used for most applications, as it performs 3797 a forward solve followed by a backward solve. 3798 3799 The vectors b and x cannot be the same, i.e., one cannot 3800 call MatForwardSolve(A,x,x). 3801 3802 For matrix in seqsbaij format with block size larger than 1, 3803 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3804 MatForwardSolve() solves U^T*D y = b, and 3805 MatBackwardSolve() solves U x = y. 3806 Thus they do not provide a symmetric preconditioner. 3807 3808 Most users should employ the simplified KSP interface for linear solvers 3809 instead of working directly with matrix algebra routines such as this. 3810 See, e.g., KSPCreate(). 3811 3812 Level: developer 3813 3814 .seealso: `MatSolve()`, `MatBackwardSolve()` 3815 @*/ 3816 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x) 3817 { 3818 PetscFunctionBegin; 3819 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3820 PetscValidType(mat,1); 3821 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3822 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3823 PetscCheckSameComm(mat,1,b,2); 3824 PetscCheckSameComm(mat,1,x,3); 3825 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3826 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); 3827 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); 3828 PetscCheck(mat->rmap->n == b->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,b->map->n); 3829 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3830 MatCheckPreallocated(mat,1); 3831 3832 PetscCheck(mat->ops->forwardsolve,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3833 PetscCall(PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0)); 3834 PetscCall((*mat->ops->forwardsolve)(mat,b,x)); 3835 PetscCall(PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0)); 3836 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3837 PetscFunctionReturn(0); 3838 } 3839 3840 /*@ 3841 MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU. 3842 D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U, 3843 3844 Neighbor-wise Collective on Mat 3845 3846 Input Parameters: 3847 + mat - the factored matrix 3848 - b - the right-hand-side vector 3849 3850 Output Parameter: 3851 . x - the result vector 3852 3853 Notes: 3854 MatSolve() should be used for most applications, as it performs 3855 a forward solve followed by a backward solve. 3856 3857 The vectors b and x cannot be the same. I.e., one cannot 3858 call MatBackwardSolve(A,x,x). 3859 3860 For matrix in seqsbaij format with block size larger than 1, 3861 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3862 MatForwardSolve() solves U^T*D y = b, and 3863 MatBackwardSolve() solves U x = y. 3864 Thus they do not provide a symmetric preconditioner. 3865 3866 Most users should employ the simplified KSP interface for linear solvers 3867 instead of working directly with matrix algebra routines such as this. 3868 See, e.g., KSPCreate(). 3869 3870 Level: developer 3871 3872 .seealso: `MatSolve()`, `MatForwardSolve()` 3873 @*/ 3874 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x) 3875 { 3876 PetscFunctionBegin; 3877 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3878 PetscValidType(mat,1); 3879 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3880 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3881 PetscCheckSameComm(mat,1,b,2); 3882 PetscCheckSameComm(mat,1,x,3); 3883 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3884 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); 3885 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); 3886 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); 3887 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3888 MatCheckPreallocated(mat,1); 3889 3890 PetscCheck(mat->ops->backwardsolve,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3891 PetscCall(PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0)); 3892 PetscCall((*mat->ops->backwardsolve)(mat,b,x)); 3893 PetscCall(PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0)); 3894 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3895 PetscFunctionReturn(0); 3896 } 3897 3898 /*@ 3899 MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix. 3900 3901 Neighbor-wise Collective on Mat 3902 3903 Input Parameters: 3904 + mat - the factored matrix 3905 . b - the right-hand-side vector 3906 - y - the vector to be added to 3907 3908 Output Parameter: 3909 . x - the result vector 3910 3911 Notes: 3912 The vectors b and x cannot be the same. I.e., one cannot 3913 call MatSolveAdd(A,x,y,x). 3914 3915 Most users should employ the simplified KSP interface for linear solvers 3916 instead of working directly with matrix algebra routines such as this. 3917 See, e.g., KSPCreate(). 3918 3919 Level: developer 3920 3921 .seealso: `MatSolve()`, `MatSolveTranspose()`, `MatSolveTransposeAdd()` 3922 @*/ 3923 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x) 3924 { 3925 PetscScalar one = 1.0; 3926 Vec tmp; 3927 3928 PetscFunctionBegin; 3929 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3930 PetscValidType(mat,1); 3931 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 3932 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3933 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 3934 PetscCheckSameComm(mat,1,b,2); 3935 PetscCheckSameComm(mat,1,y,3); 3936 PetscCheckSameComm(mat,1,x,4); 3937 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3938 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); 3939 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); 3940 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); 3941 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); 3942 PetscCheck(x->map->n == y->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %" PetscInt_FMT " %" PetscInt_FMT,x->map->n,y->map->n); 3943 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3944 MatCheckPreallocated(mat,1); 3945 3946 PetscCall(PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y)); 3947 if (mat->factorerrortype) { 3948 3949 PetscCall(PetscInfo(mat,"MatFactorError %d\n",mat->factorerrortype)); 3950 PetscCall(VecSetInf(x)); 3951 } else if (mat->ops->solveadd) { 3952 PetscCall((*mat->ops->solveadd)(mat,b,y,x)); 3953 } else { 3954 /* do the solve then the add manually */ 3955 if (x != y) { 3956 PetscCall(MatSolve(mat,b,x)); 3957 PetscCall(VecAXPY(x,one,y)); 3958 } else { 3959 PetscCall(VecDuplicate(x,&tmp)); 3960 PetscCall(PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp)); 3961 PetscCall(VecCopy(x,tmp)); 3962 PetscCall(MatSolve(mat,b,x)); 3963 PetscCall(VecAXPY(x,one,tmp)); 3964 PetscCall(VecDestroy(&tmp)); 3965 } 3966 } 3967 PetscCall(PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y)); 3968 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3969 PetscFunctionReturn(0); 3970 } 3971 3972 /*@ 3973 MatSolveTranspose - Solves A' x = b, given a factored matrix. 3974 3975 Neighbor-wise Collective on Mat 3976 3977 Input Parameters: 3978 + mat - the factored matrix 3979 - b - the right-hand-side vector 3980 3981 Output Parameter: 3982 . x - the result vector 3983 3984 Notes: 3985 The vectors b and x cannot be the same. I.e., one cannot 3986 call MatSolveTranspose(A,x,x). 3987 3988 Most users should employ the simplified KSP interface for linear solvers 3989 instead of working directly with matrix algebra routines such as this. 3990 See, e.g., KSPCreate(). 3991 3992 Level: developer 3993 3994 .seealso: `MatSolve()`, `MatSolveAdd()`, `MatSolveTransposeAdd()` 3995 @*/ 3996 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x) 3997 { 3998 PetscErrorCode (*f)(Mat,Vec,Vec) = (!mat->ops->solvetranspose && mat->symmetric) ? mat->ops->solve : mat->ops->solvetranspose; 3999 4000 PetscFunctionBegin; 4001 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4002 PetscValidType(mat,1); 4003 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 4004 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 4005 PetscCheckSameComm(mat,1,b,2); 4006 PetscCheckSameComm(mat,1,x,3); 4007 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 4008 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); 4009 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); 4010 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 4011 MatCheckPreallocated(mat,1); 4012 PetscCall(PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0)); 4013 if (mat->factorerrortype) { 4014 PetscCall(PetscInfo(mat,"MatFactorError %d\n",mat->factorerrortype)); 4015 PetscCall(VecSetInf(x)); 4016 } else { 4017 PetscCheck(f,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name); 4018 PetscCall((*f)(mat,b,x)); 4019 } 4020 PetscCall(PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0)); 4021 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 4022 PetscFunctionReturn(0); 4023 } 4024 4025 /*@ 4026 MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a 4027 factored matrix. 4028 4029 Neighbor-wise Collective on Mat 4030 4031 Input Parameters: 4032 + mat - the factored matrix 4033 . b - the right-hand-side vector 4034 - y - the vector to be added to 4035 4036 Output Parameter: 4037 . x - the result vector 4038 4039 Notes: 4040 The vectors b and x cannot be the same. I.e., one cannot 4041 call MatSolveTransposeAdd(A,x,y,x). 4042 4043 Most users should employ the simplified KSP interface for linear solvers 4044 instead of working directly with matrix algebra routines such as this. 4045 See, e.g., KSPCreate(). 4046 4047 Level: developer 4048 4049 .seealso: `MatSolve()`, `MatSolveAdd()`, `MatSolveTranspose()` 4050 @*/ 4051 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x) 4052 { 4053 PetscScalar one = 1.0; 4054 Vec tmp; 4055 PetscErrorCode (*f)(Mat,Vec,Vec,Vec) = (!mat->ops->solvetransposeadd && mat->symmetric) ? mat->ops->solveadd : mat->ops->solvetransposeadd; 4056 4057 PetscFunctionBegin; 4058 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4059 PetscValidType(mat,1); 4060 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 4061 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 4062 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 4063 PetscCheckSameComm(mat,1,b,2); 4064 PetscCheckSameComm(mat,1,y,3); 4065 PetscCheckSameComm(mat,1,x,4); 4066 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 4067 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); 4068 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); 4069 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); 4070 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); 4071 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 4072 MatCheckPreallocated(mat,1); 4073 4074 PetscCall(PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y)); 4075 if (mat->factorerrortype) { 4076 PetscCall(PetscInfo(mat,"MatFactorError %d\n",mat->factorerrortype)); 4077 PetscCall(VecSetInf(x)); 4078 } else if (f) { 4079 PetscCall((*f)(mat,b,y,x)); 4080 } else { 4081 /* do the solve then the add manually */ 4082 if (x != y) { 4083 PetscCall(MatSolveTranspose(mat,b,x)); 4084 PetscCall(VecAXPY(x,one,y)); 4085 } else { 4086 PetscCall(VecDuplicate(x,&tmp)); 4087 PetscCall(PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp)); 4088 PetscCall(VecCopy(x,tmp)); 4089 PetscCall(MatSolveTranspose(mat,b,x)); 4090 PetscCall(VecAXPY(x,one,tmp)); 4091 PetscCall(VecDestroy(&tmp)); 4092 } 4093 } 4094 PetscCall(PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y)); 4095 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 4096 PetscFunctionReturn(0); 4097 } 4098 /* ----------------------------------------------------------------*/ 4099 4100 /*@ 4101 MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps. 4102 4103 Neighbor-wise Collective on Mat 4104 4105 Input Parameters: 4106 + mat - the matrix 4107 . b - the right hand side 4108 . omega - the relaxation factor 4109 . flag - flag indicating the type of SOR (see below) 4110 . shift - diagonal shift 4111 . its - the number of iterations 4112 - lits - the number of local iterations 4113 4114 Output Parameter: 4115 . x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess) 4116 4117 SOR Flags: 4118 + SOR_FORWARD_SWEEP - forward SOR 4119 . SOR_BACKWARD_SWEEP - backward SOR 4120 . SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR) 4121 . SOR_LOCAL_FORWARD_SWEEP - local forward SOR 4122 . SOR_LOCAL_BACKWARD_SWEEP - local forward SOR 4123 . SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR 4124 . SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies 4125 upper/lower triangular part of matrix to 4126 vector (with omega) 4127 - SOR_ZERO_INITIAL_GUESS - zero initial guess 4128 4129 Notes: 4130 SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and 4131 SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings 4132 on each processor. 4133 4134 Application programmers will not generally use MatSOR() directly, 4135 but instead will employ the KSP/PC interface. 4136 4137 Notes: 4138 for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing 4139 4140 Notes for Advanced Users: 4141 The flags are implemented as bitwise inclusive or operations. 4142 For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP) 4143 to specify a zero initial guess for SSOR. 4144 4145 Most users should employ the simplified KSP interface for linear solvers 4146 instead of working directly with matrix algebra routines such as this. 4147 See, e.g., KSPCreate(). 4148 4149 Vectors x and b CANNOT be the same 4150 4151 Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes 4152 4153 Level: developer 4154 4155 @*/ 4156 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x) 4157 { 4158 PetscFunctionBegin; 4159 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4160 PetscValidType(mat,1); 4161 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 4162 PetscValidHeaderSpecific(x,VEC_CLASSID,8); 4163 PetscCheckSameComm(mat,1,b,2); 4164 PetscCheckSameComm(mat,1,x,8); 4165 PetscCheck(mat->ops->sor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4166 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4167 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4168 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); 4169 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); 4170 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); 4171 PetscCheck(its > 0,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %" PetscInt_FMT " positive",its); 4172 PetscCheck(lits > 0,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %" PetscInt_FMT " positive",lits); 4173 PetscCheck(b != x,PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same"); 4174 4175 MatCheckPreallocated(mat,1); 4176 PetscCall(PetscLogEventBegin(MAT_SOR,mat,b,x,0)); 4177 PetscCall((*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x)); 4178 PetscCall(PetscLogEventEnd(MAT_SOR,mat,b,x,0)); 4179 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 4180 PetscFunctionReturn(0); 4181 } 4182 4183 /* 4184 Default matrix copy routine. 4185 */ 4186 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str) 4187 { 4188 PetscInt i,rstart = 0,rend = 0,nz; 4189 const PetscInt *cwork; 4190 const PetscScalar *vwork; 4191 4192 PetscFunctionBegin; 4193 if (B->assembled) PetscCall(MatZeroEntries(B)); 4194 if (str == SAME_NONZERO_PATTERN) { 4195 PetscCall(MatGetOwnershipRange(A,&rstart,&rend)); 4196 for (i=rstart; i<rend; i++) { 4197 PetscCall(MatGetRow(A,i,&nz,&cwork,&vwork)); 4198 PetscCall(MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES)); 4199 PetscCall(MatRestoreRow(A,i,&nz,&cwork,&vwork)); 4200 } 4201 } else { 4202 PetscCall(MatAYPX(B,0.0,A,str)); 4203 } 4204 PetscCall(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY)); 4205 PetscCall(MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY)); 4206 PetscFunctionReturn(0); 4207 } 4208 4209 /*@ 4210 MatCopy - Copies a matrix to another matrix. 4211 4212 Collective on Mat 4213 4214 Input Parameters: 4215 + A - the matrix 4216 - str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN 4217 4218 Output Parameter: 4219 . B - where the copy is put 4220 4221 Notes: 4222 If you use SAME_NONZERO_PATTERN then the two matrices must have the same nonzero pattern or the routine will crash. 4223 4224 MatCopy() copies the matrix entries of a matrix to another existing 4225 matrix (after first zeroing the second matrix). A related routine is 4226 MatConvert(), which first creates a new matrix and then copies the data. 4227 4228 Level: intermediate 4229 4230 .seealso: `MatConvert()`, `MatDuplicate()` 4231 @*/ 4232 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str) 4233 { 4234 PetscInt i; 4235 4236 PetscFunctionBegin; 4237 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4238 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4239 PetscValidType(A,1); 4240 PetscValidType(B,2); 4241 PetscCheckSameComm(A,1,B,2); 4242 MatCheckPreallocated(B,2); 4243 PetscCheck(A->assembled,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4244 PetscCheck(!A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4245 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,B->cmap->N); 4246 MatCheckPreallocated(A,1); 4247 if (A == B) PetscFunctionReturn(0); 4248 4249 PetscCall(PetscLogEventBegin(MAT_Copy,A,B,0,0)); 4250 if (A->ops->copy) { 4251 PetscCall((*A->ops->copy)(A,B,str)); 4252 } else { /* generic conversion */ 4253 PetscCall(MatCopy_Basic(A,B,str)); 4254 } 4255 4256 B->stencil.dim = A->stencil.dim; 4257 B->stencil.noc = A->stencil.noc; 4258 for (i=0; i<=A->stencil.dim; i++) { 4259 B->stencil.dims[i] = A->stencil.dims[i]; 4260 B->stencil.starts[i] = A->stencil.starts[i]; 4261 } 4262 4263 PetscCall(PetscLogEventEnd(MAT_Copy,A,B,0,0)); 4264 PetscCall(PetscObjectStateIncrease((PetscObject)B)); 4265 PetscFunctionReturn(0); 4266 } 4267 4268 /*@C 4269 MatConvert - Converts a matrix to another matrix, either of the same 4270 or different type. 4271 4272 Collective on Mat 4273 4274 Input Parameters: 4275 + mat - the matrix 4276 . newtype - new matrix type. Use MATSAME to create a new matrix of the 4277 same type as the original matrix. 4278 - reuse - denotes if the destination matrix is to be created or reused. 4279 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 4280 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). 4281 4282 Output Parameter: 4283 . M - pointer to place new matrix 4284 4285 Notes: 4286 MatConvert() first creates a new matrix and then copies the data from 4287 the first matrix. A related routine is MatCopy(), which copies the matrix 4288 entries of one matrix to another already existing matrix context. 4289 4290 Cannot be used to convert a sequential matrix to parallel or parallel to sequential, 4291 the MPI communicator of the generated matrix is always the same as the communicator 4292 of the input matrix. 4293 4294 Level: intermediate 4295 4296 .seealso: `MatCopy()`, `MatDuplicate()` 4297 @*/ 4298 PetscErrorCode MatConvert(Mat mat,MatType newtype,MatReuse reuse,Mat *M) 4299 { 4300 PetscBool sametype,issame,flg; 4301 PetscBool3 issymmetric,ishermitian; 4302 char convname[256],mtype[256]; 4303 Mat B; 4304 4305 PetscFunctionBegin; 4306 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4307 PetscValidType(mat,1); 4308 PetscValidPointer(M,4); 4309 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4310 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4311 MatCheckPreallocated(mat,1); 4312 4313 PetscCall(PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,sizeof(mtype),&flg)); 4314 if (flg) newtype = mtype; 4315 4316 PetscCall(PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype)); 4317 PetscCall(PetscStrcmp(newtype,"same",&issame)); 4318 PetscCheck(!(reuse == MAT_INPLACE_MATRIX) || !(mat != *M),PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix"); 4319 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"); 4320 4321 if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) { 4322 PetscCall(PetscInfo(mat,"Early return for inplace %s %d %d\n",((PetscObject)mat)->type_name,sametype,issame)); 4323 PetscFunctionReturn(0); 4324 } 4325 4326 /* Cache Mat options because some converters use MatHeaderReplace */ 4327 issymmetric = mat->symmetric; 4328 ishermitian = mat->hermitian; 4329 4330 if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) { 4331 PetscCall(PetscInfo(mat,"Calling duplicate for initial matrix %s %d %d\n",((PetscObject)mat)->type_name,sametype,issame)); 4332 PetscCall((*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M)); 4333 } else { 4334 PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL; 4335 const char *prefix[3] = {"seq","mpi",""}; 4336 PetscInt i; 4337 /* 4338 Order of precedence: 4339 0) See if newtype is a superclass of the current matrix. 4340 1) See if a specialized converter is known to the current matrix. 4341 2) See if a specialized converter is known to the desired matrix class. 4342 3) See if a good general converter is registered for the desired class 4343 (as of 6/27/03 only MATMPIADJ falls into this category). 4344 4) See if a good general converter is known for the current matrix. 4345 5) Use a really basic converter. 4346 */ 4347 4348 /* 0) See if newtype is a superclass of the current matrix. 4349 i.e mat is mpiaij and newtype is aij */ 4350 for (i=0; i<2; i++) { 4351 PetscCall(PetscStrncpy(convname,prefix[i],sizeof(convname))); 4352 PetscCall(PetscStrlcat(convname,newtype,sizeof(convname))); 4353 PetscCall(PetscStrcmp(convname,((PetscObject)mat)->type_name,&flg)); 4354 PetscCall(PetscInfo(mat,"Check superclass %s %s -> %d\n",convname,((PetscObject)mat)->type_name,flg)); 4355 if (flg) { 4356 if (reuse == MAT_INPLACE_MATRIX) { 4357 PetscCall(PetscInfo(mat,"Early return\n")); 4358 PetscFunctionReturn(0); 4359 } else if (reuse == MAT_INITIAL_MATRIX && mat->ops->duplicate) { 4360 PetscCall(PetscInfo(mat,"Calling MatDuplicate\n")); 4361 PetscCall((*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M)); 4362 PetscFunctionReturn(0); 4363 } else if (reuse == MAT_REUSE_MATRIX && mat->ops->copy) { 4364 PetscCall(PetscInfo(mat,"Calling MatCopy\n")); 4365 PetscCall(MatCopy(mat,*M,SAME_NONZERO_PATTERN)); 4366 PetscFunctionReturn(0); 4367 } 4368 } 4369 } 4370 /* 1) See if a specialized converter is known to the current matrix and the desired class */ 4371 for (i=0; i<3; i++) { 4372 PetscCall(PetscStrncpy(convname,"MatConvert_",sizeof(convname))); 4373 PetscCall(PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname))); 4374 PetscCall(PetscStrlcat(convname,"_",sizeof(convname))); 4375 PetscCall(PetscStrlcat(convname,prefix[i],sizeof(convname))); 4376 PetscCall(PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname))); 4377 PetscCall(PetscStrlcat(convname,"_C",sizeof(convname))); 4378 PetscCall(PetscObjectQueryFunction((PetscObject)mat,convname,&conv)); 4379 PetscCall(PetscInfo(mat,"Check specialized (1) %s (%s) -> %d\n",convname,((PetscObject)mat)->type_name,!!conv)); 4380 if (conv) goto foundconv; 4381 } 4382 4383 /* 2) See if a specialized converter is known to the desired matrix class. */ 4384 PetscCall(MatCreate(PetscObjectComm((PetscObject)mat),&B)); 4385 PetscCall(MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N)); 4386 PetscCall(MatSetType(B,newtype)); 4387 for (i=0; i<3; i++) { 4388 PetscCall(PetscStrncpy(convname,"MatConvert_",sizeof(convname))); 4389 PetscCall(PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname))); 4390 PetscCall(PetscStrlcat(convname,"_",sizeof(convname))); 4391 PetscCall(PetscStrlcat(convname,prefix[i],sizeof(convname))); 4392 PetscCall(PetscStrlcat(convname,newtype,sizeof(convname))); 4393 PetscCall(PetscStrlcat(convname,"_C",sizeof(convname))); 4394 PetscCall(PetscObjectQueryFunction((PetscObject)B,convname,&conv)); 4395 PetscCall(PetscInfo(mat,"Check specialized (2) %s (%s) -> %d\n",convname,((PetscObject)B)->type_name,!!conv)); 4396 if (conv) { 4397 PetscCall(MatDestroy(&B)); 4398 goto foundconv; 4399 } 4400 } 4401 4402 /* 3) See if a good general converter is registered for the desired class */ 4403 conv = B->ops->convertfrom; 4404 PetscCall(PetscInfo(mat,"Check convertfrom (%s) -> %d\n",((PetscObject)B)->type_name,!!conv)); 4405 PetscCall(MatDestroy(&B)); 4406 if (conv) goto foundconv; 4407 4408 /* 4) See if a good general converter is known for the current matrix */ 4409 if (mat->ops->convert) conv = mat->ops->convert; 4410 PetscCall(PetscInfo(mat,"Check general convert (%s) -> %d\n",((PetscObject)mat)->type_name,!!conv)); 4411 if (conv) goto foundconv; 4412 4413 /* 5) Use a really basic converter. */ 4414 PetscCall(PetscInfo(mat,"Using MatConvert_Basic\n")); 4415 conv = MatConvert_Basic; 4416 4417 foundconv: 4418 PetscCall(PetscLogEventBegin(MAT_Convert,mat,0,0,0)); 4419 PetscCall((*conv)(mat,newtype,reuse,M)); 4420 if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) { 4421 /* the block sizes must be same if the mappings are copied over */ 4422 (*M)->rmap->bs = mat->rmap->bs; 4423 (*M)->cmap->bs = mat->cmap->bs; 4424 PetscCall(PetscObjectReference((PetscObject)mat->rmap->mapping)); 4425 PetscCall(PetscObjectReference((PetscObject)mat->cmap->mapping)); 4426 (*M)->rmap->mapping = mat->rmap->mapping; 4427 (*M)->cmap->mapping = mat->cmap->mapping; 4428 } 4429 (*M)->stencil.dim = mat->stencil.dim; 4430 (*M)->stencil.noc = mat->stencil.noc; 4431 for (i=0; i<=mat->stencil.dim; i++) { 4432 (*M)->stencil.dims[i] = mat->stencil.dims[i]; 4433 (*M)->stencil.starts[i] = mat->stencil.starts[i]; 4434 } 4435 PetscCall(PetscLogEventEnd(MAT_Convert,mat,0,0,0)); 4436 } 4437 PetscCall(PetscObjectStateIncrease((PetscObject)*M)); 4438 4439 /* Copy Mat options */ 4440 if (issymmetric == PETSC_BOOL3_TRUE) PetscCall(MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE)); 4441 else if (issymmetric == PETSC_BOOL3_FALSE) PetscCall(MatSetOption(*M,MAT_SYMMETRIC,PETSC_FALSE)); 4442 if (ishermitian == PETSC_BOOL3_TRUE) PetscCall(MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE)); 4443 else if (ishermitian == PETSC_BOOL3_FALSE) PetscCall(MatSetOption(*M,MAT_HERMITIAN,PETSC_FALSE)); 4444 PetscFunctionReturn(0); 4445 } 4446 4447 /*@C 4448 MatFactorGetSolverType - Returns name of the package providing the factorization routines 4449 4450 Not Collective 4451 4452 Input Parameter: 4453 . mat - the matrix, must be a factored matrix 4454 4455 Output Parameter: 4456 . type - the string name of the package (do not free this string) 4457 4458 Notes: 4459 In Fortran you pass in a empty string and the package name will be copied into it. 4460 (Make sure the string is long enough) 4461 4462 Level: intermediate 4463 4464 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()` 4465 @*/ 4466 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type) 4467 { 4468 PetscErrorCode (*conv)(Mat,MatSolverType*); 4469 4470 PetscFunctionBegin; 4471 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4472 PetscValidType(mat,1); 4473 PetscValidPointer(type,2); 4474 PetscCheck(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 4475 PetscCall(PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv)); 4476 if (conv) PetscCall((*conv)(mat,type)); 4477 else *type = MATSOLVERPETSC; 4478 PetscFunctionReturn(0); 4479 } 4480 4481 typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType; 4482 struct _MatSolverTypeForSpecifcType { 4483 MatType mtype; 4484 /* no entry for MAT_FACTOR_NONE */ 4485 PetscErrorCode (*createfactor[MAT_FACTOR_NUM_TYPES-1])(Mat,MatFactorType,Mat*); 4486 MatSolverTypeForSpecifcType next; 4487 }; 4488 4489 typedef struct _MatSolverTypeHolder* MatSolverTypeHolder; 4490 struct _MatSolverTypeHolder { 4491 char *name; 4492 MatSolverTypeForSpecifcType handlers; 4493 MatSolverTypeHolder next; 4494 }; 4495 4496 static MatSolverTypeHolder MatSolverTypeHolders = NULL; 4497 4498 /*@C 4499 MatSolverTypeRegister - Registers a MatSolverType that works for a particular matrix type 4500 4501 Input Parameters: 4502 + package - name of the package, for example petsc or superlu 4503 . mtype - the matrix type that works with this package 4504 . ftype - the type of factorization supported by the package 4505 - createfactor - routine that will create the factored matrix ready to be used 4506 4507 Level: intermediate 4508 4509 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()` 4510 @*/ 4511 PetscErrorCode MatSolverTypeRegister(MatSolverType package,MatType mtype,MatFactorType ftype,PetscErrorCode (*createfactor)(Mat,MatFactorType,Mat*)) 4512 { 4513 MatSolverTypeHolder next = MatSolverTypeHolders,prev = NULL; 4514 PetscBool flg; 4515 MatSolverTypeForSpecifcType inext,iprev = NULL; 4516 4517 PetscFunctionBegin; 4518 PetscCall(MatInitializePackage()); 4519 if (!next) { 4520 PetscCall(PetscNew(&MatSolverTypeHolders)); 4521 PetscCall(PetscStrallocpy(package,&MatSolverTypeHolders->name)); 4522 PetscCall(PetscNew(&MatSolverTypeHolders->handlers)); 4523 PetscCall(PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype)); 4524 MatSolverTypeHolders->handlers->createfactor[(int)ftype-1] = createfactor; 4525 PetscFunctionReturn(0); 4526 } 4527 while (next) { 4528 PetscCall(PetscStrcasecmp(package,next->name,&flg)); 4529 if (flg) { 4530 PetscCheck(next->handlers,PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers"); 4531 inext = next->handlers; 4532 while (inext) { 4533 PetscCall(PetscStrcasecmp(mtype,inext->mtype,&flg)); 4534 if (flg) { 4535 inext->createfactor[(int)ftype-1] = createfactor; 4536 PetscFunctionReturn(0); 4537 } 4538 iprev = inext; 4539 inext = inext->next; 4540 } 4541 PetscCall(PetscNew(&iprev->next)); 4542 PetscCall(PetscStrallocpy(mtype,(char **)&iprev->next->mtype)); 4543 iprev->next->createfactor[(int)ftype-1] = createfactor; 4544 PetscFunctionReturn(0); 4545 } 4546 prev = next; 4547 next = next->next; 4548 } 4549 PetscCall(PetscNew(&prev->next)); 4550 PetscCall(PetscStrallocpy(package,&prev->next->name)); 4551 PetscCall(PetscNew(&prev->next->handlers)); 4552 PetscCall(PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype)); 4553 prev->next->handlers->createfactor[(int)ftype-1] = createfactor; 4554 PetscFunctionReturn(0); 4555 } 4556 4557 /*@C 4558 MatSolverTypeGet - Gets the function that creates the factor matrix if it exist 4559 4560 Input Parameters: 4561 + type - name of the package, for example petsc or superlu 4562 . ftype - the type of factorization supported by the type 4563 - mtype - the matrix type that works with this type 4564 4565 Output Parameters: 4566 + foundtype - PETSC_TRUE if the type was registered 4567 . foundmtype - PETSC_TRUE if the type supports the requested mtype 4568 - createfactor - routine that will create the factored matrix ready to be used or NULL if not found 4569 4570 Level: intermediate 4571 4572 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatSolverTypeRegister()`, `MatGetFactor()` 4573 @*/ 4574 PetscErrorCode MatSolverTypeGet(MatSolverType type,MatType mtype,MatFactorType ftype,PetscBool *foundtype,PetscBool *foundmtype,PetscErrorCode (**createfactor)(Mat,MatFactorType,Mat*)) 4575 { 4576 MatSolverTypeHolder next = MatSolverTypeHolders; 4577 PetscBool flg; 4578 MatSolverTypeForSpecifcType inext; 4579 4580 PetscFunctionBegin; 4581 if (foundtype) *foundtype = PETSC_FALSE; 4582 if (foundmtype) *foundmtype = PETSC_FALSE; 4583 if (createfactor) *createfactor = NULL; 4584 4585 if (type) { 4586 while (next) { 4587 PetscCall(PetscStrcasecmp(type,next->name,&flg)); 4588 if (flg) { 4589 if (foundtype) *foundtype = PETSC_TRUE; 4590 inext = next->handlers; 4591 while (inext) { 4592 PetscCall(PetscStrbeginswith(mtype,inext->mtype,&flg)); 4593 if (flg) { 4594 if (foundmtype) *foundmtype = PETSC_TRUE; 4595 if (createfactor) *createfactor = inext->createfactor[(int)ftype-1]; 4596 PetscFunctionReturn(0); 4597 } 4598 inext = inext->next; 4599 } 4600 } 4601 next = next->next; 4602 } 4603 } else { 4604 while (next) { 4605 inext = next->handlers; 4606 while (inext) { 4607 PetscCall(PetscStrcmp(mtype,inext->mtype,&flg)); 4608 if (flg && inext->createfactor[(int)ftype-1]) { 4609 if (foundtype) *foundtype = PETSC_TRUE; 4610 if (foundmtype) *foundmtype = PETSC_TRUE; 4611 if (createfactor) *createfactor = inext->createfactor[(int)ftype-1]; 4612 PetscFunctionReturn(0); 4613 } 4614 inext = inext->next; 4615 } 4616 next = next->next; 4617 } 4618 /* try with base classes inext->mtype */ 4619 next = MatSolverTypeHolders; 4620 while (next) { 4621 inext = next->handlers; 4622 while (inext) { 4623 PetscCall(PetscStrbeginswith(mtype,inext->mtype,&flg)); 4624 if (flg && inext->createfactor[(int)ftype-1]) { 4625 if (foundtype) *foundtype = PETSC_TRUE; 4626 if (foundmtype) *foundmtype = PETSC_TRUE; 4627 if (createfactor) *createfactor = inext->createfactor[(int)ftype-1]; 4628 PetscFunctionReturn(0); 4629 } 4630 inext = inext->next; 4631 } 4632 next = next->next; 4633 } 4634 } 4635 PetscFunctionReturn(0); 4636 } 4637 4638 PetscErrorCode MatSolverTypeDestroy(void) 4639 { 4640 MatSolverTypeHolder next = MatSolverTypeHolders,prev; 4641 MatSolverTypeForSpecifcType inext,iprev; 4642 4643 PetscFunctionBegin; 4644 while (next) { 4645 PetscCall(PetscFree(next->name)); 4646 inext = next->handlers; 4647 while (inext) { 4648 PetscCall(PetscFree(inext->mtype)); 4649 iprev = inext; 4650 inext = inext->next; 4651 PetscCall(PetscFree(iprev)); 4652 } 4653 prev = next; 4654 next = next->next; 4655 PetscCall(PetscFree(prev)); 4656 } 4657 MatSolverTypeHolders = NULL; 4658 PetscFunctionReturn(0); 4659 } 4660 4661 /*@C 4662 MatFactorGetCanUseOrdering - Indicates if the factorization can use the ordering provided in MatLUFactorSymbolic(), MatCholeskyFactorSymbolic() 4663 4664 Logically Collective on Mat 4665 4666 Input Parameters: 4667 . mat - the matrix 4668 4669 Output Parameters: 4670 . flg - PETSC_TRUE if uses the ordering 4671 4672 Notes: 4673 Most internal PETSc factorizations use the ordering passed to the factorization routine but external 4674 packages do not, thus we want to skip generating the ordering when it is not needed or used. 4675 4676 Level: developer 4677 4678 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()` 4679 @*/ 4680 PetscErrorCode MatFactorGetCanUseOrdering(Mat mat, PetscBool *flg) 4681 { 4682 PetscFunctionBegin; 4683 *flg = mat->canuseordering; 4684 PetscFunctionReturn(0); 4685 } 4686 4687 /*@C 4688 MatFactorGetPreferredOrdering - The preferred ordering for a particular matrix factor object 4689 4690 Logically Collective on Mat 4691 4692 Input Parameters: 4693 . mat - the matrix 4694 4695 Output Parameters: 4696 . otype - the preferred type 4697 4698 Level: developer 4699 4700 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()` 4701 @*/ 4702 PetscErrorCode MatFactorGetPreferredOrdering(Mat mat, MatFactorType ftype, MatOrderingType *otype) 4703 { 4704 PetscFunctionBegin; 4705 *otype = mat->preferredordering[ftype]; 4706 PetscCheck(*otype,PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatFactor did not have a preferred ordering"); 4707 PetscFunctionReturn(0); 4708 } 4709 4710 /*@C 4711 MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic() 4712 4713 Collective on Mat 4714 4715 Input Parameters: 4716 + mat - the matrix 4717 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4718 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4719 4720 Output Parameters: 4721 . f - the factor matrix used with MatXXFactorSymbolic() calls 4722 4723 Options Database Key: 4724 . -mat_factor_bind_factorization <host, device> - Where to do matrix factorization? Default is device (might consume more device memory. 4725 One can choose host to save device memory). Currently only supported with SEQAIJCUSPARSE matrices. 4726 4727 Notes: 4728 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4729 such as pastix, superlu, mumps etc. 4730 4731 PETSc must have been ./configure to use the external solver, using the option --download-package 4732 4733 Some of the packages have options for controlling the factorization, these are in the form -prefix_mat_packagename_packageoption 4734 where prefix is normally obtained from the calling `KSP`/`PC`. If `MatGetFactor()` is called directly one can set 4735 call `MatSetOptionsPrefixFactor()` on the originating matrix or `MatSetOptionsPrefix()` on the resulting factor matrix. 4736 4737 Developer Notes: 4738 This should actually be called MatCreateFactor() since it creates a new factor object 4739 4740 Level: intermediate 4741 4742 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatFactorGetCanUseOrdering()`, `MatSolverTypeRegister()` 4743 @*/ 4744 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f) 4745 { 4746 PetscBool foundtype,foundmtype; 4747 PetscErrorCode (*conv)(Mat,MatFactorType,Mat*); 4748 4749 PetscFunctionBegin; 4750 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4751 PetscValidType(mat,1); 4752 4753 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4754 MatCheckPreallocated(mat,1); 4755 4756 PetscCall(MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundtype,&foundmtype,&conv)); 4757 if (!foundtype) { 4758 if (type) { 4759 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],((PetscObject)mat)->type_name,type); 4760 } else { 4761 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); 4762 } 4763 } 4764 PetscCheck(foundmtype,PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name); 4765 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); 4766 4767 PetscCall((*conv)(mat,ftype,f)); 4768 if (mat->factorprefix) PetscCall(MatSetOptionsPrefix(*f,mat->factorprefix)); 4769 PetscFunctionReturn(0); 4770 } 4771 4772 /*@C 4773 MatGetFactorAvailable - Returns a a flag if matrix supports particular type and factor type 4774 4775 Not Collective 4776 4777 Input Parameters: 4778 + mat - the matrix 4779 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4780 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4781 4782 Output Parameter: 4783 . flg - PETSC_TRUE if the factorization is available 4784 4785 Notes: 4786 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4787 such as pastix, superlu, mumps etc. 4788 4789 PETSc must have been ./configure to use the external solver, using the option --download-package 4790 4791 Developer Notes: 4792 This should actually be called MatCreateFactorAvailable() since MatGetFactor() creates a new factor object 4793 4794 Level: intermediate 4795 4796 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactor()`, `MatSolverTypeRegister()` 4797 @*/ 4798 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool *flg) 4799 { 4800 PetscErrorCode (*gconv)(Mat,MatFactorType,Mat*); 4801 4802 PetscFunctionBegin; 4803 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4804 PetscValidType(mat,1); 4805 PetscValidBoolPointer(flg,4); 4806 4807 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4808 MatCheckPreallocated(mat,1); 4809 4810 PetscCall(MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv)); 4811 *flg = gconv ? PETSC_TRUE : PETSC_FALSE; 4812 PetscFunctionReturn(0); 4813 } 4814 4815 /*@ 4816 MatDuplicate - Duplicates a matrix including the non-zero structure. 4817 4818 Collective on Mat 4819 4820 Input Parameters: 4821 + mat - the matrix 4822 - op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN. 4823 See the manual page for MatDuplicateOption for an explanation of these options. 4824 4825 Output Parameter: 4826 . M - pointer to place new matrix 4827 4828 Level: intermediate 4829 4830 Notes: 4831 You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN. 4832 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. 4833 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. 4834 4835 .seealso: `MatCopy()`, `MatConvert()`, `MatDuplicateOption` 4836 @*/ 4837 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M) 4838 { 4839 Mat B; 4840 VecType vtype; 4841 PetscInt i; 4842 PetscObject dm; 4843 void (*viewf)(void); 4844 4845 PetscFunctionBegin; 4846 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4847 PetscValidType(mat,1); 4848 PetscValidPointer(M,3); 4849 PetscCheck(op != MAT_COPY_VALUES || mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix"); 4850 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4851 MatCheckPreallocated(mat,1); 4852 4853 *M = NULL; 4854 PetscCheck(mat->ops->duplicate,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for matrix type %s",((PetscObject)mat)->type_name); 4855 PetscCall(PetscLogEventBegin(MAT_Convert,mat,0,0,0)); 4856 PetscCall((*mat->ops->duplicate)(mat,op,M)); 4857 PetscCall(PetscLogEventEnd(MAT_Convert,mat,0,0,0)); 4858 B = *M; 4859 4860 PetscCall(MatGetOperation(mat,MATOP_VIEW,&viewf)); 4861 if (viewf) PetscCall(MatSetOperation(B,MATOP_VIEW,viewf)); 4862 PetscCall(MatGetVecType(mat,&vtype)); 4863 PetscCall(MatSetVecType(B,vtype)); 4864 4865 B->stencil.dim = mat->stencil.dim; 4866 B->stencil.noc = mat->stencil.noc; 4867 for (i=0; i<=mat->stencil.dim; i++) { 4868 B->stencil.dims[i] = mat->stencil.dims[i]; 4869 B->stencil.starts[i] = mat->stencil.starts[i]; 4870 } 4871 4872 B->nooffproczerorows = mat->nooffproczerorows; 4873 B->nooffprocentries = mat->nooffprocentries; 4874 4875 PetscCall(PetscObjectQuery((PetscObject) mat, "__PETSc_dm", &dm)); 4876 if (dm) { 4877 PetscCall(PetscObjectCompose((PetscObject) B, "__PETSc_dm", dm)); 4878 } 4879 PetscCall(PetscObjectStateIncrease((PetscObject)B)); 4880 PetscFunctionReturn(0); 4881 } 4882 4883 /*@ 4884 MatGetDiagonal - Gets the diagonal of a matrix. 4885 4886 Logically Collective on Mat 4887 4888 Input Parameters: 4889 + mat - the matrix 4890 - v - the vector for storing the diagonal 4891 4892 Output Parameter: 4893 . v - the diagonal of the matrix 4894 4895 Level: intermediate 4896 4897 Note: 4898 Currently only correct in parallel for square matrices. 4899 4900 .seealso: `MatGetRow()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMaxAbs()` 4901 @*/ 4902 PetscErrorCode MatGetDiagonal(Mat mat,Vec v) 4903 { 4904 PetscFunctionBegin; 4905 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4906 PetscValidType(mat,1); 4907 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4908 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4909 PetscCheck(mat->ops->getdiagonal,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4910 MatCheckPreallocated(mat,1); 4911 4912 PetscCall((*mat->ops->getdiagonal)(mat,v)); 4913 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 4914 PetscFunctionReturn(0); 4915 } 4916 4917 /*@C 4918 MatGetRowMin - Gets the minimum value (of the real part) of each 4919 row of the matrix 4920 4921 Logically Collective on Mat 4922 4923 Input Parameter: 4924 . mat - the matrix 4925 4926 Output Parameters: 4927 + v - the vector for storing the maximums 4928 - idx - the indices of the column found for each row (optional) 4929 4930 Level: intermediate 4931 4932 Notes: 4933 The result of this call are the same as if one converted the matrix to dense format 4934 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4935 4936 This code is only implemented for a couple of matrix formats. 4937 4938 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMaxAbs()`, 4939 `MatGetRowMax()` 4940 @*/ 4941 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[]) 4942 { 4943 PetscFunctionBegin; 4944 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4945 PetscValidType(mat,1); 4946 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4947 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4948 4949 if (!mat->cmap->N) { 4950 PetscCall(VecSet(v,PETSC_MAX_REAL)); 4951 if (idx) { 4952 PetscInt i,m = mat->rmap->n; 4953 for (i=0; i<m; i++) idx[i] = -1; 4954 } 4955 } else { 4956 PetscCheck(mat->ops->getrowmin,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4957 MatCheckPreallocated(mat,1); 4958 } 4959 PetscCall((*mat->ops->getrowmin)(mat,v,idx)); 4960 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 4961 PetscFunctionReturn(0); 4962 } 4963 4964 /*@C 4965 MatGetRowMinAbs - Gets the minimum value (in absolute value) of each 4966 row of the matrix 4967 4968 Logically Collective on Mat 4969 4970 Input Parameter: 4971 . mat - the matrix 4972 4973 Output Parameters: 4974 + v - the vector for storing the minimums 4975 - idx - the indices of the column found for each row (or NULL if not needed) 4976 4977 Level: intermediate 4978 4979 Notes: 4980 if a row is completely empty or has only 0.0 values then the idx[] value for that 4981 row is 0 (the first column). 4982 4983 This code is only implemented for a couple of matrix formats. 4984 4985 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMax()`, `MatGetRowMaxAbs()`, `MatGetRowMin()` 4986 @*/ 4987 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[]) 4988 { 4989 PetscFunctionBegin; 4990 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4991 PetscValidType(mat,1); 4992 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4993 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4994 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4995 4996 if (!mat->cmap->N) { 4997 PetscCall(VecSet(v,0.0)); 4998 if (idx) { 4999 PetscInt i,m = mat->rmap->n; 5000 for (i=0; i<m; i++) idx[i] = -1; 5001 } 5002 } else { 5003 PetscCheck(mat->ops->getrowminabs,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5004 MatCheckPreallocated(mat,1); 5005 if (idx) PetscCall(PetscArrayzero(idx,mat->rmap->n)); 5006 PetscCall((*mat->ops->getrowminabs)(mat,v,idx)); 5007 } 5008 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 5009 PetscFunctionReturn(0); 5010 } 5011 5012 /*@C 5013 MatGetRowMax - Gets the maximum value (of the real part) of each 5014 row of the matrix 5015 5016 Logically Collective on Mat 5017 5018 Input Parameter: 5019 . mat - the matrix 5020 5021 Output Parameters: 5022 + v - the vector for storing the maximums 5023 - idx - the indices of the column found for each row (optional) 5024 5025 Level: intermediate 5026 5027 Notes: 5028 The result of this call are the same as if one converted the matrix to dense format 5029 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 5030 5031 This code is only implemented for a couple of matrix formats. 5032 5033 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMaxAbs()`, `MatGetRowMin()` 5034 @*/ 5035 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[]) 5036 { 5037 PetscFunctionBegin; 5038 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5039 PetscValidType(mat,1); 5040 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 5041 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5042 5043 if (!mat->cmap->N) { 5044 PetscCall(VecSet(v,PETSC_MIN_REAL)); 5045 if (idx) { 5046 PetscInt i,m = mat->rmap->n; 5047 for (i=0; i<m; i++) idx[i] = -1; 5048 } 5049 } else { 5050 PetscCheck(mat->ops->getrowmax,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5051 MatCheckPreallocated(mat,1); 5052 PetscCall((*mat->ops->getrowmax)(mat,v,idx)); 5053 } 5054 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 5055 PetscFunctionReturn(0); 5056 } 5057 5058 /*@C 5059 MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each 5060 row of the matrix 5061 5062 Logically Collective on Mat 5063 5064 Input Parameter: 5065 . mat - the matrix 5066 5067 Output Parameters: 5068 + v - the vector for storing the maximums 5069 - idx - the indices of the column found for each row (or NULL if not needed) 5070 5071 Level: intermediate 5072 5073 Notes: 5074 if a row is completely empty or has only 0.0 values then the idx[] value for that 5075 row is 0 (the first column). 5076 5077 This code is only implemented for a couple of matrix formats. 5078 5079 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMax()`, `MatGetRowMin()` 5080 @*/ 5081 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[]) 5082 { 5083 PetscFunctionBegin; 5084 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5085 PetscValidType(mat,1); 5086 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 5087 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5088 5089 if (!mat->cmap->N) { 5090 PetscCall(VecSet(v,0.0)); 5091 if (idx) { 5092 PetscInt i,m = mat->rmap->n; 5093 for (i=0; i<m; i++) idx[i] = -1; 5094 } 5095 } else { 5096 PetscCheck(mat->ops->getrowmaxabs,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5097 MatCheckPreallocated(mat,1); 5098 if (idx) PetscCall(PetscArrayzero(idx,mat->rmap->n)); 5099 PetscCall((*mat->ops->getrowmaxabs)(mat,v,idx)); 5100 } 5101 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 5102 PetscFunctionReturn(0); 5103 } 5104 5105 /*@ 5106 MatGetRowSum - Gets the sum of each row of the matrix 5107 5108 Logically or Neighborhood Collective on Mat 5109 5110 Input Parameters: 5111 . mat - the matrix 5112 5113 Output Parameter: 5114 . v - the vector for storing the sum of rows 5115 5116 Level: intermediate 5117 5118 Notes: 5119 This code is slow since it is not currently specialized for different formats 5120 5121 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMax()`, `MatGetRowMin()` 5122 @*/ 5123 PetscErrorCode MatGetRowSum(Mat mat, Vec v) 5124 { 5125 Vec ones; 5126 5127 PetscFunctionBegin; 5128 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5129 PetscValidType(mat,1); 5130 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 5131 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5132 MatCheckPreallocated(mat,1); 5133 PetscCall(MatCreateVecs(mat,&ones,NULL)); 5134 PetscCall(VecSet(ones,1.)); 5135 PetscCall(MatMult(mat,ones,v)); 5136 PetscCall(VecDestroy(&ones)); 5137 PetscFunctionReturn(0); 5138 } 5139 5140 /*@ 5141 MatTransposeSetPrecursor - Set the matrix from which the second matrix will receive numerical transpose data with a call to `MatTranspose`(A,`MAT_REUSE_MATRIX`,&B) 5142 when B was not obtained with `MatTranspose`(A,`MAT_INITIAL_MATRIX`,&B) 5143 5144 Collective on Mat 5145 5146 Input Parameter: 5147 . mat - the matrix to provide the transpose 5148 5149 Output Parameter: 5150 . 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 5151 5152 Level: advanced 5153 5154 Note: 5155 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 5156 routine allows bypassing that call. 5157 5158 .seealso: `MatTransposeSymbolic()`, `MatTranspose()`, `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse`, `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, `MAT_INPLACE_MATRIX` 5159 @*/ 5160 PetscErrorCode MatTransposeSetPrecursor(Mat mat,Mat B) 5161 { 5162 PetscContainer rB = NULL; 5163 MatParentState *rb = NULL; 5164 5165 PetscFunctionBegin; 5166 PetscCall(PetscNew(&rb)); 5167 rb->id = ((PetscObject)mat)->id; 5168 rb->state = 0; 5169 PetscCall(MatGetNonzeroState(mat,&rb->nonzerostate)); 5170 PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)B),&rB)); 5171 PetscCall(PetscContainerSetPointer(rB,rb)); 5172 PetscCall(PetscContainerSetUserDestroy(rB,PetscContainerUserDestroyDefault)); 5173 PetscCall(PetscObjectCompose((PetscObject)B,"MatTransposeParent",(PetscObject)rB)); 5174 PetscCall(PetscObjectDereference((PetscObject)rB)); 5175 PetscFunctionReturn(0); 5176 } 5177 5178 /*@ 5179 MatTranspose - Computes an in-place or out-of-place transpose of a matrix. 5180 5181 Collective on Mat 5182 5183 Input Parameters: 5184 + mat - the matrix to transpose 5185 - reuse - either `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, or `MAT_INPLACE_MATRIX` 5186 5187 Output Parameter: 5188 . B - the transpose 5189 5190 Notes: 5191 If you use `MAT_INPLACE_MATRIX` then you must pass in &mat for B 5192 5193 `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 5194 transpose, call `MatTransposeSetPrecursor`(mat,B) before calling this routine. 5195 5196 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. 5197 5198 Consider using `MatCreateTranspose()` instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed. 5199 5200 If mat is unchanged from the last call this function returns immediately without recomputing the result 5201 5202 If you only need the symbolic transpose, and not the numerical values, use `MatTransposeSymbolic()` 5203 5204 Level: intermediate 5205 5206 .seealso: `MatTransposeSetPrecursor()`, `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse`, `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, `MAT_INPLACE_MATRIX`, 5207 `MatTransposeSymbolic()` 5208 @*/ 5209 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B) 5210 { 5211 PetscContainer rB = NULL; 5212 MatParentState *rb = NULL; 5213 5214 PetscFunctionBegin; 5215 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5216 PetscValidType(mat,1); 5217 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5218 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5219 PetscCheck(mat->ops->transpose,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5220 PetscCheck(reuse != MAT_INPLACE_MATRIX || mat == *B,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first"); 5221 PetscCheck(reuse != MAT_REUSE_MATRIX || mat != *B,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX"); 5222 MatCheckPreallocated(mat,1); 5223 if (reuse == MAT_REUSE_MATRIX) { 5224 PetscCall(PetscObjectQuery((PetscObject)*B,"MatTransposeParent",(PetscObject*)&rB)); 5225 PetscCheck(rB,PetscObjectComm((PetscObject)*B),PETSC_ERR_ARG_WRONG,"Reuse matrix used was not generated from call to MatTranspose(). Suggest MatTransposeSetPrecursor()."); 5226 PetscCall(PetscContainerGetPointer(rB,(void**)&rb)); 5227 PetscCheck(rb->id == ((PetscObject)mat)->id,PetscObjectComm((PetscObject)*B),PETSC_ERR_ARG_WRONG,"Reuse matrix used was not generated from input matrix"); 5228 if (rb->state == ((PetscObject)mat)->state) PetscFunctionReturn(0); 5229 } 5230 5231 PetscCall(PetscLogEventBegin(MAT_Transpose,mat,0,0,0)); 5232 if (reuse != MAT_INPLACE_MATRIX || mat->symmetric != PETSC_BOOL3_TRUE) { 5233 PetscCall((*mat->ops->transpose)(mat,reuse,B)); 5234 PetscCall(PetscObjectStateIncrease((PetscObject)*B)); 5235 } 5236 PetscCall(PetscLogEventEnd(MAT_Transpose,mat,0,0,0)); 5237 5238 if (reuse == MAT_INITIAL_MATRIX) PetscCall(MatTransposeSetPrecursor(mat,*B)); 5239 if (reuse != MAT_INPLACE_MATRIX) { 5240 PetscCall(PetscObjectQuery((PetscObject)*B,"MatTransposeParent",(PetscObject*)&rB)); 5241 PetscCall(PetscContainerGetPointer(rB,(void**)&rb)); 5242 rb->state = ((PetscObject)mat)->state; 5243 rb->nonzerostate = mat->nonzerostate; 5244 } 5245 PetscFunctionReturn(0); 5246 } 5247 5248 /*@ 5249 MatTransposeSymbolic - Computes the symbolic part of the transpose of a matrix. 5250 5251 Collective on Mat 5252 5253 Input Parameters: 5254 . A - the matrix to transpose 5255 5256 Output Parameter: 5257 . 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 5258 numerical portion. 5259 5260 Level: intermediate 5261 5262 Note: 5263 This is not supported for many matrix types, use `MatTranspose()` in those cases 5264 5265 .seealso: `MatTransposeSetPrecursor()`, `MatTranspose()`, `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse`, `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, `MAT_INPLACE_MATRIX` 5266 @*/ 5267 PetscErrorCode MatTransposeSymbolic(Mat A,Mat *B) 5268 { 5269 PetscFunctionBegin; 5270 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5271 PetscValidType(A,1); 5272 PetscCheck(A->assembled,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5273 PetscCheck(!A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5274 PetscCheck(A->ops->transposesymbolic,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 5275 PetscCall(PetscLogEventBegin(MAT_Transpose,A,0,0,0)); 5276 PetscCall((*A->ops->transposesymbolic)(A,B)); 5277 PetscCall(PetscLogEventEnd(MAT_Transpose,A,0,0,0)); 5278 5279 PetscCall(MatTransposeSetPrecursor(A,*B)); 5280 PetscFunctionReturn(0); 5281 } 5282 5283 PetscErrorCode MatTransposeCheckNonzeroState_Private(Mat A,Mat B) 5284 { 5285 PetscContainer rB; 5286 MatParentState *rb; 5287 5288 PetscFunctionBegin; 5289 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5290 PetscValidType(A,1); 5291 PetscCheck(A->assembled,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5292 PetscCheck(!A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5293 PetscCall(PetscObjectQuery((PetscObject)B,"MatTransposeParent",(PetscObject*)&rB)); 5294 PetscCheck(rB,PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONG,"Reuse matrix used was not generated from call to MatTranspose()"); 5295 PetscCall(PetscContainerGetPointer(rB,(void**)&rb)); 5296 PetscCheck(rb->id == ((PetscObject)A)->id,PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONG,"Reuse matrix used was not generated from input matrix"); 5297 PetscCheck(rb->nonzerostate == A->nonzerostate,PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Reuse matrix has changed nonzero structure"); 5298 PetscFunctionReturn(0); 5299 } 5300 5301 /*@ 5302 MatIsTranspose - Test whether a matrix is another one's transpose, 5303 or its own, in which case it tests symmetry. 5304 5305 Collective on Mat 5306 5307 Input Parameters: 5308 + A - the matrix to test 5309 - B - the matrix to test against, this can equal the first parameter 5310 5311 Output Parameters: 5312 . flg - the result 5313 5314 Notes: 5315 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 5316 has a running time of the order of the number of nonzeros; the parallel 5317 test involves parallel copies of the block-offdiagonal parts of the matrix. 5318 5319 Level: intermediate 5320 5321 .seealso: `MatTranspose()`, `MatIsSymmetric()`, `MatIsHermitian()` 5322 @*/ 5323 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 5324 { 5325 PetscErrorCode (*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 5326 5327 PetscFunctionBegin; 5328 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5329 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5330 PetscValidBoolPointer(flg,4); 5331 PetscCall(PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f)); 5332 PetscCall(PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g)); 5333 *flg = PETSC_FALSE; 5334 if (f && g) { 5335 PetscCheck(f == g,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test"); 5336 PetscCall((*f)(A,B,tol,flg)); 5337 } else { 5338 MatType mattype; 5339 5340 PetscCall(MatGetType(f ? B : A,&mattype)); 5341 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for transpose",mattype); 5342 } 5343 PetscFunctionReturn(0); 5344 } 5345 5346 /*@ 5347 MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate. 5348 5349 Collective on Mat 5350 5351 Input Parameters: 5352 + mat - the matrix to transpose and complex conjugate 5353 - reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX 5354 5355 Output Parameter: 5356 . B - the Hermitian 5357 5358 Level: intermediate 5359 5360 .seealso: `MatTranspose()`, `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse` 5361 @*/ 5362 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B) 5363 { 5364 PetscFunctionBegin; 5365 PetscCall(MatTranspose(mat,reuse,B)); 5366 #if defined(PETSC_USE_COMPLEX) 5367 PetscCall(MatConjugate(*B)); 5368 #endif 5369 PetscFunctionReturn(0); 5370 } 5371 5372 /*@ 5373 MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose, 5374 5375 Collective on Mat 5376 5377 Input Parameters: 5378 + A - the matrix to test 5379 - B - the matrix to test against, this can equal the first parameter 5380 5381 Output Parameters: 5382 . flg - the result 5383 5384 Notes: 5385 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 5386 has a running time of the order of the number of nonzeros; the parallel 5387 test involves parallel copies of the block-offdiagonal parts of the matrix. 5388 5389 Level: intermediate 5390 5391 .seealso: `MatTranspose()`, `MatIsSymmetric()`, `MatIsHermitian()`, `MatIsTranspose()` 5392 @*/ 5393 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 5394 { 5395 PetscErrorCode (*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 5396 5397 PetscFunctionBegin; 5398 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5399 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5400 PetscValidBoolPointer(flg,4); 5401 PetscCall(PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f)); 5402 PetscCall(PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g)); 5403 if (f && g) { 5404 PetscCheck(f != g,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test"); 5405 PetscCall((*f)(A,B,tol,flg)); 5406 } 5407 PetscFunctionReturn(0); 5408 } 5409 5410 /*@ 5411 MatPermute - Creates a new matrix with rows and columns permuted from the 5412 original. 5413 5414 Collective on Mat 5415 5416 Input Parameters: 5417 + mat - the matrix to permute 5418 . row - row permutation, each processor supplies only the permutation for its rows 5419 - col - column permutation, each processor supplies only the permutation for its columns 5420 5421 Output Parameters: 5422 . B - the permuted matrix 5423 5424 Level: advanced 5425 5426 Note: 5427 The index sets map from row/col of permuted matrix to row/col of original matrix. 5428 The index sets should be on the same communicator as Mat and have the same local sizes. 5429 5430 Developer Note: 5431 If you want to implement MatPermute for a matrix type, and your approach doesn't 5432 exploit the fact that row and col are permutations, consider implementing the 5433 more general MatCreateSubMatrix() instead. 5434 5435 .seealso: `MatGetOrdering()`, `ISAllGather()` 5436 5437 @*/ 5438 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B) 5439 { 5440 PetscFunctionBegin; 5441 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5442 PetscValidType(mat,1); 5443 PetscValidHeaderSpecific(row,IS_CLASSID,2); 5444 PetscValidHeaderSpecific(col,IS_CLASSID,3); 5445 PetscValidPointer(B,4); 5446 PetscCheckSameComm(mat,1,row,2); 5447 if (row != col) PetscCheckSameComm(row,2,col,3); 5448 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5449 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5450 PetscCheck(mat->ops->permute || mat->ops->createsubmatrix,PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name); 5451 MatCheckPreallocated(mat,1); 5452 5453 if (mat->ops->permute) { 5454 PetscCall((*mat->ops->permute)(mat,row,col,B)); 5455 PetscCall(PetscObjectStateIncrease((PetscObject)*B)); 5456 } else { 5457 PetscCall(MatCreateSubMatrix(mat, row, col, MAT_INITIAL_MATRIX, B)); 5458 } 5459 PetscFunctionReturn(0); 5460 } 5461 5462 /*@ 5463 MatEqual - Compares two matrices. 5464 5465 Collective on Mat 5466 5467 Input Parameters: 5468 + A - the first matrix 5469 - B - the second matrix 5470 5471 Output Parameter: 5472 . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise. 5473 5474 Level: intermediate 5475 5476 @*/ 5477 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool *flg) 5478 { 5479 PetscFunctionBegin; 5480 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5481 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5482 PetscValidType(A,1); 5483 PetscValidType(B,2); 5484 PetscValidBoolPointer(flg,3); 5485 PetscCheckSameComm(A,1,B,2); 5486 MatCheckPreallocated(A,1); 5487 MatCheckPreallocated(B,2); 5488 PetscCheck(A->assembled,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5489 PetscCheck(B->assembled,PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5490 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,B->cmap->N); 5491 if (A->ops->equal && A->ops->equal == B->ops->equal) { 5492 PetscCall((*A->ops->equal)(A,B,flg)); 5493 } else { 5494 PetscCall(MatMultEqual(A,B,10,flg)); 5495 } 5496 PetscFunctionReturn(0); 5497 } 5498 5499 /*@ 5500 MatDiagonalScale - Scales a matrix on the left and right by diagonal 5501 matrices that are stored as vectors. Either of the two scaling 5502 matrices can be NULL. 5503 5504 Collective on Mat 5505 5506 Input Parameters: 5507 + mat - the matrix to be scaled 5508 . l - the left scaling vector (or NULL) 5509 - r - the right scaling vector (or NULL) 5510 5511 Notes: 5512 MatDiagonalScale() computes A = LAR, where 5513 L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector) 5514 The L scales the rows of the matrix, the R scales the columns of the matrix. 5515 5516 Level: intermediate 5517 5518 .seealso: `MatScale()`, `MatShift()`, `MatDiagonalSet()` 5519 @*/ 5520 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r) 5521 { 5522 PetscFunctionBegin; 5523 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5524 PetscValidType(mat,1); 5525 if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);} 5526 if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);} 5527 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5528 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5529 MatCheckPreallocated(mat,1); 5530 if (!l && !r) PetscFunctionReturn(0); 5531 5532 PetscCheck(mat->ops->diagonalscale,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5533 PetscCall(PetscLogEventBegin(MAT_Scale,mat,0,0,0)); 5534 PetscCall((*mat->ops->diagonalscale)(mat,l,r)); 5535 PetscCall(PetscLogEventEnd(MAT_Scale,mat,0,0,0)); 5536 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5537 if (l != r) mat->symmetric = PETSC_BOOL3_FALSE; 5538 PetscFunctionReturn(0); 5539 } 5540 5541 /*@ 5542 MatScale - Scales all elements of a matrix by a given number. 5543 5544 Logically Collective on Mat 5545 5546 Input Parameters: 5547 + mat - the matrix to be scaled 5548 - a - the scaling value 5549 5550 Output Parameter: 5551 . mat - the scaled matrix 5552 5553 Level: intermediate 5554 5555 .seealso: `MatDiagonalScale()` 5556 @*/ 5557 PetscErrorCode MatScale(Mat mat,PetscScalar a) 5558 { 5559 PetscFunctionBegin; 5560 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5561 PetscValidType(mat,1); 5562 PetscCheck(a == (PetscScalar)1.0 || mat->ops->scale,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5563 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5564 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5565 PetscValidLogicalCollectiveScalar(mat,a,2); 5566 MatCheckPreallocated(mat,1); 5567 5568 PetscCall(PetscLogEventBegin(MAT_Scale,mat,0,0,0)); 5569 if (a != (PetscScalar)1.0) { 5570 PetscCall((*mat->ops->scale)(mat,a)); 5571 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5572 } 5573 PetscCall(PetscLogEventEnd(MAT_Scale,mat,0,0,0)); 5574 PetscFunctionReturn(0); 5575 } 5576 5577 /*@ 5578 MatNorm - Calculates various norms of a matrix. 5579 5580 Collective on Mat 5581 5582 Input Parameters: 5583 + mat - the matrix 5584 - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY 5585 5586 Output Parameter: 5587 . nrm - the resulting norm 5588 5589 Level: intermediate 5590 5591 @*/ 5592 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm) 5593 { 5594 PetscFunctionBegin; 5595 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5596 PetscValidType(mat,1); 5597 PetscValidRealPointer(nrm,3); 5598 5599 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5600 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5601 PetscCheck(mat->ops->norm,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5602 MatCheckPreallocated(mat,1); 5603 5604 PetscCall((*mat->ops->norm)(mat,type,nrm)); 5605 PetscFunctionReturn(0); 5606 } 5607 5608 /* 5609 This variable is used to prevent counting of MatAssemblyBegin() that 5610 are called from within a MatAssemblyEnd(). 5611 */ 5612 static PetscInt MatAssemblyEnd_InUse = 0; 5613 /*@ 5614 MatAssemblyBegin - Begins assembling the matrix. This routine should 5615 be called after completing all calls to MatSetValues(). 5616 5617 Collective on Mat 5618 5619 Input Parameters: 5620 + mat - the matrix 5621 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5622 5623 Notes: 5624 MatSetValues() generally caches the values. The matrix is ready to 5625 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5626 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5627 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5628 using the matrix. 5629 5630 ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the 5631 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 5632 a global collective operation requring all processes that share the matrix. 5633 5634 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5635 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5636 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5637 5638 Level: beginner 5639 5640 .seealso: `MatAssemblyEnd()`, `MatSetValues()`, `MatAssembled()` 5641 @*/ 5642 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type) 5643 { 5644 PetscFunctionBegin; 5645 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5646 PetscValidType(mat,1); 5647 MatCheckPreallocated(mat,1); 5648 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?"); 5649 if (mat->assembled) { 5650 mat->was_assembled = PETSC_TRUE; 5651 mat->assembled = PETSC_FALSE; 5652 } 5653 5654 if (!MatAssemblyEnd_InUse) { 5655 PetscCall(PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0)); 5656 if (mat->ops->assemblybegin) PetscCall((*mat->ops->assemblybegin)(mat,type)); 5657 PetscCall(PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0)); 5658 } else if (mat->ops->assemblybegin) PetscCall((*mat->ops->assemblybegin)(mat,type)); 5659 PetscFunctionReturn(0); 5660 } 5661 5662 /*@ 5663 MatAssembled - Indicates if a matrix has been assembled and is ready for 5664 use; for example, in matrix-vector product. 5665 5666 Not Collective 5667 5668 Input Parameter: 5669 . mat - the matrix 5670 5671 Output Parameter: 5672 . assembled - PETSC_TRUE or PETSC_FALSE 5673 5674 Level: advanced 5675 5676 .seealso: `MatAssemblyEnd()`, `MatSetValues()`, `MatAssemblyBegin()` 5677 @*/ 5678 PetscErrorCode MatAssembled(Mat mat,PetscBool *assembled) 5679 { 5680 PetscFunctionBegin; 5681 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5682 PetscValidBoolPointer(assembled,2); 5683 *assembled = mat->assembled; 5684 PetscFunctionReturn(0); 5685 } 5686 5687 /*@ 5688 MatAssemblyEnd - Completes assembling the matrix. This routine should 5689 be called after MatAssemblyBegin(). 5690 5691 Collective on Mat 5692 5693 Input Parameters: 5694 + mat - the matrix 5695 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5696 5697 Options Database Keys: 5698 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly() 5699 . -mat_view ::ascii_info_detail - Prints more detailed info 5700 . -mat_view - Prints matrix in ASCII format 5701 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 5702 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 5703 . -display <name> - Sets display name (default is host) 5704 . -draw_pause <sec> - Sets number of seconds to pause after display 5705 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab) 5706 . -viewer_socket_machine <machine> - Machine to use for socket 5707 . -viewer_socket_port <port> - Port number to use for socket 5708 - -mat_view binary:filename[:append] - Save matrix to file in binary format 5709 5710 Notes: 5711 MatSetValues() generally caches the values. The matrix is ready to 5712 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5713 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5714 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5715 using the matrix. 5716 5717 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5718 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5719 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5720 5721 Level: beginner 5722 5723 .seealso: `MatAssemblyBegin()`, `MatSetValues()`, `PetscDrawOpenX()`, `PetscDrawCreate()`, `MatView()`, `MatAssembled()`, `PetscViewerSocketOpen()` 5724 @*/ 5725 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type) 5726 { 5727 static PetscInt inassm = 0; 5728 PetscBool flg = PETSC_FALSE; 5729 5730 PetscFunctionBegin; 5731 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5732 PetscValidType(mat,1); 5733 5734 inassm++; 5735 MatAssemblyEnd_InUse++; 5736 if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */ 5737 PetscCall(PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0)); 5738 if (mat->ops->assemblyend) PetscCall((*mat->ops->assemblyend)(mat,type)); 5739 PetscCall(PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0)); 5740 } else if (mat->ops->assemblyend) PetscCall((*mat->ops->assemblyend)(mat,type)); 5741 5742 /* Flush assembly is not a true assembly */ 5743 if (type != MAT_FLUSH_ASSEMBLY) { 5744 if (mat->num_ass) { 5745 if (!mat->symmetry_eternal) { 5746 mat->symmetric = PETSC_BOOL3_UNKNOWN; 5747 mat->hermitian = PETSC_BOOL3_UNKNOWN; 5748 } 5749 if (!mat->structural_symmetry_eternal && mat->ass_nonzerostate != mat->nonzerostate) { 5750 mat->structurally_symmetric = PETSC_BOOL3_UNKNOWN; 5751 } 5752 if (!mat->spd_eternal) mat->spd = PETSC_BOOL3_UNKNOWN; 5753 } 5754 mat->num_ass++; 5755 mat->assembled = PETSC_TRUE; 5756 mat->ass_nonzerostate = mat->nonzerostate; 5757 } 5758 5759 mat->insertmode = NOT_SET_VALUES; 5760 MatAssemblyEnd_InUse--; 5761 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5762 if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) { 5763 PetscCall(MatViewFromOptions(mat,NULL,"-mat_view")); 5764 5765 if (mat->checksymmetryonassembly) { 5766 PetscCall(MatIsSymmetric(mat,mat->checksymmetrytol,&flg)); 5767 if (flg) { 5768 PetscCall(PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol)); 5769 } else { 5770 PetscCall(PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol)); 5771 } 5772 } 5773 if (mat->nullsp && mat->checknullspaceonassembly) { 5774 PetscCall(MatNullSpaceTest(mat->nullsp,mat,NULL)); 5775 } 5776 } 5777 inassm--; 5778 PetscFunctionReturn(0); 5779 } 5780 5781 /*@ 5782 MatSetOption - Sets a parameter option for a matrix. Some options 5783 may be specific to certain storage formats. Some options 5784 determine how values will be inserted (or added). Sorted, 5785 row-oriented input will generally assemble the fastest. The default 5786 is row-oriented. 5787 5788 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5789 5790 Input Parameters: 5791 + mat - the matrix 5792 . option - the option, one of those listed below (and possibly others), 5793 - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5794 5795 Options Describing Matrix Structure: 5796 + MAT_SPD - symmetric positive definite 5797 . MAT_SYMMETRIC - symmetric in terms of both structure and value 5798 . MAT_HERMITIAN - transpose is the complex conjugation 5799 . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure 5800 . MAT_SYMMETRY_ETERNAL - indicates the symmetry (or Hermitian structure) or its absence will persist through any changes to the matrix 5801 . MAT_STRUCTURAL_SYMMETRY_ETERNAL - indicates the structural symmetry or its absence will persist through any changes to the matrix 5802 - MAT_SPD_ETERNAL - indicates the value of MAT_SPD (true or false) will persist through any changes to the matrix 5803 5804 These are not really options of the matrix, they are knowledge about the structure of the matrix that users may provide so that they 5805 do not need to be computed (usually at a high cost) 5806 5807 Options For Use with MatSetValues(): 5808 Insert a logically dense subblock, which can be 5809 . MAT_ROW_ORIENTED - row-oriented (default) 5810 5811 Note these options reflect the data you pass in with MatSetValues(); it has 5812 nothing to do with how the data is stored internally in the matrix 5813 data structure. 5814 5815 When (re)assembling a matrix, we can restrict the input for 5816 efficiency/debugging purposes. These options include 5817 + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow) 5818 . MAT_FORCE_DIAGONAL_ENTRIES - forces diagonal entries to be allocated 5819 . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries 5820 . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry 5821 . MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly 5822 . MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if 5823 any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves 5824 performance for very large process counts. 5825 - MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset 5826 of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly 5827 functions, instead sending only neighbor messages. 5828 5829 Notes: 5830 Except for MAT_UNUSED_NONZERO_LOCATION_ERR and MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg! 5831 5832 Some options are relevant only for particular matrix types and 5833 are thus ignored by others. Other options are not supported by 5834 certain matrix types and will generate an error message if set. 5835 5836 If using a Fortran 77 module to compute a matrix, one may need to 5837 use the column-oriented option (or convert to the row-oriented 5838 format). 5839 5840 MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion 5841 that would generate a new entry in the nonzero structure is instead 5842 ignored. Thus, if memory has not alredy been allocated for this particular 5843 data, then the insertion is ignored. For dense matrices, in which 5844 the entire array is allocated, no entries are ever ignored. 5845 Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5846 5847 MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5848 that would generate a new entry in the nonzero structure instead produces 5849 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 5850 5851 MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5852 that would generate a new entry that has not been preallocated will 5853 instead produce an error. (Currently supported for AIJ and BAIJ formats 5854 only.) This is a useful flag when debugging matrix memory preallocation. 5855 If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5856 5857 MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for 5858 other processors should be dropped, rather than stashed. 5859 This is useful if you know that the "owning" processor is also 5860 always generating the correct matrix entries, so that PETSc need 5861 not transfer duplicate entries generated on another processor. 5862 5863 MAT_USE_HASH_TABLE indicates that a hash table be used to improve the 5864 searches during matrix assembly. When this flag is set, the hash table 5865 is created during the first Matrix Assembly. This hash table is 5866 used the next time through, during MatSetVaules()/MatSetVaulesBlocked() 5867 to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag 5868 should be used with MAT_USE_HASH_TABLE flag. This option is currently 5869 supported by MATMPIBAIJ format only. 5870 5871 MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries 5872 are kept in the nonzero structure 5873 5874 MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating 5875 a zero location in the matrix 5876 5877 MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types 5878 5879 MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the 5880 zero row routines and thus improves performance for very large process counts. 5881 5882 MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular 5883 part of the matrix (since they should match the upper triangular part). 5884 5885 MAT_SORTED_FULL - each process provides exactly its local rows; all column indices for a given row are passed in a 5886 single call to MatSetValues(), preallocation is perfect, row oriented, INSERT_VALUES is used. Common 5887 with finite difference schemes with non-periodic boundary conditions. 5888 5889 Developer Note: 5890 MAT_SYMMETRY_ETERNAL, MAT_STRUCTURAL_SYMMETRY_ETERNAL, and MAT_SPD_ETERNAL are used by MatAssemblyEnd() and in other 5891 places where otherwise the value of MAT_SYMMETRIC, MAT_STRUCTURAL_SYMMETRIC or MAT_SPD would need to be changed back 5892 to PETSC_BOOL3_UNKNOWN because the matrix values had changed so the code cannot be certain that the related property had 5893 not changed. 5894 5895 Level: intermediate 5896 5897 .seealso: `MatOption`, `Mat`, `MatGetOption()` 5898 5899 @*/ 5900 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg) 5901 { 5902 PetscFunctionBegin; 5903 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5904 if (op > 0) { 5905 PetscValidLogicalCollectiveEnum(mat,op,2); 5906 PetscValidLogicalCollectiveBool(mat,flg,3); 5907 } 5908 5909 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); 5910 5911 switch (op) { 5912 case MAT_FORCE_DIAGONAL_ENTRIES: 5913 mat->force_diagonals = flg; 5914 PetscFunctionReturn(0); 5915 case MAT_NO_OFF_PROC_ENTRIES: 5916 mat->nooffprocentries = flg; 5917 PetscFunctionReturn(0); 5918 case MAT_SUBSET_OFF_PROC_ENTRIES: 5919 mat->assembly_subset = flg; 5920 if (!mat->assembly_subset) { /* See the same logic in VecAssembly wrt VEC_SUBSET_OFF_PROC_ENTRIES */ 5921 #if !defined(PETSC_HAVE_MPIUNI) 5922 PetscCall(MatStashScatterDestroy_BTS(&mat->stash)); 5923 #endif 5924 mat->stash.first_assembly_done = PETSC_FALSE; 5925 } 5926 PetscFunctionReturn(0); 5927 case MAT_NO_OFF_PROC_ZERO_ROWS: 5928 mat->nooffproczerorows = flg; 5929 PetscFunctionReturn(0); 5930 case MAT_SPD: 5931 if (flg) { 5932 mat->spd = PETSC_BOOL3_TRUE; 5933 mat->symmetric = PETSC_BOOL3_TRUE; 5934 mat->structurally_symmetric = PETSC_BOOL3_TRUE; 5935 } else { 5936 mat->spd = PETSC_BOOL3_FALSE; 5937 } 5938 break; 5939 case MAT_SYMMETRIC: 5940 mat->symmetric = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5941 if (flg) mat->structurally_symmetric = PETSC_BOOL3_TRUE; 5942 #if !defined(PETSC_USE_COMPLEX) 5943 mat->hermitian = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5944 #endif 5945 break; 5946 case MAT_HERMITIAN: 5947 mat->hermitian = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5948 if (flg) mat->structurally_symmetric = PETSC_BOOL3_TRUE; 5949 #if !defined(PETSC_USE_COMPLEX) 5950 mat->symmetric = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5951 #endif 5952 break; 5953 case MAT_STRUCTURALLY_SYMMETRIC: 5954 mat->structurally_symmetric = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5955 break; 5956 case MAT_SYMMETRY_ETERNAL: 5957 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"); 5958 mat->symmetry_eternal = flg; 5959 if (flg) mat->structural_symmetry_eternal = PETSC_TRUE; 5960 break; 5961 case MAT_STRUCTURAL_SYMMETRY_ETERNAL: 5962 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"); 5963 mat->structural_symmetry_eternal = flg; 5964 break; 5965 case MAT_SPD_ETERNAL: 5966 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"); 5967 mat->spd_eternal = flg; 5968 if (flg) { 5969 mat->structural_symmetry_eternal = PETSC_TRUE; 5970 mat->symmetry_eternal = PETSC_TRUE; 5971 } 5972 break; 5973 case MAT_STRUCTURE_ONLY: 5974 mat->structure_only = flg; 5975 break; 5976 case MAT_SORTED_FULL: 5977 mat->sortedfull = flg; 5978 break; 5979 default: 5980 break; 5981 } 5982 if (mat->ops->setoption) PetscCall((*mat->ops->setoption)(mat,op,flg)); 5983 PetscFunctionReturn(0); 5984 } 5985 5986 /*@ 5987 MatGetOption - Gets a parameter option that has been set for a matrix. 5988 5989 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5990 5991 Input Parameters: 5992 + mat - the matrix 5993 - option - the option, this only responds to certain options, check the code for which ones 5994 5995 Output Parameter: 5996 . flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5997 5998 Notes: 5999 Can only be called after MatSetSizes() and MatSetType() have been set. 6000 6001 Certain option values may be unknown, for those use the routines `MatIsSymmetric()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, or 6002 `MatIsSymmetricKnown()`, `MatIsHermitianKnown()`, `MatIsStructurallySymmetricKnown()` 6003 6004 Level: intermediate 6005 6006 .seealso: `MatOption`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, 6007 `MatIsSymmetricKnown()`, `MatIsHermitianKnown()`, `MatIsStructurallySymmetricKnown()` 6008 6009 @*/ 6010 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg) 6011 { 6012 PetscFunctionBegin; 6013 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6014 PetscValidType(mat,1); 6015 6016 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); 6017 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()"); 6018 6019 switch (op) { 6020 case MAT_NO_OFF_PROC_ENTRIES: 6021 *flg = mat->nooffprocentries; 6022 break; 6023 case MAT_NO_OFF_PROC_ZERO_ROWS: 6024 *flg = mat->nooffproczerorows; 6025 break; 6026 case MAT_SYMMETRIC: 6027 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Use MatIsSymmetric() or MatIsSymmetricKnown()"); 6028 break; 6029 case MAT_HERMITIAN: 6030 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Use MatIsHermitian() or MatIsHermitianKnown()"); 6031 break; 6032 case MAT_STRUCTURALLY_SYMMETRIC: 6033 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Use MatIsStructurallySymmetric() or MatIsStructurallySymmetricKnown()"); 6034 break; 6035 case MAT_SPD: 6036 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Use MatIsSPDKnown()"); 6037 break; 6038 case MAT_SYMMETRY_ETERNAL: 6039 *flg = mat->symmetry_eternal; 6040 break; 6041 case MAT_STRUCTURAL_SYMMETRY_ETERNAL: 6042 *flg = mat->symmetry_eternal; 6043 break; 6044 default: 6045 break; 6046 } 6047 PetscFunctionReturn(0); 6048 } 6049 6050 /*@ 6051 MatZeroEntries - Zeros all entries of a matrix. For sparse matrices 6052 this routine retains the old nonzero structure. 6053 6054 Logically Collective on Mat 6055 6056 Input Parameters: 6057 . mat - the matrix 6058 6059 Level: intermediate 6060 6061 Notes: 6062 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. 6063 See the Performance chapter of the users manual for information on preallocating matrices. 6064 6065 .seealso: `MatZeroRows()` 6066 @*/ 6067 PetscErrorCode MatZeroEntries(Mat mat) 6068 { 6069 PetscFunctionBegin; 6070 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6071 PetscValidType(mat,1); 6072 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6073 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"); 6074 PetscCheck(mat->ops->zeroentries,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6075 MatCheckPreallocated(mat,1); 6076 6077 PetscCall(PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0)); 6078 PetscCall((*mat->ops->zeroentries)(mat)); 6079 PetscCall(PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0)); 6080 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6081 PetscFunctionReturn(0); 6082 } 6083 6084 /*@ 6085 MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal) 6086 of a set of rows and columns of a matrix. 6087 6088 Collective on Mat 6089 6090 Input Parameters: 6091 + mat - the matrix 6092 . numRows - the number of rows to remove 6093 . rows - the global row indices 6094 . diag - value put in the diagonal of the eliminated rows 6095 . x - optional vector of solutions for zeroed rows (other entries in vector are not used), these must be set before this call 6096 - b - optional vector of right hand side, that will be adjusted by provided solution 6097 6098 Notes: 6099 This routine, along with `MatZeroRows()`, is typically used to eliminate known Dirichlet boundary conditions from a linear system. 6100 6101 For each zeroed row, the value of the corresponding b is set to diag times the value of the corresponding x. 6102 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 6103 6104 If the resulting linear system is to be solved with KSP then one can (but does not have to) call `KSPSetInitialGuessNonzero()` to allow the 6105 Krylov method to take advantage of the known solution on the zeroed rows. 6106 6107 For the parallel case, all processes that share the matrix (i.e., 6108 those in the communicator used for matrix creation) MUST call this 6109 routine, regardless of whether any rows being zeroed are owned by 6110 them. 6111 6112 Unlike `MatZeroRows()` this does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 6113 6114 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6115 list only rows local to itself). 6116 6117 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 6118 6119 Level: intermediate 6120 6121 .seealso: `MatZeroRowsIS()`, `MatZeroRows()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6122 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6123 @*/ 6124 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6125 { 6126 PetscFunctionBegin; 6127 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6128 PetscValidType(mat,1); 6129 if (numRows) PetscValidIntPointer(rows,3); 6130 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6131 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6132 PetscCheck(mat->ops->zerorowscolumns,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6133 MatCheckPreallocated(mat,1); 6134 6135 PetscCall((*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b)); 6136 PetscCall(MatViewFromOptions(mat,NULL,"-mat_view")); 6137 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6138 PetscFunctionReturn(0); 6139 } 6140 6141 /*@ 6142 MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal) 6143 of a set of rows and columns of a matrix. 6144 6145 Collective on Mat 6146 6147 Input Parameters: 6148 + mat - the matrix 6149 . is - the rows to zero 6150 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6151 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6152 - b - optional vector of right hand side, that will be adjusted by provided solution 6153 6154 Note: 6155 See `MatZeroRowsColumns()` for details on how this routine operates. 6156 6157 Level: intermediate 6158 6159 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6160 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRows()`, `MatZeroRowsColumnsStencil()` 6161 @*/ 6162 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6163 { 6164 PetscInt numRows; 6165 const PetscInt *rows; 6166 6167 PetscFunctionBegin; 6168 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6169 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6170 PetscValidType(mat,1); 6171 PetscValidType(is,2); 6172 PetscCall(ISGetLocalSize(is,&numRows)); 6173 PetscCall(ISGetIndices(is,&rows)); 6174 PetscCall(MatZeroRowsColumns(mat,numRows,rows,diag,x,b)); 6175 PetscCall(ISRestoreIndices(is,&rows)); 6176 PetscFunctionReturn(0); 6177 } 6178 6179 /*@ 6180 MatZeroRows - Zeros all entries (except possibly the main diagonal) 6181 of a set of rows of a matrix. 6182 6183 Collective on Mat 6184 6185 Input Parameters: 6186 + mat - the matrix 6187 . numRows - the number of rows to remove 6188 . rows - the global row indices 6189 . diag - value put in the diagonal of the eliminated rows 6190 . x - optional vector of solutions for zeroed rows (other entries in vector are not used), these must be set before this call 6191 - b - optional vector of right hand side, that will be adjusted by provided solution 6192 6193 Notes: 6194 This routine, along with `MatZeroRowsColumns()`, is typically used to eliminate known Dirichlet boundary conditions from a linear system. 6195 6196 For each zeroed row, the value of the corresponding b is set to diag times the value of the corresponding x. 6197 6198 If the resulting linear system is to be solved with KSP then one can (but does not have to) call `KSPSetInitialGuessNonzero()` to allow the 6199 Krylov method to take advantage of the known solution on the zeroed rows. 6200 6201 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) 6202 from the matrix. 6203 6204 Unlike `MatZeroRowsColumns()` for the AIJ and BAIJ matrix formats this removes the old nonzero structure, from the eliminated rows of the matrix 6205 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 6206 formats this does not alter the nonzero structure. 6207 6208 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6209 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6210 merely zeroed. 6211 6212 The user can set a value in the diagonal entry (or for the AIJ and 6213 row formats can optionally remove the main diagonal entry from the 6214 nonzero structure as well, by passing 0.0 as the final argument). 6215 6216 For the parallel case, all processes that share the matrix (i.e., 6217 those in the communicator used for matrix creation) MUST call this 6218 routine, regardless of whether any rows being zeroed are owned by 6219 them. 6220 6221 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6222 list only rows local to itself). 6223 6224 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6225 owns that are to be zeroed. This saves a global synchronization in the implementation. 6226 6227 Level: intermediate 6228 6229 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6230 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()`, `PCREDISTRIBUTE` 6231 @*/ 6232 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6233 { 6234 PetscFunctionBegin; 6235 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6236 PetscValidType(mat,1); 6237 if (numRows) PetscValidIntPointer(rows,3); 6238 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6239 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6240 PetscCheck(mat->ops->zerorows,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6241 MatCheckPreallocated(mat,1); 6242 6243 PetscCall((*mat->ops->zerorows)(mat,numRows,rows,diag,x,b)); 6244 PetscCall(MatViewFromOptions(mat,NULL,"-mat_view")); 6245 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6246 PetscFunctionReturn(0); 6247 } 6248 6249 /*@ 6250 MatZeroRowsIS - Zeros all entries (except possibly the main diagonal) 6251 of a set of rows of a matrix. 6252 6253 Collective on Mat 6254 6255 Input Parameters: 6256 + mat - the matrix 6257 . is - index set of rows to remove (if NULL then no row is removed) 6258 . diag - value put in all diagonals of eliminated rows 6259 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6260 - b - optional vector of right hand side, that will be adjusted by provided solution 6261 6262 Note: 6263 See `MatZeroRows()` for details on how this routine operates. 6264 6265 Level: intermediate 6266 6267 .seealso: `MatZeroRows()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6268 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6269 @*/ 6270 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6271 { 6272 PetscInt numRows = 0; 6273 const PetscInt *rows = NULL; 6274 6275 PetscFunctionBegin; 6276 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6277 PetscValidType(mat,1); 6278 if (is) { 6279 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6280 PetscCall(ISGetLocalSize(is,&numRows)); 6281 PetscCall(ISGetIndices(is,&rows)); 6282 } 6283 PetscCall(MatZeroRows(mat,numRows,rows,diag,x,b)); 6284 if (is) { 6285 PetscCall(ISRestoreIndices(is,&rows)); 6286 } 6287 PetscFunctionReturn(0); 6288 } 6289 6290 /*@ 6291 MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal) 6292 of a set of rows of a matrix. These rows must be local to the process. 6293 6294 Collective on Mat 6295 6296 Input Parameters: 6297 + mat - the matrix 6298 . numRows - the number of rows to remove 6299 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 6300 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6301 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6302 - b - optional vector of right hand side, that will be adjusted by provided solution 6303 6304 Notes: 6305 See `MatZeroRows()` for details on how this routine operates. 6306 6307 The grid coordinates are across the entire grid, not just the local portion 6308 6309 In Fortran idxm and idxn should be declared as 6310 $ MatStencil idxm(4,m) 6311 and the values inserted using 6312 $ idxm(MatStencil_i,1) = i 6313 $ idxm(MatStencil_j,1) = j 6314 $ idxm(MatStencil_k,1) = k 6315 $ idxm(MatStencil_c,1) = c 6316 etc 6317 6318 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6319 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6320 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6321 DM_BOUNDARY_PERIODIC boundary type. 6322 6323 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 6324 a single value per point) you can skip filling those indices. 6325 6326 Level: intermediate 6327 6328 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsl()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6329 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6330 @*/ 6331 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 6332 { 6333 PetscInt dim = mat->stencil.dim; 6334 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 6335 PetscInt *dims = mat->stencil.dims+1; 6336 PetscInt *starts = mat->stencil.starts; 6337 PetscInt *dxm = (PetscInt*) rows; 6338 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6339 6340 PetscFunctionBegin; 6341 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6342 PetscValidType(mat,1); 6343 if (numRows) PetscValidPointer(rows,3); 6344 6345 PetscCall(PetscMalloc1(numRows, &jdxm)); 6346 for (i = 0; i < numRows; ++i) { 6347 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6348 for (j = 0; j < 3-sdim; ++j) dxm++; 6349 /* Local index in X dir */ 6350 tmp = *dxm++ - starts[0]; 6351 /* Loop over remaining dimensions */ 6352 for (j = 0; j < dim-1; ++j) { 6353 /* If nonlocal, set index to be negative */ 6354 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6355 /* Update local index */ 6356 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6357 } 6358 /* Skip component slot if necessary */ 6359 if (mat->stencil.noc) dxm++; 6360 /* Local row number */ 6361 if (tmp >= 0) { 6362 jdxm[numNewRows++] = tmp; 6363 } 6364 } 6365 PetscCall(MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b)); 6366 PetscCall(PetscFree(jdxm)); 6367 PetscFunctionReturn(0); 6368 } 6369 6370 /*@ 6371 MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal) 6372 of a set of rows and columns of a matrix. 6373 6374 Collective on Mat 6375 6376 Input Parameters: 6377 + mat - the matrix 6378 . numRows - the number of rows/columns to remove 6379 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 6380 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6381 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6382 - b - optional vector of right hand side, that will be adjusted by provided solution 6383 6384 Notes: 6385 See `MatZeroRowsColumns()` for details on how this routine operates. 6386 6387 The grid coordinates are across the entire grid, not just the local portion 6388 6389 In Fortran idxm and idxn should be declared as 6390 $ MatStencil idxm(4,m) 6391 and the values inserted using 6392 $ idxm(MatStencil_i,1) = i 6393 $ idxm(MatStencil_j,1) = j 6394 $ idxm(MatStencil_k,1) = k 6395 $ idxm(MatStencil_c,1) = c 6396 etc 6397 6398 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6399 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6400 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6401 DM_BOUNDARY_PERIODIC boundary type. 6402 6403 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 6404 a single value per point) you can skip filling those indices. 6405 6406 Level: intermediate 6407 6408 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6409 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRows()` 6410 @*/ 6411 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 6412 { 6413 PetscInt dim = mat->stencil.dim; 6414 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 6415 PetscInt *dims = mat->stencil.dims+1; 6416 PetscInt *starts = mat->stencil.starts; 6417 PetscInt *dxm = (PetscInt*) rows; 6418 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6419 6420 PetscFunctionBegin; 6421 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6422 PetscValidType(mat,1); 6423 if (numRows) PetscValidPointer(rows,3); 6424 6425 PetscCall(PetscMalloc1(numRows, &jdxm)); 6426 for (i = 0; i < numRows; ++i) { 6427 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6428 for (j = 0; j < 3-sdim; ++j) dxm++; 6429 /* Local index in X dir */ 6430 tmp = *dxm++ - starts[0]; 6431 /* Loop over remaining dimensions */ 6432 for (j = 0; j < dim-1; ++j) { 6433 /* If nonlocal, set index to be negative */ 6434 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6435 /* Update local index */ 6436 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6437 } 6438 /* Skip component slot if necessary */ 6439 if (mat->stencil.noc) dxm++; 6440 /* Local row number */ 6441 if (tmp >= 0) { 6442 jdxm[numNewRows++] = tmp; 6443 } 6444 } 6445 PetscCall(MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b)); 6446 PetscCall(PetscFree(jdxm)); 6447 PetscFunctionReturn(0); 6448 } 6449 6450 /*@C 6451 MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal) 6452 of a set of rows of a matrix; using local numbering of rows. 6453 6454 Collective on Mat 6455 6456 Input Parameters: 6457 + mat - the matrix 6458 . numRows - the number of rows to remove 6459 . rows - the local row indices 6460 . diag - value put in all diagonals of eliminated rows 6461 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6462 - b - optional vector of right hand side, that will be adjusted by provided solution 6463 6464 Notes: 6465 Before calling `MatZeroRowsLocal()`, the user must first set the 6466 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6467 6468 See `MatZeroRows()` for details on how this routine operates. 6469 6470 Level: intermediate 6471 6472 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRows()`, `MatSetOption()`, 6473 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6474 @*/ 6475 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6476 { 6477 PetscFunctionBegin; 6478 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6479 PetscValidType(mat,1); 6480 if (numRows) PetscValidIntPointer(rows,3); 6481 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6482 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6483 MatCheckPreallocated(mat,1); 6484 6485 if (mat->ops->zerorowslocal) { 6486 PetscCall((*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b)); 6487 } else { 6488 IS is, newis; 6489 const PetscInt *newRows; 6490 6491 PetscCheck(mat->rmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6492 PetscCall(ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is)); 6493 PetscCall(ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis)); 6494 PetscCall(ISGetIndices(newis,&newRows)); 6495 PetscCall((*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b)); 6496 PetscCall(ISRestoreIndices(newis,&newRows)); 6497 PetscCall(ISDestroy(&newis)); 6498 PetscCall(ISDestroy(&is)); 6499 } 6500 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6501 PetscFunctionReturn(0); 6502 } 6503 6504 /*@ 6505 MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal) 6506 of a set of rows of a matrix; using local numbering of rows. 6507 6508 Collective on Mat 6509 6510 Input Parameters: 6511 + mat - the matrix 6512 . is - index set of rows to remove 6513 . diag - value put in all diagonals of eliminated rows 6514 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6515 - b - optional vector of right hand side, that will be adjusted by provided solution 6516 6517 Notes: 6518 Before calling `MatZeroRowsLocalIS()`, the user must first set the 6519 local-to-global mapping by calling `MatSetLocalToGlobalMapping()`. 6520 6521 See `MatZeroRows()` for details on how this routine operates. 6522 6523 Level: intermediate 6524 6525 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRows()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6526 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6527 @*/ 6528 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6529 { 6530 PetscInt numRows; 6531 const PetscInt *rows; 6532 6533 PetscFunctionBegin; 6534 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6535 PetscValidType(mat,1); 6536 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6537 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6538 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6539 MatCheckPreallocated(mat,1); 6540 6541 PetscCall(ISGetLocalSize(is,&numRows)); 6542 PetscCall(ISGetIndices(is,&rows)); 6543 PetscCall(MatZeroRowsLocal(mat,numRows,rows,diag,x,b)); 6544 PetscCall(ISRestoreIndices(is,&rows)); 6545 PetscFunctionReturn(0); 6546 } 6547 6548 /*@ 6549 MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal) 6550 of a set of rows and columns of a matrix; using local numbering of rows. 6551 6552 Collective on Mat 6553 6554 Input Parameters: 6555 + mat - the matrix 6556 . numRows - the number of rows to remove 6557 . rows - the global row indices 6558 . diag - value put in all diagonals of eliminated rows 6559 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6560 - b - optional vector of right hand side, that will be adjusted by provided solution 6561 6562 Notes: 6563 Before calling MatZeroRowsColumnsLocal(), the user must first set the 6564 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6565 6566 See `MatZeroRowsColumns()` for details on how this routine operates. 6567 6568 Level: intermediate 6569 6570 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6571 `MatZeroRows()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6572 @*/ 6573 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6574 { 6575 IS is, newis; 6576 const PetscInt *newRows; 6577 6578 PetscFunctionBegin; 6579 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6580 PetscValidType(mat,1); 6581 if (numRows) PetscValidIntPointer(rows,3); 6582 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6583 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6584 MatCheckPreallocated(mat,1); 6585 6586 PetscCheck(mat->cmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6587 PetscCall(ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is)); 6588 PetscCall(ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis)); 6589 PetscCall(ISGetIndices(newis,&newRows)); 6590 PetscCall((*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b)); 6591 PetscCall(ISRestoreIndices(newis,&newRows)); 6592 PetscCall(ISDestroy(&newis)); 6593 PetscCall(ISDestroy(&is)); 6594 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6595 PetscFunctionReturn(0); 6596 } 6597 6598 /*@ 6599 MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal) 6600 of a set of rows and columns of a matrix; using local numbering of rows. 6601 6602 Collective on Mat 6603 6604 Input Parameters: 6605 + mat - the matrix 6606 . is - index set of rows to remove 6607 . diag - value put in all diagonals of eliminated rows 6608 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6609 - b - optional vector of right hand side, that will be adjusted by provided solution 6610 6611 Notes: 6612 Before calling `MatZeroRowsColumnsLocalIS()`, the user must first set the 6613 local-to-global mapping by calling `MatSetLocalToGlobalMapping()`. 6614 6615 See `MatZeroRowsColumns()` for details on how this routine operates. 6616 6617 Level: intermediate 6618 6619 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6620 `MatZeroRowsColumnsLocal()`, `MatZeroRows()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6621 @*/ 6622 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6623 { 6624 PetscInt numRows; 6625 const PetscInt *rows; 6626 6627 PetscFunctionBegin; 6628 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6629 PetscValidType(mat,1); 6630 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6631 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6632 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6633 MatCheckPreallocated(mat,1); 6634 6635 PetscCall(ISGetLocalSize(is,&numRows)); 6636 PetscCall(ISGetIndices(is,&rows)); 6637 PetscCall(MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b)); 6638 PetscCall(ISRestoreIndices(is,&rows)); 6639 PetscFunctionReturn(0); 6640 } 6641 6642 /*@C 6643 MatGetSize - Returns the numbers of rows and columns in a matrix. 6644 6645 Not Collective 6646 6647 Input Parameter: 6648 . mat - the matrix 6649 6650 Output Parameters: 6651 + m - the number of global rows 6652 - n - the number of global columns 6653 6654 Note: both output parameters can be NULL on input. 6655 6656 Level: beginner 6657 6658 .seealso: `MatGetLocalSize()` 6659 @*/ 6660 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n) 6661 { 6662 PetscFunctionBegin; 6663 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6664 if (m) *m = mat->rmap->N; 6665 if (n) *n = mat->cmap->N; 6666 PetscFunctionReturn(0); 6667 } 6668 6669 /*@C 6670 MatGetLocalSize - For most matrix formats, excluding `MATELEMENTAL` and `MATSCALAPACK`, Returns the number of local rows and local columns 6671 of a matrix. For all matrices this is the local size of the left and right vectors as returned by MatCreateVecs(). 6672 6673 Not Collective 6674 6675 Input Parameter: 6676 . mat - the matrix 6677 6678 Output Parameters: 6679 + m - the number of local rows, use `NULL` to not obtain this value 6680 - n - the number of local columns, use `NULL` to not obtain this value 6681 6682 Level: beginner 6683 6684 .seealso: `MatGetSize()` 6685 @*/ 6686 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n) 6687 { 6688 PetscFunctionBegin; 6689 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6690 if (m) PetscValidIntPointer(m,2); 6691 if (n) PetscValidIntPointer(n,3); 6692 if (m) *m = mat->rmap->n; 6693 if (n) *n = mat->cmap->n; 6694 PetscFunctionReturn(0); 6695 } 6696 6697 /*@C 6698 MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies this matrix by that are owned by 6699 this processor. (The columns of the "diagonal block" for most sparse matrix formats). See :any:`<sec_matlayout>` for details on matrix layouts. 6700 6701 Not Collective, unless matrix has not been allocated, then collective on Mat 6702 6703 Input Parameter: 6704 . mat - the matrix 6705 6706 Output Parameters: 6707 + m - the global index of the first local column, use `NULL` to not obtain this value 6708 - n - one more than the global index of the last local column, use `NULL` to not obtain this value 6709 6710 Level: developer 6711 6712 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRanges()`, `MatGetOwnershipRangesColumn()`, `PetscLayout` 6713 6714 @*/ 6715 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n) 6716 { 6717 PetscFunctionBegin; 6718 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6719 PetscValidType(mat,1); 6720 if (m) PetscValidIntPointer(m,2); 6721 if (n) PetscValidIntPointer(n,3); 6722 MatCheckPreallocated(mat,1); 6723 if (m) *m = mat->cmap->rstart; 6724 if (n) *n = mat->cmap->rend; 6725 PetscFunctionReturn(0); 6726 } 6727 6728 /*@C 6729 MatGetOwnershipRange - For matrices that own values by row, excludes `MATELEMENTAL` and `MATSCALAPACK`, returns the range of matrix rows owned by 6730 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 6731 vector product with this matrix. See :any:`<sec_matlayout>` for details on matrix layouts 6732 6733 Not Collective 6734 6735 Input Parameter: 6736 . mat - the matrix 6737 6738 Output Parameters: 6739 + m - the global index of the first local row, use `NULL` to not obtain this value 6740 - n - one more than the global index of the last local row, use `NULL` to not obtain this value 6741 6742 Note: 6743 This function requires that the matrix be preallocated. If you have not preallocated, consider using 6744 `PetscSplitOwnership`(`MPI_Comm` comm, `PetscInt` *n, `PetscInt` *N) 6745 and then `MPI_Scan()` to calculate prefix sums of the local sizes. 6746 6747 Level: beginner 6748 6749 .seealso: `MatGetOwnershipRanges()`, `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRangesColumn()`, `PetscSplitOwnership()`, `PetscSplitOwnershipBlock()`, 6750 `PetscLayout` 6751 6752 @*/ 6753 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n) 6754 { 6755 PetscFunctionBegin; 6756 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6757 PetscValidType(mat,1); 6758 if (m) PetscValidIntPointer(m,2); 6759 if (n) PetscValidIntPointer(n,3); 6760 MatCheckPreallocated(mat,1); 6761 if (m) *m = mat->rmap->rstart; 6762 if (n) *n = mat->rmap->rend; 6763 PetscFunctionReturn(0); 6764 } 6765 6766 /*@C 6767 MatGetOwnershipRanges - For matrices that own values by row, excludes `MATELEMENTAL` and `MATSCALAPACK`, returns the range of matrix rows owned by 6768 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 6769 vector product with this matrix. See :any:`<sec_matlayout>` for details on matrix layouts 6770 6771 Not Collective, unless matrix has not been allocated, then collective on Mat 6772 6773 Input Parameters: 6774 . mat - the matrix 6775 6776 Output Parameters: 6777 . ranges - start of each processors portion plus one more than the total length at the end 6778 6779 Level: beginner 6780 6781 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRangesColumn()`, `PetscLayout` 6782 6783 @*/ 6784 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges) 6785 { 6786 PetscFunctionBegin; 6787 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6788 PetscValidType(mat,1); 6789 MatCheckPreallocated(mat,1); 6790 PetscCall(PetscLayoutGetRanges(mat->rmap,ranges)); 6791 PetscFunctionReturn(0); 6792 } 6793 6794 /*@C 6795 MatGetOwnershipRangesColumn - Returns the ranges of matrix columns associated with rows of a vector one multiplies this vector by that are owned by 6796 each processor. (The columns of the "diagonal blocks", for most sparse matrix formats). See :any:`<sec_matlayout>` for details on matrix layouts. 6797 6798 Not Collective, unless matrix has not been allocated, then collective on Mat 6799 6800 Input Parameters: 6801 . mat - the matrix 6802 6803 Output Parameters: 6804 . ranges - start of each processors portion plus one more then the total length at the end 6805 6806 Level: beginner 6807 6808 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRanges()` 6809 6810 @*/ 6811 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges) 6812 { 6813 PetscFunctionBegin; 6814 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6815 PetscValidType(mat,1); 6816 MatCheckPreallocated(mat,1); 6817 PetscCall(PetscLayoutGetRanges(mat->cmap,ranges)); 6818 PetscFunctionReturn(0); 6819 } 6820 6821 /*@C 6822 MatGetOwnershipIS - Get row and column ownership of a matrices' values as index sets. For most matrices, excluding `MATELEMENTAL` and `MATSCALAPACK`, this 6823 corresponds to values returned by `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`. For `MATELEMENTAL` and `MATSCALAPACK` the ownership 6824 is more complicated. See :any:`<sec_matlayout>` for details on matrix layouts. 6825 6826 Not Collective 6827 6828 Input Parameter: 6829 . A - matrix 6830 6831 Output Parameters: 6832 + rows - rows in which this process owns elements, , use `NULL` to not obtain this value 6833 - cols - columns in which this process owns elements, use `NULL` to not obtain this value 6834 6835 Level: intermediate 6836 6837 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`, `MatSetValues()`, ``MATELEMENTAL``, ``MATSCALAPACK`` 6838 @*/ 6839 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols) 6840 { 6841 PetscErrorCode (*f)(Mat,IS*,IS*); 6842 6843 PetscFunctionBegin; 6844 MatCheckPreallocated(A,1); 6845 PetscCall(PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f)); 6846 if (f) { 6847 PetscCall((*f)(A,rows,cols)); 6848 } else { /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */ 6849 if (rows) PetscCall(ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows)); 6850 if (cols) PetscCall(ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols)); 6851 } 6852 PetscFunctionReturn(0); 6853 } 6854 6855 /*@C 6856 MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix. 6857 Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric() 6858 to complete the factorization. 6859 6860 Collective on Mat 6861 6862 Input Parameters: 6863 + mat - the matrix 6864 . row - row permutation 6865 . column - column permutation 6866 - info - structure containing 6867 $ levels - number of levels of fill. 6868 $ expected fill - as ratio of original fill. 6869 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 6870 missing diagonal entries) 6871 6872 Output Parameters: 6873 . fact - new matrix that has been symbolically factored 6874 6875 Notes: 6876 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 6877 6878 Most users should employ the simplified KSP interface for linear solvers 6879 instead of working directly with matrix algebra routines such as this. 6880 See, e.g., KSPCreate(). 6881 6882 Level: developer 6883 6884 .seealso: `MatLUFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()` 6885 `MatGetOrdering()`, `MatFactorInfo` 6886 6887 Note: this uses the definition of level of fill as in Y. Saad, 2003 6888 6889 Developer Note: fortran interface is not autogenerated as the f90 6890 interface definition cannot be generated correctly [due to MatFactorInfo] 6891 6892 References: 6893 . * - Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6894 @*/ 6895 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 6896 { 6897 PetscFunctionBegin; 6898 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 6899 PetscValidType(mat,2); 6900 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,3); 6901 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,4); 6902 PetscValidPointer(info,5); 6903 PetscValidPointer(fact,1); 6904 PetscCheck(info->levels >= 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %" PetscInt_FMT,(PetscInt)info->levels); 6905 PetscCheck(info->fill >= 1.0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6906 if (!fact->ops->ilufactorsymbolic) { 6907 MatSolverType stype; 6908 PetscCall(MatFactorGetSolverType(fact,&stype)); 6909 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver type %s",((PetscObject)mat)->type_name,stype); 6910 } 6911 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6912 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6913 MatCheckPreallocated(mat,2); 6914 6915 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0)); 6916 PetscCall((fact->ops->ilufactorsymbolic)(fact,mat,row,col,info)); 6917 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0)); 6918 PetscFunctionReturn(0); 6919 } 6920 6921 /*@C 6922 MatICCFactorSymbolic - Performs symbolic incomplete 6923 Cholesky factorization for a symmetric matrix. Use 6924 MatCholeskyFactorNumeric() to complete the factorization. 6925 6926 Collective on Mat 6927 6928 Input Parameters: 6929 + mat - the matrix 6930 . perm - row and column permutation 6931 - info - structure containing 6932 $ levels - number of levels of fill. 6933 $ expected fill - as ratio of original fill. 6934 6935 Output Parameter: 6936 . fact - the factored matrix 6937 6938 Notes: 6939 Most users should employ the KSP interface for linear solvers 6940 instead of working directly with matrix algebra routines such as this. 6941 See, e.g., KSPCreate(). 6942 6943 Level: developer 6944 6945 .seealso: `MatCholeskyFactorNumeric()`, `MatCholeskyFactor()`, `MatFactorInfo` 6946 6947 Note: this uses the definition of level of fill as in Y. Saad, 2003 6948 6949 Developer Note: fortran interface is not autogenerated as the f90 6950 interface definition cannot be generated correctly [due to MatFactorInfo] 6951 6952 References: 6953 . * - Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6954 @*/ 6955 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 6956 { 6957 PetscFunctionBegin; 6958 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 6959 PetscValidType(mat,2); 6960 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,3); 6961 PetscValidPointer(info,4); 6962 PetscValidPointer(fact,1); 6963 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6964 PetscCheck(info->levels >= 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %" PetscInt_FMT,(PetscInt) info->levels); 6965 PetscCheck(info->fill >= 1.0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6966 if (!(fact)->ops->iccfactorsymbolic) { 6967 MatSolverType stype; 6968 PetscCall(MatFactorGetSolverType(fact,&stype)); 6969 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver type %s",((PetscObject)mat)->type_name,stype); 6970 } 6971 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6972 MatCheckPreallocated(mat,2); 6973 6974 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0)); 6975 PetscCall((fact->ops->iccfactorsymbolic)(fact,mat,perm,info)); 6976 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0)); 6977 PetscFunctionReturn(0); 6978 } 6979 6980 /*@C 6981 MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat 6982 points to an array of valid matrices, they may be reused to store the new 6983 submatrices. 6984 6985 Collective on Mat 6986 6987 Input Parameters: 6988 + mat - the matrix 6989 . n - the number of submatrixes to be extracted (on this processor, may be zero) 6990 . irow, icol - index sets of rows and columns to extract 6991 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6992 6993 Output Parameter: 6994 . submat - the array of submatrices 6995 6996 Notes: 6997 MatCreateSubMatrices() can extract ONLY sequential submatrices 6998 (from both sequential and parallel matrices). Use MatCreateSubMatrix() 6999 to extract a parallel submatrix. 7000 7001 Some matrix types place restrictions on the row and column 7002 indices, such as that they be sorted or that they be equal to each other. 7003 7004 The index sets may not have duplicate entries. 7005 7006 When extracting submatrices from a parallel matrix, each processor can 7007 form a different submatrix by setting the rows and columns of its 7008 individual index sets according to the local submatrix desired. 7009 7010 When finished using the submatrices, the user should destroy 7011 them with MatDestroySubMatrices(). 7012 7013 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 7014 original matrix has not changed from that last call to MatCreateSubMatrices(). 7015 7016 This routine creates the matrices in submat; you should NOT create them before 7017 calling it. It also allocates the array of matrix pointers submat. 7018 7019 For BAIJ matrices the index sets must respect the block structure, that is if they 7020 request one row/column in a block, they must request all rows/columns that are in 7021 that block. For example, if the block size is 2 you cannot request just row 0 and 7022 column 0. 7023 7024 Fortran Note: 7025 The Fortran interface is slightly different from that given below; it 7026 requires one to pass in as submat a Mat (integer) array of size at least n+1. 7027 7028 Level: advanced 7029 7030 .seealso: `MatDestroySubMatrices()`, `MatCreateSubMatrix()`, `MatGetRow()`, `MatGetDiagonal()`, `MatReuse` 7031 @*/ 7032 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 7033 { 7034 PetscInt i; 7035 PetscBool eq; 7036 7037 PetscFunctionBegin; 7038 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7039 PetscValidType(mat,1); 7040 if (n) { 7041 PetscValidPointer(irow,3); 7042 for (i=0; i<n; i++) PetscValidHeaderSpecific(irow[i],IS_CLASSID,3); 7043 PetscValidPointer(icol,4); 7044 for (i=0; i<n; i++) PetscValidHeaderSpecific(icol[i],IS_CLASSID,4); 7045 } 7046 PetscValidPointer(submat,6); 7047 if (n && scall == MAT_REUSE_MATRIX) { 7048 PetscValidPointer(*submat,6); 7049 for (i=0; i<n; i++) PetscValidHeaderSpecific((*submat)[i],MAT_CLASSID,6); 7050 } 7051 PetscCheck(mat->ops->createsubmatrices,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7052 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7053 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7054 MatCheckPreallocated(mat,1); 7055 PetscCall(PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0)); 7056 PetscCall((*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat)); 7057 PetscCall(PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0)); 7058 for (i=0; i<n; i++) { 7059 (*submat)[i]->factortype = MAT_FACTOR_NONE; /* in case in place factorization was previously done on submatrix */ 7060 PetscCall(ISEqualUnsorted(irow[i],icol[i],&eq)); 7061 if (eq) { 7062 PetscCall(MatPropagateSymmetryOptions(mat,(*submat)[i])); 7063 } 7064 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 7065 if (mat->boundtocpu && mat->bindingpropagates) { 7066 PetscCall(MatBindToCPU((*submat)[i],PETSC_TRUE)); 7067 PetscCall(MatSetBindingPropagates((*submat)[i],PETSC_TRUE)); 7068 } 7069 #endif 7070 } 7071 PetscFunctionReturn(0); 7072 } 7073 7074 /*@C 7075 MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms). 7076 7077 Collective on Mat 7078 7079 Input Parameters: 7080 + mat - the matrix 7081 . n - the number of submatrixes to be extracted 7082 . irow, icol - index sets of rows and columns to extract 7083 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 7084 7085 Output Parameter: 7086 . submat - the array of submatrices 7087 7088 Level: advanced 7089 7090 .seealso: `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRow()`, `MatGetDiagonal()`, `MatReuse` 7091 @*/ 7092 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 7093 { 7094 PetscInt i; 7095 PetscBool eq; 7096 7097 PetscFunctionBegin; 7098 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7099 PetscValidType(mat,1); 7100 if (n) { 7101 PetscValidPointer(irow,3); 7102 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 7103 PetscValidPointer(icol,4); 7104 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 7105 } 7106 PetscValidPointer(submat,6); 7107 if (n && scall == MAT_REUSE_MATRIX) { 7108 PetscValidPointer(*submat,6); 7109 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 7110 } 7111 PetscCheck(mat->ops->createsubmatricesmpi,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7112 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7113 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7114 MatCheckPreallocated(mat,1); 7115 7116 PetscCall(PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0)); 7117 PetscCall((*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat)); 7118 PetscCall(PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0)); 7119 for (i=0; i<n; i++) { 7120 PetscCall(ISEqualUnsorted(irow[i],icol[i],&eq)); 7121 if (eq) { 7122 PetscCall(MatPropagateSymmetryOptions(mat,(*submat)[i])); 7123 } 7124 } 7125 PetscFunctionReturn(0); 7126 } 7127 7128 /*@C 7129 MatDestroyMatrices - Destroys an array of matrices. 7130 7131 Collective on Mat 7132 7133 Input Parameters: 7134 + n - the number of local matrices 7135 - mat - the matrices (note that this is a pointer to the array of matrices) 7136 7137 Level: advanced 7138 7139 Notes: 7140 Frees not only the matrices, but also the array that contains the matrices 7141 In Fortran will not free the array. 7142 7143 .seealso: `MatCreateSubMatrices()` `MatDestroySubMatrices()` 7144 @*/ 7145 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[]) 7146 { 7147 PetscInt i; 7148 7149 PetscFunctionBegin; 7150 if (!*mat) PetscFunctionReturn(0); 7151 PetscCheck(n >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %" PetscInt_FMT,n); 7152 PetscValidPointer(mat,2); 7153 7154 for (i=0; i<n; i++) { 7155 PetscCall(MatDestroy(&(*mat)[i])); 7156 } 7157 7158 /* memory is allocated even if n = 0 */ 7159 PetscCall(PetscFree(*mat)); 7160 PetscFunctionReturn(0); 7161 } 7162 7163 /*@C 7164 MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices(). 7165 7166 Collective on Mat 7167 7168 Input Parameters: 7169 + n - the number of local matrices 7170 - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling 7171 sequence of MatCreateSubMatrices()) 7172 7173 Level: advanced 7174 7175 Notes: 7176 Frees not only the matrices, but also the array that contains the matrices 7177 In Fortran will not free the array. 7178 7179 .seealso: `MatCreateSubMatrices()` 7180 @*/ 7181 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[]) 7182 { 7183 Mat mat0; 7184 7185 PetscFunctionBegin; 7186 if (!*mat) PetscFunctionReturn(0); 7187 /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */ 7188 PetscCheck(n >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %" PetscInt_FMT,n); 7189 PetscValidPointer(mat,2); 7190 7191 mat0 = (*mat)[0]; 7192 if (mat0 && mat0->ops->destroysubmatrices) { 7193 PetscCall((mat0->ops->destroysubmatrices)(n,mat)); 7194 } else { 7195 PetscCall(MatDestroyMatrices(n,mat)); 7196 } 7197 PetscFunctionReturn(0); 7198 } 7199 7200 /*@C 7201 MatGetSeqNonzeroStructure - Extracts the nonzero structure from a matrix and stores it, in its entirety, on each process 7202 7203 Collective on Mat 7204 7205 Input Parameters: 7206 . mat - the matrix 7207 7208 Output Parameter: 7209 . matstruct - the sequential matrix with the nonzero structure of mat 7210 7211 Level: intermediate 7212 7213 .seealso: `MatDestroySeqNonzeroStructure()`, `MatCreateSubMatrices()`, `MatDestroyMatrices()` 7214 @*/ 7215 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct) 7216 { 7217 PetscFunctionBegin; 7218 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7219 PetscValidPointer(matstruct,2); 7220 7221 PetscValidType(mat,1); 7222 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7223 MatCheckPreallocated(mat,1); 7224 7225 PetscCheck(mat->ops->getseqnonzerostructure,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s",((PetscObject)mat)->type_name); 7226 PetscCall(PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0)); 7227 PetscCall((*mat->ops->getseqnonzerostructure)(mat,matstruct)); 7228 PetscCall(PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0)); 7229 PetscFunctionReturn(0); 7230 } 7231 7232 /*@C 7233 MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure(). 7234 7235 Collective on Mat 7236 7237 Input Parameters: 7238 . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling 7239 sequence of MatGetSequentialNonzeroStructure()) 7240 7241 Level: advanced 7242 7243 Notes: 7244 Frees not only the matrices, but also the array that contains the matrices 7245 7246 .seealso: `MatGetSeqNonzeroStructure()` 7247 @*/ 7248 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat) 7249 { 7250 PetscFunctionBegin; 7251 PetscValidPointer(mat,1); 7252 PetscCall(MatDestroy(mat)); 7253 PetscFunctionReturn(0); 7254 } 7255 7256 /*@ 7257 MatIncreaseOverlap - Given a set of submatrices indicated by index sets, 7258 replaces the index sets by larger ones that represent submatrices with 7259 additional overlap. 7260 7261 Collective on Mat 7262 7263 Input Parameters: 7264 + mat - the matrix 7265 . n - the number of index sets 7266 . is - the array of index sets (these index sets will changed during the call) 7267 - ov - the additional overlap requested 7268 7269 Options Database: 7270 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7271 7272 Level: developer 7273 7274 Developer Note: 7275 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. 7276 7277 .seealso: `MatCreateSubMatrices()` 7278 @*/ 7279 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov) 7280 { 7281 PetscInt i,bs,cbs; 7282 7283 PetscFunctionBegin; 7284 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7285 PetscValidType(mat,1); 7286 PetscValidLogicalCollectiveInt(mat,n,2); 7287 PetscCheck(n >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %" PetscInt_FMT,n); 7288 if (n) { 7289 PetscValidPointer(is,3); 7290 for (i = 0; i < n; i++) PetscValidHeaderSpecific(is[i],IS_CLASSID,3); 7291 } 7292 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7293 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7294 MatCheckPreallocated(mat,1); 7295 7296 if (!ov || !n) PetscFunctionReturn(0); 7297 PetscCheck(mat->ops->increaseoverlap,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7298 PetscCall(PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0)); 7299 PetscCall((*mat->ops->increaseoverlap)(mat,n,is,ov)); 7300 PetscCall(PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0)); 7301 PetscCall(MatGetBlockSizes(mat,&bs,&cbs)); 7302 if (bs == cbs) { 7303 for (i=0; i<n; i++) { 7304 PetscCall(ISSetBlockSize(is[i],bs)); 7305 } 7306 } 7307 PetscFunctionReturn(0); 7308 } 7309 7310 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt); 7311 7312 /*@ 7313 MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across 7314 a sub communicator, replaces the index sets by larger ones that represent submatrices with 7315 additional overlap. 7316 7317 Collective on Mat 7318 7319 Input Parameters: 7320 + mat - the matrix 7321 . n - the number of index sets 7322 . is - the array of index sets (these index sets will changed during the call) 7323 - ov - the additional overlap requested 7324 7325 Options Database: 7326 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7327 7328 Level: developer 7329 7330 .seealso: `MatCreateSubMatrices()` 7331 @*/ 7332 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov) 7333 { 7334 PetscInt i; 7335 7336 PetscFunctionBegin; 7337 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7338 PetscValidType(mat,1); 7339 PetscCheck(n >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %" PetscInt_FMT,n); 7340 if (n) { 7341 PetscValidPointer(is,3); 7342 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 7343 } 7344 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7345 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7346 MatCheckPreallocated(mat,1); 7347 if (!ov) PetscFunctionReturn(0); 7348 PetscCall(PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0)); 7349 for (i=0; i<n; i++) { 7350 PetscCall(MatIncreaseOverlapSplit_Single(mat,&is[i],ov)); 7351 } 7352 PetscCall(PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0)); 7353 PetscFunctionReturn(0); 7354 } 7355 7356 /*@ 7357 MatGetBlockSize - Returns the matrix block size. 7358 7359 Not Collective 7360 7361 Input Parameter: 7362 . mat - the matrix 7363 7364 Output Parameter: 7365 . bs - block size 7366 7367 Notes: 7368 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7369 7370 If the block size has not been set yet this routine returns 1. 7371 7372 Level: intermediate 7373 7374 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSizes()` 7375 @*/ 7376 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs) 7377 { 7378 PetscFunctionBegin; 7379 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7380 PetscValidIntPointer(bs,2); 7381 *bs = PetscAbs(mat->rmap->bs); 7382 PetscFunctionReturn(0); 7383 } 7384 7385 /*@ 7386 MatGetBlockSizes - Returns the matrix block row and column sizes. 7387 7388 Not Collective 7389 7390 Input Parameter: 7391 . mat - the matrix 7392 7393 Output Parameters: 7394 + rbs - row block size 7395 - cbs - column block size 7396 7397 Notes: 7398 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7399 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7400 7401 If a block size has not been set yet this routine returns 1. 7402 7403 Level: intermediate 7404 7405 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSize()`, `MatSetBlockSizes()` 7406 @*/ 7407 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs) 7408 { 7409 PetscFunctionBegin; 7410 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7411 if (rbs) PetscValidIntPointer(rbs,2); 7412 if (cbs) PetscValidIntPointer(cbs,3); 7413 if (rbs) *rbs = PetscAbs(mat->rmap->bs); 7414 if (cbs) *cbs = PetscAbs(mat->cmap->bs); 7415 PetscFunctionReturn(0); 7416 } 7417 7418 /*@ 7419 MatSetBlockSize - Sets the matrix block size. 7420 7421 Logically Collective on Mat 7422 7423 Input Parameters: 7424 + mat - the matrix 7425 - bs - block size 7426 7427 Notes: 7428 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7429 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7430 7431 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size 7432 is compatible with the matrix local sizes. 7433 7434 Level: intermediate 7435 7436 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`, `MatGetBlockSizes()` 7437 @*/ 7438 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs) 7439 { 7440 PetscFunctionBegin; 7441 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7442 PetscValidLogicalCollectiveInt(mat,bs,2); 7443 PetscCall(MatSetBlockSizes(mat,bs,bs)); 7444 PetscFunctionReturn(0); 7445 } 7446 7447 typedef struct { 7448 PetscInt n; 7449 IS *is; 7450 Mat *mat; 7451 PetscObjectState nonzerostate; 7452 Mat C; 7453 } EnvelopeData; 7454 7455 static PetscErrorCode EnvelopeDataDestroy(EnvelopeData *edata) 7456 { 7457 for (PetscInt i=0; i<edata->n; i++) { 7458 PetscCall(ISDestroy(&edata->is[i])); 7459 } 7460 PetscCall(PetscFree(edata->is)); 7461 PetscCall(PetscFree(edata)); 7462 return 0; 7463 } 7464 7465 /* 7466 MatComputeVariableBlockEnvelope - Given a matrix whose nonzeros are in blocks along the diagonal this computes and stores 7467 the sizes of these blocks in the matrix. An individual block may lie over several processes. 7468 7469 Collective on mat 7470 7471 Input Parameter: 7472 . mat - the matrix 7473 7474 Notes: 7475 There can be zeros within the blocks 7476 7477 The blocks can overlap between processes, including laying on more than two processes 7478 7479 */ 7480 static PetscErrorCode MatComputeVariableBlockEnvelope(Mat mat) 7481 { 7482 PetscInt n,*sizes,*starts,i = 0,env = 0, tbs = 0, lblocks = 0,rstart,II,ln = 0,cnt = 0,cstart,cend; 7483 PetscInt *diag,*odiag,sc; 7484 VecScatter scatter; 7485 PetscScalar *seqv; 7486 const PetscScalar *parv; 7487 const PetscInt *ia,*ja; 7488 PetscBool set,flag,done; 7489 Mat AA = mat,A; 7490 MPI_Comm comm; 7491 PetscMPIInt rank,size,tag; 7492 MPI_Status status; 7493 PetscContainer container; 7494 EnvelopeData *edata; 7495 Vec seq,par; 7496 IS isglobal; 7497 7498 PetscFunctionBegin; 7499 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7500 PetscCall(MatIsSymmetricKnown(mat,&set,&flag)); 7501 if (!set || !flag) { 7502 /* TOO: only needs nonzero structure of transpose */ 7503 PetscCall(MatTranspose(mat,MAT_INITIAL_MATRIX,&AA)); 7504 PetscCall(MatAXPY(AA,1.0,mat,DIFFERENT_NONZERO_PATTERN)); 7505 } 7506 PetscCall(MatAIJGetLocalMat(AA,&A)); 7507 PetscCall(MatGetRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ia,&ja,&done)); 7508 PetscCheck(done,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Unable to get IJ structure from matrix"); 7509 7510 PetscCall(MatGetLocalSize(mat,&n,NULL)); 7511 PetscCall(PetscObjectGetNewTag((PetscObject)mat,&tag)); 7512 PetscCall(PetscObjectGetComm((PetscObject)mat,&comm)); 7513 PetscCallMPI(MPI_Comm_size(comm,&size)); 7514 PetscCallMPI(MPI_Comm_rank(comm,&rank)); 7515 7516 PetscCall(PetscMalloc2(n,&sizes,n,&starts)); 7517 7518 if (rank > 0) { 7519 PetscCallMPI(MPI_Recv(&env,1,MPIU_INT,rank-1,tag,comm,&status)); 7520 PetscCallMPI(MPI_Recv(&tbs,1,MPIU_INT,rank-1,tag,comm,&status)); 7521 } 7522 PetscCall(MatGetOwnershipRange(mat,&rstart,NULL)); 7523 for (i=0; i<n; i++) { 7524 env = PetscMax(env,ja[ia[i+1]-1]); 7525 II = rstart + i; 7526 if (env == II) { 7527 starts[lblocks] = tbs; 7528 sizes[lblocks++] = 1 + II - tbs; 7529 tbs = 1 + II; 7530 } 7531 } 7532 if (rank < size-1) { 7533 PetscCallMPI(MPI_Send(&env,1,MPIU_INT,rank+1,tag,comm)); 7534 PetscCallMPI(MPI_Send(&tbs,1,MPIU_INT,rank+1,tag,comm)); 7535 } 7536 7537 PetscCall(MatRestoreRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ia,&ja,&done)); 7538 if (!set || !flag) { 7539 PetscCall(MatDestroy(&AA)); 7540 } 7541 PetscCall(MatDestroy(&A)); 7542 7543 PetscCall(PetscNew(&edata)); 7544 PetscCall(MatGetNonzeroState(mat,&edata->nonzerostate)); 7545 edata->n = lblocks; 7546 /* create IS needed for extracting blocks from the original matrix */ 7547 PetscCall(PetscMalloc1(lblocks,&edata->is)); 7548 for (PetscInt i=0; i<lblocks; i++) { 7549 PetscCall(ISCreateStride(PETSC_COMM_SELF,sizes[i],starts[i],1,&edata->is[i])); 7550 } 7551 7552 /* Create the resulting inverse matrix structure with preallocation information */ 7553 PetscCall(MatCreate(PetscObjectComm((PetscObject)mat),&edata->C)); 7554 PetscCall(MatSetSizes(edata->C,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N)); 7555 PetscCall(MatSetBlockSizesFromMats(edata->C,mat,mat)); 7556 PetscCall(MatSetType(edata->C,MATAIJ)); 7557 7558 /* Communicate the start and end of each row, from each block to the correct rank */ 7559 /* TODO: Use PetscSF instead of VecScatter */ 7560 for (PetscInt i=0; i<lblocks; i++) ln += sizes[i]; 7561 PetscCall(VecCreateSeq(PETSC_COMM_SELF,2*ln,&seq)); 7562 PetscCall(VecGetArrayWrite(seq,&seqv)); 7563 for (PetscInt i=0; i<lblocks; i++) { 7564 for (PetscInt j=0; j<sizes[i]; j++) { 7565 seqv[cnt] = starts[i]; 7566 seqv[cnt+1] = starts[i] + sizes[i]; 7567 cnt += 2; 7568 } 7569 } 7570 PetscCall(VecRestoreArrayWrite(seq,&seqv)); 7571 PetscCallMPI(MPI_Scan(&cnt,&sc,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat))); 7572 sc -= cnt; 7573 PetscCall(VecCreateMPI(PetscObjectComm((PetscObject)mat),2*mat->rmap->n,2*mat->rmap->N,&par)); 7574 PetscCall(ISCreateStride(PETSC_COMM_SELF,cnt,sc,1,&isglobal)); 7575 PetscCall(VecScatterCreate(seq, NULL ,par, isglobal,&scatter)); 7576 PetscCall(ISDestroy(&isglobal)); 7577 PetscCall(VecScatterBegin(scatter,seq,par,INSERT_VALUES,SCATTER_FORWARD)); 7578 PetscCall(VecScatterEnd(scatter,seq,par,INSERT_VALUES,SCATTER_FORWARD)); 7579 PetscCall(VecScatterDestroy(&scatter)); 7580 PetscCall(VecDestroy(&seq)); 7581 PetscCall(MatGetOwnershipRangeColumn(mat,&cstart,&cend)); 7582 PetscCall(PetscMalloc2(mat->rmap->n,&diag,mat->rmap->n,&odiag)); 7583 PetscCall(VecGetArrayRead(par,&parv)); 7584 cnt = 0; 7585 PetscCall(MatGetSize(mat,NULL,&n)); 7586 for (PetscInt i=0; i<mat->rmap->n; i++) { 7587 PetscInt start,end,d = 0,od = 0; 7588 7589 start = (PetscInt)PetscRealPart(parv[cnt]); 7590 end = (PetscInt)PetscRealPart(parv[cnt+1]); 7591 cnt += 2; 7592 7593 if (start < cstart) {od += cstart - start + n - cend; d += cend - cstart;} 7594 else if (start < cend) {od += n - cend; d += cend - start;} 7595 else od += n - start; 7596 if (end <= cstart) {od -= cstart - end + n - cend; d -= cend - cstart;} 7597 else if (end < cend) {od -= n - cend; d -= cend - end;} 7598 else od -= n - end; 7599 7600 odiag[i] = od; 7601 diag[i] = d; 7602 } 7603 PetscCall(VecRestoreArrayRead(par,&parv)); 7604 PetscCall(VecDestroy(&par)); 7605 PetscCall(MatXAIJSetPreallocation(edata->C,mat->rmap->bs,diag,odiag,NULL,NULL)); 7606 PetscCall(PetscFree2(diag,odiag)); 7607 PetscCall(PetscFree2(sizes,starts)); 7608 7609 PetscCall(PetscContainerCreate(PETSC_COMM_SELF,&container)); 7610 PetscCall(PetscContainerSetPointer(container,edata)); 7611 PetscCall(PetscContainerSetUserDestroy(container,(PetscErrorCode (*)(void*))EnvelopeDataDestroy)); 7612 PetscCall(PetscObjectCompose((PetscObject)mat,"EnvelopeData",(PetscObject)container)); 7613 PetscCall(PetscObjectDereference((PetscObject)container)); 7614 PetscFunctionReturn(0); 7615 } 7616 7617 /*@ 7618 MatInvertVariableBlockEnvelope - set matrix C to be the inverted block diagonal of matrix A 7619 7620 Collective on Mat 7621 7622 Input Parameters: 7623 . A - the matrix 7624 7625 Output Parameters: 7626 . C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set. 7627 7628 Notes: 7629 For efficiency the matrix A should have all the nonzero entries clustered in smallish blocks along the diagonal. 7630 7631 Level: advanced 7632 7633 .seealso: MatInvertBlockDiagonal(), MatComputeBlockDiagonal() 7634 @*/ 7635 PetscErrorCode MatInvertVariableBlockEnvelope(Mat A,MatReuse reuse, Mat *C) 7636 { 7637 PetscContainer container; 7638 EnvelopeData *edata; 7639 PetscObjectState nonzerostate; 7640 7641 PetscFunctionBegin; 7642 PetscCall(PetscObjectQuery((PetscObject)A,"EnvelopeData",(PetscObject*)&container)); 7643 if (!container) { 7644 PetscCall(MatComputeVariableBlockEnvelope(A)); 7645 PetscCall(PetscObjectQuery((PetscObject)A,"EnvelopeData",(PetscObject*)&container)); 7646 } 7647 PetscCall(PetscContainerGetPointer(container,(void**)&edata)); 7648 PetscCall(MatGetNonzeroState(A,&nonzerostate)); 7649 PetscCheck(nonzerostate <= edata->nonzerostate,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Cannot handle changes to matrix nonzero structure"); 7650 PetscCheck(reuse != MAT_REUSE_MATRIX || *C == edata->C,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C matrix must be the same as previously output"); 7651 7652 PetscCall(MatCreateSubMatrices(A,edata->n,edata->is,edata->is,MAT_INITIAL_MATRIX,&edata->mat)); 7653 *C = edata->C; 7654 7655 for (PetscInt i=0; i<edata->n; i++) { 7656 Mat D; 7657 PetscScalar *dvalues; 7658 7659 PetscCall(MatConvert(edata->mat[i], MATSEQDENSE,MAT_INITIAL_MATRIX,&D)); 7660 PetscCall(MatSetOption(*C,MAT_ROW_ORIENTED,PETSC_FALSE)); 7661 PetscCall(MatSeqDenseInvert(D)); 7662 PetscCall(MatDenseGetArray(D,&dvalues)); 7663 PetscCall(MatSetValuesIS(*C,edata->is[i],edata->is[i],dvalues,INSERT_VALUES)); 7664 PetscCall(MatDestroy(&D)); 7665 } 7666 PetscCall(MatDestroySubMatrices(edata->n,&edata->mat)); 7667 PetscCall(MatAssemblyBegin(*C,MAT_FINAL_ASSEMBLY)); 7668 PetscCall(MatAssemblyEnd(*C,MAT_FINAL_ASSEMBLY)); 7669 PetscFunctionReturn(0); 7670 } 7671 7672 /*@ 7673 MatSetVariableBlockSizes - Sets diagonal point-blocks of the matrix that need not be of the same size 7674 7675 Logically Collective on Mat 7676 7677 Input Parameters: 7678 + mat - the matrix 7679 . nblocks - the number of blocks on this process, each block can only exist on a single process 7680 - bsizes - the block sizes 7681 7682 Notes: 7683 Currently used by PCVPBJACOBI for AIJ matrices 7684 7685 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. 7686 7687 Level: intermediate 7688 7689 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`, `MatGetBlockSizes()`, `MatGetVariableBlockSizes()`, `MatComputeVariableBlockEnvelope()`, `PCVPBJACOBI` 7690 @*/ 7691 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes) 7692 { 7693 PetscInt i,ncnt = 0, nlocal; 7694 7695 PetscFunctionBegin; 7696 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7697 PetscCheck(nblocks >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero"); 7698 PetscCall(MatGetLocalSize(mat,&nlocal,NULL)); 7699 for (i=0; i<nblocks; i++) ncnt += bsizes[i]; 7700 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); 7701 PetscCall(PetscFree(mat->bsizes)); 7702 mat->nblocks = nblocks; 7703 PetscCall(PetscMalloc1(nblocks,&mat->bsizes)); 7704 PetscCall(PetscArraycpy(mat->bsizes,bsizes,nblocks)); 7705 PetscFunctionReturn(0); 7706 } 7707 7708 /*@C 7709 MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size 7710 7711 Logically Collective on Mat 7712 7713 Input Parameter: 7714 . mat - the matrix 7715 7716 Output Parameters: 7717 + nblocks - the number of blocks on this process 7718 - bsizes - the block sizes 7719 7720 Notes: Currently not supported from Fortran 7721 7722 Level: intermediate 7723 7724 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`, `MatGetBlockSizes()`, `MatSetVariableBlockSizes()`, `MatComputeVariableBlockEnvelope()` 7725 @*/ 7726 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes) 7727 { 7728 PetscFunctionBegin; 7729 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7730 *nblocks = mat->nblocks; 7731 *bsizes = mat->bsizes; 7732 PetscFunctionReturn(0); 7733 } 7734 7735 /*@ 7736 MatSetBlockSizes - Sets the matrix block row and column sizes. 7737 7738 Logically Collective on Mat 7739 7740 Input Parameters: 7741 + mat - the matrix 7742 . rbs - row block size 7743 - cbs - column block size 7744 7745 Notes: 7746 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7747 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7748 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7749 7750 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes 7751 are compatible with the matrix local sizes. 7752 7753 The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs(). 7754 7755 Level: intermediate 7756 7757 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSize()`, `MatGetBlockSizes()` 7758 @*/ 7759 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs) 7760 { 7761 PetscFunctionBegin; 7762 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7763 PetscValidLogicalCollectiveInt(mat,rbs,2); 7764 PetscValidLogicalCollectiveInt(mat,cbs,3); 7765 if (mat->ops->setblocksizes) PetscCall((*mat->ops->setblocksizes)(mat,rbs,cbs)); 7766 if (mat->rmap->refcnt) { 7767 ISLocalToGlobalMapping l2g = NULL; 7768 PetscLayout nmap = NULL; 7769 7770 PetscCall(PetscLayoutDuplicate(mat->rmap,&nmap)); 7771 if (mat->rmap->mapping) { 7772 PetscCall(ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g)); 7773 } 7774 PetscCall(PetscLayoutDestroy(&mat->rmap)); 7775 mat->rmap = nmap; 7776 mat->rmap->mapping = l2g; 7777 } 7778 if (mat->cmap->refcnt) { 7779 ISLocalToGlobalMapping l2g = NULL; 7780 PetscLayout nmap = NULL; 7781 7782 PetscCall(PetscLayoutDuplicate(mat->cmap,&nmap)); 7783 if (mat->cmap->mapping) { 7784 PetscCall(ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g)); 7785 } 7786 PetscCall(PetscLayoutDestroy(&mat->cmap)); 7787 mat->cmap = nmap; 7788 mat->cmap->mapping = l2g; 7789 } 7790 PetscCall(PetscLayoutSetBlockSize(mat->rmap,rbs)); 7791 PetscCall(PetscLayoutSetBlockSize(mat->cmap,cbs)); 7792 PetscFunctionReturn(0); 7793 } 7794 7795 /*@ 7796 MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices 7797 7798 Logically Collective on Mat 7799 7800 Input Parameters: 7801 + mat - the matrix 7802 . fromRow - matrix from which to copy row block size 7803 - fromCol - matrix from which to copy column block size (can be same as fromRow) 7804 7805 Level: developer 7806 7807 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()` 7808 @*/ 7809 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol) 7810 { 7811 PetscFunctionBegin; 7812 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7813 PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2); 7814 PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3); 7815 if (fromRow->rmap->bs > 0) PetscCall(PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs)); 7816 if (fromCol->cmap->bs > 0) PetscCall(PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs)); 7817 PetscFunctionReturn(0); 7818 } 7819 7820 /*@ 7821 MatResidual - Default routine to calculate the residual. 7822 7823 Collective on Mat 7824 7825 Input Parameters: 7826 + mat - the matrix 7827 . b - the right-hand-side 7828 - x - the approximate solution 7829 7830 Output Parameter: 7831 . r - location to store the residual 7832 7833 Level: developer 7834 7835 .seealso: `PCMGSetResidual()` 7836 @*/ 7837 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r) 7838 { 7839 PetscFunctionBegin; 7840 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7841 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 7842 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 7843 PetscValidHeaderSpecific(r,VEC_CLASSID,4); 7844 PetscValidType(mat,1); 7845 MatCheckPreallocated(mat,1); 7846 PetscCall(PetscLogEventBegin(MAT_Residual,mat,0,0,0)); 7847 if (!mat->ops->residual) { 7848 PetscCall(MatMult(mat,x,r)); 7849 PetscCall(VecAYPX(r,-1.0,b)); 7850 } else { 7851 PetscCall((*mat->ops->residual)(mat,b,x,r)); 7852 } 7853 PetscCall(PetscLogEventEnd(MAT_Residual,mat,0,0,0)); 7854 PetscFunctionReturn(0); 7855 } 7856 7857 /*@C 7858 MatGetRowIJ - Returns the compressed row storage i and j indices for the local rows of a sparse matrix 7859 7860 Collective on Mat 7861 7862 Input Parameters: 7863 + mat - the matrix 7864 . shift - 0 or 1 indicating we want the indices starting at 0 or 1 7865 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized 7866 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7867 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7868 always used. 7869 7870 Output Parameters: 7871 + n - number of local rows in the (possibly compressed) matrix 7872 . ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix 7873 . ja - the column indices 7874 - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers 7875 are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set 7876 7877 Level: developer 7878 7879 Notes: 7880 You CANNOT change any of the ia[] or ja[] values. 7881 7882 Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values. 7883 7884 Fortran Notes: 7885 In Fortran use 7886 $ 7887 $ PetscInt ia(1), ja(1) 7888 $ PetscOffset iia, jja 7889 $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr) 7890 $ ! Access the ith and jth entries via ia(iia + i) and ja(jja + j) 7891 7892 or 7893 $ 7894 $ PetscInt, pointer :: ia(:),ja(:) 7895 $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr) 7896 $ ! Access the ith and jth entries via ia(i) and ja(j) 7897 7898 .seealso: `MatGetColumnIJ()`, `MatRestoreRowIJ()`, `MatSeqAIJGetArray()` 7899 @*/ 7900 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7901 { 7902 PetscFunctionBegin; 7903 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7904 PetscValidType(mat,1); 7905 if (n) PetscValidIntPointer(n,5); 7906 if (ia) PetscValidPointer(ia,6); 7907 if (ja) PetscValidPointer(ja,7); 7908 if (done) PetscValidBoolPointer(done,8); 7909 MatCheckPreallocated(mat,1); 7910 if (!mat->ops->getrowij && done) *done = PETSC_FALSE; 7911 else { 7912 if (done) *done = PETSC_TRUE; 7913 PetscCall(PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0)); 7914 PetscCall((*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done)); 7915 PetscCall(PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0)); 7916 } 7917 PetscFunctionReturn(0); 7918 } 7919 7920 /*@C 7921 MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices. 7922 7923 Collective on Mat 7924 7925 Input Parameters: 7926 + mat - the matrix 7927 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7928 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7929 symmetrized 7930 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7931 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7932 always used. 7933 . n - number of columns in the (possibly compressed) matrix 7934 . ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix 7935 - ja - the row indices 7936 7937 Output Parameters: 7938 . done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned 7939 7940 Level: developer 7941 7942 .seealso: `MatGetRowIJ()`, `MatRestoreColumnIJ()` 7943 @*/ 7944 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7945 { 7946 PetscFunctionBegin; 7947 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7948 PetscValidType(mat,1); 7949 PetscValidIntPointer(n,5); 7950 if (ia) PetscValidPointer(ia,6); 7951 if (ja) PetscValidPointer(ja,7); 7952 PetscValidBoolPointer(done,8); 7953 MatCheckPreallocated(mat,1); 7954 if (!mat->ops->getcolumnij) *done = PETSC_FALSE; 7955 else { 7956 *done = PETSC_TRUE; 7957 PetscCall((*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done)); 7958 } 7959 PetscFunctionReturn(0); 7960 } 7961 7962 /*@C 7963 MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with 7964 MatGetRowIJ(). 7965 7966 Collective on Mat 7967 7968 Input Parameters: 7969 + mat - the matrix 7970 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7971 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7972 symmetrized 7973 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7974 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7975 always used. 7976 . n - size of (possibly compressed) matrix 7977 . ia - the row pointers 7978 - ja - the column indices 7979 7980 Output Parameters: 7981 . done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7982 7983 Note: 7984 This routine zeros out n, ia, and ja. This is to prevent accidental 7985 us of the array after it has been restored. If you pass NULL, it will 7986 not zero the pointers. Use of ia or ja after MatRestoreRowIJ() is invalid. 7987 7988 Level: developer 7989 7990 .seealso: `MatGetRowIJ()`, `MatRestoreColumnIJ()` 7991 @*/ 7992 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7993 { 7994 PetscFunctionBegin; 7995 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7996 PetscValidType(mat,1); 7997 if (ia) PetscValidPointer(ia,6); 7998 if (ja) PetscValidPointer(ja,7); 7999 if (done) PetscValidBoolPointer(done,8); 8000 MatCheckPreallocated(mat,1); 8001 8002 if (!mat->ops->restorerowij && done) *done = PETSC_FALSE; 8003 else { 8004 if (done) *done = PETSC_TRUE; 8005 PetscCall((*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done)); 8006 if (n) *n = 0; 8007 if (ia) *ia = NULL; 8008 if (ja) *ja = NULL; 8009 } 8010 PetscFunctionReturn(0); 8011 } 8012 8013 /*@C 8014 MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with 8015 MatGetColumnIJ(). 8016 8017 Collective on Mat 8018 8019 Input Parameters: 8020 + mat - the matrix 8021 . shift - 1 or zero indicating we want the indices starting at 0 or 1 8022 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 8023 symmetrized 8024 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 8025 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 8026 always used. 8027 8028 Output Parameters: 8029 + n - size of (possibly compressed) matrix 8030 . ia - the column pointers 8031 . ja - the row indices 8032 - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 8033 8034 Level: developer 8035 8036 .seealso: `MatGetColumnIJ()`, `MatRestoreRowIJ()` 8037 @*/ 8038 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 8039 { 8040 PetscFunctionBegin; 8041 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8042 PetscValidType(mat,1); 8043 if (ia) PetscValidPointer(ia,6); 8044 if (ja) PetscValidPointer(ja,7); 8045 PetscValidBoolPointer(done,8); 8046 MatCheckPreallocated(mat,1); 8047 8048 if (!mat->ops->restorecolumnij) *done = PETSC_FALSE; 8049 else { 8050 *done = PETSC_TRUE; 8051 PetscCall((*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done)); 8052 if (n) *n = 0; 8053 if (ia) *ia = NULL; 8054 if (ja) *ja = NULL; 8055 } 8056 PetscFunctionReturn(0); 8057 } 8058 8059 /*@C 8060 MatColoringPatch -Used inside matrix coloring routines that 8061 use MatGetRowIJ() and/or MatGetColumnIJ(). 8062 8063 Collective on Mat 8064 8065 Input Parameters: 8066 + mat - the matrix 8067 . ncolors - max color value 8068 . n - number of entries in colorarray 8069 - colorarray - array indicating color for each column 8070 8071 Output Parameters: 8072 . iscoloring - coloring generated using colorarray information 8073 8074 Level: developer 8075 8076 .seealso: `MatGetRowIJ()`, `MatGetColumnIJ()` 8077 8078 @*/ 8079 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring) 8080 { 8081 PetscFunctionBegin; 8082 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8083 PetscValidType(mat,1); 8084 PetscValidIntPointer(colorarray,4); 8085 PetscValidPointer(iscoloring,5); 8086 MatCheckPreallocated(mat,1); 8087 8088 if (!mat->ops->coloringpatch) { 8089 PetscCall(ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring)); 8090 } else { 8091 PetscCall((*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring)); 8092 } 8093 PetscFunctionReturn(0); 8094 } 8095 8096 /*@ 8097 MatSetUnfactored - Resets a factored matrix to be treated as unfactored. 8098 8099 Logically Collective on Mat 8100 8101 Input Parameter: 8102 . mat - the factored matrix to be reset 8103 8104 Notes: 8105 This routine should be used only with factored matrices formed by in-place 8106 factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE 8107 format). This option can save memory, for example, when solving nonlinear 8108 systems with a matrix-free Newton-Krylov method and a matrix-based, in-place 8109 ILU(0) preconditioner. 8110 8111 Note that one can specify in-place ILU(0) factorization by calling 8112 .vb 8113 PCType(pc,PCILU); 8114 PCFactorSeUseInPlace(pc); 8115 .ve 8116 or by using the options -pc_type ilu -pc_factor_in_place 8117 8118 In-place factorization ILU(0) can also be used as a local 8119 solver for the blocks within the block Jacobi or additive Schwarz 8120 methods (runtime option: -sub_pc_factor_in_place). See Users-Manual: ch_pc 8121 for details on setting local solver options. 8122 8123 Most users should employ the simplified KSP interface for linear solvers 8124 instead of working directly with matrix algebra routines such as this. 8125 See, e.g., KSPCreate(). 8126 8127 Level: developer 8128 8129 .seealso: `PCFactorSetUseInPlace()`, `PCFactorGetUseInPlace()` 8130 8131 @*/ 8132 PetscErrorCode MatSetUnfactored(Mat mat) 8133 { 8134 PetscFunctionBegin; 8135 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8136 PetscValidType(mat,1); 8137 MatCheckPreallocated(mat,1); 8138 mat->factortype = MAT_FACTOR_NONE; 8139 if (!mat->ops->setunfactored) PetscFunctionReturn(0); 8140 PetscCall((*mat->ops->setunfactored)(mat)); 8141 PetscFunctionReturn(0); 8142 } 8143 8144 /*MC 8145 MatDenseGetArrayF90 - Accesses a matrix array from Fortran90. 8146 8147 Synopsis: 8148 MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 8149 8150 Not collective 8151 8152 Input Parameter: 8153 . x - matrix 8154 8155 Output Parameters: 8156 + xx_v - the Fortran90 pointer to the array 8157 - ierr - error code 8158 8159 Example of Usage: 8160 .vb 8161 PetscScalar, pointer xx_v(:,:) 8162 .... 8163 call MatDenseGetArrayF90(x,xx_v,ierr) 8164 a = xx_v(3) 8165 call MatDenseRestoreArrayF90(x,xx_v,ierr) 8166 .ve 8167 8168 Level: advanced 8169 8170 .seealso: `MatDenseRestoreArrayF90()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatSeqAIJGetArrayF90()` 8171 8172 M*/ 8173 8174 /*MC 8175 MatDenseRestoreArrayF90 - Restores a matrix array that has been 8176 accessed with MatDenseGetArrayF90(). 8177 8178 Synopsis: 8179 MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 8180 8181 Not collective 8182 8183 Input Parameters: 8184 + x - matrix 8185 - xx_v - the Fortran90 pointer to the array 8186 8187 Output Parameter: 8188 . ierr - error code 8189 8190 Example of Usage: 8191 .vb 8192 PetscScalar, pointer xx_v(:,:) 8193 .... 8194 call MatDenseGetArrayF90(x,xx_v,ierr) 8195 a = xx_v(3) 8196 call MatDenseRestoreArrayF90(x,xx_v,ierr) 8197 .ve 8198 8199 Level: advanced 8200 8201 .seealso: `MatDenseGetArrayF90()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatSeqAIJRestoreArrayF90()` 8202 8203 M*/ 8204 8205 /*MC 8206 MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90. 8207 8208 Synopsis: 8209 MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 8210 8211 Not collective 8212 8213 Input Parameter: 8214 . x - matrix 8215 8216 Output Parameters: 8217 + xx_v - the Fortran90 pointer to the array 8218 - ierr - error code 8219 8220 Example of Usage: 8221 .vb 8222 PetscScalar, pointer xx_v(:) 8223 .... 8224 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 8225 a = xx_v(3) 8226 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 8227 .ve 8228 8229 Level: advanced 8230 8231 .seealso: `MatSeqAIJRestoreArrayF90()`, `MatSeqAIJGetArray()`, `MatSeqAIJRestoreArray()`, `MatDenseGetArrayF90()` 8232 8233 M*/ 8234 8235 /*MC 8236 MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been 8237 accessed with MatSeqAIJGetArrayF90(). 8238 8239 Synopsis: 8240 MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 8241 8242 Not collective 8243 8244 Input Parameters: 8245 + x - matrix 8246 - xx_v - the Fortran90 pointer to the array 8247 8248 Output Parameter: 8249 . ierr - error code 8250 8251 Example of Usage: 8252 .vb 8253 PetscScalar, pointer xx_v(:) 8254 .... 8255 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 8256 a = xx_v(3) 8257 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 8258 .ve 8259 8260 Level: advanced 8261 8262 .seealso: `MatSeqAIJGetArrayF90()`, `MatSeqAIJGetArray()`, `MatSeqAIJRestoreArray()`, `MatDenseRestoreArrayF90()` 8263 8264 M*/ 8265 8266 /*@ 8267 MatCreateSubMatrix - Gets a single submatrix on the same number of processors 8268 as the original matrix. 8269 8270 Collective on Mat 8271 8272 Input Parameters: 8273 + mat - the original matrix 8274 . isrow - parallel IS containing the rows this processor should obtain 8275 . 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. 8276 - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 8277 8278 Output Parameter: 8279 . newmat - the new submatrix, of the same type as the old 8280 8281 Level: advanced 8282 8283 Notes: 8284 The submatrix will be able to be multiplied with vectors using the same layout as iscol. 8285 8286 Some matrix types place restrictions on the row and column indices, such 8287 as that they be sorted or that they be equal to each other. 8288 8289 The index sets may not have duplicate entries. 8290 8291 The first time this is called you should use a cll of MAT_INITIAL_MATRIX, 8292 the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls 8293 to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX 8294 will reuse the matrix generated the first time. You should call MatDestroy() on newmat when 8295 you are finished using it. 8296 8297 The communicator of the newly obtained matrix is ALWAYS the same as the communicator of 8298 the input matrix. 8299 8300 If iscol is NULL then all columns are obtained (not supported in Fortran). 8301 8302 Example usage: 8303 Consider the following 8x8 matrix with 34 non-zero values, that is 8304 assembled across 3 processors. Let's assume that proc0 owns 3 rows, 8305 proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown 8306 as follows: 8307 8308 .vb 8309 1 2 0 | 0 3 0 | 0 4 8310 Proc0 0 5 6 | 7 0 0 | 8 0 8311 9 0 10 | 11 0 0 | 12 0 8312 ------------------------------------- 8313 13 0 14 | 15 16 17 | 0 0 8314 Proc1 0 18 0 | 19 20 21 | 0 0 8315 0 0 0 | 22 23 0 | 24 0 8316 ------------------------------------- 8317 Proc2 25 26 27 | 0 0 28 | 29 0 8318 30 0 0 | 31 32 33 | 0 34 8319 .ve 8320 8321 Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is 8322 8323 .vb 8324 2 0 | 0 3 0 | 0 8325 Proc0 5 6 | 7 0 0 | 8 8326 ------------------------------- 8327 Proc1 18 0 | 19 20 21 | 0 8328 ------------------------------- 8329 Proc2 26 27 | 0 0 28 | 29 8330 0 0 | 31 32 33 | 0 8331 .ve 8332 8333 .seealso: `MatCreateSubMatrices()`, `MatCreateSubMatricesMPI()`, `MatCreateSubMatrixVirtual()`, `MatSubMatrixVirtualUpdate()` 8334 @*/ 8335 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat) 8336 { 8337 PetscMPIInt size; 8338 Mat *local; 8339 IS iscoltmp; 8340 PetscBool flg; 8341 8342 PetscFunctionBegin; 8343 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8344 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 8345 if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 8346 PetscValidPointer(newmat,5); 8347 if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5); 8348 PetscValidType(mat,1); 8349 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8350 PetscCheck(cll != MAT_IGNORE_MATRIX,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX"); 8351 8352 MatCheckPreallocated(mat,1); 8353 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 8354 8355 if (!iscol || isrow == iscol) { 8356 PetscBool stride; 8357 PetscMPIInt grabentirematrix = 0,grab; 8358 PetscCall(PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride)); 8359 if (stride) { 8360 PetscInt first,step,n,rstart,rend; 8361 PetscCall(ISStrideGetInfo(isrow,&first,&step)); 8362 if (step == 1) { 8363 PetscCall(MatGetOwnershipRange(mat,&rstart,&rend)); 8364 if (rstart == first) { 8365 PetscCall(ISGetLocalSize(isrow,&n)); 8366 if (n == rend-rstart) { 8367 grabentirematrix = 1; 8368 } 8369 } 8370 } 8371 } 8372 PetscCall(MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat))); 8373 if (grab) { 8374 PetscCall(PetscInfo(mat,"Getting entire matrix as submatrix\n")); 8375 if (cll == MAT_INITIAL_MATRIX) { 8376 *newmat = mat; 8377 PetscCall(PetscObjectReference((PetscObject)mat)); 8378 } 8379 PetscFunctionReturn(0); 8380 } 8381 } 8382 8383 if (!iscol) { 8384 PetscCall(ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp)); 8385 } else { 8386 iscoltmp = iscol; 8387 } 8388 8389 /* if original matrix is on just one processor then use submatrix generated */ 8390 if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) { 8391 PetscCall(MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat)); 8392 goto setproperties; 8393 } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) { 8394 PetscCall(MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local)); 8395 *newmat = *local; 8396 PetscCall(PetscFree(local)); 8397 goto setproperties; 8398 } else if (!mat->ops->createsubmatrix) { 8399 /* Create a new matrix type that implements the operation using the full matrix */ 8400 PetscCall(PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0)); 8401 switch (cll) { 8402 case MAT_INITIAL_MATRIX: 8403 PetscCall(MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat)); 8404 break; 8405 case MAT_REUSE_MATRIX: 8406 PetscCall(MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp)); 8407 break; 8408 default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX"); 8409 } 8410 PetscCall(PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0)); 8411 goto setproperties; 8412 } 8413 8414 PetscCheck(mat->ops->createsubmatrix,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8415 PetscCall(PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0)); 8416 PetscCall((*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat)); 8417 PetscCall(PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0)); 8418 8419 setproperties: 8420 PetscCall(ISEqualUnsorted(isrow,iscoltmp,&flg)); 8421 if (flg) PetscCall(MatPropagateSymmetryOptions(mat,*newmat)); 8422 if (!iscol) PetscCall(ISDestroy(&iscoltmp)); 8423 if (*newmat && cll == MAT_INITIAL_MATRIX) PetscCall(PetscObjectStateIncrease((PetscObject)*newmat)); 8424 PetscFunctionReturn(0); 8425 } 8426 8427 /*@ 8428 MatPropagateSymmetryOptions - Propagates symmetry options set on a matrix to another matrix 8429 8430 Not Collective 8431 8432 Input Parameters: 8433 + A - the matrix we wish to propagate options from 8434 - B - the matrix we wish to propagate options to 8435 8436 Level: beginner 8437 8438 Notes: 8439 Propagates the options associated to `MAT_SYMMETRY_ETERNAL`, `MAT_STRUCTURALLY_SYMMETRIC`, `MAT_HERMITIAN`, `MAT_SPD`, `MAT_SYMMETRIC`, and `MAT_STRUCTURAL_SYMMETRY_ETERNAL` 8440 8441 .seealso: `MatSetOption()`, `MatIsSymmetricKnown()`, `MatIsSPDKnown()`, `MatIsHermitianKnown()`, MatIsStructurallySymmetricKnown()` 8442 @*/ 8443 PetscErrorCode MatPropagateSymmetryOptions(Mat A, Mat B) 8444 { 8445 PetscFunctionBegin; 8446 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8447 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 8448 B->symmetry_eternal = A->symmetry_eternal; 8449 B->structural_symmetry_eternal = A->structural_symmetry_eternal; 8450 B->symmetric = A->symmetric; 8451 B->structurally_symmetric = A->structurally_symmetric; 8452 B->spd = A->spd; 8453 B->hermitian = A->hermitian; 8454 PetscFunctionReturn(0); 8455 } 8456 8457 /*@ 8458 MatStashSetInitialSize - sets the sizes of the matrix stash, that is 8459 used during the assembly process to store values that belong to 8460 other processors. 8461 8462 Not Collective 8463 8464 Input Parameters: 8465 + mat - the matrix 8466 . size - the initial size of the stash. 8467 - bsize - the initial size of the block-stash(if used). 8468 8469 Options Database Keys: 8470 + -matstash_initial_size <size> or <size0,size1,...sizep-1> 8471 - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1> 8472 8473 Level: intermediate 8474 8475 Notes: 8476 The block-stash is used for values set with MatSetValuesBlocked() while 8477 the stash is used for values set with MatSetValues() 8478 8479 Run with the option -info and look for output of the form 8480 MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs. 8481 to determine the appropriate value, MM, to use for size and 8482 MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs. 8483 to determine the value, BMM to use for bsize 8484 8485 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `Mat`, `MatStashGetInfo()` 8486 8487 @*/ 8488 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize) 8489 { 8490 PetscFunctionBegin; 8491 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8492 PetscValidType(mat,1); 8493 PetscCall(MatStashSetInitialSize_Private(&mat->stash,size)); 8494 PetscCall(MatStashSetInitialSize_Private(&mat->bstash,bsize)); 8495 PetscFunctionReturn(0); 8496 } 8497 8498 /*@ 8499 MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 8500 the matrix 8501 8502 Neighbor-wise Collective on Mat 8503 8504 Input Parameters: 8505 + mat - the matrix 8506 . x,y - the vectors 8507 - w - where the result is stored 8508 8509 Level: intermediate 8510 8511 Notes: 8512 w may be the same vector as y. 8513 8514 This allows one to use either the restriction or interpolation (its transpose) 8515 matrix to do the interpolation 8516 8517 .seealso: `MatMultAdd()`, `MatMultTransposeAdd()`, `MatRestrict()` 8518 8519 @*/ 8520 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w) 8521 { 8522 PetscInt M,N,Ny; 8523 8524 PetscFunctionBegin; 8525 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8526 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8527 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8528 PetscValidHeaderSpecific(w,VEC_CLASSID,4); 8529 PetscCall(MatGetSize(A,&M,&N)); 8530 PetscCall(VecGetSize(y,&Ny)); 8531 if (M == Ny) { 8532 PetscCall(MatMultAdd(A,x,y,w)); 8533 } else { 8534 PetscCall(MatMultTransposeAdd(A,x,y,w)); 8535 } 8536 PetscFunctionReturn(0); 8537 } 8538 8539 /*@ 8540 MatInterpolate - y = A*x or A'*x depending on the shape of 8541 the matrix 8542 8543 Neighbor-wise Collective on Mat 8544 8545 Input Parameters: 8546 + mat - the matrix 8547 - x,y - the vectors 8548 8549 Level: intermediate 8550 8551 Notes: 8552 This allows one to use either the restriction or interpolation (its transpose) 8553 matrix to do the interpolation 8554 8555 .seealso: `MatMultAdd()`, `MatMultTransposeAdd()`, `MatRestrict()` 8556 8557 @*/ 8558 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y) 8559 { 8560 PetscInt M,N,Ny; 8561 8562 PetscFunctionBegin; 8563 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8564 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8565 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8566 PetscCall(MatGetSize(A,&M,&N)); 8567 PetscCall(VecGetSize(y,&Ny)); 8568 if (M == Ny) { 8569 PetscCall(MatMult(A,x,y)); 8570 } else { 8571 PetscCall(MatMultTranspose(A,x,y)); 8572 } 8573 PetscFunctionReturn(0); 8574 } 8575 8576 /*@ 8577 MatRestrict - y = A*x or A'*x 8578 8579 Neighbor-wise Collective on Mat 8580 8581 Input Parameters: 8582 + mat - the matrix 8583 - x,y - the vectors 8584 8585 Level: intermediate 8586 8587 Notes: 8588 This allows one to use either the restriction or interpolation (its transpose) 8589 matrix to do the restriction 8590 8591 .seealso: `MatMultAdd()`, `MatMultTransposeAdd()`, `MatInterpolate()` 8592 8593 @*/ 8594 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y) 8595 { 8596 PetscInt M,N,Ny; 8597 8598 PetscFunctionBegin; 8599 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8600 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8601 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8602 PetscCall(MatGetSize(A,&M,&N)); 8603 PetscCall(VecGetSize(y,&Ny)); 8604 if (M == Ny) { 8605 PetscCall(MatMult(A,x,y)); 8606 } else { 8607 PetscCall(MatMultTranspose(A,x,y)); 8608 } 8609 PetscFunctionReturn(0); 8610 } 8611 8612 /*@ 8613 MatMatInterpolateAdd - Y = W + A*X or W + A'*X 8614 8615 Neighbor-wise Collective on Mat 8616 8617 Input Parameters: 8618 + mat - the matrix 8619 - w, x - the input dense matrices 8620 8621 Output Parameters: 8622 . y - the output dense matrix 8623 8624 Level: intermediate 8625 8626 Notes: 8627 This allows one to use either the restriction or interpolation (its transpose) 8628 matrix to do the interpolation. y matrix can be reused if already created with the proper sizes, 8629 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8630 8631 .seealso: `MatInterpolateAdd()`, `MatMatInterpolate()`, `MatMatRestrict()` 8632 8633 @*/ 8634 PetscErrorCode MatMatInterpolateAdd(Mat A,Mat x,Mat w,Mat *y) 8635 { 8636 PetscInt M,N,Mx,Nx,Mo,My = 0,Ny = 0; 8637 PetscBool trans = PETSC_TRUE; 8638 MatReuse reuse = MAT_INITIAL_MATRIX; 8639 8640 PetscFunctionBegin; 8641 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8642 PetscValidHeaderSpecific(x,MAT_CLASSID,2); 8643 PetscValidType(x,2); 8644 if (w) PetscValidHeaderSpecific(w,MAT_CLASSID,3); 8645 if (*y) PetscValidHeaderSpecific(*y,MAT_CLASSID,4); 8646 PetscCall(MatGetSize(A,&M,&N)); 8647 PetscCall(MatGetSize(x,&Mx,&Nx)); 8648 if (N == Mx) trans = PETSC_FALSE; 8649 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); 8650 Mo = trans ? N : M; 8651 if (*y) { 8652 PetscCall(MatGetSize(*y,&My,&Ny)); 8653 if (Mo == My && Nx == Ny) { reuse = MAT_REUSE_MATRIX; } 8654 else { 8655 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); 8656 PetscCall(MatDestroy(y)); 8657 } 8658 } 8659 8660 if (w && *y == w) { /* this is to minimize changes in PCMG */ 8661 PetscBool flg; 8662 8663 PetscCall(PetscObjectQuery((PetscObject)*y,"__MatMatIntAdd_w",(PetscObject*)&w)); 8664 if (w) { 8665 PetscInt My,Ny,Mw,Nw; 8666 8667 PetscCall(PetscObjectTypeCompare((PetscObject)*y,((PetscObject)w)->type_name,&flg)); 8668 PetscCall(MatGetSize(*y,&My,&Ny)); 8669 PetscCall(MatGetSize(w,&Mw,&Nw)); 8670 if (!flg || My != Mw || Ny != Nw) w = NULL; 8671 } 8672 if (!w) { 8673 PetscCall(MatDuplicate(*y,MAT_COPY_VALUES,&w)); 8674 PetscCall(PetscObjectCompose((PetscObject)*y,"__MatMatIntAdd_w",(PetscObject)w)); 8675 PetscCall(PetscLogObjectParent((PetscObject)*y,(PetscObject)w)); 8676 PetscCall(PetscObjectDereference((PetscObject)w)); 8677 } else { 8678 PetscCall(MatCopy(*y,w,UNKNOWN_NONZERO_PATTERN)); 8679 } 8680 } 8681 if (!trans) { 8682 PetscCall(MatMatMult(A,x,reuse,PETSC_DEFAULT,y)); 8683 } else { 8684 PetscCall(MatTransposeMatMult(A,x,reuse,PETSC_DEFAULT,y)); 8685 } 8686 if (w) PetscCall(MatAXPY(*y,1.0,w,UNKNOWN_NONZERO_PATTERN)); 8687 PetscFunctionReturn(0); 8688 } 8689 8690 /*@ 8691 MatMatInterpolate - Y = A*X or A'*X 8692 8693 Neighbor-wise Collective on Mat 8694 8695 Input Parameters: 8696 + mat - the matrix 8697 - x - the input dense matrix 8698 8699 Output Parameters: 8700 . y - the output dense matrix 8701 8702 Level: intermediate 8703 8704 Notes: 8705 This allows one to use either the restriction or interpolation (its transpose) 8706 matrix to do the interpolation. y matrix can be reused if already created with the proper sizes, 8707 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8708 8709 .seealso: `MatInterpolate()`, `MatRestrict()`, `MatMatRestrict()` 8710 8711 @*/ 8712 PetscErrorCode MatMatInterpolate(Mat A,Mat x,Mat *y) 8713 { 8714 PetscFunctionBegin; 8715 PetscCall(MatMatInterpolateAdd(A,x,NULL,y)); 8716 PetscFunctionReturn(0); 8717 } 8718 8719 /*@ 8720 MatMatRestrict - Y = A*X or A'*X 8721 8722 Neighbor-wise Collective on Mat 8723 8724 Input Parameters: 8725 + mat - the matrix 8726 - x - the input dense matrix 8727 8728 Output Parameters: 8729 . y - the output dense matrix 8730 8731 Level: intermediate 8732 8733 Notes: 8734 This allows one to use either the restriction or interpolation (its transpose) 8735 matrix to do the restriction. y matrix can be reused if already created with the proper sizes, 8736 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8737 8738 .seealso: `MatRestrict()`, `MatInterpolate()`, `MatMatInterpolate()` 8739 @*/ 8740 PetscErrorCode MatMatRestrict(Mat A,Mat x,Mat *y) 8741 { 8742 PetscFunctionBegin; 8743 PetscCall(MatMatInterpolateAdd(A,x,NULL,y)); 8744 PetscFunctionReturn(0); 8745 } 8746 8747 /*@ 8748 MatGetNullSpace - retrieves the null space of a matrix. 8749 8750 Logically Collective on Mat 8751 8752 Input Parameters: 8753 + mat - the matrix 8754 - nullsp - the null space object 8755 8756 Level: developer 8757 8758 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatSetNullSpace()` 8759 @*/ 8760 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp) 8761 { 8762 PetscFunctionBegin; 8763 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8764 PetscValidPointer(nullsp,2); 8765 *nullsp = (mat->symmetric == PETSC_BOOL3_TRUE && !mat->nullsp) ? mat->transnullsp : mat->nullsp; 8766 PetscFunctionReturn(0); 8767 } 8768 8769 /*@ 8770 MatSetNullSpace - attaches a null space to a matrix. 8771 8772 Logically Collective on Mat 8773 8774 Input Parameters: 8775 + mat - the matrix 8776 - nullsp - the null space object 8777 8778 Level: advanced 8779 8780 Notes: 8781 This null space is used by the KSP linear solvers to solve singular systems. 8782 8783 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 8784 8785 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 8786 to zero but the linear system will still be solved in a least squares sense. 8787 8788 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8789 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). 8790 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 8791 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 8792 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). 8793 This \hat{b} can be obtained by calling MatNullSpaceRemove() with the null space of the transpose of the matrix. 8794 8795 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 8796 routine also automatically calls MatSetTransposeNullSpace(). 8797 8798 The user should call `MatNullSpaceDestroy()`. 8799 8800 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatGetNullSpace()`, `MatSetTransposeNullSpace()`, `MatGetTransposeNullSpace()`, `MatNullSpaceRemove()`, 8801 `KSPSetPCSide()` 8802 @*/ 8803 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp) 8804 { 8805 PetscFunctionBegin; 8806 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8807 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8808 if (nullsp) PetscCall(PetscObjectReference((PetscObject)nullsp)); 8809 PetscCall(MatNullSpaceDestroy(&mat->nullsp)); 8810 mat->nullsp = nullsp; 8811 if (mat->symmetric == PETSC_BOOL3_TRUE) { 8812 PetscCall(MatSetTransposeNullSpace(mat,nullsp)); 8813 } 8814 PetscFunctionReturn(0); 8815 } 8816 8817 /*@ 8818 MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix. 8819 8820 Logically Collective on Mat 8821 8822 Input Parameters: 8823 + mat - the matrix 8824 - nullsp - the null space object 8825 8826 Level: developer 8827 8828 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatSetTransposeNullSpace()`, `MatSetNullSpace()`, `MatGetNullSpace()` 8829 @*/ 8830 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp) 8831 { 8832 PetscFunctionBegin; 8833 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8834 PetscValidType(mat,1); 8835 PetscValidPointer(nullsp,2); 8836 *nullsp = (mat->symmetric == PETSC_BOOL3_TRUE && !mat->transnullsp) ? mat->nullsp : mat->transnullsp; 8837 PetscFunctionReturn(0); 8838 } 8839 8840 /*@ 8841 MatSetTransposeNullSpace - attaches the null space of a transpose of a matrix to the matrix 8842 8843 Logically Collective on Mat 8844 8845 Input Parameters: 8846 + mat - the matrix 8847 - nullsp - the null space object 8848 8849 Level: advanced 8850 8851 Notes: 8852 This allows solving singular linear systems defined by the transpose of the matrix using KSP solvers with left preconditioning. 8853 8854 See MatSetNullSpace() 8855 8856 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatGetNullSpace()`, `MatSetNullSpace()`, `MatGetTransposeNullSpace()`, `MatNullSpaceRemove()`, `KSPSetPCSide()` 8857 @*/ 8858 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp) 8859 { 8860 PetscFunctionBegin; 8861 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8862 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8863 if (nullsp) PetscCall(PetscObjectReference((PetscObject)nullsp)); 8864 PetscCall(MatNullSpaceDestroy(&mat->transnullsp)); 8865 mat->transnullsp = nullsp; 8866 PetscFunctionReturn(0); 8867 } 8868 8869 /*@ 8870 MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions 8871 This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix. 8872 8873 Logically Collective on Mat 8874 8875 Input Parameters: 8876 + mat - the matrix 8877 - nullsp - the null space object 8878 8879 Level: advanced 8880 8881 Notes: 8882 Overwrites any previous near null space that may have been attached 8883 8884 You can remove the null space by calling this routine with an nullsp of NULL 8885 8886 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNullSpace()`, `MatNullSpaceCreateRigidBody()`, `MatGetNearNullSpace()` 8887 @*/ 8888 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp) 8889 { 8890 PetscFunctionBegin; 8891 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8892 PetscValidType(mat,1); 8893 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8894 MatCheckPreallocated(mat,1); 8895 if (nullsp) PetscCall(PetscObjectReference((PetscObject)nullsp)); 8896 PetscCall(MatNullSpaceDestroy(&mat->nearnullsp)); 8897 mat->nearnullsp = nullsp; 8898 PetscFunctionReturn(0); 8899 } 8900 8901 /*@ 8902 MatGetNearNullSpace - Get null space attached with MatSetNearNullSpace() 8903 8904 Not Collective 8905 8906 Input Parameter: 8907 . mat - the matrix 8908 8909 Output Parameter: 8910 . nullsp - the null space object, NULL if not set 8911 8912 Level: developer 8913 8914 .seealso: `MatSetNearNullSpace()`, `MatGetNullSpace()`, `MatNullSpaceCreate()` 8915 @*/ 8916 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp) 8917 { 8918 PetscFunctionBegin; 8919 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8920 PetscValidType(mat,1); 8921 PetscValidPointer(nullsp,2); 8922 MatCheckPreallocated(mat,1); 8923 *nullsp = mat->nearnullsp; 8924 PetscFunctionReturn(0); 8925 } 8926 8927 /*@C 8928 MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix. 8929 8930 Collective on Mat 8931 8932 Input Parameters: 8933 + mat - the matrix 8934 . row - row/column permutation 8935 . fill - expected fill factor >= 1.0 8936 - level - level of fill, for ICC(k) 8937 8938 Notes: 8939 Probably really in-place only when level of fill is zero, otherwise allocates 8940 new space to store factored matrix and deletes previous memory. 8941 8942 Most users should employ the simplified KSP interface for linear solvers 8943 instead of working directly with matrix algebra routines such as this. 8944 See, e.g., KSPCreate(). 8945 8946 Level: developer 8947 8948 .seealso: `MatICCFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()` 8949 8950 Developer Note: fortran interface is not autogenerated as the f90 8951 interface definition cannot be generated correctly [due to MatFactorInfo] 8952 8953 @*/ 8954 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info) 8955 { 8956 PetscFunctionBegin; 8957 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8958 PetscValidType(mat,1); 8959 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 8960 PetscValidPointer(info,3); 8961 PetscCheck(mat->rmap->N == mat->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 8962 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8963 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8964 PetscCheck(mat->ops->iccfactor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8965 MatCheckPreallocated(mat,1); 8966 PetscCall((*mat->ops->iccfactor)(mat,row,info)); 8967 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 8968 PetscFunctionReturn(0); 8969 } 8970 8971 /*@ 8972 MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 8973 ghosted ones. 8974 8975 Not Collective 8976 8977 Input Parameters: 8978 + mat - the matrix 8979 - diag - the diagonal values, including ghost ones 8980 8981 Level: developer 8982 8983 Notes: 8984 Works only for MPIAIJ and MPIBAIJ matrices 8985 8986 .seealso: `MatDiagonalScale()` 8987 @*/ 8988 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag) 8989 { 8990 PetscMPIInt size; 8991 8992 PetscFunctionBegin; 8993 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8994 PetscValidHeaderSpecific(diag,VEC_CLASSID,2); 8995 PetscValidType(mat,1); 8996 8997 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled"); 8998 PetscCall(PetscLogEventBegin(MAT_Scale,mat,0,0,0)); 8999 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 9000 if (size == 1) { 9001 PetscInt n,m; 9002 PetscCall(VecGetSize(diag,&n)); 9003 PetscCall(MatGetSize(mat,NULL,&m)); 9004 if (m == n) { 9005 PetscCall(MatDiagonalScale(mat,NULL,diag)); 9006 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions"); 9007 } else { 9008 PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag)); 9009 } 9010 PetscCall(PetscLogEventEnd(MAT_Scale,mat,0,0,0)); 9011 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 9012 PetscFunctionReturn(0); 9013 } 9014 9015 /*@ 9016 MatGetInertia - Gets the inertia from a factored matrix 9017 9018 Collective on Mat 9019 9020 Input Parameter: 9021 . mat - the matrix 9022 9023 Output Parameters: 9024 + nneg - number of negative eigenvalues 9025 . nzero - number of zero eigenvalues 9026 - npos - number of positive eigenvalues 9027 9028 Level: advanced 9029 9030 Notes: 9031 Matrix must have been factored by MatCholeskyFactor() 9032 9033 @*/ 9034 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos) 9035 { 9036 PetscFunctionBegin; 9037 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9038 PetscValidType(mat,1); 9039 PetscCheck(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 9040 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled"); 9041 PetscCheck(mat->ops->getinertia,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 9042 PetscCall((*mat->ops->getinertia)(mat,nneg,nzero,npos)); 9043 PetscFunctionReturn(0); 9044 } 9045 9046 /* ----------------------------------------------------------------*/ 9047 /*@C 9048 MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors 9049 9050 Neighbor-wise Collective on Mats 9051 9052 Input Parameters: 9053 + mat - the factored matrix 9054 - b - the right-hand-side vectors 9055 9056 Output Parameter: 9057 . x - the result vectors 9058 9059 Notes: 9060 The vectors b and x cannot be the same. I.e., one cannot 9061 call MatSolves(A,x,x). 9062 9063 Notes: 9064 Most users should employ the simplified KSP interface for linear solvers 9065 instead of working directly with matrix algebra routines such as this. 9066 See, e.g., KSPCreate(). 9067 9068 Level: developer 9069 9070 .seealso: `MatSolveAdd()`, `MatSolveTranspose()`, `MatSolveTransposeAdd()`, `MatSolve()` 9071 @*/ 9072 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x) 9073 { 9074 PetscFunctionBegin; 9075 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9076 PetscValidType(mat,1); 9077 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 9078 PetscCheck(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 9079 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 9080 9081 PetscCheck(mat->ops->solves,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 9082 MatCheckPreallocated(mat,1); 9083 PetscCall(PetscLogEventBegin(MAT_Solves,mat,0,0,0)); 9084 PetscCall((*mat->ops->solves)(mat,b,x)); 9085 PetscCall(PetscLogEventEnd(MAT_Solves,mat,0,0,0)); 9086 PetscFunctionReturn(0); 9087 } 9088 9089 /*@ 9090 MatIsSymmetric - Test whether a matrix is symmetric 9091 9092 Collective on Mat 9093 9094 Input Parameters: 9095 + A - the matrix to test 9096 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose) 9097 9098 Output Parameters: 9099 . flg - the result 9100 9101 Notes: 9102 For real numbers MatIsSymmetric() and MatIsHermitian() return identical results 9103 9104 If the matrix does not yet know if it is symmetric or not this can be an expensive operation, also available `MatIsSymmetricKnown()` 9105 9106 Level: intermediate 9107 9108 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetricKnown()` 9109 @*/ 9110 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg) 9111 { 9112 PetscFunctionBegin; 9113 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9114 PetscValidBoolPointer(flg,3); 9115 9116 if (A->symmetric == PETSC_BOOL3_TRUE) *flg = PETSC_TRUE; 9117 else if (A->symmetric == PETSC_BOOL3_FALSE) *flg = PETSC_FALSE; 9118 else { 9119 if (!A->ops->issymmetric) { 9120 MatType mattype; 9121 PetscCall(MatGetType(A,&mattype)); 9122 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for symmetric",mattype); 9123 } 9124 PetscCall((*A->ops->issymmetric)(A,tol,flg)); 9125 if (!tol) PetscCall(MatSetOption(A,MAT_SYMMETRIC,*flg)); 9126 } 9127 PetscFunctionReturn(0); 9128 } 9129 9130 /*@ 9131 MatIsHermitian - Test whether a matrix is Hermitian 9132 9133 Collective on Mat 9134 9135 Input Parameters: 9136 + A - the matrix to test 9137 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian) 9138 9139 Output Parameters: 9140 . flg - the result 9141 9142 Level: intermediate 9143 9144 Notes: 9145 For real numbers MatIsSymmetric() and MatIsHermitian() return identical results 9146 9147 If the matrix does not yet know if it is hermitian or not this can be an expensive operation, also available `MatIsHermitianKnown()` 9148 9149 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitianKnown()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, 9150 `MatIsSymmetricKnown()`, `MatIsSymmetric()` 9151 @*/ 9152 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg) 9153 { 9154 PetscFunctionBegin; 9155 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9156 PetscValidBoolPointer(flg,3); 9157 9158 if (A->hermitian == PETSC_BOOL3_TRUE) *flg = PETSC_TRUE; 9159 else if (A->hermitian == PETSC_BOOL3_FALSE) *flg = PETSC_FALSE; 9160 else { 9161 if (!A->ops->ishermitian) { 9162 MatType mattype; 9163 PetscCall(MatGetType(A,&mattype)); 9164 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for hermitian",mattype); 9165 } 9166 PetscCall((*A->ops->ishermitian)(A,tol,flg)); 9167 if (!tol) PetscCall(MatSetOption(A,MAT_HERMITIAN,*flg)); 9168 } 9169 PetscFunctionReturn(0); 9170 } 9171 9172 /*@ 9173 MatIsSymmetricKnown - Checks if a matrix knows if it is symmetric or not and its symmetric state 9174 9175 Not Collective 9176 9177 Input Parameter: 9178 . A - the matrix to check 9179 9180 Output Parameters: 9181 + set - PETSC_TRUE if the matrix knows its symmetry state (this tells you if the next flag is valid) 9182 - flg - the result (only valid if set is PETSC_TRUE) 9183 9184 Level: advanced 9185 9186 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric() 9187 if you want it explicitly checked 9188 9189 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitianKnown()` 9190 @*/ 9191 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg) 9192 { 9193 PetscFunctionBegin; 9194 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9195 PetscValidBoolPointer(set,2); 9196 PetscValidBoolPointer(flg,3); 9197 if (A->symmetric != PETSC_BOOL3_UNKNOWN) { 9198 *set = PETSC_TRUE; 9199 *flg = PetscBool3ToBool(A->symmetric); 9200 } else { 9201 *set = PETSC_FALSE; 9202 } 9203 PetscFunctionReturn(0); 9204 } 9205 9206 /*@ 9207 MatIsSPDKnown - Checks if a matrix knows if it is symmetric positive definite or not and its symmetric positive definite state 9208 9209 Not Collective 9210 9211 Input Parameter: 9212 . A - the matrix to check 9213 9214 Output Parameters: 9215 + set - PETSC_TRUE if the matrix knows its symmetric positive definite state (this tells you if the next flag is valid) 9216 - flg - the result (only valid if set is PETSC_TRUE) 9217 9218 Level: advanced 9219 9220 Note: 9221 Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). 9222 9223 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitianKnown()` 9224 @*/ 9225 PetscErrorCode MatIsSPDKnown(Mat A,PetscBool *set,PetscBool *flg) 9226 { 9227 PetscFunctionBegin; 9228 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9229 PetscValidBoolPointer(set,2); 9230 PetscValidBoolPointer(flg,3); 9231 if (A->spd != PETSC_BOOL3_UNKNOWN) { 9232 *set = PETSC_TRUE; 9233 *flg = PetscBool3ToBool(A->spd); 9234 } else { 9235 *set = PETSC_FALSE; 9236 } 9237 PetscFunctionReturn(0); 9238 } 9239 9240 /*@ 9241 MatIsHermitianKnown - Checks if a matrix knows if it is Hermitian or not and its Hermitian state 9242 9243 Not Collective 9244 9245 Input Parameter: 9246 . A - the matrix to check 9247 9248 Output Parameters: 9249 + set - PETSC_TRUE if the matrix knows its Hermitian state (this tells you if the next flag is valid) 9250 - flg - the result (only valid if set is PETSC_TRUE) 9251 9252 Level: advanced 9253 9254 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian() 9255 if you want it explicitly checked 9256 9257 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()` 9258 @*/ 9259 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg) 9260 { 9261 PetscFunctionBegin; 9262 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9263 PetscValidBoolPointer(set,2); 9264 PetscValidBoolPointer(flg,3); 9265 if (A->hermitian != PETSC_BOOL3_UNKNOWN) { 9266 *set = PETSC_TRUE; 9267 *flg = PetscBool3ToBool(A->hermitian); 9268 } else { 9269 *set = PETSC_FALSE; 9270 } 9271 PetscFunctionReturn(0); 9272 } 9273 9274 /*@ 9275 MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric 9276 9277 Collective on Mat 9278 9279 Input Parameter: 9280 . A - the matrix to test 9281 9282 Output Parameters: 9283 . flg - the result 9284 9285 Notes: 9286 If the matrix does yet know it is structurally symmetric this can be an expensive operation, also available `MatIsStructurallySymmetricKnown()` 9287 9288 Level: intermediate 9289 9290 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsSymmetric()`, `MatSetOption()`, `MatIsStructurallySymmetricKnown()` 9291 @*/ 9292 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg) 9293 { 9294 PetscFunctionBegin; 9295 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9296 PetscValidBoolPointer(flg,2); 9297 if (A->structurally_symmetric != PETSC_BOOL3_UNKNOWN) { 9298 *flg = PetscBool3ToBool(A->structurally_symmetric); 9299 } else { 9300 PetscCheck(A->ops->isstructurallysymmetric,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix of type %s does not support checking for structural symmetry",((PetscObject)A)->type_name); 9301 PetscCall((*A->ops->isstructurallysymmetric)(A,flg)); 9302 PetscCall(MatSetOption(A,MAT_STRUCTURALLY_SYMMETRIC,*flg)); 9303 } 9304 PetscFunctionReturn(0); 9305 } 9306 9307 /*@ 9308 MatIsStructurallySymmetricKnown - Checks if a matrix knows if it is structurally symmetric or not and its structurally symmetric state 9309 9310 Not Collective 9311 9312 Input Parameter: 9313 . A - the matrix to check 9314 9315 Output Parameters: 9316 + set - PETSC_TRUE if the matrix knows its structurally symmetric state (this tells you if the next flag is valid) 9317 - flg - the result (only valid if set is PETSC_TRUE) 9318 9319 Level: advanced 9320 9321 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitianKnown()` 9322 @*/ 9323 PetscErrorCode MatIsStructurallySymmetricKnown(Mat A,PetscBool *set,PetscBool *flg) 9324 { 9325 PetscFunctionBegin; 9326 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9327 PetscValidBoolPointer(set,2); 9328 PetscValidBoolPointer(flg,3); 9329 if (A->structurally_symmetric != PETSC_BOOL3_UNKNOWN) { 9330 *set = PETSC_TRUE; 9331 *flg = PetscBool3ToBool(A->structurally_symmetric); 9332 } else { 9333 *set = PETSC_FALSE; 9334 } 9335 PetscFunctionReturn(0); 9336 } 9337 9338 /*@ 9339 MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need 9340 to be communicated to other processors during the MatAssemblyBegin/End() process 9341 9342 Not collective 9343 9344 Input Parameter: 9345 . vec - the vector 9346 9347 Output Parameters: 9348 + nstash - the size of the stash 9349 . reallocs - the number of additional mallocs incurred. 9350 . bnstash - the size of the block stash 9351 - breallocs - the number of additional mallocs incurred.in the block stash 9352 9353 Level: advanced 9354 9355 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `Mat`, `MatStashSetInitialSize()` 9356 9357 @*/ 9358 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs) 9359 { 9360 PetscFunctionBegin; 9361 PetscCall(MatStashGetInfo_Private(&mat->stash,nstash,reallocs)); 9362 PetscCall(MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs)); 9363 PetscFunctionReturn(0); 9364 } 9365 9366 /*@C 9367 MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same 9368 parallel layout 9369 9370 Collective on Mat 9371 9372 Input Parameter: 9373 . mat - the matrix 9374 9375 Output Parameters: 9376 + right - (optional) vector that the matrix can be multiplied against 9377 - left - (optional) vector that the matrix vector product can be stored in 9378 9379 Notes: 9380 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(). 9381 9382 Notes: 9383 These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed 9384 9385 Level: advanced 9386 9387 .seealso: `MatCreate()`, `VecDestroy()` 9388 @*/ 9389 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left) 9390 { 9391 PetscFunctionBegin; 9392 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9393 PetscValidType(mat,1); 9394 if (mat->ops->getvecs) { 9395 PetscCall((*mat->ops->getvecs)(mat,right,left)); 9396 } else { 9397 PetscInt rbs,cbs; 9398 PetscCall(MatGetBlockSizes(mat,&rbs,&cbs)); 9399 if (right) { 9400 PetscCheck(mat->cmap->n >= 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup"); 9401 PetscCall(VecCreate(PetscObjectComm((PetscObject)mat),right)); 9402 PetscCall(VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE)); 9403 PetscCall(VecSetBlockSize(*right,cbs)); 9404 PetscCall(VecSetType(*right,mat->defaultvectype)); 9405 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 9406 if (mat->boundtocpu && mat->bindingpropagates) { 9407 PetscCall(VecSetBindingPropagates(*right,PETSC_TRUE)); 9408 PetscCall(VecBindToCPU(*right,PETSC_TRUE)); 9409 } 9410 #endif 9411 PetscCall(PetscLayoutReference(mat->cmap,&(*right)->map)); 9412 } 9413 if (left) { 9414 PetscCheck(mat->rmap->n >= 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup"); 9415 PetscCall(VecCreate(PetscObjectComm((PetscObject)mat),left)); 9416 PetscCall(VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE)); 9417 PetscCall(VecSetBlockSize(*left,rbs)); 9418 PetscCall(VecSetType(*left,mat->defaultvectype)); 9419 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 9420 if (mat->boundtocpu && mat->bindingpropagates) { 9421 PetscCall(VecSetBindingPropagates(*left,PETSC_TRUE)); 9422 PetscCall(VecBindToCPU(*left,PETSC_TRUE)); 9423 } 9424 #endif 9425 PetscCall(PetscLayoutReference(mat->rmap,&(*left)->map)); 9426 } 9427 } 9428 PetscFunctionReturn(0); 9429 } 9430 9431 /*@C 9432 MatFactorInfoInitialize - Initializes a MatFactorInfo data structure 9433 with default values. 9434 9435 Not Collective 9436 9437 Input Parameters: 9438 . info - the MatFactorInfo data structure 9439 9440 Notes: 9441 The solvers are generally used through the KSP and PC objects, for example 9442 PCLU, PCILU, PCCHOLESKY, PCICC 9443 9444 Level: developer 9445 9446 .seealso: `MatFactorInfo` 9447 9448 Developer Note: fortran interface is not autogenerated as the f90 9449 interface definition cannot be generated correctly [due to MatFactorInfo] 9450 9451 @*/ 9452 9453 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info) 9454 { 9455 PetscFunctionBegin; 9456 PetscCall(PetscMemzero(info,sizeof(MatFactorInfo))); 9457 PetscFunctionReturn(0); 9458 } 9459 9460 /*@ 9461 MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed 9462 9463 Collective on Mat 9464 9465 Input Parameters: 9466 + mat - the factored matrix 9467 - is - the index set defining the Schur indices (0-based) 9468 9469 Notes: 9470 Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system. 9471 9472 You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call. 9473 9474 Level: developer 9475 9476 .seealso: `MatGetFactor()`, `MatFactorGetSchurComplement()`, `MatFactorRestoreSchurComplement()`, `MatFactorCreateSchurComplement()`, `MatFactorSolveSchurComplement()`, 9477 `MatFactorSolveSchurComplementTranspose()`, `MatFactorSolveSchurComplement()` 9478 9479 @*/ 9480 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is) 9481 { 9482 PetscErrorCode (*f)(Mat,IS); 9483 9484 PetscFunctionBegin; 9485 PetscValidType(mat,1); 9486 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9487 PetscValidType(is,2); 9488 PetscValidHeaderSpecific(is,IS_CLASSID,2); 9489 PetscCheckSameComm(mat,1,is,2); 9490 PetscCheck(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 9491 PetscCall(PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f)); 9492 PetscCheck(f,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"The selected MatSolverType does not support Schur complement computation. You should use MATSOLVERMUMPS or MATSOLVERMKL_PARDISO"); 9493 PetscCall(MatDestroy(&mat->schur)); 9494 PetscCall((*f)(mat,is)); 9495 PetscCheck(mat->schur,PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created"); 9496 PetscFunctionReturn(0); 9497 } 9498 9499 /*@ 9500 MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step 9501 9502 Logically Collective on Mat 9503 9504 Input Parameters: 9505 + F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface 9506 . S - location where to return the Schur complement, can be NULL 9507 - status - the status of the Schur complement matrix, can be NULL 9508 9509 Notes: 9510 You must call MatFactorSetSchurIS() before calling this routine. 9511 9512 The routine provides a copy of the Schur matrix stored within the solver data structures. 9513 The caller must destroy the object when it is no longer needed. 9514 If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse. 9515 9516 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) 9517 9518 Developer Notes: 9519 The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc 9520 matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix. 9521 9522 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 9523 9524 Level: advanced 9525 9526 References: 9527 9528 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorGetSchurComplement()`, `MatFactorSchurStatus` 9529 @*/ 9530 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 9531 { 9532 PetscFunctionBegin; 9533 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9534 if (S) PetscValidPointer(S,2); 9535 if (status) PetscValidPointer(status,3); 9536 if (S) { 9537 PetscErrorCode (*f)(Mat,Mat*); 9538 9539 PetscCall(PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f)); 9540 if (f) { 9541 PetscCall((*f)(F,S)); 9542 } else { 9543 PetscCall(MatDuplicate(F->schur,MAT_COPY_VALUES,S)); 9544 } 9545 } 9546 if (status) *status = F->schur_status; 9547 PetscFunctionReturn(0); 9548 } 9549 9550 /*@ 9551 MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix 9552 9553 Logically Collective on Mat 9554 9555 Input Parameters: 9556 + F - the factored matrix obtained by calling MatGetFactor() 9557 . *S - location where to return the Schur complement, can be NULL 9558 - status - the status of the Schur complement matrix, can be NULL 9559 9560 Notes: 9561 You must call MatFactorSetSchurIS() before calling this routine. 9562 9563 Schur complement mode is currently implemented for sequential matrices. 9564 The routine returns a the Schur Complement stored within the data strutures of the solver. 9565 If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement. 9566 The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed. 9567 9568 Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix 9569 9570 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 9571 9572 Level: advanced 9573 9574 References: 9575 9576 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorRestoreSchurComplement()`, `MatFactorCreateSchurComplement()`, `MatFactorSchurStatus` 9577 @*/ 9578 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 9579 { 9580 PetscFunctionBegin; 9581 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9582 if (S) PetscValidPointer(S,2); 9583 if (status) PetscValidPointer(status,3); 9584 if (S) *S = F->schur; 9585 if (status) *status = F->schur_status; 9586 PetscFunctionReturn(0); 9587 } 9588 9589 /*@ 9590 MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement 9591 9592 Logically Collective on Mat 9593 9594 Input Parameters: 9595 + F - the factored matrix obtained by calling MatGetFactor() 9596 . *S - location where the Schur complement is stored 9597 - status - the status of the Schur complement matrix (see MatFactorSchurStatus) 9598 9599 Notes: 9600 9601 Level: advanced 9602 9603 References: 9604 9605 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorRestoreSchurComplement()`, `MatFactorCreateSchurComplement()`, `MatFactorSchurStatus` 9606 @*/ 9607 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status) 9608 { 9609 PetscFunctionBegin; 9610 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9611 if (S) { 9612 PetscValidHeaderSpecific(*S,MAT_CLASSID,2); 9613 *S = NULL; 9614 } 9615 F->schur_status = status; 9616 PetscCall(MatFactorUpdateSchurStatus_Private(F)); 9617 PetscFunctionReturn(0); 9618 } 9619 9620 /*@ 9621 MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step 9622 9623 Logically Collective on Mat 9624 9625 Input Parameters: 9626 + F - the factored matrix obtained by calling MatGetFactor() 9627 . rhs - location where the right hand side of the Schur complement system is stored 9628 - sol - location where the solution of the Schur complement system has to be returned 9629 9630 Notes: 9631 The sizes of the vectors should match the size of the Schur complement 9632 9633 Must be called after MatFactorSetSchurIS() 9634 9635 Level: advanced 9636 9637 References: 9638 9639 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorSolveSchurComplement()` 9640 @*/ 9641 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol) 9642 { 9643 PetscFunctionBegin; 9644 PetscValidType(F,1); 9645 PetscValidType(rhs,2); 9646 PetscValidType(sol,3); 9647 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9648 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9649 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9650 PetscCheckSameComm(F,1,rhs,2); 9651 PetscCheckSameComm(F,1,sol,3); 9652 PetscCall(MatFactorFactorizeSchurComplement(F)); 9653 switch (F->schur_status) { 9654 case MAT_FACTOR_SCHUR_FACTORED: 9655 PetscCall(MatSolveTranspose(F->schur,rhs,sol)); 9656 break; 9657 case MAT_FACTOR_SCHUR_INVERTED: 9658 PetscCall(MatMultTranspose(F->schur,rhs,sol)); 9659 break; 9660 default: 9661 SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %d",F->schur_status); 9662 } 9663 PetscFunctionReturn(0); 9664 } 9665 9666 /*@ 9667 MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step 9668 9669 Logically Collective on Mat 9670 9671 Input Parameters: 9672 + F - the factored matrix obtained by calling MatGetFactor() 9673 . rhs - location where the right hand side of the Schur complement system is stored 9674 - sol - location where the solution of the Schur complement system has to be returned 9675 9676 Notes: 9677 The sizes of the vectors should match the size of the Schur complement 9678 9679 Must be called after MatFactorSetSchurIS() 9680 9681 Level: advanced 9682 9683 References: 9684 9685 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorSolveSchurComplementTranspose()` 9686 @*/ 9687 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol) 9688 { 9689 PetscFunctionBegin; 9690 PetscValidType(F,1); 9691 PetscValidType(rhs,2); 9692 PetscValidType(sol,3); 9693 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9694 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9695 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9696 PetscCheckSameComm(F,1,rhs,2); 9697 PetscCheckSameComm(F,1,sol,3); 9698 PetscCall(MatFactorFactorizeSchurComplement(F)); 9699 switch (F->schur_status) { 9700 case MAT_FACTOR_SCHUR_FACTORED: 9701 PetscCall(MatSolve(F->schur,rhs,sol)); 9702 break; 9703 case MAT_FACTOR_SCHUR_INVERTED: 9704 PetscCall(MatMult(F->schur,rhs,sol)); 9705 break; 9706 default: 9707 SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %d",F->schur_status); 9708 } 9709 PetscFunctionReturn(0); 9710 } 9711 9712 /*@ 9713 MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step 9714 9715 Logically Collective on Mat 9716 9717 Input Parameters: 9718 . F - the factored matrix obtained by calling MatGetFactor() 9719 9720 Notes: 9721 Must be called after MatFactorSetSchurIS(). 9722 9723 Call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it. 9724 9725 Level: advanced 9726 9727 References: 9728 9729 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorGetSchurComplement()`, `MatFactorCreateSchurComplement()` 9730 @*/ 9731 PetscErrorCode MatFactorInvertSchurComplement(Mat F) 9732 { 9733 PetscFunctionBegin; 9734 PetscValidType(F,1); 9735 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9736 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0); 9737 PetscCall(MatFactorFactorizeSchurComplement(F)); 9738 PetscCall(MatFactorInvertSchurComplement_Private(F)); 9739 F->schur_status = MAT_FACTOR_SCHUR_INVERTED; 9740 PetscFunctionReturn(0); 9741 } 9742 9743 /*@ 9744 MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step 9745 9746 Logically Collective on Mat 9747 9748 Input Parameters: 9749 . F - the factored matrix obtained by calling MatGetFactor() 9750 9751 Notes: 9752 Must be called after MatFactorSetSchurIS(). 9753 9754 Level: advanced 9755 9756 References: 9757 9758 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorInvertSchurComplement()` 9759 @*/ 9760 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F) 9761 { 9762 PetscFunctionBegin; 9763 PetscValidType(F,1); 9764 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9765 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0); 9766 PetscCall(MatFactorFactorizeSchurComplement_Private(F)); 9767 F->schur_status = MAT_FACTOR_SCHUR_FACTORED; 9768 PetscFunctionReturn(0); 9769 } 9770 9771 /*@ 9772 MatPtAP - Creates the matrix product C = P^T * A * P 9773 9774 Neighbor-wise Collective on Mat 9775 9776 Input Parameters: 9777 + A - the matrix 9778 . P - the projection matrix 9779 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9780 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate 9781 if the result is a dense matrix this is irrelevant 9782 9783 Output Parameters: 9784 . C - the product matrix 9785 9786 Notes: 9787 C will be created and must be destroyed by the user with MatDestroy(). 9788 9789 For matrix types without special implementation the function fallbacks to MatMatMult() followed by MatTransposeMatMult(). 9790 9791 Level: intermediate 9792 9793 .seealso: `MatMatMult()`, `MatRARt()` 9794 @*/ 9795 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 9796 { 9797 PetscFunctionBegin; 9798 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*C,5); 9799 PetscCheck(scall != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9800 9801 if (scall == MAT_INITIAL_MATRIX) { 9802 PetscCall(MatProductCreate(A,P,NULL,C)); 9803 PetscCall(MatProductSetType(*C,MATPRODUCT_PtAP)); 9804 PetscCall(MatProductSetAlgorithm(*C,"default")); 9805 PetscCall(MatProductSetFill(*C,fill)); 9806 9807 (*C)->product->api_user = PETSC_TRUE; 9808 PetscCall(MatProductSetFromOptions(*C)); 9809 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); 9810 PetscCall(MatProductSymbolic(*C)); 9811 } else { /* scall == MAT_REUSE_MATRIX */ 9812 PetscCall(MatProductReplaceMats(A,P,NULL,*C)); 9813 } 9814 9815 PetscCall(MatProductNumeric(*C)); 9816 (*C)->symmetric = A->symmetric; 9817 (*C)->spd = A->spd; 9818 PetscFunctionReturn(0); 9819 } 9820 9821 /*@ 9822 MatRARt - Creates the matrix product C = R * A * R^T 9823 9824 Neighbor-wise Collective on Mat 9825 9826 Input Parameters: 9827 + A - the matrix 9828 . R - the projection matrix 9829 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9830 - fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate 9831 if the result is a dense matrix this is irrelevant 9832 9833 Output Parameters: 9834 . C - the product matrix 9835 9836 Notes: 9837 C will be created and must be destroyed by the user with MatDestroy(). 9838 9839 This routine is currently only implemented for pairs of AIJ matrices and classes 9840 which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes, 9841 parallel MatRARt is implemented via explicit transpose of R, which could be very expensive. 9842 We recommend using MatPtAP(). 9843 9844 Level: intermediate 9845 9846 .seealso: `MatMatMult()`, `MatPtAP()` 9847 @*/ 9848 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C) 9849 { 9850 PetscFunctionBegin; 9851 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*C,5); 9852 PetscCheck(scall != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9853 9854 if (scall == MAT_INITIAL_MATRIX) { 9855 PetscCall(MatProductCreate(A,R,NULL,C)); 9856 PetscCall(MatProductSetType(*C,MATPRODUCT_RARt)); 9857 PetscCall(MatProductSetAlgorithm(*C,"default")); 9858 PetscCall(MatProductSetFill(*C,fill)); 9859 9860 (*C)->product->api_user = PETSC_TRUE; 9861 PetscCall(MatProductSetFromOptions(*C)); 9862 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); 9863 PetscCall(MatProductSymbolic(*C)); 9864 } else { /* scall == MAT_REUSE_MATRIX */ 9865 PetscCall(MatProductReplaceMats(A,R,NULL,*C)); 9866 } 9867 9868 PetscCall(MatProductNumeric(*C)); 9869 if (A->symmetric == PETSC_BOOL3_TRUE) { 9870 PetscCall(MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE)); 9871 } 9872 PetscFunctionReturn(0); 9873 } 9874 9875 static PetscErrorCode MatProduct_Private(Mat A,Mat B,MatReuse scall,PetscReal fill,MatProductType ptype, Mat *C) 9876 { 9877 PetscFunctionBegin; 9878 PetscCheck(scall != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9879 9880 if (scall == MAT_INITIAL_MATRIX) { 9881 PetscCall(PetscInfo(A,"Calling MatProduct API with MAT_INITIAL_MATRIX and product type %s\n",MatProductTypes[ptype])); 9882 PetscCall(MatProductCreate(A,B,NULL,C)); 9883 PetscCall(MatProductSetType(*C,ptype)); 9884 PetscCall(MatProductSetAlgorithm(*C,MATPRODUCTALGORITHMDEFAULT)); 9885 PetscCall(MatProductSetFill(*C,fill)); 9886 9887 (*C)->product->api_user = PETSC_TRUE; 9888 PetscCall(MatProductSetFromOptions(*C)); 9889 PetscCall(MatProductSymbolic(*C)); 9890 } else { /* scall == MAT_REUSE_MATRIX */ 9891 Mat_Product *product = (*C)->product; 9892 PetscBool isdense; 9893 9894 PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)(*C),&isdense,MATSEQDENSE,MATMPIDENSE,"")); 9895 if (isdense && product && product->type != ptype) { 9896 PetscCall(MatProductClear(*C)); 9897 product = NULL; 9898 } 9899 PetscCall(PetscInfo(A,"Calling MatProduct API with MAT_REUSE_MATRIX %s product present and product type %s\n",product ? "with" : "without",MatProductTypes[ptype])); 9900 if (!product) { /* user provide the dense matrix *C without calling MatProductCreate() or reusing it from previous calls */ 9901 if (isdense) { 9902 PetscCall(MatProductCreate_Private(A,B,NULL,*C)); 9903 product = (*C)->product; 9904 product->fill = fill; 9905 product->api_user = PETSC_TRUE; 9906 product->clear = PETSC_TRUE; 9907 9908 PetscCall(MatProductSetType(*C,ptype)); 9909 PetscCall(MatProductSetFromOptions(*C)); 9910 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); 9911 PetscCall(MatProductSymbolic(*C)); 9912 } else SETERRQ(PetscObjectComm((PetscObject)(*C)),PETSC_ERR_SUP,"Call MatProductCreate() first"); 9913 } else { /* user may change input matrices A or B when REUSE */ 9914 PetscCall(MatProductReplaceMats(A,B,NULL,*C)); 9915 } 9916 } 9917 PetscCall(MatProductNumeric(*C)); 9918 PetscFunctionReturn(0); 9919 } 9920 9921 /*@ 9922 MatMatMult - Performs Matrix-Matrix Multiplication C=A*B. 9923 9924 Neighbor-wise Collective on Mat 9925 9926 Input Parameters: 9927 + A - the left matrix 9928 . B - the right matrix 9929 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9930 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate 9931 if the result is a dense matrix this is irrelevant 9932 9933 Output Parameters: 9934 . C - the product matrix 9935 9936 Notes: 9937 Unless scall is MAT_REUSE_MATRIX C will be created. 9938 9939 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 9940 call to this function with MAT_INITIAL_MATRIX. 9941 9942 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value actually needed. 9943 9944 If you have many matrices with the same non-zero structure to multiply, you should use MatProductCreate()/MatProductSymbolic()/MatProductReplaceMats(), and call MatProductNumeric() repeatedly. 9945 9946 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. 9947 9948 Example of Usage: 9949 .vb 9950 MatProductCreate(A,B,NULL,&C); 9951 MatProductSetType(C,MATPRODUCT_AB); 9952 MatProductSymbolic(C); 9953 MatProductNumeric(C); // compute C=A * B 9954 MatProductReplaceMats(A1,B1,NULL,C); // compute C=A1 * B1 9955 MatProductNumeric(C); 9956 MatProductReplaceMats(A2,NULL,NULL,C); // compute C=A2 * B1 9957 MatProductNumeric(C); 9958 .ve 9959 9960 Level: intermediate 9961 9962 .seealso: `MatTransposeMatMult()`, `MatMatTransposeMult()`, `MatPtAP()`, `MatProductCreate()`, `MatProductSymbolic()`, `MatProductReplaceMats()`, `MatProductNumeric()` 9963 @*/ 9964 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9965 { 9966 PetscFunctionBegin; 9967 PetscCall(MatProduct_Private(A,B,scall,fill,MATPRODUCT_AB,C)); 9968 PetscFunctionReturn(0); 9969 } 9970 9971 /*@ 9972 MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T. 9973 9974 Neighbor-wise Collective on Mat 9975 9976 Input Parameters: 9977 + A - the left matrix 9978 . B - the right matrix 9979 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9980 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9981 9982 Output Parameters: 9983 . C - the product matrix 9984 9985 Notes: 9986 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9987 9988 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9989 9990 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9991 actually needed. 9992 9993 This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class, 9994 and for pairs of MPIDense matrices. 9995 9996 Options Database Keys: 9997 . -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorithms for MPIDense matrices: the 9998 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity; 9999 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity. 10000 10001 Level: intermediate 10002 10003 .seealso: `MatMatMult()`, `MatTransposeMatMult()` `MatPtAP()` 10004 @*/ 10005 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 10006 { 10007 PetscFunctionBegin; 10008 PetscCall(MatProduct_Private(A,B,scall,fill,MATPRODUCT_ABt,C)); 10009 if (A == B) { 10010 PetscCall(MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE)); 10011 } 10012 PetscFunctionReturn(0); 10013 } 10014 10015 /*@ 10016 MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B. 10017 10018 Neighbor-wise Collective on Mat 10019 10020 Input Parameters: 10021 + A - the left matrix 10022 . B - the right matrix 10023 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10024 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 10025 10026 Output Parameters: 10027 . C - the product matrix 10028 10029 Notes: 10030 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 10031 10032 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call. 10033 10034 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 10035 actually needed. 10036 10037 This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes 10038 which inherit from SeqAIJ. C will be of the same type as the input matrices. 10039 10040 Level: intermediate 10041 10042 .seealso: `MatMatMult()`, `MatMatTransposeMult()`, `MatPtAP()` 10043 @*/ 10044 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 10045 { 10046 PetscFunctionBegin; 10047 PetscCall(MatProduct_Private(A,B,scall,fill,MATPRODUCT_AtB,C)); 10048 PetscFunctionReturn(0); 10049 } 10050 10051 /*@ 10052 MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C. 10053 10054 Neighbor-wise Collective on Mat 10055 10056 Input Parameters: 10057 + A - the left matrix 10058 . B - the middle matrix 10059 . C - the right matrix 10060 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10061 - 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 10062 if the result is a dense matrix this is irrelevant 10063 10064 Output Parameters: 10065 . D - the product matrix 10066 10067 Notes: 10068 Unless scall is MAT_REUSE_MATRIX D will be created. 10069 10070 MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call 10071 10072 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 10073 actually needed. 10074 10075 If you have many matrices with the same non-zero structure to multiply, you 10076 should use MAT_REUSE_MATRIX in all calls but the first 10077 10078 Level: intermediate 10079 10080 .seealso: `MatMatMult`, `MatPtAP()`, `MatMatTransposeMult()`, `MatTransposeMatMult()` 10081 @*/ 10082 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D) 10083 { 10084 PetscFunctionBegin; 10085 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*D,6); 10086 PetscCheck(scall != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 10087 10088 if (scall == MAT_INITIAL_MATRIX) { 10089 PetscCall(MatProductCreate(A,B,C,D)); 10090 PetscCall(MatProductSetType(*D,MATPRODUCT_ABC)); 10091 PetscCall(MatProductSetAlgorithm(*D,"default")); 10092 PetscCall(MatProductSetFill(*D,fill)); 10093 10094 (*D)->product->api_user = PETSC_TRUE; 10095 PetscCall(MatProductSetFromOptions(*D)); 10096 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,((PetscObject)C)->type_name); 10097 PetscCall(MatProductSymbolic(*D)); 10098 } else { /* user may change input matrices when REUSE */ 10099 PetscCall(MatProductReplaceMats(A,B,C,*D)); 10100 } 10101 PetscCall(MatProductNumeric(*D)); 10102 PetscFunctionReturn(0); 10103 } 10104 10105 /*@ 10106 MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators. 10107 10108 Collective on Mat 10109 10110 Input Parameters: 10111 + mat - the matrix 10112 . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices) 10113 . subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used) 10114 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10115 10116 Output Parameter: 10117 . matredundant - redundant matrix 10118 10119 Notes: 10120 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 10121 original matrix has not changed from that last call to MatCreateRedundantMatrix(). 10122 10123 This routine creates the duplicated matrices in the subcommunicators; you should NOT create them before 10124 calling it. 10125 10126 Level: advanced 10127 10128 .seealso: `MatDestroy()` 10129 @*/ 10130 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant) 10131 { 10132 MPI_Comm comm; 10133 PetscMPIInt size; 10134 PetscInt mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs; 10135 Mat_Redundant *redund=NULL; 10136 PetscSubcomm psubcomm=NULL; 10137 MPI_Comm subcomm_in=subcomm; 10138 Mat *matseq; 10139 IS isrow,iscol; 10140 PetscBool newsubcomm=PETSC_FALSE; 10141 10142 PetscFunctionBegin; 10143 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10144 if (nsubcomm && reuse == MAT_REUSE_MATRIX) { 10145 PetscValidPointer(*matredundant,5); 10146 PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5); 10147 } 10148 10149 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 10150 if (size == 1 || nsubcomm == 1) { 10151 if (reuse == MAT_INITIAL_MATRIX) { 10152 PetscCall(MatDuplicate(mat,MAT_COPY_VALUES,matredundant)); 10153 } else { 10154 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"); 10155 PetscCall(MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN)); 10156 } 10157 PetscFunctionReturn(0); 10158 } 10159 10160 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10161 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10162 MatCheckPreallocated(mat,1); 10163 10164 PetscCall(PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0)); 10165 if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */ 10166 /* create psubcomm, then get subcomm */ 10167 PetscCall(PetscObjectGetComm((PetscObject)mat,&comm)); 10168 PetscCallMPI(MPI_Comm_size(comm,&size)); 10169 PetscCheck(nsubcomm >= 1 && nsubcomm <= size,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %d",size); 10170 10171 PetscCall(PetscSubcommCreate(comm,&psubcomm)); 10172 PetscCall(PetscSubcommSetNumber(psubcomm,nsubcomm)); 10173 PetscCall(PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS)); 10174 PetscCall(PetscSubcommSetFromOptions(psubcomm)); 10175 PetscCall(PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL)); 10176 newsubcomm = PETSC_TRUE; 10177 PetscCall(PetscSubcommDestroy(&psubcomm)); 10178 } 10179 10180 /* get isrow, iscol and a local sequential matrix matseq[0] */ 10181 if (reuse == MAT_INITIAL_MATRIX) { 10182 mloc_sub = PETSC_DECIDE; 10183 nloc_sub = PETSC_DECIDE; 10184 if (bs < 1) { 10185 PetscCall(PetscSplitOwnership(subcomm,&mloc_sub,&M)); 10186 PetscCall(PetscSplitOwnership(subcomm,&nloc_sub,&N)); 10187 } else { 10188 PetscCall(PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M)); 10189 PetscCall(PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N)); 10190 } 10191 PetscCallMPI(MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm)); 10192 rstart = rend - mloc_sub; 10193 PetscCall(ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow)); 10194 PetscCall(ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol)); 10195 } else { /* reuse == MAT_REUSE_MATRIX */ 10196 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"); 10197 /* retrieve subcomm */ 10198 PetscCall(PetscObjectGetComm((PetscObject)(*matredundant),&subcomm)); 10199 redund = (*matredundant)->redundant; 10200 isrow = redund->isrow; 10201 iscol = redund->iscol; 10202 matseq = redund->matseq; 10203 } 10204 PetscCall(MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq)); 10205 10206 /* get matredundant over subcomm */ 10207 if (reuse == MAT_INITIAL_MATRIX) { 10208 PetscCall(MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant)); 10209 10210 /* create a supporting struct and attach it to C for reuse */ 10211 PetscCall(PetscNewLog(*matredundant,&redund)); 10212 (*matredundant)->redundant = redund; 10213 redund->isrow = isrow; 10214 redund->iscol = iscol; 10215 redund->matseq = matseq; 10216 if (newsubcomm) { 10217 redund->subcomm = subcomm; 10218 } else { 10219 redund->subcomm = MPI_COMM_NULL; 10220 } 10221 } else { 10222 PetscCall(MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant)); 10223 } 10224 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 10225 if (matseq[0]->boundtocpu && matseq[0]->bindingpropagates) { 10226 PetscCall(MatBindToCPU(*matredundant,PETSC_TRUE)); 10227 PetscCall(MatSetBindingPropagates(*matredundant,PETSC_TRUE)); 10228 } 10229 #endif 10230 PetscCall(PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0)); 10231 PetscFunctionReturn(0); 10232 } 10233 10234 /*@C 10235 MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from 10236 a given 'mat' object. Each submatrix can span multiple procs. 10237 10238 Collective on Mat 10239 10240 Input Parameters: 10241 + mat - the matrix 10242 . subcomm - the subcommunicator obtained by com_split(comm) 10243 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10244 10245 Output Parameter: 10246 . subMat - 'parallel submatrices each spans a given subcomm 10247 10248 Notes: 10249 The submatrix partition across processors is dictated by 'subComm' a 10250 communicator obtained by MPI_comm_split(). The subComm 10251 is not restriced to be grouped with consecutive original ranks. 10252 10253 Due the MPI_Comm_split() usage, the parallel layout of the submatrices 10254 map directly to the layout of the original matrix [wrt the local 10255 row,col partitioning]. So the original 'DiagonalMat' naturally maps 10256 into the 'DiagonalMat' of the subMat, hence it is used directly from 10257 the subMat. However the offDiagMat looses some columns - and this is 10258 reconstructed with MatSetValues() 10259 10260 Level: advanced 10261 10262 .seealso: `MatCreateSubMatrices()` 10263 @*/ 10264 PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat) 10265 { 10266 PetscMPIInt commsize,subCommSize; 10267 10268 PetscFunctionBegin; 10269 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize)); 10270 PetscCallMPI(MPI_Comm_size(subComm,&subCommSize)); 10271 PetscCheck(subCommSize <= commsize,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %d < SubCommZize %d",commsize,subCommSize); 10272 10273 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"); 10274 PetscCall(PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0)); 10275 PetscCall((*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat)); 10276 PetscCall(PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0)); 10277 PetscFunctionReturn(0); 10278 } 10279 10280 /*@ 10281 MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering 10282 10283 Not Collective 10284 10285 Input Parameters: 10286 + mat - matrix to extract local submatrix from 10287 . isrow - local row indices for submatrix 10288 - iscol - local column indices for submatrix 10289 10290 Output Parameter: 10291 . submat - the submatrix 10292 10293 Level: intermediate 10294 10295 Notes: 10296 The submat should be returned with MatRestoreLocalSubMatrix(). 10297 10298 Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be 10299 the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's. 10300 10301 The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then 10302 MatSetValuesBlockedLocal() will also be implemented. 10303 10304 The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that 10305 matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided. 10306 10307 .seealso: `MatRestoreLocalSubMatrix()`, `MatCreateLocalRef()`, `MatSetLocalToGlobalMapping()` 10308 @*/ 10309 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10310 { 10311 PetscFunctionBegin; 10312 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10313 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10314 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10315 PetscCheckSameComm(isrow,2,iscol,3); 10316 PetscValidPointer(submat,4); 10317 PetscCheck(mat->rmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call"); 10318 10319 if (mat->ops->getlocalsubmatrix) { 10320 PetscCall((*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat)); 10321 } else { 10322 PetscCall(MatCreateLocalRef(mat,isrow,iscol,submat)); 10323 } 10324 PetscFunctionReturn(0); 10325 } 10326 10327 /*@ 10328 MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering 10329 10330 Not Collective 10331 10332 Input Parameters: 10333 + mat - matrix to extract local submatrix from 10334 . isrow - local row indices for submatrix 10335 . iscol - local column indices for submatrix 10336 - submat - the submatrix 10337 10338 Level: intermediate 10339 10340 .seealso: `MatGetLocalSubMatrix()` 10341 @*/ 10342 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10343 { 10344 PetscFunctionBegin; 10345 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10346 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10347 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10348 PetscCheckSameComm(isrow,2,iscol,3); 10349 PetscValidPointer(submat,4); 10350 if (*submat) { 10351 PetscValidHeaderSpecific(*submat,MAT_CLASSID,4); 10352 } 10353 10354 if (mat->ops->restorelocalsubmatrix) { 10355 PetscCall((*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat)); 10356 } else { 10357 PetscCall(MatDestroy(submat)); 10358 } 10359 *submat = NULL; 10360 PetscFunctionReturn(0); 10361 } 10362 10363 /* --------------------------------------------------------*/ 10364 /*@ 10365 MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix 10366 10367 Collective on Mat 10368 10369 Input Parameter: 10370 . mat - the matrix 10371 10372 Output Parameter: 10373 . is - if any rows have zero diagonals this contains the list of them 10374 10375 Level: developer 10376 10377 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 10378 @*/ 10379 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is) 10380 { 10381 PetscFunctionBegin; 10382 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10383 PetscValidType(mat,1); 10384 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10385 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10386 10387 if (!mat->ops->findzerodiagonals) { 10388 Vec diag; 10389 const PetscScalar *a; 10390 PetscInt *rows; 10391 PetscInt rStart, rEnd, r, nrow = 0; 10392 10393 PetscCall(MatCreateVecs(mat, &diag, NULL)); 10394 PetscCall(MatGetDiagonal(mat, diag)); 10395 PetscCall(MatGetOwnershipRange(mat, &rStart, &rEnd)); 10396 PetscCall(VecGetArrayRead(diag, &a)); 10397 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow; 10398 PetscCall(PetscMalloc1(nrow, &rows)); 10399 nrow = 0; 10400 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart; 10401 PetscCall(VecRestoreArrayRead(diag, &a)); 10402 PetscCall(VecDestroy(&diag)); 10403 PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is)); 10404 } else { 10405 PetscCall((*mat->ops->findzerodiagonals)(mat, is)); 10406 } 10407 PetscFunctionReturn(0); 10408 } 10409 10410 /*@ 10411 MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size) 10412 10413 Collective on Mat 10414 10415 Input Parameter: 10416 . mat - the matrix 10417 10418 Output Parameter: 10419 . is - contains the list of rows with off block diagonal entries 10420 10421 Level: developer 10422 10423 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 10424 @*/ 10425 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is) 10426 { 10427 PetscFunctionBegin; 10428 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10429 PetscValidType(mat,1); 10430 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10431 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10432 10433 PetscCheck(mat->ops->findoffblockdiagonalentries,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a find off block diagonal entries defined",((PetscObject)mat)->type_name); 10434 PetscCall((*mat->ops->findoffblockdiagonalentries)(mat,is)); 10435 PetscFunctionReturn(0); 10436 } 10437 10438 /*@C 10439 MatInvertBlockDiagonal - Inverts the block diagonal entries. 10440 10441 Collective on Mat 10442 10443 Input Parameters: 10444 . mat - the matrix 10445 10446 Output Parameters: 10447 . values - the block inverses in column major order (FORTRAN-like) 10448 10449 Note: 10450 The size of the blocks is determined by the block size of the matrix. 10451 10452 Fortran Note: 10453 This routine is not available from Fortran. 10454 10455 Level: advanced 10456 10457 .seealso: `MatInvertVariableBlockEnvelope()`, `MatInvertBlockDiagonalMat()` 10458 @*/ 10459 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values) 10460 { 10461 PetscFunctionBegin; 10462 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10463 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10464 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10465 PetscCheck(mat->ops->invertblockdiagonal,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for type %s",((PetscObject)mat)->type_name); 10466 PetscCall((*mat->ops->invertblockdiagonal)(mat,values)); 10467 PetscFunctionReturn(0); 10468 } 10469 10470 /*@C 10471 MatInvertVariableBlockDiagonal - Inverts the point block diagonal entries. 10472 10473 Collective on Mat 10474 10475 Input Parameters: 10476 + mat - the matrix 10477 . nblocks - the number of blocks on the process, set with MatSetVariableBlockSizes() 10478 - bsizes - the size of each block on the process, set with MatSetVariableBlockSizes() 10479 10480 Output Parameters: 10481 . values - the block inverses in column major order (FORTRAN-like) 10482 10483 Note: 10484 This routine is not available from Fortran. 10485 10486 Level: advanced 10487 10488 .seealso: `MatInvertBlockDiagonal()`, `MatSetVariableBlockSizes()`, `MatInvertVariableBlockEnvelope()` 10489 @*/ 10490 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values) 10491 { 10492 PetscFunctionBegin; 10493 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10494 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10495 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10496 PetscCheck(mat->ops->invertvariableblockdiagonal,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for type %s",((PetscObject)mat)->type_name); 10497 PetscCall((*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values)); 10498 PetscFunctionReturn(0); 10499 } 10500 10501 /*@ 10502 MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A 10503 10504 Collective on Mat 10505 10506 Input Parameters: 10507 . A - the matrix 10508 10509 Output Parameters: 10510 . C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set. 10511 10512 Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C 10513 10514 Level: advanced 10515 10516 .seealso: `MatInvertBlockDiagonal()` 10517 @*/ 10518 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C) 10519 { 10520 const PetscScalar *vals; 10521 PetscInt *dnnz; 10522 PetscInt m,rstart,rend,bs,i,j; 10523 10524 PetscFunctionBegin; 10525 PetscCall(MatInvertBlockDiagonal(A,&vals)); 10526 PetscCall(MatGetBlockSize(A,&bs)); 10527 PetscCall(MatGetLocalSize(A,&m,NULL)); 10528 PetscCall(MatSetLayouts(C,A->rmap,A->cmap)); 10529 PetscCall(PetscMalloc1(m/bs,&dnnz)); 10530 for (j = 0; j < m/bs; j++) dnnz[j] = 1; 10531 PetscCall(MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL)); 10532 PetscCall(PetscFree(dnnz)); 10533 PetscCall(MatGetOwnershipRange(C,&rstart,&rend)); 10534 PetscCall(MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE)); 10535 for (i = rstart/bs; i < rend/bs; i++) { 10536 PetscCall(MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES)); 10537 } 10538 PetscCall(MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY)); 10539 PetscCall(MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY)); 10540 PetscCall(MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE)); 10541 PetscFunctionReturn(0); 10542 } 10543 10544 /*@C 10545 MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created 10546 via MatTransposeColoringCreate(). 10547 10548 Collective on MatTransposeColoring 10549 10550 Input Parameter: 10551 . c - coloring context 10552 10553 Level: intermediate 10554 10555 .seealso: `MatTransposeColoringCreate()` 10556 @*/ 10557 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c) 10558 { 10559 MatTransposeColoring matcolor=*c; 10560 10561 PetscFunctionBegin; 10562 if (!matcolor) PetscFunctionReturn(0); 10563 if (--((PetscObject)matcolor)->refct > 0) {matcolor = NULL; PetscFunctionReturn(0);} 10564 10565 PetscCall(PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow)); 10566 PetscCall(PetscFree(matcolor->rows)); 10567 PetscCall(PetscFree(matcolor->den2sp)); 10568 PetscCall(PetscFree(matcolor->colorforcol)); 10569 PetscCall(PetscFree(matcolor->columns)); 10570 if (matcolor->brows>0) PetscCall(PetscFree(matcolor->lstart)); 10571 PetscCall(PetscHeaderDestroy(c)); 10572 PetscFunctionReturn(0); 10573 } 10574 10575 /*@C 10576 MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which 10577 a MatTransposeColoring context has been created, computes a dense B^T by Apply 10578 MatTransposeColoring to sparse B. 10579 10580 Collective on MatTransposeColoring 10581 10582 Input Parameters: 10583 + B - sparse matrix B 10584 . Btdense - symbolic dense matrix B^T 10585 - coloring - coloring context created with MatTransposeColoringCreate() 10586 10587 Output Parameter: 10588 . Btdense - dense matrix B^T 10589 10590 Level: advanced 10591 10592 Notes: 10593 These are used internally for some implementations of MatRARt() 10594 10595 .seealso: `MatTransposeColoringCreate()`, `MatTransposeColoringDestroy()`, `MatTransColoringApplyDenToSp()` 10596 10597 @*/ 10598 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense) 10599 { 10600 PetscFunctionBegin; 10601 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 10602 PetscValidHeaderSpecific(Btdense,MAT_CLASSID,3); 10603 PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,1); 10604 10605 PetscCheck(B->ops->transcoloringapplysptoden,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name); 10606 PetscCall((B->ops->transcoloringapplysptoden)(coloring,B,Btdense)); 10607 PetscFunctionReturn(0); 10608 } 10609 10610 /*@C 10611 MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which 10612 a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense 10613 in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix 10614 Csp from Cden. 10615 10616 Collective on MatTransposeColoring 10617 10618 Input Parameters: 10619 + coloring - coloring context created with MatTransposeColoringCreate() 10620 - Cden - matrix product of a sparse matrix and a dense matrix Btdense 10621 10622 Output Parameter: 10623 . Csp - sparse matrix 10624 10625 Level: advanced 10626 10627 Notes: 10628 These are used internally for some implementations of MatRARt() 10629 10630 .seealso: `MatTransposeColoringCreate()`, `MatTransposeColoringDestroy()`, `MatTransColoringApplySpToDen()` 10631 10632 @*/ 10633 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp) 10634 { 10635 PetscFunctionBegin; 10636 PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1); 10637 PetscValidHeaderSpecific(Cden,MAT_CLASSID,2); 10638 PetscValidHeaderSpecific(Csp,MAT_CLASSID,3); 10639 10640 PetscCheck(Csp->ops->transcoloringapplydentosp,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name); 10641 PetscCall((Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp)); 10642 PetscCall(MatAssemblyBegin(Csp,MAT_FINAL_ASSEMBLY)); 10643 PetscCall(MatAssemblyEnd(Csp,MAT_FINAL_ASSEMBLY)); 10644 PetscFunctionReturn(0); 10645 } 10646 10647 /*@C 10648 MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T. 10649 10650 Collective on Mat 10651 10652 Input Parameters: 10653 + mat - the matrix product C 10654 - iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring() 10655 10656 Output Parameter: 10657 . color - the new coloring context 10658 10659 Level: intermediate 10660 10661 .seealso: `MatTransposeColoringDestroy()`, `MatTransColoringApplySpToDen()`, 10662 `MatTransColoringApplyDenToSp()` 10663 @*/ 10664 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color) 10665 { 10666 MatTransposeColoring c; 10667 MPI_Comm comm; 10668 10669 PetscFunctionBegin; 10670 PetscCall(PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0)); 10671 PetscCall(PetscObjectGetComm((PetscObject)mat,&comm)); 10672 PetscCall(PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL)); 10673 10674 c->ctype = iscoloring->ctype; 10675 if (mat->ops->transposecoloringcreate) { 10676 PetscCall((*mat->ops->transposecoloringcreate)(mat,iscoloring,c)); 10677 } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for matrix type %s",((PetscObject)mat)->type_name); 10678 10679 *color = c; 10680 PetscCall(PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0)); 10681 PetscFunctionReturn(0); 10682 } 10683 10684 /*@ 10685 MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the 10686 matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the 10687 same, otherwise it will be larger 10688 10689 Not Collective 10690 10691 Input Parameter: 10692 . A - the matrix 10693 10694 Output Parameter: 10695 . state - the current state 10696 10697 Notes: 10698 You can only compare states from two different calls to the SAME matrix, you cannot compare calls between 10699 different matrices 10700 10701 Level: intermediate 10702 10703 .seealso: `PetscObjectStateGet()` 10704 @*/ 10705 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state) 10706 { 10707 PetscFunctionBegin; 10708 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10709 *state = mat->nonzerostate; 10710 PetscFunctionReturn(0); 10711 } 10712 10713 /*@ 10714 MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential 10715 matrices from each processor 10716 10717 Collective 10718 10719 Input Parameters: 10720 + comm - the communicators the parallel matrix will live on 10721 . seqmat - the input sequential matrices 10722 . n - number of local columns (or PETSC_DECIDE) 10723 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10724 10725 Output Parameter: 10726 . mpimat - the parallel matrix generated 10727 10728 Level: advanced 10729 10730 Notes: 10731 The number of columns of the matrix in EACH processor MUST be the same. 10732 10733 @*/ 10734 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat) 10735 { 10736 PetscMPIInt size; 10737 10738 PetscFunctionBegin; 10739 PetscCallMPI(MPI_Comm_size(comm,&size)); 10740 if (size == 1) { 10741 if (reuse == MAT_INITIAL_MATRIX) { 10742 PetscCall(MatDuplicate(seqmat,MAT_COPY_VALUES,mpimat)); 10743 } else { 10744 PetscCall(MatCopy(seqmat,*mpimat,SAME_NONZERO_PATTERN)); 10745 } 10746 PetscFunctionReturn(0); 10747 } 10748 10749 PetscCheck(seqmat->ops->creatempimatconcatenateseqmat,PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name); 10750 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"); 10751 10752 PetscCall(PetscLogEventBegin(MAT_Merge,seqmat,0,0,0)); 10753 PetscCall((*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat)); 10754 PetscCall(PetscLogEventEnd(MAT_Merge,seqmat,0,0,0)); 10755 PetscFunctionReturn(0); 10756 } 10757 10758 /*@ 10759 MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent 10760 ranks' ownership ranges. 10761 10762 Collective on A 10763 10764 Input Parameters: 10765 + A - the matrix to create subdomains from 10766 - N - requested number of subdomains 10767 10768 Output Parameters: 10769 + n - number of subdomains resulting on this rank 10770 - iss - IS list with indices of subdomains on this rank 10771 10772 Level: advanced 10773 10774 Notes: 10775 number of subdomains must be smaller than the communicator size 10776 @*/ 10777 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[]) 10778 { 10779 MPI_Comm comm,subcomm; 10780 PetscMPIInt size,rank,color; 10781 PetscInt rstart,rend,k; 10782 10783 PetscFunctionBegin; 10784 PetscCall(PetscObjectGetComm((PetscObject)A,&comm)); 10785 PetscCallMPI(MPI_Comm_size(comm,&size)); 10786 PetscCallMPI(MPI_Comm_rank(comm,&rank)); 10787 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); 10788 *n = 1; 10789 k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */ 10790 color = rank/k; 10791 PetscCallMPI(MPI_Comm_split(comm,color,rank,&subcomm)); 10792 PetscCall(PetscMalloc1(1,iss)); 10793 PetscCall(MatGetOwnershipRange(A,&rstart,&rend)); 10794 PetscCall(ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0])); 10795 PetscCallMPI(MPI_Comm_free(&subcomm)); 10796 PetscFunctionReturn(0); 10797 } 10798 10799 /*@ 10800 MatGalerkin - Constructs the coarse grid problem via Galerkin projection. 10801 10802 If the interpolation and restriction operators are the same, uses MatPtAP. 10803 If they are not the same, use MatMatMatMult. 10804 10805 Once the coarse grid problem is constructed, correct for interpolation operators 10806 that are not of full rank, which can legitimately happen in the case of non-nested 10807 geometric multigrid. 10808 10809 Input Parameters: 10810 + restrct - restriction operator 10811 . dA - fine grid matrix 10812 . interpolate - interpolation operator 10813 . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10814 - fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate 10815 10816 Output Parameters: 10817 . A - the Galerkin coarse matrix 10818 10819 Options Database Key: 10820 . -pc_mg_galerkin <both,pmat,mat,none> - for what matrices the Galerkin process should be used 10821 10822 Level: developer 10823 10824 .seealso: `MatPtAP()`, `MatMatMatMult()` 10825 @*/ 10826 PetscErrorCode MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A) 10827 { 10828 IS zerorows; 10829 Vec diag; 10830 10831 PetscFunctionBegin; 10832 PetscCheck(reuse != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 10833 /* Construct the coarse grid matrix */ 10834 if (interpolate == restrct) { 10835 PetscCall(MatPtAP(dA,interpolate,reuse,fill,A)); 10836 } else { 10837 PetscCall(MatMatMatMult(restrct,dA,interpolate,reuse,fill,A)); 10838 } 10839 10840 /* If the interpolation matrix is not of full rank, A will have zero rows. 10841 This can legitimately happen in the case of non-nested geometric multigrid. 10842 In that event, we set the rows of the matrix to the rows of the identity, 10843 ignoring the equations (as the RHS will also be zero). */ 10844 10845 PetscCall(MatFindZeroRows(*A, &zerorows)); 10846 10847 if (zerorows != NULL) { /* if there are any zero rows */ 10848 PetscCall(MatCreateVecs(*A, &diag, NULL)); 10849 PetscCall(MatGetDiagonal(*A, diag)); 10850 PetscCall(VecISSet(diag, zerorows, 1.0)); 10851 PetscCall(MatDiagonalSet(*A, diag, INSERT_VALUES)); 10852 PetscCall(VecDestroy(&diag)); 10853 PetscCall(ISDestroy(&zerorows)); 10854 } 10855 PetscFunctionReturn(0); 10856 } 10857 10858 /*@C 10859 MatSetOperation - Allows user to set a matrix operation for any matrix type 10860 10861 Logically Collective on Mat 10862 10863 Input Parameters: 10864 + mat - the matrix 10865 . op - the name of the operation 10866 - f - the function that provides the operation 10867 10868 Level: developer 10869 10870 Usage: 10871 $ extern PetscErrorCode usermult(Mat,Vec,Vec); 10872 $ PetscCall(MatCreateXXX(comm,...&A); 10873 $ PetscCall(MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult); 10874 10875 Notes: 10876 See the file include/petscmat.h for a complete list of matrix 10877 operations, which all have the form MATOP_<OPERATION>, where 10878 <OPERATION> is the name (in all capital letters) of the 10879 user interface routine (e.g., MatMult() -> MATOP_MULT). 10880 10881 All user-provided functions (except for MATOP_DESTROY) should have the same calling 10882 sequence as the usual matrix interface routines, since they 10883 are intended to be accessed via the usual matrix interface 10884 routines, e.g., 10885 $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 10886 10887 In particular each function MUST return an error code of 0 on success and 10888 nonzero on failure. 10889 10890 This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type. 10891 10892 .seealso: `MatGetOperation()`, `MatCreateShell()`, `MatShellSetContext()`, `MatShellSetOperation()` 10893 @*/ 10894 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void)) 10895 { 10896 PetscFunctionBegin; 10897 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10898 if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) { 10899 mat->ops->viewnative = mat->ops->view; 10900 } 10901 (((void(**)(void))mat->ops)[op]) = f; 10902 PetscFunctionReturn(0); 10903 } 10904 10905 /*@C 10906 MatGetOperation - Gets a matrix operation for any matrix type. 10907 10908 Not Collective 10909 10910 Input Parameters: 10911 + mat - the matrix 10912 - op - the name of the operation 10913 10914 Output Parameter: 10915 . f - the function that provides the operation 10916 10917 Level: developer 10918 10919 Usage: 10920 $ PetscErrorCode (*usermult)(Mat,Vec,Vec); 10921 $ MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult); 10922 10923 Notes: 10924 See the file include/petscmat.h for a complete list of matrix 10925 operations, which all have the form MATOP_<OPERATION>, where 10926 <OPERATION> is the name (in all capital letters) of the 10927 user interface routine (e.g., MatMult() -> MATOP_MULT). 10928 10929 This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type. 10930 10931 .seealso: `MatSetOperation()`, `MatCreateShell()`, `MatShellGetContext()`, `MatShellGetOperation()` 10932 @*/ 10933 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void)) 10934 { 10935 PetscFunctionBegin; 10936 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10937 *f = (((void (**)(void))mat->ops)[op]); 10938 PetscFunctionReturn(0); 10939 } 10940 10941 /*@ 10942 MatHasOperation - Determines whether the given matrix supports the particular 10943 operation. 10944 10945 Not Collective 10946 10947 Input Parameters: 10948 + mat - the matrix 10949 - op - the operation, for example, MATOP_GET_DIAGONAL 10950 10951 Output Parameter: 10952 . has - either PETSC_TRUE or PETSC_FALSE 10953 10954 Level: advanced 10955 10956 Notes: 10957 See the file include/petscmat.h for a complete list of matrix 10958 operations, which all have the form MATOP_<OPERATION>, where 10959 <OPERATION> is the name (in all capital letters) of the 10960 user-level routine. E.g., MatNorm() -> MATOP_NORM. 10961 10962 .seealso: `MatCreateShell()` 10963 @*/ 10964 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has) 10965 { 10966 PetscFunctionBegin; 10967 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10968 PetscValidBoolPointer(has,3); 10969 if (mat->ops->hasoperation) { 10970 PetscCall((*mat->ops->hasoperation)(mat,op,has)); 10971 } else { 10972 if (((void**)mat->ops)[op]) *has = PETSC_TRUE; 10973 else { 10974 *has = PETSC_FALSE; 10975 if (op == MATOP_CREATE_SUBMATRIX) { 10976 PetscMPIInt size; 10977 10978 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 10979 if (size == 1) { 10980 PetscCall(MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has)); 10981 } 10982 } 10983 } 10984 } 10985 PetscFunctionReturn(0); 10986 } 10987 10988 /*@ 10989 MatHasCongruentLayouts - Determines whether the rows and columns layouts 10990 of the matrix are congruent 10991 10992 Collective on mat 10993 10994 Input Parameters: 10995 . mat - the matrix 10996 10997 Output Parameter: 10998 . cong - either PETSC_TRUE or PETSC_FALSE 10999 11000 Level: beginner 11001 11002 Notes: 11003 11004 .seealso: `MatCreate()`, `MatSetSizes()` 11005 @*/ 11006 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong) 11007 { 11008 PetscFunctionBegin; 11009 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 11010 PetscValidType(mat,1); 11011 PetscValidBoolPointer(cong,2); 11012 if (!mat->rmap || !mat->cmap) { 11013 *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE; 11014 PetscFunctionReturn(0); 11015 } 11016 if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */ 11017 PetscCall(PetscLayoutSetUp(mat->rmap)); 11018 PetscCall(PetscLayoutSetUp(mat->cmap)); 11019 PetscCall(PetscLayoutCompare(mat->rmap,mat->cmap,cong)); 11020 if (*cong) mat->congruentlayouts = 1; 11021 else mat->congruentlayouts = 0; 11022 } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE; 11023 PetscFunctionReturn(0); 11024 } 11025 11026 PetscErrorCode MatSetInf(Mat A) 11027 { 11028 PetscFunctionBegin; 11029 PetscCheck(A->ops->setinf,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"No support for this operation for this matrix type"); 11030 PetscCall((*A->ops->setinf)(A)); 11031 PetscFunctionReturn(0); 11032 } 11033 11034 /*C 11035 MatCreateGraph - create a scalar matrix, for use in graph algorithms 11036 11037 Collective on mat 11038 11039 Input Parameters: 11040 + A - the matrix 11041 - sym - PETSC_TRUE indicates that the graph will be symmetrized 11042 . scale - PETSC_TRUE indicates that the graph will be scaled with the diagonal 11043 11044 Output Parameter: 11045 . graph - the resulting graph 11046 11047 Level: advanced 11048 11049 Notes: 11050 11051 .seealso: `MatCreate()`, `MatFilter()` 11052 */ 11053 PETSC_EXTERN PetscErrorCode MatCreateGraph(Mat A, PetscBool sym, PetscBool scale, Mat *graph) 11054 { 11055 PetscFunctionBegin; 11056 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 11057 PetscValidType(A,1); 11058 PetscValidPointer(graph,3); 11059 PetscCheck(A->ops->creategraph,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"No support for this operation for this matrix type"); 11060 PetscCall((*A->ops->creategraph)(A,sym,scale,graph)); 11061 PetscFunctionReturn(0); 11062 } 11063 11064 /*C 11065 MatFilter - filters a Mat values with an absolut value equal to or below a give threshold 11066 11067 Collective on mat 11068 11069 Input Parameter: 11070 . value - filter value - < 0: does nothing; == 0: removes only 0.0 entries; otherwise: removes entries <= value 11071 11072 Input/Output Parameter: 11073 . A - the Mat to filter in place 11074 11075 Level: developer 11076 11077 Note: 11078 This is called before graph coarsers are called in GAMG 11079 11080 .seealso: `MatCreate()`, `MatCreateGraph()` 11081 */ 11082 PETSC_EXTERN PetscErrorCode MatFilter(Mat G,PetscReal value,Mat *F) 11083 { 11084 PetscFunctionBegin; 11085 PetscValidHeaderSpecific(G,MAT_CLASSID,1); 11086 PetscValidType(G,1); 11087 PetscValidPointer(F,3); 11088 if (value >= 0.0) { 11089 PetscCheck(G->ops->filter,PetscObjectComm((PetscObject)G),PETSC_ERR_SUP,"No support for this operation for this matrix type"); 11090 PetscCall((G->ops->filter)(G,value,F)); 11091 } 11092 PetscFunctionReturn(0); 11093 } 11094