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)) { 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 } 586 PetscFunctionReturn(0); 587 } 588 589 /*@C 590 MatRestoreRow - Frees any temporary space allocated by `MatGetRow()`. 591 592 Not Collective 593 594 Input Parameters: 595 + mat - the matrix 596 . row - the row to get 597 . ncols, cols - the number of nonzeros and their columns 598 - vals - if nonzero the column values 599 600 Notes: 601 This routine should be called after you have finished examining the entries. 602 603 This routine zeros out ncols, cols, and vals. This is to prevent accidental 604 us of the array after it has been restored. If you pass NULL, it will 605 not zero the pointers. Use of cols or vals after `MatRestoreRow()` is invalid. 606 607 Fortran Notes: 608 The calling sequence from Fortran is 609 .vb 610 MatRestoreRow(matrix,row,ncols,cols,values,ierr) 611 Mat matrix (input) 612 integer row (input) 613 integer ncols (output) 614 integer cols(maxcols) (output) 615 double precision (or double complex) values(maxcols) output 616 .ve 617 Where maxcols >= maximum nonzeros in any row of the matrix. 618 619 In Fortran `MatRestoreRow()` MUST be called after `MatGetRow()` 620 before another call to `MatGetRow()` can be made. 621 622 Level: advanced 623 624 .seealso: `MatGetRow()` 625 @*/ 626 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 627 { 628 PetscFunctionBegin; 629 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 630 if (ncols) PetscValidIntPointer(ncols,3); 631 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 632 if (!mat->ops->restorerow) PetscFunctionReturn(0); 633 PetscCall((*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals)); 634 if (ncols) *ncols = 0; 635 if (cols) *cols = NULL; 636 if (vals) *vals = NULL; 637 PetscFunctionReturn(0); 638 } 639 640 /*@ 641 MatGetRowUpperTriangular - Sets a flag to enable calls to `MatGetRow()` for matrix in `MATSBAIJ` format. 642 You should call `MatRestoreRowUpperTriangular()` after calling` MatGetRow()` and `MatRestoreRow()` to disable the flag. 643 644 Not Collective 645 646 Input Parameters: 647 . mat - the matrix 648 649 Notes: 650 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. 651 652 Level: advanced 653 654 .seealso: `MatRestoreRowUpperTriangular()` 655 @*/ 656 PetscErrorCode MatGetRowUpperTriangular(Mat mat) 657 { 658 PetscFunctionBegin; 659 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 660 PetscValidType(mat,1); 661 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 662 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 663 MatCheckPreallocated(mat,1); 664 if (!mat->ops->getrowuppertriangular) PetscFunctionReturn(0); 665 PetscCall((*mat->ops->getrowuppertriangular)(mat)); 666 PetscFunctionReturn(0); 667 } 668 669 /*@ 670 MatRestoreRowUpperTriangular - Disable calls to `MatGetRow()` for matrix in `MATSBAIJ` format. 671 672 Not Collective 673 674 Input Parameters: 675 . mat - the matrix 676 677 Notes: 678 This routine should be called after you have finished calls to `MatGetRow()` and `MatRestoreRow()`. 679 680 Level: advanced 681 682 .seealso: `MatGetRowUpperTriangular()` 683 @*/ 684 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat) 685 { 686 PetscFunctionBegin; 687 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 688 PetscValidType(mat,1); 689 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 690 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 691 MatCheckPreallocated(mat,1); 692 if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0); 693 PetscCall((*mat->ops->restorerowuppertriangular)(mat)); 694 PetscFunctionReturn(0); 695 } 696 697 /*@C 698 MatSetOptionsPrefix - Sets the prefix used for searching for all 699 Mat options in the database. 700 701 Logically Collective on Mat 702 703 Input Parameters: 704 + A - the Mat context 705 - prefix - the prefix to prepend to all option names 706 707 Notes: 708 A hyphen (-) must NOT be given at the beginning of the prefix name. 709 The first character of all runtime options is AUTOMATICALLY the hyphen. 710 711 This is NOT used for options for the factorization of the matrix. Normally the 712 prefix is automatically passed in from the PC calling the factorization. To set 713 it directly use `MatSetOptionsPrefixFactor()` 714 715 Level: advanced 716 717 .seealso: `MatSetFromOptions()`, `MatSetOptionsPrefixFactor()` 718 @*/ 719 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[]) 720 { 721 PetscFunctionBegin; 722 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 723 PetscCall(PetscObjectSetOptionsPrefix((PetscObject)A,prefix)); 724 PetscFunctionReturn(0); 725 } 726 727 /*@C 728 MatSetOptionsPrefixFactor - Sets the prefix used for searching for all Mat factor options in the database for 729 for matrices created with `MatGetFactor()` 730 731 Logically Collective on Mat 732 733 Input Parameters: 734 + A - the Mat context 735 - prefix - the prefix to prepend to all option names for the factored matrix 736 737 Notes: 738 A hyphen (-) must NOT be given at the beginning of the prefix name. 739 The first character of all runtime options is AUTOMATICALLY the hyphen. 740 741 Normally the prefix is automatically passed in from the PC calling the factorization. To set 742 it directly when not using `KSP`/`PC` use `MatSetOptionsPrefixFactor()` 743 744 Level: developer 745 746 .seealso: `MatSetFromOptions()`, `MatSetOptionsPrefix()`, `MatAppendOptionsPrefixFactor()` 747 @*/ 748 PetscErrorCode MatSetOptionsPrefixFactor(Mat A,const char prefix[]) 749 { 750 PetscFunctionBegin; 751 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 752 if (prefix) { 753 PetscValidCharPointer(prefix,2); 754 PetscCheck(prefix[0] != '-',PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Options prefix should not begin with a hyphen"); 755 if (prefix != A->factorprefix) { 756 PetscCall(PetscFree(A->factorprefix)); 757 PetscCall(PetscStrallocpy(prefix,&A->factorprefix)); 758 } 759 } else PetscCall(PetscFree(A->factorprefix)); 760 PetscFunctionReturn(0); 761 } 762 763 /*@C 764 MatAppendOptionsPrefixFactor - Appends to the prefix used for searching for all Mat factor options in the database for 765 for matrices created with `MatGetFactor()` 766 767 Logically Collective on Mat 768 769 Input Parameters: 770 + A - the Mat context 771 - prefix - the prefix to prepend to all option names for the factored matrix 772 773 Notes: 774 A hyphen (-) must NOT be given at the beginning of the prefix name. 775 The first character of all runtime options is AUTOMATICALLY the hyphen. 776 777 Normally the prefix is automatically passed in from the PC calling the factorization. To set 778 it directly when not using `KSP`/`PC` use `MatAppendOptionsPrefixFactor()` 779 780 Level: developer 781 .seealso: `PetscOptionsCreate()`, `PetscOptionsDestroy()`, `PetscObjectSetOptionsPrefix()`, `PetscObjectPrependOptionsPrefix()`, 782 `PetscObjectGetOptionsPrefix()`, `TSAppendOptionsPrefix()`, `SNESAppendOptionsPrefix()`, `KSPAppendOptionsPrefix()`, `MatSetOptionsPrefixFactor()`, 783 `MatSetOptionsPrefix()` 784 @*/ 785 PetscErrorCode MatAppendOptionsPrefixFactor(Mat A,const char prefix[]) 786 { 787 char *buf = A->factorprefix; 788 size_t len1,len2; 789 790 PetscFunctionBegin; 791 PetscValidHeader(A,1); 792 if (!prefix) PetscFunctionReturn(0); 793 if (!buf) { 794 PetscCall(MatSetOptionsPrefixFactor(A,prefix)); 795 PetscFunctionReturn(0); 796 } 797 PetscCheck(prefix[0] != '-',PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Options prefix should not begin with a hyphen"); 798 799 PetscCall(PetscStrlen(prefix,&len1)); 800 PetscCall(PetscStrlen(buf,&len2)); 801 PetscCall(PetscMalloc1(1+len1+len2,&A->factorprefix)); 802 PetscCall(PetscStrcpy(A->factorprefix,buf)); 803 PetscCall(PetscStrcat(A->factorprefix,prefix)); 804 PetscCall(PetscFree(buf)); 805 PetscFunctionReturn(0); 806 } 807 808 /*@C 809 MatAppendOptionsPrefix - Appends to the prefix used for searching for all 810 Mat options in the database. 811 812 Logically Collective on Mat 813 814 Input Parameters: 815 + A - the Mat context 816 - prefix - the prefix to prepend to all option names 817 818 Notes: 819 A hyphen (-) must NOT be given at the beginning of the prefix name. 820 The first character of all runtime options is AUTOMATICALLY the hyphen. 821 822 Level: advanced 823 824 .seealso: `MatGetOptionsPrefix()` 825 @*/ 826 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[]) 827 { 828 PetscFunctionBegin; 829 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 830 PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)A,prefix)); 831 PetscFunctionReturn(0); 832 } 833 834 /*@C 835 MatGetOptionsPrefix - Gets the prefix used for searching for all 836 Mat options in the database. 837 838 Not Collective 839 840 Input Parameter: 841 . A - the Mat context 842 843 Output Parameter: 844 . prefix - pointer to the prefix string used 845 846 Notes: 847 On the fortran side, the user should pass in a string 'prefix' of 848 sufficient length to hold the prefix. 849 850 Level: advanced 851 852 .seealso: `MatAppendOptionsPrefix()` 853 @*/ 854 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[]) 855 { 856 PetscFunctionBegin; 857 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 858 PetscValidPointer(prefix,2); 859 PetscCall(PetscObjectGetOptionsPrefix((PetscObject)A,prefix)); 860 PetscFunctionReturn(0); 861 } 862 863 /*@ 864 MatResetPreallocation - Reset mat to use the original nonzero pattern provided by users. 865 866 Collective on Mat 867 868 Input Parameters: 869 . A - the Mat context 870 871 Notes: 872 The allocated memory will be shrunk after calling `MatAssemblyBegin()` and `MatAssemblyEnd()` with `MAT_FINAL_ASSEMBLY`. 873 874 Users can reset the preallocation to access the original memory. 875 876 Currently only supported for `MATMPIAIJ` and `MATSEQAIJ` matrices. 877 878 Level: beginner 879 880 .seealso: `MatSeqAIJSetPreallocation()`, `MatMPIAIJSetPreallocation()`, `MatXAIJSetPreallocation()` 881 @*/ 882 PetscErrorCode MatResetPreallocation(Mat A) 883 { 884 PetscFunctionBegin; 885 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 886 PetscValidType(A,1); 887 PetscUseMethod(A,"MatResetPreallocation_C",(Mat),(A)); 888 PetscFunctionReturn(0); 889 } 890 891 /*@ 892 MatSetUp - Sets up the internal matrix data structures for later use. 893 894 Collective on Mat 895 896 Input Parameters: 897 . A - the Mat context 898 899 Notes: 900 If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used. 901 902 If a suitable preallocation routine is used, this function does not need to be called. 903 904 See the Performance chapter of the PETSc users manual for how to preallocate matrices 905 906 Level: beginner 907 908 .seealso: `MatCreate()`, `MatDestroy()` 909 @*/ 910 PetscErrorCode MatSetUp(Mat A) 911 { 912 PetscFunctionBegin; 913 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 914 if (!((PetscObject)A)->type_name) { 915 PetscMPIInt size; 916 917 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)A), &size)); 918 PetscCall(MatSetType(A, size == 1 ? MATSEQAIJ : MATMPIAIJ)); 919 } 920 if (!A->preallocated && A->ops->setup) { 921 PetscCall(PetscInfo(A,"Warning not preallocating matrix storage\n")); 922 PetscCall((*A->ops->setup)(A)); 923 } 924 PetscCall(PetscLayoutSetUp(A->rmap)); 925 PetscCall(PetscLayoutSetUp(A->cmap)); 926 A->preallocated = PETSC_TRUE; 927 PetscFunctionReturn(0); 928 } 929 930 #if defined(PETSC_HAVE_SAWS) 931 #include <petscviewersaws.h> 932 #endif 933 934 /*@C 935 MatViewFromOptions - View from Options 936 937 Collective on Mat 938 939 Input Parameters: 940 + A - the Mat context 941 . obj - Optional object 942 - name - command line option 943 944 Level: intermediate 945 .seealso: `Mat`, `MatView`, `PetscObjectViewFromOptions()`, `MatCreate()` 946 @*/ 947 PetscErrorCode MatViewFromOptions(Mat A,PetscObject obj,const char name[]) 948 { 949 PetscFunctionBegin; 950 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 951 PetscCall(PetscObjectViewFromOptions((PetscObject)A,obj,name)); 952 PetscFunctionReturn(0); 953 } 954 955 /*@C 956 MatView - Visualizes a matrix object. 957 958 Collective on Mat 959 960 Input Parameters: 961 + mat - the matrix 962 - viewer - visualization context 963 964 Notes: 965 The available visualization contexts include 966 + `PETSC_VIEWER_STDOUT_SELF` - for sequential matrices 967 . `PETSC_VIEWER_STDOUT_WORLD` - for parallel matrices created on `PETSC_COMM_WORLD` 968 . `PETSC_VIEWER_STDOUT_`(comm) - for matrices created on MPI communicator comm 969 - `PETSC_VIEWER_DRAW_WORLD` - graphical display of nonzero structure 970 971 The user can open alternative visualization contexts with 972 + `PetscViewerASCIIOpen()` - Outputs matrix to a specified file 973 . `PetscViewerBinaryOpen()` - Outputs matrix in binary to a 974 specified file; corresponding input uses MatLoad() 975 . `PetscViewerDrawOpen()` - Outputs nonzero matrix structure to 976 an X window display 977 - `PetscViewerSocketOpen()` - Outputs matrix to Socket viewer. 978 Currently only the sequential dense and AIJ 979 matrix types support the Socket viewer. 980 981 The user can call `PetscViewerPushFormat()` to specify the output 982 format of ASCII printed objects (when using `PETSC_VIEWER_STDOUT_SELF`, 983 `PETSC_VIEWER_STDOUT_WORLD` and `PetscViewerASCIIOpen()`). Available formats include 984 + `PETSC_VIEWER_DEFAULT` - default, prints matrix contents 985 . `PETSC_VIEWER_ASCII_MATLAB` - prints matrix contents in Matlab format 986 . `PETSC_VIEWER_ASCII_DENSE` - prints entire matrix including zeros 987 . `PETSC_VIEWER_ASCII_COMMON` - prints matrix contents, using a sparse 988 format common among all matrix types 989 . `PETSC_VIEWER_ASCII_IMPL` - prints matrix contents, using an implementation-specific 990 format (which is in many cases the same as the default) 991 . `PETSC_VIEWER_ASCII_INFO` - prints basic information about the matrix 992 size and structure (not the matrix entries) 993 - `PETSC_VIEWER_ASCII_INFO_DETAIL` - prints more detailed information about 994 the matrix structure 995 996 Options Database Keys: 997 + -mat_view ::ascii_info - Prints info on matrix at conclusion of `MatAssemblyEnd()` 998 . -mat_view ::ascii_info_detail - Prints more detailed info 999 . -mat_view - Prints matrix in ASCII format 1000 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 1001 . -mat_view draw - PetscDraws nonzero structure of matrix, using `MatView()` and `PetscDrawOpenX()`. 1002 . -display <name> - Sets display name (default is host) 1003 . -draw_pause <sec> - Sets number of seconds to pause after display 1004 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details) 1005 . -viewer_socket_machine <machine> - 1006 . -viewer_socket_port <port> - 1007 . -mat_view binary - save matrix to file in binary format 1008 - -viewer_binary_filename <name> - 1009 1010 Level: beginner 1011 1012 Notes: 1013 The ASCII viewers are only recommended for small matrices on at most a moderate number of processes, 1014 the program will seemingly hang and take hours for larger matrices, for larger matrices one should use the binary format. 1015 1016 In the debugger you can do "call MatView(mat,0)" to display the matrix. (The same holds for any PETSc object viewer). 1017 1018 See the manual page for `MatLoad()` for the exact format of the binary file when the binary 1019 viewer is used. 1020 1021 See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary 1022 viewer is used and lib/petsc/bin/PetscBinaryIO.py for loading them into Python. 1023 1024 One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure, 1025 and then use the following mouse functions. 1026 .vb 1027 left mouse: zoom in 1028 middle mouse: zoom out 1029 right mouse: continue with the simulation 1030 .ve 1031 1032 .seealso: `PetscViewerPushFormat()`, `PetscViewerASCIIOpen()`, `PetscViewerDrawOpen()`, 1033 `PetscViewerSocketOpen()`, `PetscViewerBinaryOpen()`, `MatLoad()` 1034 @*/ 1035 PetscErrorCode MatView(Mat mat,PetscViewer viewer) 1036 { 1037 PetscInt rows,cols,rbs,cbs; 1038 PetscBool isascii,isstring,issaws; 1039 PetscViewerFormat format; 1040 PetscMPIInt size; 1041 1042 PetscFunctionBegin; 1043 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1044 PetscValidType(mat,1); 1045 if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer)); 1046 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1047 PetscCheckSameComm(mat,1,viewer,2); 1048 MatCheckPreallocated(mat,1); 1049 1050 PetscCall(PetscViewerGetFormat(viewer,&format)); 1051 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 1052 if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0); 1053 1054 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring)); 1055 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii)); 1056 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws)); 1057 if ((!isascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) { 1058 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detail"); 1059 } 1060 1061 PetscCall(PetscLogEventBegin(MAT_View,mat,viewer,0,0)); 1062 if (isascii) { 1063 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix"); 1064 PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer)); 1065 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1066 MatNullSpace nullsp,transnullsp; 1067 1068 PetscCall(PetscViewerASCIIPushTab(viewer)); 1069 PetscCall(MatGetSize(mat,&rows,&cols)); 1070 PetscCall(MatGetBlockSizes(mat,&rbs,&cbs)); 1071 if (rbs != 1 || cbs != 1) { 1072 if (rbs != cbs) PetscCall(PetscViewerASCIIPrintf(viewer,"rows=%" PetscInt_FMT ", cols=%" PetscInt_FMT ", rbs=%" PetscInt_FMT ", cbs=%" PetscInt_FMT "\n",rows,cols,rbs,cbs)); 1073 else PetscCall(PetscViewerASCIIPrintf(viewer,"rows=%" PetscInt_FMT ", cols=%" PetscInt_FMT ", bs=%" PetscInt_FMT "\n",rows,cols,rbs)); 1074 } else PetscCall(PetscViewerASCIIPrintf(viewer,"rows=%" PetscInt_FMT ", cols=%" PetscInt_FMT "\n",rows,cols)); 1075 if (mat->factortype) { 1076 MatSolverType solver; 1077 PetscCall(MatFactorGetSolverType(mat,&solver)); 1078 PetscCall(PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver)); 1079 } 1080 if (mat->ops->getinfo) { 1081 MatInfo info; 1082 PetscCall(MatGetInfo(mat,MAT_GLOBAL_SUM,&info)); 1083 PetscCall(PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated)); 1084 if (!mat->factortype) PetscCall(PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls=%" PetscInt_FMT "\n",(PetscInt)info.mallocs)); 1085 } 1086 PetscCall(MatGetNullSpace(mat,&nullsp)); 1087 PetscCall(MatGetTransposeNullSpace(mat,&transnullsp)); 1088 if (nullsp) PetscCall(PetscViewerASCIIPrintf(viewer," has attached null space\n")); 1089 if (transnullsp && transnullsp != nullsp) PetscCall(PetscViewerASCIIPrintf(viewer," has attached transposed null space\n")); 1090 PetscCall(MatGetNearNullSpace(mat,&nullsp)); 1091 if (nullsp) PetscCall(PetscViewerASCIIPrintf(viewer," has attached near null space\n")); 1092 PetscCall(PetscViewerASCIIPushTab(viewer)); 1093 PetscCall(MatProductView(mat,viewer)); 1094 PetscCall(PetscViewerASCIIPopTab(viewer)); 1095 } 1096 } else if (issaws) { 1097 #if defined(PETSC_HAVE_SAWS) 1098 PetscMPIInt rank; 1099 1100 PetscCall(PetscObjectName((PetscObject)mat)); 1101 PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD,&rank)); 1102 if (!((PetscObject)mat)->amsmem && rank == 0) { 1103 PetscCall(PetscObjectViewSAWs((PetscObject)mat,viewer)); 1104 } 1105 #endif 1106 } else if (isstring) { 1107 const char *type; 1108 PetscCall(MatGetType(mat,&type)); 1109 PetscCall(PetscViewerStringSPrintf(viewer," MatType: %-7.7s",type)); 1110 if (mat->ops->view) PetscCall((*mat->ops->view)(mat,viewer)); 1111 } 1112 if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) { 1113 PetscCall(PetscViewerASCIIPushTab(viewer)); 1114 PetscCall((*mat->ops->viewnative)(mat,viewer)); 1115 PetscCall(PetscViewerASCIIPopTab(viewer)); 1116 } else if (mat->ops->view) { 1117 PetscCall(PetscViewerASCIIPushTab(viewer)); 1118 PetscCall((*mat->ops->view)(mat,viewer)); 1119 PetscCall(PetscViewerASCIIPopTab(viewer)); 1120 } 1121 if (isascii) { 1122 PetscCall(PetscViewerGetFormat(viewer,&format)); 1123 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1124 PetscCall(PetscViewerASCIIPopTab(viewer)); 1125 } 1126 } 1127 PetscCall(PetscLogEventEnd(MAT_View,mat,viewer,0,0)); 1128 PetscFunctionReturn(0); 1129 } 1130 1131 #if defined(PETSC_USE_DEBUG) 1132 #include <../src/sys/totalview/tv_data_display.h> 1133 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat) 1134 { 1135 TV_add_row("Local rows", "int", &mat->rmap->n); 1136 TV_add_row("Local columns", "int", &mat->cmap->n); 1137 TV_add_row("Global rows", "int", &mat->rmap->N); 1138 TV_add_row("Global columns", "int", &mat->cmap->N); 1139 TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name); 1140 return TV_format_OK; 1141 } 1142 #endif 1143 1144 /*@C 1145 MatLoad - Loads a matrix that has been stored in binary/HDF5 format 1146 with `MatView()`. The matrix format is determined from the options database. 1147 Generates a parallel MPI matrix if the communicator has more than one 1148 processor. The default matrix type is AIJ. 1149 1150 Collective on PetscViewer 1151 1152 Input Parameters: 1153 + mat - the newly loaded matrix, this needs to have been created with `MatCreate()` 1154 or some related function before a call to `MatLoad()` 1155 - viewer - binary/HDF5 file viewer 1156 1157 Options Database Keys: 1158 Used with block matrix formats (`MATSEQBAIJ`, ...) to specify 1159 block size 1160 . -matload_block_size <bs> - set block size 1161 1162 Level: beginner 1163 1164 Notes: 1165 If the Mat type has not yet been given then `MATAIJ` is used, call `MatSetFromOptions()` on the 1166 Mat before calling this routine if you wish to set it from the options database. 1167 1168 `MatLoad()` automatically loads into the options database any options 1169 given in the file filename.info where filename is the name of the file 1170 that was passed to the `PetscViewerBinaryOpen()`. The options in the info 1171 file will be ignored if you use the -viewer_binary_skip_info option. 1172 1173 If the type or size of mat is not set before a call to `MatLoad()`, PETSc 1174 sets the default matrix type AIJ and sets the local and global sizes. 1175 If type and/or size is already set, then the same are used. 1176 1177 In parallel, each processor can load a subset of rows (or the 1178 entire matrix). This routine is especially useful when a large 1179 matrix is stored on disk and only part of it is desired on each 1180 processor. For example, a parallel solver may access only some of 1181 the rows from each processor. The algorithm used here reads 1182 relatively small blocks of data rather than reading the entire 1183 matrix and then subsetting it. 1184 1185 Viewer's `PetscViewerType` must be either `PETSCVIEWERBINARY` or `PETSCVIEWERHDF5`. 1186 Such viewer can be created using `PetscViewerBinaryOpen()` or `PetscViewerHDF5Open()`, 1187 or the sequence like 1188 .vb 1189 `PetscViewer` v; 1190 `PetscViewerCreate`(`PETSC_COMM_WORLD`,&v); 1191 `PetscViewerSetType`(v,`PETSCVIEWERBINARY`); 1192 `PetscViewerSetFromOptions`(v); 1193 `PetscViewerFileSetMode`(v,`FILE_MODE_READ`); 1194 `PetscViewerFileSetName`(v,"datafile"); 1195 .ve 1196 The optional `PetscViewerSetFromOptions()` call allows overriding `PetscViewerSetType()` using the option 1197 $ -viewer_type {binary,hdf5} 1198 1199 See the example src/ksp/ksp/tutorials/ex27.c with the first approach, 1200 and src/mat/tutorials/ex10.c with the second approach. 1201 1202 Notes about the PETSc binary format: 1203 In case of `PETSCVIEWERBINARY`, a native PETSc binary format is used. Each of the blocks 1204 is read onto rank 0 and then shipped to its destination rank, one after another. 1205 Multiple objects, both matrices and vectors, can be stored within the same file. 1206 Their PetscObject name is ignored; they are loaded in the order of their storage. 1207 1208 Most users should not need to know the details of the binary storage 1209 format, since `MatLoad()` and `MatView()` completely hide these details. 1210 But for anyone who's interested, the standard binary matrix storage 1211 format is 1212 1213 $ PetscInt MAT_FILE_CLASSID 1214 $ PetscInt number of rows 1215 $ PetscInt number of columns 1216 $ PetscInt total number of nonzeros 1217 $ PetscInt *number nonzeros in each row 1218 $ PetscInt *column indices of all nonzeros (starting index is zero) 1219 $ PetscScalar *values of all nonzeros 1220 1221 PETSc automatically does the byte swapping for 1222 machines that store the bytes reversed, e.g. DEC alpha, freebsd, 1223 Linux, Microsoft Windows and the Intel Paragon; thus if you write your own binary 1224 read/write routines you have to swap the bytes; see `PetscBinaryRead()` 1225 and `PetscBinaryWrite()` to see how this may be done. 1226 1227 Notes about the HDF5 (MATLAB MAT-File Version 7.3) format: 1228 In case of `PETSCVIEWERHDF5`, a parallel HDF5 reader is used. 1229 Each processor's chunk is loaded independently by its owning rank. 1230 Multiple objects, both matrices and vectors, can be stored within the same file. 1231 They are looked up by their PetscObject name. 1232 1233 As the MATLAB MAT-File Version 7.3 format is also a HDF5 flavor, we decided to use 1234 by default the same structure and naming of the AIJ arrays and column count 1235 within the HDF5 file. This means that a MAT file saved with -v7.3 flag, e.g. 1236 $ save example.mat A b -v7.3 1237 can be directly read by this routine (see Reference 1 for details). 1238 Note that depending on your MATLAB version, this format might be a default, 1239 otherwise you can set it as default in Preferences. 1240 1241 Unless -nocompression flag is used to save the file in MATLAB, 1242 PETSc must be configured with ZLIB package. 1243 1244 See also examples src/mat/tutorials/ex10.c and src/ksp/ksp/tutorials/ex27.c 1245 1246 Current HDF5 (MAT-File) limitations: 1247 This reader currently supports only real `MATSEQAIJ`, `MATMPIAIJ`, `MATSEQDENSE` and `MATMPIDENSE` matrices. 1248 1249 Corresponding `MatView()` is not yet implemented. 1250 1251 The loaded matrix is actually a transpose of the original one in MATLAB, 1252 unless you push `PETSC_VIEWER_HDF5_MAT` format (see examples above). 1253 With this format, matrix is automatically transposed by PETSc, 1254 unless the matrix is marked as SPD or symmetric 1255 (see `MatSetOption()`, `MAT_SPD`, `MAT_SYMMETRIC`). 1256 1257 References: 1258 . * - MATLAB(R) Documentation, manual page of save(), https://www.mathworks.com/help/matlab/ref/save.html#btox10b-1-version 1259 1260 .seealso: `PetscViewerBinaryOpen()`, `PetscViewerSetType()`, `MatView()`, `VecLoad()` 1261 1262 @*/ 1263 PetscErrorCode MatLoad(Mat mat,PetscViewer viewer) 1264 { 1265 PetscBool flg; 1266 1267 PetscFunctionBegin; 1268 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1269 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1270 1271 if (!((PetscObject)mat)->type_name) PetscCall(MatSetType(mat,MATAIJ)); 1272 1273 flg = PETSC_FALSE; 1274 PetscCall(PetscOptionsGetBool(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matload_symmetric",&flg,NULL)); 1275 if (flg) { 1276 PetscCall(MatSetOption(mat,MAT_SYMMETRIC,PETSC_TRUE)); 1277 PetscCall(MatSetOption(mat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE)); 1278 } 1279 flg = PETSC_FALSE; 1280 PetscCall(PetscOptionsGetBool(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matload_spd",&flg,NULL)); 1281 if (flg) PetscCall(MatSetOption(mat,MAT_SPD,PETSC_TRUE)); 1282 1283 PetscCheck(mat->ops->load,PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type %s",((PetscObject)mat)->type_name); 1284 PetscCall(PetscLogEventBegin(MAT_Load,mat,viewer,0,0)); 1285 PetscCall((*mat->ops->load)(mat,viewer)); 1286 PetscCall(PetscLogEventEnd(MAT_Load,mat,viewer,0,0)); 1287 PetscFunctionReturn(0); 1288 } 1289 1290 static PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant) 1291 { 1292 Mat_Redundant *redund = *redundant; 1293 1294 PetscFunctionBegin; 1295 if (redund) { 1296 if (redund->matseq) { /* via MatCreateSubMatrices() */ 1297 PetscCall(ISDestroy(&redund->isrow)); 1298 PetscCall(ISDestroy(&redund->iscol)); 1299 PetscCall(MatDestroySubMatrices(1,&redund->matseq)); 1300 } else { 1301 PetscCall(PetscFree2(redund->send_rank,redund->recv_rank)); 1302 PetscCall(PetscFree(redund->sbuf_j)); 1303 PetscCall(PetscFree(redund->sbuf_a)); 1304 for (PetscInt i=0; i<redund->nrecvs; i++) { 1305 PetscCall(PetscFree(redund->rbuf_j[i])); 1306 PetscCall(PetscFree(redund->rbuf_a[i])); 1307 } 1308 PetscCall(PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a)); 1309 } 1310 1311 if (redund->subcomm) PetscCall(PetscCommDestroy(&redund->subcomm)); 1312 PetscCall(PetscFree(redund)); 1313 } 1314 PetscFunctionReturn(0); 1315 } 1316 1317 /*@C 1318 MatDestroy - Frees space taken by a matrix. 1319 1320 Collective on Mat 1321 1322 Input Parameter: 1323 . A - the matrix 1324 1325 Level: beginner 1326 1327 Developer Notes: 1328 Some special arrays of matrices are not destroyed in this routine but instead by the routines called by 1329 `MatDestroySubMatrices()`. Thus one must be sure that any changes here must also be made in those routines. 1330 MatHeaderMerge() and MatHeaderReplace() also manipulate the data in the `Mat` object and likely need changes 1331 if changes are needed here. 1332 @*/ 1333 PetscErrorCode MatDestroy(Mat *A) 1334 { 1335 PetscFunctionBegin; 1336 if (!*A) PetscFunctionReturn(0); 1337 PetscValidHeaderSpecific(*A,MAT_CLASSID,1); 1338 if (--((PetscObject)(*A))->refct > 0) {*A = NULL; PetscFunctionReturn(0);} 1339 1340 /* if memory was published with SAWs then destroy it */ 1341 PetscCall(PetscObjectSAWsViewOff((PetscObject)*A)); 1342 if ((*A)->ops->destroy) PetscCall((*(*A)->ops->destroy)(*A)); 1343 1344 PetscCall(PetscFree((*A)->factorprefix)); 1345 PetscCall(PetscFree((*A)->defaultvectype)); 1346 PetscCall(PetscFree((*A)->bsizes)); 1347 PetscCall(PetscFree((*A)->solvertype)); 1348 for (PetscInt i=0; i<MAT_FACTOR_NUM_TYPES; i++) PetscCall(PetscFree((*A)->preferredordering[i])); 1349 if ((*A)->redundant && (*A)->redundant->matseq[0] == *A) (*A)->redundant->matseq[0] = NULL; 1350 PetscCall(MatDestroy_Redundant(&(*A)->redundant)); 1351 PetscCall(MatProductClear(*A)); 1352 PetscCall(MatNullSpaceDestroy(&(*A)->nullsp)); 1353 PetscCall(MatNullSpaceDestroy(&(*A)->transnullsp)); 1354 PetscCall(MatNullSpaceDestroy(&(*A)->nearnullsp)); 1355 PetscCall(MatDestroy(&(*A)->schur)); 1356 PetscCall(PetscLayoutDestroy(&(*A)->rmap)); 1357 PetscCall(PetscLayoutDestroy(&(*A)->cmap)); 1358 PetscCall(PetscHeaderDestroy(A)); 1359 PetscFunctionReturn(0); 1360 } 1361 1362 /*@C 1363 MatSetValues - Inserts or adds a block of values into a matrix. 1364 These values may be cached, so `MatAssemblyBegin()` and `MatAssemblyEnd()` 1365 MUST be called after all calls to `MatSetValues()` have been completed. 1366 1367 Not Collective 1368 1369 Input Parameters: 1370 + mat - the matrix 1371 . v - a logically two-dimensional array of values 1372 . m, idxm - the number of rows and their global indices 1373 . n, idxn - the number of columns and their global indices 1374 - addv - either `ADD_VALUES` or `INSERT_VALUES`, where 1375 `ADD_VALUES` adds values to any existing entries, and 1376 `INSERT_VALUES` replaces existing entries with new values 1377 1378 Notes: 1379 If you create the matrix yourself (that is not with a call to `DMCreateMatrix()`) then you MUST call MatXXXXSetPreallocation() or 1380 `MatSetUp()` before using this routine 1381 1382 By default the values, v, are row-oriented. See `MatSetOption()` for other options. 1383 1384 Calls to `MatSetValues()` with the `INSERT_VALUES` and `ADD_VALUES` 1385 options cannot be mixed without intervening calls to the assembly 1386 routines. 1387 1388 `MatSetValues()` uses 0-based row and column numbers in Fortran 1389 as well as in C. 1390 1391 Negative indices may be passed in idxm and idxn, these rows and columns are 1392 simply ignored. This allows easily inserting element stiffness matrices 1393 with homogeneous Dirchlet boundary conditions that you don't want represented 1394 in the matrix. 1395 1396 Efficiency Alert: 1397 The routine `MatSetValuesBlocked()` may offer much better efficiency 1398 for users of block sparse formats (`MATSEQBAIJ` and `MATMPIBAIJ`). 1399 1400 Level: beginner 1401 1402 Developer Notes: 1403 This is labeled with C so does not automatically generate Fortran stubs and interfaces 1404 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 1405 1406 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 1407 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES` 1408 @*/ 1409 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1410 { 1411 PetscFunctionBeginHot; 1412 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1413 PetscValidType(mat,1); 1414 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1415 PetscValidIntPointer(idxm,3); 1416 PetscValidIntPointer(idxn,5); 1417 MatCheckPreallocated(mat,1); 1418 1419 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 1420 else PetscCheck(mat->insertmode == addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1421 1422 if (PetscDefined(USE_DEBUG)) { 1423 PetscInt i,j; 1424 1425 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1426 PetscCheck(mat->ops->setvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1427 1428 for (i=0; i<m; i++) { 1429 for (j=0; j<n; j++) { 1430 if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j])) 1431 #if defined(PETSC_USE_COMPLEX) 1432 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]); 1433 #else 1434 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]); 1435 #endif 1436 } 1437 } 1438 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); 1439 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); 1440 } 1441 1442 if (mat->assembled) { 1443 mat->was_assembled = PETSC_TRUE; 1444 mat->assembled = PETSC_FALSE; 1445 } 1446 PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 1447 PetscCall((*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv)); 1448 PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 1449 PetscFunctionReturn(0); 1450 } 1451 1452 /*@C 1453 MatSetValuesIS - Inserts or adds a block of values into a matrix using IS to indicate the rows and columns 1454 These values may be cached, so `MatAssemblyBegin()` and `MatAssemblyEnd()` 1455 MUST be called after all calls to `MatSetValues()` have been completed. 1456 1457 Not Collective 1458 1459 Input Parameters: 1460 + mat - the matrix 1461 . v - a logically two-dimensional array of values 1462 . ism - the rows to provide 1463 . isn - the columns to provide 1464 - addv - either `ADD_VALUES` or `INSERT_VALUES`, where 1465 `ADD_VALUES` adds values to any existing entries, and 1466 `INSERT_VALUES` replaces existing entries with new values 1467 1468 Notes: 1469 If you create the matrix yourself (that is not with a call to `DMCreateMatrix()`) then you MUST call MatXXXXSetPreallocation() or 1470 `MatSetUp()` before using this routine 1471 1472 By default the values, v, are row-oriented. See `MatSetOption()` for other options. 1473 1474 Calls to `MatSetValues()` with the `INSERT_VALUES` and `ADD_VALUES` 1475 options cannot be mixed without intervening calls to the assembly 1476 routines. 1477 1478 MatSetValues() uses 0-based row and column numbers in Fortran 1479 as well as in C. 1480 1481 Negative indices may be passed in ism and isn, these rows and columns are 1482 simply ignored. This allows easily inserting element stiffness matrices 1483 with homogeneous Dirchlet boundary conditions that you don't want represented 1484 in the matrix. 1485 1486 Efficiency Alert: 1487 The routine `MatSetValuesBlocked()` may offer much better efficiency 1488 for users of block sparse formats (`MATSEQBAIJ` and `MATMPIBAIJ`). 1489 1490 Level: beginner 1491 1492 Developer Notes: 1493 This is labeled with C so does not automatically generate Fortran stubs and interfaces 1494 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 1495 1496 This is currently not optimized for any particular IS type 1497 1498 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 1499 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()` 1500 @*/ 1501 PetscErrorCode MatSetValuesIS(Mat mat,IS ism,IS isn,const PetscScalar v[],InsertMode addv) 1502 { 1503 PetscInt m,n; 1504 const PetscInt *rows,*cols; 1505 1506 PetscFunctionBeginHot; 1507 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1508 PetscCall(ISGetIndices(ism,&rows)); 1509 PetscCall(ISGetIndices(isn,&cols)); 1510 PetscCall(ISGetLocalSize(ism,&m)); 1511 PetscCall(ISGetLocalSize(isn,&n)); 1512 PetscCall(MatSetValues(mat,m,rows,n,cols,v,addv)); 1513 PetscCall(ISRestoreIndices(ism,&rows)); 1514 PetscCall(ISRestoreIndices(isn,&cols)); 1515 PetscFunctionReturn(0); 1516 } 1517 1518 /*@ 1519 MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero 1520 values into a matrix 1521 1522 Not Collective 1523 1524 Input Parameters: 1525 + mat - the matrix 1526 . row - the (block) row to set 1527 - v - a logically two-dimensional array of values 1528 1529 Notes: 1530 By the values, v, are column-oriented (for the block version) and sorted 1531 1532 All the nonzeros in the row must be provided 1533 1534 The matrix must have previously had its column indices set 1535 1536 The row must belong to this process 1537 1538 Level: intermediate 1539 1540 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 1541 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()`, `MatSetValuesRow()`, `MatSetLocalToGlobalMapping()` 1542 @*/ 1543 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[]) 1544 { 1545 PetscInt globalrow; 1546 1547 PetscFunctionBegin; 1548 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1549 PetscValidType(mat,1); 1550 PetscValidScalarPointer(v,3); 1551 PetscCall(ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow)); 1552 PetscCall(MatSetValuesRow(mat,globalrow,v)); 1553 PetscFunctionReturn(0); 1554 } 1555 1556 /*@ 1557 MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero 1558 values into a matrix 1559 1560 Not Collective 1561 1562 Input Parameters: 1563 + mat - the matrix 1564 . row - the (block) row to set 1565 - 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 1566 1567 Notes: 1568 The values, v, are column-oriented for the block version. 1569 1570 All the nonzeros in the row must be provided 1571 1572 THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually `MatSetValues()` is used. 1573 1574 The row must belong to this process 1575 1576 Level: advanced 1577 1578 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 1579 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()` 1580 @*/ 1581 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[]) 1582 { 1583 PetscFunctionBeginHot; 1584 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1585 PetscValidType(mat,1); 1586 MatCheckPreallocated(mat,1); 1587 PetscValidScalarPointer(v,3); 1588 PetscCheck(mat->insertmode != ADD_VALUES,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values"); 1589 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1590 mat->insertmode = INSERT_VALUES; 1591 1592 if (mat->assembled) { 1593 mat->was_assembled = PETSC_TRUE; 1594 mat->assembled = PETSC_FALSE; 1595 } 1596 PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 1597 PetscCheck(mat->ops->setvaluesrow,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1598 PetscCall((*mat->ops->setvaluesrow)(mat,row,v)); 1599 PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 1600 PetscFunctionReturn(0); 1601 } 1602 1603 /*@ 1604 MatSetValuesStencil - Inserts or adds a block of values into a matrix. 1605 Using structured grid indexing 1606 1607 Not Collective 1608 1609 Input Parameters: 1610 + mat - the matrix 1611 . m - number of rows being entered 1612 . idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered 1613 . n - number of columns being entered 1614 . idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered 1615 . v - a logically two-dimensional array of values 1616 - addv - either ADD_VALUES or INSERT_VALUES, where 1617 ADD_VALUES adds values to any existing entries, and 1618 INSERT_VALUES replaces existing entries with new values 1619 1620 Notes: 1621 By default the values, v, are row-oriented. See `MatSetOption()` for other options. 1622 1623 Calls to `MatSetValuesStencil()` with the `INSERT_VALUES` and `ADD_VALUES` 1624 options cannot be mixed without intervening calls to the assembly 1625 routines. 1626 1627 The grid coordinates are across the entire grid, not just the local portion 1628 1629 `MatSetValuesStencil()` uses 0-based row and column numbers in Fortran 1630 as well as in C. 1631 1632 For setting/accessing vector values via array coordinates you can use the `DMDAVecGetArray()` routine 1633 1634 In order to use this routine you must either obtain the matrix with `DMCreateMatrix()` 1635 or call `MatSetLocalToGlobalMapping()` and `MatSetStencil()` first. 1636 1637 The columns and rows in the stencil passed in MUST be contained within the 1638 ghost region of the given process as set with DMDACreateXXX() or `MatSetStencil()`. For example, 1639 if you create a `DMDA` with an overlap of one grid level and on a particular process its first 1640 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1641 first i index you can use in your column and row indices in `MatSetStencil()` is 5. 1642 1643 In Fortran idxm and idxn should be declared as 1644 $ MatStencil idxm(4,m),idxn(4,n) 1645 and the values inserted using 1646 $ idxm(MatStencil_i,1) = i 1647 $ idxm(MatStencil_j,1) = j 1648 $ idxm(MatStencil_k,1) = k 1649 $ idxm(MatStencil_c,1) = c 1650 etc 1651 1652 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 1653 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 1654 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 1655 `DM_BOUNDARY_PERIODIC` boundary type. 1656 1657 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 1658 a single value per point) you can skip filling those indices. 1659 1660 Inspired by the structured grid interface to the HYPRE package 1661 (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods) 1662 1663 Efficiency Alert: 1664 The routine `MatSetValuesBlockedStencil()` may offer much better efficiency 1665 for users of block sparse formats (`MATSEQBAIJ` and `MATMPIBAIJ`). 1666 1667 Level: beginner 1668 1669 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()` 1670 `MatSetValues()`, `MatSetValuesBlockedStencil()`, `MatSetStencil()`, `DMCreateMatrix()`, `DMDAVecGetArray()`, `MatStencil` 1671 @*/ 1672 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1673 { 1674 PetscInt buf[8192],*bufm=NULL,*bufn=NULL,*jdxm,*jdxn; 1675 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1676 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1677 1678 PetscFunctionBegin; 1679 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1680 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1681 PetscValidType(mat,1); 1682 PetscValidPointer(idxm,3); 1683 PetscValidPointer(idxn,5); 1684 1685 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1686 jdxm = buf; jdxn = buf+m; 1687 } else { 1688 PetscCall(PetscMalloc2(m,&bufm,n,&bufn)); 1689 jdxm = bufm; jdxn = bufn; 1690 } 1691 for (i=0; i<m; i++) { 1692 for (j=0; j<3-sdim; j++) dxm++; 1693 tmp = *dxm++ - starts[0]; 1694 for (j=0; j<dim-1; j++) { 1695 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1696 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1697 } 1698 if (mat->stencil.noc) dxm++; 1699 jdxm[i] = tmp; 1700 } 1701 for (i=0; i<n; i++) { 1702 for (j=0; j<3-sdim; j++) dxn++; 1703 tmp = *dxn++ - starts[0]; 1704 for (j=0; j<dim-1; j++) { 1705 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1706 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1707 } 1708 if (mat->stencil.noc) dxn++; 1709 jdxn[i] = tmp; 1710 } 1711 PetscCall(MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv)); 1712 PetscCall(PetscFree2(bufm,bufn)); 1713 PetscFunctionReturn(0); 1714 } 1715 1716 /*@ 1717 MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix. 1718 Using structured grid indexing 1719 1720 Not Collective 1721 1722 Input Parameters: 1723 + mat - the matrix 1724 . m - number of rows being entered 1725 . idxm - grid coordinates for matrix rows being entered 1726 . n - number of columns being entered 1727 . idxn - grid coordinates for matrix columns being entered 1728 . v - a logically two-dimensional array of values 1729 - addv - either ADD_VALUES or INSERT_VALUES, where 1730 ADD_VALUES adds values to any existing entries, and 1731 INSERT_VALUES replaces existing entries with new values 1732 1733 Notes: 1734 By default the values, v, are row-oriented and unsorted. 1735 See MatSetOption() for other options. 1736 1737 Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES 1738 options cannot be mixed without intervening calls to the assembly 1739 routines. 1740 1741 The grid coordinates are across the entire grid, not just the local portion 1742 1743 MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran 1744 as well as in C. 1745 1746 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine 1747 1748 In order to use this routine you must either obtain the matrix with DMCreateMatrix() 1749 or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first. 1750 1751 The columns and rows in the stencil passed in MUST be contained within the 1752 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example, 1753 if you create a DMDA with an overlap of one grid level and on a particular process its first 1754 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1755 first i index you can use in your column and row indices in MatSetStencil() is 5. 1756 1757 In Fortran idxm and idxn should be declared as 1758 $ MatStencil idxm(4,m),idxn(4,n) 1759 and the values inserted using 1760 $ idxm(MatStencil_i,1) = i 1761 $ idxm(MatStencil_j,1) = j 1762 $ idxm(MatStencil_k,1) = k 1763 etc 1764 1765 Negative indices may be passed in idxm and idxn, these rows and columns are 1766 simply ignored. This allows easily inserting element stiffness matrices 1767 with homogeneous Dirchlet boundary conditions that you don't want represented 1768 in the matrix. 1769 1770 Inspired by the structured grid interface to the HYPRE package 1771 (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods) 1772 1773 Level: beginner 1774 1775 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()` 1776 `MatSetValues()`, `MatSetValuesStencil()`, `MatSetStencil()`, `DMCreateMatrix()`, `DMDAVecGetArray()`, `MatStencil`, 1777 `MatSetBlockSize()`, `MatSetLocalToGlobalMapping()` 1778 @*/ 1779 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1780 { 1781 PetscInt buf[8192],*bufm=NULL,*bufn=NULL,*jdxm,*jdxn; 1782 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1783 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1784 1785 PetscFunctionBegin; 1786 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1787 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1788 PetscValidType(mat,1); 1789 PetscValidPointer(idxm,3); 1790 PetscValidPointer(idxn,5); 1791 PetscValidScalarPointer(v,6); 1792 1793 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1794 jdxm = buf; jdxn = buf+m; 1795 } else { 1796 PetscCall(PetscMalloc2(m,&bufm,n,&bufn)); 1797 jdxm = bufm; jdxn = bufn; 1798 } 1799 for (i=0; i<m; i++) { 1800 for (j=0; j<3-sdim; j++) dxm++; 1801 tmp = *dxm++ - starts[0]; 1802 for (j=0; j<sdim-1; j++) { 1803 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1804 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1805 } 1806 dxm++; 1807 jdxm[i] = tmp; 1808 } 1809 for (i=0; i<n; i++) { 1810 for (j=0; j<3-sdim; j++) dxn++; 1811 tmp = *dxn++ - starts[0]; 1812 for (j=0; j<sdim-1; j++) { 1813 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1814 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1815 } 1816 dxn++; 1817 jdxn[i] = tmp; 1818 } 1819 PetscCall(MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv)); 1820 PetscCall(PetscFree2(bufm,bufn)); 1821 PetscFunctionReturn(0); 1822 } 1823 1824 /*@ 1825 MatSetStencil - Sets the grid information for setting values into a matrix via 1826 MatSetValuesStencil() 1827 1828 Not Collective 1829 1830 Input Parameters: 1831 + mat - the matrix 1832 . dim - dimension of the grid 1, 2, or 3 1833 . dims - number of grid points in x, y, and z direction, including ghost points on your processor 1834 . starts - starting point of ghost nodes on your processor in x, y, and z direction 1835 - dof - number of degrees of freedom per node 1836 1837 Inspired by the structured grid interface to the HYPRE package 1838 (www.llnl.gov/CASC/hyper) 1839 1840 For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the 1841 user. 1842 1843 Level: beginner 1844 1845 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()` 1846 `MatSetValues()`, `MatSetValuesBlockedStencil()`, `MatSetValuesStencil()` 1847 @*/ 1848 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof) 1849 { 1850 PetscFunctionBegin; 1851 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1852 PetscValidIntPointer(dims,3); 1853 PetscValidIntPointer(starts,4); 1854 1855 mat->stencil.dim = dim + (dof > 1); 1856 for (PetscInt i=0; i<dim; i++) { 1857 mat->stencil.dims[i] = dims[dim-i-1]; /* copy the values in backwards */ 1858 mat->stencil.starts[i] = starts[dim-i-1]; 1859 } 1860 mat->stencil.dims[dim] = dof; 1861 mat->stencil.starts[dim] = 0; 1862 mat->stencil.noc = (PetscBool)(dof == 1); 1863 PetscFunctionReturn(0); 1864 } 1865 1866 /*@C 1867 MatSetValuesBlocked - Inserts or adds a block of values into a matrix. 1868 1869 Not Collective 1870 1871 Input Parameters: 1872 + mat - the matrix 1873 . v - a logically two-dimensional array of values 1874 . m, idxm - the number of block rows and their global block indices 1875 . n, idxn - the number of block columns and their global block indices 1876 - addv - either ADD_VALUES or INSERT_VALUES, where 1877 ADD_VALUES adds values to any existing entries, and 1878 INSERT_VALUES replaces existing entries with new values 1879 1880 Notes: 1881 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call 1882 MatXXXXSetPreallocation() or MatSetUp() before using this routine. 1883 1884 The m and n count the NUMBER of blocks in the row direction and column direction, 1885 NOT the total number of rows/columns; for example, if the block size is 2 and 1886 you are passing in values for rows 2,3,4,5 then m would be 2 (not 4). 1887 The values in idxm would be 1 2; that is the first index for each block divided by 1888 the block size. 1889 1890 Note that you must call MatSetBlockSize() when constructing this matrix (before 1891 preallocating it). 1892 1893 By default the values, v, are row-oriented, so the layout of 1894 v is the same as for MatSetValues(). See MatSetOption() for other options. 1895 1896 Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES 1897 options cannot be mixed without intervening calls to the assembly 1898 routines. 1899 1900 MatSetValuesBlocked() uses 0-based row and column numbers in Fortran 1901 as well as in C. 1902 1903 Negative indices may be passed in idxm and idxn, these rows and columns are 1904 simply ignored. This allows easily inserting element stiffness matrices 1905 with homogeneous Dirchlet boundary conditions that you don't want represented 1906 in the matrix. 1907 1908 Each time an entry is set within a sparse matrix via MatSetValues(), 1909 internal searching must be done to determine where to place the 1910 data in the matrix storage space. By instead inserting blocks of 1911 entries via MatSetValuesBlocked(), the overhead of matrix assembly is 1912 reduced. 1913 1914 Example: 1915 $ Suppose m=n=2 and block size(bs) = 2 The array is 1916 $ 1917 $ 1 2 | 3 4 1918 $ 5 6 | 7 8 1919 $ - - - | - - - 1920 $ 9 10 | 11 12 1921 $ 13 14 | 15 16 1922 $ 1923 $ v[] should be passed in like 1924 $ v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] 1925 $ 1926 $ If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then 1927 $ v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16] 1928 1929 Level: intermediate 1930 1931 .seealso: `MatSetBlockSize()`, `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetValuesBlockedLocal()` 1932 @*/ 1933 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1934 { 1935 PetscFunctionBeginHot; 1936 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1937 PetscValidType(mat,1); 1938 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1939 PetscValidIntPointer(idxm,3); 1940 PetscValidIntPointer(idxn,5); 1941 MatCheckPreallocated(mat,1); 1942 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 1943 else PetscCheck(mat->insertmode == addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1944 if (PetscDefined(USE_DEBUG)) { 1945 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1946 PetscCheck(mat->ops->setvaluesblocked || mat->ops->setvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1947 } 1948 if (PetscDefined(USE_DEBUG)) { 1949 PetscInt rbs,cbs,M,N,i; 1950 PetscCall(MatGetBlockSizes(mat,&rbs,&cbs)); 1951 PetscCall(MatGetSize(mat,&M,&N)); 1952 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); 1953 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); 1954 } 1955 if (mat->assembled) { 1956 mat->was_assembled = PETSC_TRUE; 1957 mat->assembled = PETSC_FALSE; 1958 } 1959 PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 1960 if (mat->ops->setvaluesblocked) { 1961 PetscCall((*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv)); 1962 } else { 1963 PetscInt buf[8192],*bufr=NULL,*bufc=NULL,*iidxm,*iidxn; 1964 PetscInt i,j,bs,cbs; 1965 1966 PetscCall(MatGetBlockSizes(mat,&bs,&cbs)); 1967 if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1968 iidxm = buf; 1969 iidxn = buf + m*bs; 1970 } else { 1971 PetscCall(PetscMalloc2(m*bs,&bufr,n*cbs,&bufc)); 1972 iidxm = bufr; 1973 iidxn = bufc; 1974 } 1975 for (i=0; i<m; i++) { 1976 for (j=0; j<bs; j++) { 1977 iidxm[i*bs+j] = bs*idxm[i] + j; 1978 } 1979 } 1980 if (m != n || bs != cbs || idxm != idxn) { 1981 for (i=0; i<n; i++) { 1982 for (j=0; j<cbs; j++) { 1983 iidxn[i*cbs+j] = cbs*idxn[i] + j; 1984 } 1985 } 1986 } else iidxn = iidxm; 1987 PetscCall(MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv)); 1988 PetscCall(PetscFree2(bufr,bufc)); 1989 } 1990 PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 1991 PetscFunctionReturn(0); 1992 } 1993 1994 /*@C 1995 MatGetValues - Gets a block of values from a matrix. 1996 1997 Not Collective; can only return values that are owned by the give process 1998 1999 Input Parameters: 2000 + mat - the matrix 2001 . v - a logically two-dimensional array for storing the values 2002 . m, idxm - the number of rows and their global indices 2003 - n, idxn - the number of columns and their global indices 2004 2005 Notes: 2006 The user must allocate space (m*n PetscScalars) for the values, v. 2007 The values, v, are then returned in a row-oriented format, 2008 analogous to that used by default in MatSetValues(). 2009 2010 MatGetValues() uses 0-based row and column numbers in 2011 Fortran as well as in C. 2012 2013 MatGetValues() requires that the matrix has been assembled 2014 with MatAssemblyBegin()/MatAssemblyEnd(). Thus, calls to 2015 MatSetValues() and MatGetValues() CANNOT be made in succession 2016 without intermediate matrix assembly. 2017 2018 Negative row or column indices will be ignored and those locations in v[] will be 2019 left unchanged. 2020 2021 For the standard row-based matrix formats, idxm[] can only contain rows owned by the requesting MPI rank. 2022 That is, rows with global index greater than or equal to rstart and less than rend where rstart and rend are obtainable 2023 from MatGetOwnershipRange(mat,&rstart,&rend). 2024 2025 Level: advanced 2026 2027 .seealso: `MatGetRow()`, `MatCreateSubMatrices()`, `MatSetValues()`, `MatGetOwnershipRange()`, `MatGetValuesLocal()`, `MatGetValue()` 2028 @*/ 2029 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[]) 2030 { 2031 PetscFunctionBegin; 2032 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2033 PetscValidType(mat,1); 2034 if (!m || !n) PetscFunctionReturn(0); 2035 PetscValidIntPointer(idxm,3); 2036 PetscValidIntPointer(idxn,5); 2037 PetscValidScalarPointer(v,6); 2038 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2039 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2040 PetscCheck(mat->ops->getvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2041 MatCheckPreallocated(mat,1); 2042 2043 PetscCall(PetscLogEventBegin(MAT_GetValues,mat,0,0,0)); 2044 PetscCall((*mat->ops->getvalues)(mat,m,idxm,n,idxn,v)); 2045 PetscCall(PetscLogEventEnd(MAT_GetValues,mat,0,0,0)); 2046 PetscFunctionReturn(0); 2047 } 2048 2049 /*@C 2050 MatGetValuesLocal - retrieves values from certain locations in a matrix using the local numbering of the indices 2051 defined previously by MatSetLocalToGlobalMapping() 2052 2053 Not Collective 2054 2055 Input Parameters: 2056 + mat - the matrix 2057 . nrow, irow - number of rows and their local indices 2058 - ncol, icol - number of columns and their local indices 2059 2060 Output Parameter: 2061 . y - a logically two-dimensional array of values 2062 2063 Notes: 2064 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine. 2065 2066 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, 2067 are greater than or equal to rstart and less than rend where rstart and rend are obtainable from MatGetOwnershipRange(mat,&rstart,&rend). One can 2068 determine if the resulting global row associated with the local row r is owned by the requesting MPI rank by applying the ISLocalToGlobalMapping set 2069 with MatSetLocalToGlobalMapping(). 2070 2071 Developer Notes: 2072 This is labelled with C so does not automatically generate Fortran stubs and interfaces 2073 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2074 2075 Level: advanced 2076 2077 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetLocalToGlobalMapping()`, 2078 `MatSetValuesLocal()`, `MatGetValues()` 2079 @*/ 2080 PetscErrorCode MatGetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],PetscScalar y[]) 2081 { 2082 PetscFunctionBeginHot; 2083 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2084 PetscValidType(mat,1); 2085 MatCheckPreallocated(mat,1); 2086 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to retrieve */ 2087 PetscValidIntPointer(irow,3); 2088 PetscValidIntPointer(icol,5); 2089 if (PetscDefined(USE_DEBUG)) { 2090 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2091 PetscCheck(mat->ops->getvalueslocal || mat->ops->getvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2092 } 2093 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2094 PetscCall(PetscLogEventBegin(MAT_GetValues,mat,0,0,0)); 2095 if (mat->ops->getvalueslocal) { 2096 PetscCall((*mat->ops->getvalueslocal)(mat,nrow,irow,ncol,icol,y)); 2097 } else { 2098 PetscInt buf[8192],*bufr=NULL,*bufc=NULL,*irowm,*icolm; 2099 if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2100 irowm = buf; icolm = buf+nrow; 2101 } else { 2102 PetscCall(PetscMalloc2(nrow,&bufr,ncol,&bufc)); 2103 irowm = bufr; icolm = bufc; 2104 } 2105 PetscCheck(mat->rmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MatGetValuesLocal() cannot proceed without local-to-global row mapping (See MatSetLocalToGlobalMapping())."); 2106 PetscCheck(mat->cmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MatGetValuesLocal() cannot proceed without local-to-global column mapping (See MatSetLocalToGlobalMapping())."); 2107 PetscCall(ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm)); 2108 PetscCall(ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm)); 2109 PetscCall(MatGetValues(mat,nrow,irowm,ncol,icolm,y)); 2110 PetscCall(PetscFree2(bufr,bufc)); 2111 } 2112 PetscCall(PetscLogEventEnd(MAT_GetValues,mat,0,0,0)); 2113 PetscFunctionReturn(0); 2114 } 2115 2116 /*@ 2117 MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and 2118 the same size. Currently, this can only be called once and creates the given matrix. 2119 2120 Not Collective 2121 2122 Input Parameters: 2123 + mat - the matrix 2124 . nb - the number of blocks 2125 . bs - the number of rows (and columns) in each block 2126 . rows - a concatenation of the rows for each block 2127 - v - a concatenation of logically two-dimensional arrays of values 2128 2129 Notes: 2130 In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix. 2131 2132 Level: advanced 2133 2134 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 2135 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()` 2136 @*/ 2137 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[]) 2138 { 2139 PetscFunctionBegin; 2140 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2141 PetscValidType(mat,1); 2142 PetscValidIntPointer(rows,4); 2143 PetscValidScalarPointer(v,5); 2144 PetscAssert(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2145 2146 PetscCall(PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0)); 2147 if (mat->ops->setvaluesbatch) { 2148 PetscCall((*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v)); 2149 } else { 2150 for (PetscInt b = 0; b < nb; ++b) PetscCall(MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES)); 2151 } 2152 PetscCall(PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0)); 2153 PetscFunctionReturn(0); 2154 } 2155 2156 /*@ 2157 MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by 2158 the routine MatSetValuesLocal() to allow users to insert matrix entries 2159 using a local (per-processor) numbering. 2160 2161 Not Collective 2162 2163 Input Parameters: 2164 + x - the matrix 2165 . rmapping - row mapping created with ISLocalToGlobalMappingCreate() or ISLocalToGlobalMappingCreateIS() 2166 - cmapping - column mapping 2167 2168 Level: intermediate 2169 2170 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetValuesLocal()`, `MatGetValuesLocal()` 2171 @*/ 2172 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 2173 { 2174 PetscFunctionBegin; 2175 PetscValidHeaderSpecific(x,MAT_CLASSID,1); 2176 PetscValidType(x,1); 2177 if (rmapping) PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2); 2178 if (cmapping) PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3); 2179 if (x->ops->setlocaltoglobalmapping) { 2180 PetscCall((*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping)); 2181 } else { 2182 PetscCall(PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping)); 2183 PetscCall(PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping)); 2184 } 2185 PetscFunctionReturn(0); 2186 } 2187 2188 /*@ 2189 MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping() 2190 2191 Not Collective 2192 2193 Input Parameter: 2194 . A - the matrix 2195 2196 Output Parameters: 2197 + rmapping - row mapping 2198 - cmapping - column mapping 2199 2200 Level: advanced 2201 2202 .seealso: `MatSetValuesLocal()` 2203 @*/ 2204 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping) 2205 { 2206 PetscFunctionBegin; 2207 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2208 PetscValidType(A,1); 2209 if (rmapping) { 2210 PetscValidPointer(rmapping,2); 2211 *rmapping = A->rmap->mapping; 2212 } 2213 if (cmapping) { 2214 PetscValidPointer(cmapping,3); 2215 *cmapping = A->cmap->mapping; 2216 } 2217 PetscFunctionReturn(0); 2218 } 2219 2220 /*@ 2221 MatSetLayouts - Sets the PetscLayout objects for rows and columns of a matrix 2222 2223 Logically Collective on A 2224 2225 Input Parameters: 2226 + A - the matrix 2227 . rmap - row layout 2228 - cmap - column layout 2229 2230 Level: advanced 2231 2232 .seealso: `MatCreateVecs()`, `MatGetLocalToGlobalMapping()`, `MatGetLayouts()` 2233 @*/ 2234 PetscErrorCode MatSetLayouts(Mat A,PetscLayout rmap,PetscLayout cmap) 2235 { 2236 PetscFunctionBegin; 2237 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2238 PetscCall(PetscLayoutReference(rmap,&A->rmap)); 2239 PetscCall(PetscLayoutReference(cmap,&A->cmap)); 2240 PetscFunctionReturn(0); 2241 } 2242 2243 /*@ 2244 MatGetLayouts - Gets the PetscLayout objects for rows and columns 2245 2246 Not Collective 2247 2248 Input Parameter: 2249 . A - the matrix 2250 2251 Output Parameters: 2252 + rmap - row layout 2253 - cmap - column layout 2254 2255 Level: advanced 2256 2257 .seealso: `MatCreateVecs()`, `MatGetLocalToGlobalMapping()`, `MatSetLayouts()` 2258 @*/ 2259 PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap) 2260 { 2261 PetscFunctionBegin; 2262 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2263 PetscValidType(A,1); 2264 if (rmap) { 2265 PetscValidPointer(rmap,2); 2266 *rmap = A->rmap; 2267 } 2268 if (cmap) { 2269 PetscValidPointer(cmap,3); 2270 *cmap = A->cmap; 2271 } 2272 PetscFunctionReturn(0); 2273 } 2274 2275 /*@C 2276 MatSetValuesLocal - Inserts or adds values into certain locations of a matrix, 2277 using a local numbering of the nodes. 2278 2279 Not Collective 2280 2281 Input Parameters: 2282 + mat - the matrix 2283 . nrow, irow - number of rows and their local indices 2284 . ncol, icol - number of columns and their local indices 2285 . y - a logically two-dimensional array of values 2286 - addv - either INSERT_VALUES or ADD_VALUES, where 2287 ADD_VALUES adds values to any existing entries, and 2288 INSERT_VALUES replaces existing entries with new values 2289 2290 Notes: 2291 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2292 MatSetUp() before using this routine 2293 2294 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine 2295 2296 Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES 2297 options cannot be mixed without intervening calls to the assembly 2298 routines. 2299 2300 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2301 MUST be called after all calls to MatSetValuesLocal() have been completed. 2302 2303 Level: intermediate 2304 2305 Developer Notes: 2306 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2307 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2308 2309 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetLocalToGlobalMapping()`, 2310 `MatSetValueLocal()`, `MatGetValuesLocal()` 2311 @*/ 2312 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2313 { 2314 PetscFunctionBeginHot; 2315 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2316 PetscValidType(mat,1); 2317 MatCheckPreallocated(mat,1); 2318 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2319 PetscValidIntPointer(irow,3); 2320 PetscValidIntPointer(icol,5); 2321 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 2322 else PetscCheck(mat->insertmode == addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2323 if (PetscDefined(USE_DEBUG)) { 2324 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2325 PetscCheck(mat->ops->setvalueslocal || mat->ops->setvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2326 } 2327 2328 if (mat->assembled) { 2329 mat->was_assembled = PETSC_TRUE; 2330 mat->assembled = PETSC_FALSE; 2331 } 2332 PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 2333 if (mat->ops->setvalueslocal) { 2334 PetscCall((*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv)); 2335 } else { 2336 PetscInt buf[8192],*bufr=NULL,*bufc=NULL; 2337 const PetscInt *irowm,*icolm; 2338 2339 if ((!mat->rmap->mapping && !mat->cmap->mapping) || (nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2340 bufr = buf; 2341 bufc = buf + nrow; 2342 irowm = bufr; 2343 icolm = bufc; 2344 } else { 2345 PetscCall(PetscMalloc2(nrow,&bufr,ncol,&bufc)); 2346 irowm = bufr; 2347 icolm = bufc; 2348 } 2349 if (mat->rmap->mapping) PetscCall(ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,bufr)); 2350 else irowm = irow; 2351 if (mat->cmap->mapping) { 2352 if (mat->cmap->mapping != mat->rmap->mapping || ncol != nrow || icol != irow) { 2353 PetscCall(ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,bufc)); 2354 } else icolm = irowm; 2355 } else icolm = icol; 2356 PetscCall(MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv)); 2357 if (bufr != buf) PetscCall(PetscFree2(bufr,bufc)); 2358 } 2359 PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 2360 PetscFunctionReturn(0); 2361 } 2362 2363 /*@C 2364 MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix, 2365 using a local ordering of the nodes a block at a time. 2366 2367 Not Collective 2368 2369 Input Parameters: 2370 + x - the matrix 2371 . nrow, irow - number of rows and their local indices 2372 . ncol, icol - number of columns and their local indices 2373 . y - a logically two-dimensional array of values 2374 - addv - either INSERT_VALUES or ADD_VALUES, where 2375 ADD_VALUES adds values to any existing entries, and 2376 INSERT_VALUES replaces existing entries with new values 2377 2378 Notes: 2379 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2380 MatSetUp() before using this routine 2381 2382 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping() 2383 before using this routineBefore calling MatSetValuesLocal(), the user must first set the 2384 2385 Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES 2386 options cannot be mixed without intervening calls to the assembly 2387 routines. 2388 2389 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2390 MUST be called after all calls to MatSetValuesBlockedLocal() have been completed. 2391 2392 Level: intermediate 2393 2394 Developer Notes: 2395 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2396 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2397 2398 .seealso: `MatSetBlockSize()`, `MatSetLocalToGlobalMapping()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, 2399 `MatSetValuesLocal()`, `MatSetValuesBlocked()` 2400 @*/ 2401 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2402 { 2403 PetscFunctionBeginHot; 2404 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2405 PetscValidType(mat,1); 2406 MatCheckPreallocated(mat,1); 2407 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2408 PetscValidIntPointer(irow,3); 2409 PetscValidIntPointer(icol,5); 2410 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 2411 else PetscCheck(mat->insertmode == addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2412 if (PetscDefined(USE_DEBUG)) { 2413 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2414 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); 2415 } 2416 2417 if (mat->assembled) { 2418 mat->was_assembled = PETSC_TRUE; 2419 mat->assembled = PETSC_FALSE; 2420 } 2421 if (PetscUnlikelyDebug(mat->rmap->mapping)) { /* Condition on the mapping existing, because MatSetValuesBlockedLocal_IS does not require it to be set. */ 2422 PetscInt irbs, rbs; 2423 PetscCall(MatGetBlockSizes(mat, &rbs, NULL)); 2424 PetscCall(ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&irbs)); 2425 PetscCheck(rbs == irbs,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different row block sizes! mat %" PetscInt_FMT ", row l2g map %" PetscInt_FMT,rbs,irbs); 2426 } 2427 if (PetscUnlikelyDebug(mat->cmap->mapping)) { 2428 PetscInt icbs, cbs; 2429 PetscCall(MatGetBlockSizes(mat,NULL,&cbs)); 2430 PetscCall(ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&icbs)); 2431 PetscCheck(cbs == icbs,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different col block sizes! mat %" PetscInt_FMT ", col l2g map %" PetscInt_FMT,cbs,icbs); 2432 } 2433 PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 2434 if (mat->ops->setvaluesblockedlocal) { 2435 PetscCall((*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv)); 2436 } else { 2437 PetscInt buf[8192],*bufr=NULL,*bufc=NULL; 2438 const PetscInt *irowm,*icolm; 2439 2440 if ((!mat->rmap->mapping && !mat->cmap->mapping) || (nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2441 bufr = buf; 2442 bufc = buf + nrow; 2443 irowm = bufr; 2444 icolm = bufc; 2445 } else { 2446 PetscCall(PetscMalloc2(nrow,&bufr,ncol,&bufc)); 2447 irowm = bufr; 2448 icolm = bufc; 2449 } 2450 if (mat->rmap->mapping) PetscCall(ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,bufr)); 2451 else irowm = irow; 2452 if (mat->cmap->mapping) { 2453 if (mat->cmap->mapping != mat->rmap->mapping || ncol != nrow || icol != irow) { 2454 PetscCall(ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,bufc)); 2455 } else icolm = irowm; 2456 } else icolm = icol; 2457 PetscCall(MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv)); 2458 if (bufr != buf) PetscCall(PetscFree2(bufr,bufc)); 2459 } 2460 PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 2461 PetscFunctionReturn(0); 2462 } 2463 2464 /*@ 2465 MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal 2466 2467 Collective on Mat 2468 2469 Input Parameters: 2470 + mat - the matrix 2471 - x - the vector to be multiplied 2472 2473 Output Parameters: 2474 . y - the result 2475 2476 Notes: 2477 The vectors x and y cannot be the same. I.e., one cannot 2478 call MatMult(A,y,y). 2479 2480 Level: developer 2481 2482 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 2483 @*/ 2484 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y) 2485 { 2486 PetscFunctionBegin; 2487 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2488 PetscValidType(mat,1); 2489 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2490 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2491 2492 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2493 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2494 PetscCheck(x != y,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2495 MatCheckPreallocated(mat,1); 2496 2497 PetscCheck(mat->ops->multdiagonalblock,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a multiply defined",((PetscObject)mat)->type_name); 2498 PetscCall((*mat->ops->multdiagonalblock)(mat,x,y)); 2499 PetscCall(PetscObjectStateIncrease((PetscObject)y)); 2500 PetscFunctionReturn(0); 2501 } 2502 2503 /* --------------------------------------------------------*/ 2504 /*@ 2505 MatMult - Computes the matrix-vector product, y = Ax. 2506 2507 Neighbor-wise Collective on Mat 2508 2509 Input Parameters: 2510 + mat - the matrix 2511 - x - the vector to be multiplied 2512 2513 Output Parameters: 2514 . y - the result 2515 2516 Notes: 2517 The vectors x and y cannot be the same. I.e., one cannot 2518 call MatMult(A,y,y). 2519 2520 Level: beginner 2521 2522 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 2523 @*/ 2524 PetscErrorCode MatMult(Mat mat,Vec x,Vec y) 2525 { 2526 PetscFunctionBegin; 2527 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2528 PetscValidType(mat,1); 2529 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2530 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2531 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2532 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2533 PetscCheck(x != y,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2534 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); 2535 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); 2536 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); 2537 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); 2538 PetscCall(VecSetErrorIfLocked(y,3)); 2539 if (mat->erroriffailure) PetscCall(VecValidValues(x,2,PETSC_TRUE)); 2540 MatCheckPreallocated(mat,1); 2541 2542 PetscCall(VecLockReadPush(x)); 2543 PetscCheck(mat->ops->mult,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a multiply defined",((PetscObject)mat)->type_name); 2544 PetscCall(PetscLogEventBegin(MAT_Mult,mat,x,y,0)); 2545 PetscCall((*mat->ops->mult)(mat,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 PetscCall((*mat->ops->transpose)(mat,reuse,B)); 5233 PetscCall(PetscLogEventEnd(MAT_Transpose,mat,0,0,0)); 5234 PetscCall(PetscObjectStateIncrease((PetscObject)*B)); 5235 5236 if (reuse == MAT_INITIAL_MATRIX) PetscCall(MatTransposeSetPrecursor(mat,*B)); 5237 if (reuse != MAT_INPLACE_MATRIX) { 5238 PetscCall(PetscObjectQuery((PetscObject)*B,"MatTransposeParent",(PetscObject*)&rB)); 5239 PetscCall(PetscContainerGetPointer(rB,(void**)&rb)); 5240 rb->state = ((PetscObject)mat)->state; 5241 rb->nonzerostate = mat->nonzerostate; 5242 } 5243 PetscFunctionReturn(0); 5244 } 5245 5246 /*@ 5247 MatTransposeSymbolic - Computes the symbolic part of the transpose of a matrix. 5248 5249 Collective on Mat 5250 5251 Input Parameters: 5252 . A - the matrix to transpose 5253 5254 Output Parameter: 5255 . 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 5256 numerical portion. 5257 5258 Level: intermediate 5259 5260 Note: 5261 This is not supported for many matrix types, use `MatTranspose()` in those cases 5262 5263 .seealso: `MatTransposeSetPrecursor()`, `MatTranspose()`, `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse`, `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, `MAT_INPLACE_MATRIX` 5264 @*/ 5265 PetscErrorCode MatTransposeSymbolic(Mat A,Mat *B) 5266 { 5267 PetscFunctionBegin; 5268 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5269 PetscValidType(A,1); 5270 PetscCheck(A->assembled,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5271 PetscCheck(!A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5272 PetscCheck(A->ops->transposesymbolic,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 5273 PetscCall(PetscLogEventBegin(MAT_Transpose,A,0,0,0)); 5274 PetscCall((*A->ops->transposesymbolic)(A,B)); 5275 PetscCall(PetscLogEventEnd(MAT_Transpose,A,0,0,0)); 5276 5277 PetscCall(MatTransposeSetPrecursor(A,*B)); 5278 PetscFunctionReturn(0); 5279 } 5280 5281 PetscErrorCode MatTransposeCheckNonzeroState_Private(Mat A,Mat B) 5282 { 5283 PetscContainer rB; 5284 MatParentState *rb; 5285 5286 PetscFunctionBegin; 5287 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5288 PetscValidType(A,1); 5289 PetscCheck(A->assembled,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5290 PetscCheck(!A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5291 PetscCall(PetscObjectQuery((PetscObject)B,"MatTransposeParent",(PetscObject*)&rB)); 5292 PetscCheck(rB,PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONG,"Reuse matrix used was not generated from call to MatTranspose()"); 5293 PetscCall(PetscContainerGetPointer(rB,(void**)&rb)); 5294 PetscCheck(rb->id == ((PetscObject)A)->id,PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONG,"Reuse matrix used was not generated from input matrix"); 5295 PetscCheck(rb->nonzerostate == A->nonzerostate,PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Reuse matrix has changed nonzero structure"); 5296 PetscFunctionReturn(0); 5297 } 5298 5299 /*@ 5300 MatIsTranspose - Test whether a matrix is another one's transpose, 5301 or its own, in which case it tests symmetry. 5302 5303 Collective on Mat 5304 5305 Input Parameters: 5306 + A - the matrix to test 5307 - B - the matrix to test against, this can equal the first parameter 5308 5309 Output Parameters: 5310 . flg - the result 5311 5312 Notes: 5313 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 5314 has a running time of the order of the number of nonzeros; the parallel 5315 test involves parallel copies of the block-offdiagonal parts of the matrix. 5316 5317 Level: intermediate 5318 5319 .seealso: `MatTranspose()`, `MatIsSymmetric()`, `MatIsHermitian()` 5320 @*/ 5321 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 5322 { 5323 PetscErrorCode (*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 5324 5325 PetscFunctionBegin; 5326 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5327 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5328 PetscValidBoolPointer(flg,4); 5329 PetscCall(PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f)); 5330 PetscCall(PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g)); 5331 *flg = PETSC_FALSE; 5332 if (f && g) { 5333 PetscCheck(f == g,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test"); 5334 PetscCall((*f)(A,B,tol,flg)); 5335 } else { 5336 MatType mattype; 5337 5338 PetscCall(MatGetType(f ? B : A,&mattype)); 5339 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for transpose",mattype); 5340 } 5341 PetscFunctionReturn(0); 5342 } 5343 5344 /*@ 5345 MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate. 5346 5347 Collective on Mat 5348 5349 Input Parameters: 5350 + mat - the matrix to transpose and complex conjugate 5351 - reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX 5352 5353 Output Parameter: 5354 . B - the Hermitian 5355 5356 Level: intermediate 5357 5358 .seealso: `MatTranspose()`, `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse` 5359 @*/ 5360 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B) 5361 { 5362 PetscFunctionBegin; 5363 PetscCall(MatTranspose(mat,reuse,B)); 5364 #if defined(PETSC_USE_COMPLEX) 5365 PetscCall(MatConjugate(*B)); 5366 #endif 5367 PetscFunctionReturn(0); 5368 } 5369 5370 /*@ 5371 MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose, 5372 5373 Collective on Mat 5374 5375 Input Parameters: 5376 + A - the matrix to test 5377 - B - the matrix to test against, this can equal the first parameter 5378 5379 Output Parameters: 5380 . flg - the result 5381 5382 Notes: 5383 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 5384 has a running time of the order of the number of nonzeros; the parallel 5385 test involves parallel copies of the block-offdiagonal parts of the matrix. 5386 5387 Level: intermediate 5388 5389 .seealso: `MatTranspose()`, `MatIsSymmetric()`, `MatIsHermitian()`, `MatIsTranspose()` 5390 @*/ 5391 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 5392 { 5393 PetscErrorCode (*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 5394 5395 PetscFunctionBegin; 5396 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5397 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5398 PetscValidBoolPointer(flg,4); 5399 PetscCall(PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f)); 5400 PetscCall(PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g)); 5401 if (f && g) { 5402 PetscCheck(f != g,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test"); 5403 PetscCall((*f)(A,B,tol,flg)); 5404 } 5405 PetscFunctionReturn(0); 5406 } 5407 5408 /*@ 5409 MatPermute - Creates a new matrix with rows and columns permuted from the 5410 original. 5411 5412 Collective on Mat 5413 5414 Input Parameters: 5415 + mat - the matrix to permute 5416 . row - row permutation, each processor supplies only the permutation for its rows 5417 - col - column permutation, each processor supplies only the permutation for its columns 5418 5419 Output Parameters: 5420 . B - the permuted matrix 5421 5422 Level: advanced 5423 5424 Note: 5425 The index sets map from row/col of permuted matrix to row/col of original matrix. 5426 The index sets should be on the same communicator as Mat and have the same local sizes. 5427 5428 Developer Note: 5429 If you want to implement MatPermute for a matrix type, and your approach doesn't 5430 exploit the fact that row and col are permutations, consider implementing the 5431 more general MatCreateSubMatrix() instead. 5432 5433 .seealso: `MatGetOrdering()`, `ISAllGather()` 5434 5435 @*/ 5436 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B) 5437 { 5438 PetscFunctionBegin; 5439 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5440 PetscValidType(mat,1); 5441 PetscValidHeaderSpecific(row,IS_CLASSID,2); 5442 PetscValidHeaderSpecific(col,IS_CLASSID,3); 5443 PetscValidPointer(B,4); 5444 PetscCheckSameComm(mat,1,row,2); 5445 if (row != col) PetscCheckSameComm(row,2,col,3); 5446 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5447 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5448 PetscCheck(mat->ops->permute || mat->ops->createsubmatrix,PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name); 5449 MatCheckPreallocated(mat,1); 5450 5451 if (mat->ops->permute) { 5452 PetscCall((*mat->ops->permute)(mat,row,col,B)); 5453 PetscCall(PetscObjectStateIncrease((PetscObject)*B)); 5454 } else { 5455 PetscCall(MatCreateSubMatrix(mat, row, col, MAT_INITIAL_MATRIX, B)); 5456 } 5457 PetscFunctionReturn(0); 5458 } 5459 5460 /*@ 5461 MatEqual - Compares two matrices. 5462 5463 Collective on Mat 5464 5465 Input Parameters: 5466 + A - the first matrix 5467 - B - the second matrix 5468 5469 Output Parameter: 5470 . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise. 5471 5472 Level: intermediate 5473 5474 @*/ 5475 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool *flg) 5476 { 5477 PetscFunctionBegin; 5478 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5479 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5480 PetscValidType(A,1); 5481 PetscValidType(B,2); 5482 PetscValidBoolPointer(flg,3); 5483 PetscCheckSameComm(A,1,B,2); 5484 MatCheckPreallocated(A,1); 5485 MatCheckPreallocated(B,2); 5486 PetscCheck(A->assembled,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5487 PetscCheck(B->assembled,PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5488 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); 5489 if (A->ops->equal && A->ops->equal == B->ops->equal) { 5490 PetscCall((*A->ops->equal)(A,B,flg)); 5491 } else { 5492 PetscCall(MatMultEqual(A,B,10,flg)); 5493 } 5494 PetscFunctionReturn(0); 5495 } 5496 5497 /*@ 5498 MatDiagonalScale - Scales a matrix on the left and right by diagonal 5499 matrices that are stored as vectors. Either of the two scaling 5500 matrices can be NULL. 5501 5502 Collective on Mat 5503 5504 Input Parameters: 5505 + mat - the matrix to be scaled 5506 . l - the left scaling vector (or NULL) 5507 - r - the right scaling vector (or NULL) 5508 5509 Notes: 5510 MatDiagonalScale() computes A = LAR, where 5511 L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector) 5512 The L scales the rows of the matrix, the R scales the columns of the matrix. 5513 5514 Level: intermediate 5515 5516 .seealso: `MatScale()`, `MatShift()`, `MatDiagonalSet()` 5517 @*/ 5518 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r) 5519 { 5520 PetscFunctionBegin; 5521 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5522 PetscValidType(mat,1); 5523 if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);} 5524 if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);} 5525 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5526 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5527 MatCheckPreallocated(mat,1); 5528 if (!l && !r) PetscFunctionReturn(0); 5529 5530 PetscCheck(mat->ops->diagonalscale,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5531 PetscCall(PetscLogEventBegin(MAT_Scale,mat,0,0,0)); 5532 PetscCall((*mat->ops->diagonalscale)(mat,l,r)); 5533 PetscCall(PetscLogEventEnd(MAT_Scale,mat,0,0,0)); 5534 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5535 if (l != r) mat->symmetric = PETSC_BOOL3_FALSE; 5536 PetscFunctionReturn(0); 5537 } 5538 5539 /*@ 5540 MatScale - Scales all elements of a matrix by a given number. 5541 5542 Logically Collective on Mat 5543 5544 Input Parameters: 5545 + mat - the matrix to be scaled 5546 - a - the scaling value 5547 5548 Output Parameter: 5549 . mat - the scaled matrix 5550 5551 Level: intermediate 5552 5553 .seealso: `MatDiagonalScale()` 5554 @*/ 5555 PetscErrorCode MatScale(Mat mat,PetscScalar a) 5556 { 5557 PetscFunctionBegin; 5558 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5559 PetscValidType(mat,1); 5560 PetscCheck(a == (PetscScalar)1.0 || mat->ops->scale,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5561 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5562 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5563 PetscValidLogicalCollectiveScalar(mat,a,2); 5564 MatCheckPreallocated(mat,1); 5565 5566 PetscCall(PetscLogEventBegin(MAT_Scale,mat,0,0,0)); 5567 if (a != (PetscScalar)1.0) { 5568 PetscCall((*mat->ops->scale)(mat,a)); 5569 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5570 } 5571 PetscCall(PetscLogEventEnd(MAT_Scale,mat,0,0,0)); 5572 PetscFunctionReturn(0); 5573 } 5574 5575 /*@ 5576 MatNorm - Calculates various norms of a matrix. 5577 5578 Collective on Mat 5579 5580 Input Parameters: 5581 + mat - the matrix 5582 - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY 5583 5584 Output Parameter: 5585 . nrm - the resulting norm 5586 5587 Level: intermediate 5588 5589 @*/ 5590 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm) 5591 { 5592 PetscFunctionBegin; 5593 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5594 PetscValidType(mat,1); 5595 PetscValidRealPointer(nrm,3); 5596 5597 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5598 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5599 PetscCheck(mat->ops->norm,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5600 MatCheckPreallocated(mat,1); 5601 5602 PetscCall((*mat->ops->norm)(mat,type,nrm)); 5603 PetscFunctionReturn(0); 5604 } 5605 5606 /* 5607 This variable is used to prevent counting of MatAssemblyBegin() that 5608 are called from within a MatAssemblyEnd(). 5609 */ 5610 static PetscInt MatAssemblyEnd_InUse = 0; 5611 /*@ 5612 MatAssemblyBegin - Begins assembling the matrix. This routine should 5613 be called after completing all calls to MatSetValues(). 5614 5615 Collective on Mat 5616 5617 Input Parameters: 5618 + mat - the matrix 5619 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5620 5621 Notes: 5622 MatSetValues() generally caches the values. The matrix is ready to 5623 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5624 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5625 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5626 using the matrix. 5627 5628 ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the 5629 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 5630 a global collective operation requring all processes that share the matrix. 5631 5632 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5633 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5634 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5635 5636 Level: beginner 5637 5638 .seealso: `MatAssemblyEnd()`, `MatSetValues()`, `MatAssembled()` 5639 @*/ 5640 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type) 5641 { 5642 PetscFunctionBegin; 5643 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5644 PetscValidType(mat,1); 5645 MatCheckPreallocated(mat,1); 5646 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?"); 5647 if (mat->assembled) { 5648 mat->was_assembled = PETSC_TRUE; 5649 mat->assembled = PETSC_FALSE; 5650 } 5651 5652 if (!MatAssemblyEnd_InUse) { 5653 PetscCall(PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0)); 5654 if (mat->ops->assemblybegin) PetscCall((*mat->ops->assemblybegin)(mat,type)); 5655 PetscCall(PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0)); 5656 } else if (mat->ops->assemblybegin) PetscCall((*mat->ops->assemblybegin)(mat,type)); 5657 PetscFunctionReturn(0); 5658 } 5659 5660 /*@ 5661 MatAssembled - Indicates if a matrix has been assembled and is ready for 5662 use; for example, in matrix-vector product. 5663 5664 Not Collective 5665 5666 Input Parameter: 5667 . mat - the matrix 5668 5669 Output Parameter: 5670 . assembled - PETSC_TRUE or PETSC_FALSE 5671 5672 Level: advanced 5673 5674 .seealso: `MatAssemblyEnd()`, `MatSetValues()`, `MatAssemblyBegin()` 5675 @*/ 5676 PetscErrorCode MatAssembled(Mat mat,PetscBool *assembled) 5677 { 5678 PetscFunctionBegin; 5679 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5680 PetscValidBoolPointer(assembled,2); 5681 *assembled = mat->assembled; 5682 PetscFunctionReturn(0); 5683 } 5684 5685 /*@ 5686 MatAssemblyEnd - Completes assembling the matrix. This routine should 5687 be called after MatAssemblyBegin(). 5688 5689 Collective on Mat 5690 5691 Input Parameters: 5692 + mat - the matrix 5693 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5694 5695 Options Database Keys: 5696 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly() 5697 . -mat_view ::ascii_info_detail - Prints more detailed info 5698 . -mat_view - Prints matrix in ASCII format 5699 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 5700 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 5701 . -display <name> - Sets display name (default is host) 5702 . -draw_pause <sec> - Sets number of seconds to pause after display 5703 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab) 5704 . -viewer_socket_machine <machine> - Machine to use for socket 5705 . -viewer_socket_port <port> - Port number to use for socket 5706 - -mat_view binary:filename[:append] - Save matrix to file in binary format 5707 5708 Notes: 5709 MatSetValues() generally caches the values. The matrix is ready to 5710 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5711 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5712 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5713 using the matrix. 5714 5715 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5716 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5717 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5718 5719 Level: beginner 5720 5721 .seealso: `MatAssemblyBegin()`, `MatSetValues()`, `PetscDrawOpenX()`, `PetscDrawCreate()`, `MatView()`, `MatAssembled()`, `PetscViewerSocketOpen()` 5722 @*/ 5723 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type) 5724 { 5725 static PetscInt inassm = 0; 5726 PetscBool flg = PETSC_FALSE; 5727 5728 PetscFunctionBegin; 5729 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5730 PetscValidType(mat,1); 5731 5732 inassm++; 5733 MatAssemblyEnd_InUse++; 5734 if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */ 5735 PetscCall(PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0)); 5736 if (mat->ops->assemblyend) PetscCall((*mat->ops->assemblyend)(mat,type)); 5737 PetscCall(PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0)); 5738 } else if (mat->ops->assemblyend) PetscCall((*mat->ops->assemblyend)(mat,type)); 5739 5740 /* Flush assembly is not a true assembly */ 5741 if (type != MAT_FLUSH_ASSEMBLY) { 5742 if (mat->num_ass) { 5743 if (!mat->symmetry_eternal) { 5744 mat->symmetric = PETSC_BOOL3_UNKNOWN; 5745 mat->hermitian = PETSC_BOOL3_UNKNOWN; 5746 } 5747 if (!mat->structural_symmetry_eternal && mat->ass_nonzerostate != mat->nonzerostate) { 5748 mat->structurally_symmetric = PETSC_BOOL3_UNKNOWN; 5749 } 5750 if (!mat->spd_eternal) mat->spd = PETSC_BOOL3_UNKNOWN; 5751 } 5752 mat->num_ass++; 5753 mat->assembled = PETSC_TRUE; 5754 mat->ass_nonzerostate = mat->nonzerostate; 5755 } 5756 5757 mat->insertmode = NOT_SET_VALUES; 5758 MatAssemblyEnd_InUse--; 5759 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5760 if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) { 5761 PetscCall(MatViewFromOptions(mat,NULL,"-mat_view")); 5762 5763 if (mat->checksymmetryonassembly) { 5764 PetscCall(MatIsSymmetric(mat,mat->checksymmetrytol,&flg)); 5765 if (flg) { 5766 PetscCall(PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol)); 5767 } else { 5768 PetscCall(PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol)); 5769 } 5770 } 5771 if (mat->nullsp && mat->checknullspaceonassembly) { 5772 PetscCall(MatNullSpaceTest(mat->nullsp,mat,NULL)); 5773 } 5774 } 5775 inassm--; 5776 PetscFunctionReturn(0); 5777 } 5778 5779 /*@ 5780 MatSetOption - Sets a parameter option for a matrix. Some options 5781 may be specific to certain storage formats. Some options 5782 determine how values will be inserted (or added). Sorted, 5783 row-oriented input will generally assemble the fastest. The default 5784 is row-oriented. 5785 5786 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5787 5788 Input Parameters: 5789 + mat - the matrix 5790 . option - the option, one of those listed below (and possibly others), 5791 - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5792 5793 Options Describing Matrix Structure: 5794 + MAT_SPD - symmetric positive definite 5795 . MAT_SYMMETRIC - symmetric in terms of both structure and value 5796 . MAT_HERMITIAN - transpose is the complex conjugation 5797 . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure 5798 . MAT_SYMMETRY_ETERNAL - indicates the symmetry (or Hermitian structure) or its absence will persist through any changes to the matrix 5799 . MAT_STRUCTURAL_SYMMETRY_ETERNAL - indicates the structural symmetry or its absence will persist through any changes to the matrix 5800 - MAT_SPD_ETERNAL - indicates the value of MAT_SPD (true or false) will persist through any changes to the matrix 5801 5802 These are not really options of the matrix, they are knowledge about the structure of the matrix that users may provide so that they 5803 do not need to be computed (usually at a high cost) 5804 5805 Options For Use with MatSetValues(): 5806 Insert a logically dense subblock, which can be 5807 . MAT_ROW_ORIENTED - row-oriented (default) 5808 5809 Note these options reflect the data you pass in with MatSetValues(); it has 5810 nothing to do with how the data is stored internally in the matrix 5811 data structure. 5812 5813 When (re)assembling a matrix, we can restrict the input for 5814 efficiency/debugging purposes. These options include 5815 + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow) 5816 . MAT_FORCE_DIAGONAL_ENTRIES - forces diagonal entries to be allocated 5817 . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries 5818 . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry 5819 . MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly 5820 . MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if 5821 any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves 5822 performance for very large process counts. 5823 - MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset 5824 of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly 5825 functions, instead sending only neighbor messages. 5826 5827 Notes: 5828 Except for MAT_UNUSED_NONZERO_LOCATION_ERR and MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg! 5829 5830 Some options are relevant only for particular matrix types and 5831 are thus ignored by others. Other options are not supported by 5832 certain matrix types and will generate an error message if set. 5833 5834 If using a Fortran 77 module to compute a matrix, one may need to 5835 use the column-oriented option (or convert to the row-oriented 5836 format). 5837 5838 MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion 5839 that would generate a new entry in the nonzero structure is instead 5840 ignored. Thus, if memory has not alredy been allocated for this particular 5841 data, then the insertion is ignored. For dense matrices, in which 5842 the entire array is allocated, no entries are ever ignored. 5843 Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5844 5845 MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5846 that would generate a new entry in the nonzero structure instead produces 5847 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 5848 5849 MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5850 that would generate a new entry that has not been preallocated will 5851 instead produce an error. (Currently supported for AIJ and BAIJ formats 5852 only.) This is a useful flag when debugging matrix memory preallocation. 5853 If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5854 5855 MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for 5856 other processors should be dropped, rather than stashed. 5857 This is useful if you know that the "owning" processor is also 5858 always generating the correct matrix entries, so that PETSc need 5859 not transfer duplicate entries generated on another processor. 5860 5861 MAT_USE_HASH_TABLE indicates that a hash table be used to improve the 5862 searches during matrix assembly. When this flag is set, the hash table 5863 is created during the first Matrix Assembly. This hash table is 5864 used the next time through, during MatSetVaules()/MatSetVaulesBlocked() 5865 to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag 5866 should be used with MAT_USE_HASH_TABLE flag. This option is currently 5867 supported by MATMPIBAIJ format only. 5868 5869 MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries 5870 are kept in the nonzero structure 5871 5872 MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating 5873 a zero location in the matrix 5874 5875 MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types 5876 5877 MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the 5878 zero row routines and thus improves performance for very large process counts. 5879 5880 MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular 5881 part of the matrix (since they should match the upper triangular part). 5882 5883 MAT_SORTED_FULL - each process provides exactly its local rows; all column indices for a given row are passed in a 5884 single call to MatSetValues(), preallocation is perfect, row oriented, INSERT_VALUES is used. Common 5885 with finite difference schemes with non-periodic boundary conditions. 5886 5887 Developer Note: 5888 MAT_SYMMETRY_ETERNAL, MAT_STRUCTURAL_SYMMETRY_ETERNAL, and MAT_SPD_ETERNAL are used by MatAssemblyEnd() and in other 5889 places where otherwise the value of MAT_SYMMETRIC, MAT_STRUCTURAL_SYMMETRIC or MAT_SPD would need to be changed back 5890 to PETSC_BOOL3_UNKNOWN because the matrix values had changed so the code cannot be certain that the related property had 5891 not changed. 5892 5893 Level: intermediate 5894 5895 .seealso: `MatOption`, `Mat`, `MatGetOption()` 5896 5897 @*/ 5898 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg) 5899 { 5900 PetscFunctionBegin; 5901 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5902 if (op > 0) { 5903 PetscValidLogicalCollectiveEnum(mat,op,2); 5904 PetscValidLogicalCollectiveBool(mat,flg,3); 5905 } 5906 5907 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); 5908 5909 switch (op) { 5910 case MAT_FORCE_DIAGONAL_ENTRIES: 5911 mat->force_diagonals = flg; 5912 PetscFunctionReturn(0); 5913 case MAT_NO_OFF_PROC_ENTRIES: 5914 mat->nooffprocentries = flg; 5915 PetscFunctionReturn(0); 5916 case MAT_SUBSET_OFF_PROC_ENTRIES: 5917 mat->assembly_subset = flg; 5918 if (!mat->assembly_subset) { /* See the same logic in VecAssembly wrt VEC_SUBSET_OFF_PROC_ENTRIES */ 5919 #if !defined(PETSC_HAVE_MPIUNI) 5920 PetscCall(MatStashScatterDestroy_BTS(&mat->stash)); 5921 #endif 5922 mat->stash.first_assembly_done = PETSC_FALSE; 5923 } 5924 PetscFunctionReturn(0); 5925 case MAT_NO_OFF_PROC_ZERO_ROWS: 5926 mat->nooffproczerorows = flg; 5927 PetscFunctionReturn(0); 5928 case MAT_SPD: 5929 if (flg) { 5930 mat->spd = PETSC_BOOL3_TRUE; 5931 mat->symmetric = PETSC_BOOL3_TRUE; 5932 mat->structurally_symmetric = PETSC_BOOL3_TRUE; 5933 } else { 5934 mat->spd = PETSC_BOOL3_FALSE; 5935 } 5936 break; 5937 case MAT_SYMMETRIC: 5938 mat->symmetric = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5939 if (flg) mat->structurally_symmetric = PETSC_BOOL3_TRUE; 5940 #if !defined(PETSC_USE_COMPLEX) 5941 mat->hermitian = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5942 #endif 5943 break; 5944 case MAT_HERMITIAN: 5945 mat->hermitian = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5946 if (flg) mat->structurally_symmetric = PETSC_BOOL3_TRUE; 5947 #if !defined(PETSC_USE_COMPLEX) 5948 mat->symmetric = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5949 #endif 5950 break; 5951 case MAT_STRUCTURALLY_SYMMETRIC: 5952 mat->structurally_symmetric = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5953 break; 5954 case MAT_SYMMETRY_ETERNAL: 5955 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"); 5956 mat->symmetry_eternal = flg; 5957 if (flg) mat->structural_symmetry_eternal = PETSC_TRUE; 5958 break; 5959 case MAT_STRUCTURAL_SYMMETRY_ETERNAL: 5960 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"); 5961 mat->structural_symmetry_eternal = flg; 5962 break; 5963 case MAT_SPD_ETERNAL: 5964 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"); 5965 mat->spd_eternal = flg; 5966 if (flg) { 5967 mat->structural_symmetry_eternal = PETSC_TRUE; 5968 mat->symmetry_eternal = PETSC_TRUE; 5969 } 5970 break; 5971 case MAT_STRUCTURE_ONLY: 5972 mat->structure_only = flg; 5973 break; 5974 case MAT_SORTED_FULL: 5975 mat->sortedfull = flg; 5976 break; 5977 default: 5978 break; 5979 } 5980 if (mat->ops->setoption) PetscCall((*mat->ops->setoption)(mat,op,flg)); 5981 PetscFunctionReturn(0); 5982 } 5983 5984 /*@ 5985 MatGetOption - Gets a parameter option that has been set for a matrix. 5986 5987 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5988 5989 Input Parameters: 5990 + mat - the matrix 5991 - option - the option, this only responds to certain options, check the code for which ones 5992 5993 Output Parameter: 5994 . flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5995 5996 Notes: 5997 Can only be called after MatSetSizes() and MatSetType() have been set. 5998 5999 Certain option values may be unknown, for those use the routines `MatIsSymmetric()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, or 6000 `MatIsSymmetricKnown()`, `MatIsHermitianKnown()`, `MatIsStructurallySymmetricKnown()` 6001 6002 Level: intermediate 6003 6004 .seealso: `MatOption`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, 6005 `MatIsSymmetricKnown()`, `MatIsHermitianKnown()`, `MatIsStructurallySymmetricKnown()` 6006 6007 @*/ 6008 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg) 6009 { 6010 PetscFunctionBegin; 6011 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6012 PetscValidType(mat,1); 6013 6014 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); 6015 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()"); 6016 6017 switch (op) { 6018 case MAT_NO_OFF_PROC_ENTRIES: 6019 *flg = mat->nooffprocentries; 6020 break; 6021 case MAT_NO_OFF_PROC_ZERO_ROWS: 6022 *flg = mat->nooffproczerorows; 6023 break; 6024 case MAT_SYMMETRIC: 6025 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Use MatIsSymmetric() or MatIsSymmetricKnown()"); 6026 break; 6027 case MAT_HERMITIAN: 6028 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Use MatIsHermitian() or MatIsHermitianKnown()"); 6029 break; 6030 case MAT_STRUCTURALLY_SYMMETRIC: 6031 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Use MatIsStructurallySymmetric() or MatIsStructurallySymmetricKnown()"); 6032 break; 6033 case MAT_SPD: 6034 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Use MatIsSPDKnown()"); 6035 break; 6036 case MAT_SYMMETRY_ETERNAL: 6037 *flg = mat->symmetry_eternal; 6038 break; 6039 case MAT_STRUCTURAL_SYMMETRY_ETERNAL: 6040 *flg = mat->symmetry_eternal; 6041 break; 6042 default: 6043 break; 6044 } 6045 PetscFunctionReturn(0); 6046 } 6047 6048 /*@ 6049 MatZeroEntries - Zeros all entries of a matrix. For sparse matrices 6050 this routine retains the old nonzero structure. 6051 6052 Logically Collective on Mat 6053 6054 Input Parameters: 6055 . mat - the matrix 6056 6057 Level: intermediate 6058 6059 Notes: 6060 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. 6061 See the Performance chapter of the users manual for information on preallocating matrices. 6062 6063 .seealso: `MatZeroRows()` 6064 @*/ 6065 PetscErrorCode MatZeroEntries(Mat mat) 6066 { 6067 PetscFunctionBegin; 6068 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6069 PetscValidType(mat,1); 6070 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6071 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"); 6072 PetscCheck(mat->ops->zeroentries,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6073 MatCheckPreallocated(mat,1); 6074 6075 PetscCall(PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0)); 6076 PetscCall((*mat->ops->zeroentries)(mat)); 6077 PetscCall(PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0)); 6078 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6079 PetscFunctionReturn(0); 6080 } 6081 6082 /*@ 6083 MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal) 6084 of a set of rows and columns of a matrix. 6085 6086 Collective on Mat 6087 6088 Input Parameters: 6089 + mat - the matrix 6090 . numRows - the number of rows to remove 6091 . rows - the global row indices 6092 . diag - value put in the diagonal of the eliminated rows 6093 . x - optional vector of solutions for zeroed rows (other entries in vector are not used), these must be set before this call 6094 - b - optional vector of right hand side, that will be adjusted by provided solution 6095 6096 Notes: 6097 This routine, along with `MatZeroRows()`, is typically used to eliminate known Dirichlet boundary conditions from a linear system. 6098 6099 For each zeroed row, the value of the corresponding b is set to diag times the value of the corresponding x. 6100 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 6101 6102 If the resulting linear system is to be solved with KSP then one can (but does not have to) call `KSPSetInitialGuessNonzero()` to allow the 6103 Krylov method to take advantage of the known solution on the zeroed rows. 6104 6105 For the parallel case, all processes that share the matrix (i.e., 6106 those in the communicator used for matrix creation) MUST call this 6107 routine, regardless of whether any rows being zeroed are owned by 6108 them. 6109 6110 Unlike `MatZeroRows()` this does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 6111 6112 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6113 list only rows local to itself). 6114 6115 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 6116 6117 Level: intermediate 6118 6119 .seealso: `MatZeroRowsIS()`, `MatZeroRows()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6120 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6121 @*/ 6122 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6123 { 6124 PetscFunctionBegin; 6125 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6126 PetscValidType(mat,1); 6127 if (numRows) PetscValidIntPointer(rows,3); 6128 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6129 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6130 PetscCheck(mat->ops->zerorowscolumns,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6131 MatCheckPreallocated(mat,1); 6132 6133 PetscCall((*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b)); 6134 PetscCall(MatViewFromOptions(mat,NULL,"-mat_view")); 6135 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6136 PetscFunctionReturn(0); 6137 } 6138 6139 /*@ 6140 MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal) 6141 of a set of rows and columns of a matrix. 6142 6143 Collective on Mat 6144 6145 Input Parameters: 6146 + mat - the matrix 6147 . is - the rows to zero 6148 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6149 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6150 - b - optional vector of right hand side, that will be adjusted by provided solution 6151 6152 Note: 6153 See `MatZeroRowsColumns()` for details on how this routine operates. 6154 6155 Level: intermediate 6156 6157 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6158 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRows()`, `MatZeroRowsColumnsStencil()` 6159 @*/ 6160 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6161 { 6162 PetscInt numRows; 6163 const PetscInt *rows; 6164 6165 PetscFunctionBegin; 6166 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6167 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6168 PetscValidType(mat,1); 6169 PetscValidType(is,2); 6170 PetscCall(ISGetLocalSize(is,&numRows)); 6171 PetscCall(ISGetIndices(is,&rows)); 6172 PetscCall(MatZeroRowsColumns(mat,numRows,rows,diag,x,b)); 6173 PetscCall(ISRestoreIndices(is,&rows)); 6174 PetscFunctionReturn(0); 6175 } 6176 6177 /*@ 6178 MatZeroRows - Zeros all entries (except possibly the main diagonal) 6179 of a set of rows of a matrix. 6180 6181 Collective on Mat 6182 6183 Input Parameters: 6184 + mat - the matrix 6185 . numRows - the number of rows to remove 6186 . rows - the global row indices 6187 . diag - value put in the diagonal of the eliminated rows 6188 . x - optional vector of solutions for zeroed rows (other entries in vector are not used), these must be set before this call 6189 - b - optional vector of right hand side, that will be adjusted by provided solution 6190 6191 Notes: 6192 This routine, along with `MatZeroRowsColumns()`, is typically used to eliminate known Dirichlet boundary conditions from a linear system. 6193 6194 For each zeroed row, the value of the corresponding b is set to diag times the value of the corresponding x. 6195 6196 If the resulting linear system is to be solved with KSP then one can (but does not have to) call `KSPSetInitialGuessNonzero()` to allow the 6197 Krylov method to take advantage of the known solution on the zeroed rows. 6198 6199 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) 6200 from the matrix. 6201 6202 Unlike `MatZeroRowsColumns()` for the AIJ and BAIJ matrix formats this removes the old nonzero structure, from the eliminated rows of the matrix 6203 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 6204 formats this does not alter the nonzero structure. 6205 6206 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6207 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6208 merely zeroed. 6209 6210 The user can set a value in the diagonal entry (or for the AIJ and 6211 row formats can optionally remove the main diagonal entry from the 6212 nonzero structure as well, by passing 0.0 as the final argument). 6213 6214 For the parallel case, all processes that share the matrix (i.e., 6215 those in the communicator used for matrix creation) MUST call this 6216 routine, regardless of whether any rows being zeroed are owned by 6217 them. 6218 6219 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6220 list only rows local to itself). 6221 6222 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6223 owns that are to be zeroed. This saves a global synchronization in the implementation. 6224 6225 Level: intermediate 6226 6227 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6228 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()`, `PCREDISTRIBUTE` 6229 @*/ 6230 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6231 { 6232 PetscFunctionBegin; 6233 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6234 PetscValidType(mat,1); 6235 if (numRows) PetscValidIntPointer(rows,3); 6236 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6237 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6238 PetscCheck(mat->ops->zerorows,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6239 MatCheckPreallocated(mat,1); 6240 6241 PetscCall((*mat->ops->zerorows)(mat,numRows,rows,diag,x,b)); 6242 PetscCall(MatViewFromOptions(mat,NULL,"-mat_view")); 6243 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6244 PetscFunctionReturn(0); 6245 } 6246 6247 /*@ 6248 MatZeroRowsIS - Zeros all entries (except possibly the main diagonal) 6249 of a set of rows of a matrix. 6250 6251 Collective on Mat 6252 6253 Input Parameters: 6254 + mat - the matrix 6255 . is - index set of rows to remove (if NULL then no row is removed) 6256 . diag - value put in all diagonals of eliminated rows 6257 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6258 - b - optional vector of right hand side, that will be adjusted by provided solution 6259 6260 Note: 6261 See `MatZeroRows()` for details on how this routine operates. 6262 6263 Level: intermediate 6264 6265 .seealso: `MatZeroRows()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6266 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6267 @*/ 6268 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6269 { 6270 PetscInt numRows = 0; 6271 const PetscInt *rows = NULL; 6272 6273 PetscFunctionBegin; 6274 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6275 PetscValidType(mat,1); 6276 if (is) { 6277 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6278 PetscCall(ISGetLocalSize(is,&numRows)); 6279 PetscCall(ISGetIndices(is,&rows)); 6280 } 6281 PetscCall(MatZeroRows(mat,numRows,rows,diag,x,b)); 6282 if (is) { 6283 PetscCall(ISRestoreIndices(is,&rows)); 6284 } 6285 PetscFunctionReturn(0); 6286 } 6287 6288 /*@ 6289 MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal) 6290 of a set of rows of a matrix. These rows must be local to the process. 6291 6292 Collective on Mat 6293 6294 Input Parameters: 6295 + mat - the matrix 6296 . numRows - the number of rows to remove 6297 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 6298 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6299 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6300 - b - optional vector of right hand side, that will be adjusted by provided solution 6301 6302 Notes: 6303 See `MatZeroRows()` for details on how this routine operates. 6304 6305 The grid coordinates are across the entire grid, not just the local portion 6306 6307 In Fortran idxm and idxn should be declared as 6308 $ MatStencil idxm(4,m) 6309 and the values inserted using 6310 $ idxm(MatStencil_i,1) = i 6311 $ idxm(MatStencil_j,1) = j 6312 $ idxm(MatStencil_k,1) = k 6313 $ idxm(MatStencil_c,1) = c 6314 etc 6315 6316 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6317 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6318 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6319 DM_BOUNDARY_PERIODIC boundary type. 6320 6321 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 6322 a single value per point) you can skip filling those indices. 6323 6324 Level: intermediate 6325 6326 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsl()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6327 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6328 @*/ 6329 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 6330 { 6331 PetscInt dim = mat->stencil.dim; 6332 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 6333 PetscInt *dims = mat->stencil.dims+1; 6334 PetscInt *starts = mat->stencil.starts; 6335 PetscInt *dxm = (PetscInt*) rows; 6336 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6337 6338 PetscFunctionBegin; 6339 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6340 PetscValidType(mat,1); 6341 if (numRows) PetscValidPointer(rows,3); 6342 6343 PetscCall(PetscMalloc1(numRows, &jdxm)); 6344 for (i = 0; i < numRows; ++i) { 6345 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6346 for (j = 0; j < 3-sdim; ++j) dxm++; 6347 /* Local index in X dir */ 6348 tmp = *dxm++ - starts[0]; 6349 /* Loop over remaining dimensions */ 6350 for (j = 0; j < dim-1; ++j) { 6351 /* If nonlocal, set index to be negative */ 6352 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6353 /* Update local index */ 6354 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6355 } 6356 /* Skip component slot if necessary */ 6357 if (mat->stencil.noc) dxm++; 6358 /* Local row number */ 6359 if (tmp >= 0) { 6360 jdxm[numNewRows++] = tmp; 6361 } 6362 } 6363 PetscCall(MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b)); 6364 PetscCall(PetscFree(jdxm)); 6365 PetscFunctionReturn(0); 6366 } 6367 6368 /*@ 6369 MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal) 6370 of a set of rows and columns of a matrix. 6371 6372 Collective on Mat 6373 6374 Input Parameters: 6375 + mat - the matrix 6376 . numRows - the number of rows/columns to remove 6377 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 6378 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6379 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6380 - b - optional vector of right hand side, that will be adjusted by provided solution 6381 6382 Notes: 6383 See `MatZeroRowsColumns()` for details on how this routine operates. 6384 6385 The grid coordinates are across the entire grid, not just the local portion 6386 6387 In Fortran idxm and idxn should be declared as 6388 $ MatStencil idxm(4,m) 6389 and the values inserted using 6390 $ idxm(MatStencil_i,1) = i 6391 $ idxm(MatStencil_j,1) = j 6392 $ idxm(MatStencil_k,1) = k 6393 $ idxm(MatStencil_c,1) = c 6394 etc 6395 6396 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6397 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6398 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6399 DM_BOUNDARY_PERIODIC boundary type. 6400 6401 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 6402 a single value per point) you can skip filling those indices. 6403 6404 Level: intermediate 6405 6406 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6407 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRows()` 6408 @*/ 6409 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 6410 { 6411 PetscInt dim = mat->stencil.dim; 6412 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 6413 PetscInt *dims = mat->stencil.dims+1; 6414 PetscInt *starts = mat->stencil.starts; 6415 PetscInt *dxm = (PetscInt*) rows; 6416 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6417 6418 PetscFunctionBegin; 6419 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6420 PetscValidType(mat,1); 6421 if (numRows) PetscValidPointer(rows,3); 6422 6423 PetscCall(PetscMalloc1(numRows, &jdxm)); 6424 for (i = 0; i < numRows; ++i) { 6425 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6426 for (j = 0; j < 3-sdim; ++j) dxm++; 6427 /* Local index in X dir */ 6428 tmp = *dxm++ - starts[0]; 6429 /* Loop over remaining dimensions */ 6430 for (j = 0; j < dim-1; ++j) { 6431 /* If nonlocal, set index to be negative */ 6432 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6433 /* Update local index */ 6434 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6435 } 6436 /* Skip component slot if necessary */ 6437 if (mat->stencil.noc) dxm++; 6438 /* Local row number */ 6439 if (tmp >= 0) { 6440 jdxm[numNewRows++] = tmp; 6441 } 6442 } 6443 PetscCall(MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b)); 6444 PetscCall(PetscFree(jdxm)); 6445 PetscFunctionReturn(0); 6446 } 6447 6448 /*@C 6449 MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal) 6450 of a set of rows of a matrix; using local numbering of rows. 6451 6452 Collective on Mat 6453 6454 Input Parameters: 6455 + mat - the matrix 6456 . numRows - the number of rows to remove 6457 . rows - the local row indices 6458 . diag - value put in all diagonals of eliminated rows 6459 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6460 - b - optional vector of right hand side, that will be adjusted by provided solution 6461 6462 Notes: 6463 Before calling `MatZeroRowsLocal()`, the user must first set the 6464 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6465 6466 See `MatZeroRows()` for details on how this routine operates. 6467 6468 Level: intermediate 6469 6470 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRows()`, `MatSetOption()`, 6471 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6472 @*/ 6473 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6474 { 6475 PetscFunctionBegin; 6476 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6477 PetscValidType(mat,1); 6478 if (numRows) PetscValidIntPointer(rows,3); 6479 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6480 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6481 MatCheckPreallocated(mat,1); 6482 6483 if (mat->ops->zerorowslocal) { 6484 PetscCall((*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b)); 6485 } else { 6486 IS is, newis; 6487 const PetscInt *newRows; 6488 6489 PetscCheck(mat->rmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6490 PetscCall(ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is)); 6491 PetscCall(ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis)); 6492 PetscCall(ISGetIndices(newis,&newRows)); 6493 PetscCall((*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b)); 6494 PetscCall(ISRestoreIndices(newis,&newRows)); 6495 PetscCall(ISDestroy(&newis)); 6496 PetscCall(ISDestroy(&is)); 6497 } 6498 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6499 PetscFunctionReturn(0); 6500 } 6501 6502 /*@ 6503 MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal) 6504 of a set of rows of a matrix; using local numbering of rows. 6505 6506 Collective on Mat 6507 6508 Input Parameters: 6509 + mat - the matrix 6510 . is - index set of rows to remove 6511 . diag - value put in all diagonals of eliminated rows 6512 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6513 - b - optional vector of right hand side, that will be adjusted by provided solution 6514 6515 Notes: 6516 Before calling `MatZeroRowsLocalIS()`, the user must first set the 6517 local-to-global mapping by calling `MatSetLocalToGlobalMapping()`. 6518 6519 See `MatZeroRows()` for details on how this routine operates. 6520 6521 Level: intermediate 6522 6523 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRows()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6524 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6525 @*/ 6526 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6527 { 6528 PetscInt numRows; 6529 const PetscInt *rows; 6530 6531 PetscFunctionBegin; 6532 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6533 PetscValidType(mat,1); 6534 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6535 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6536 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6537 MatCheckPreallocated(mat,1); 6538 6539 PetscCall(ISGetLocalSize(is,&numRows)); 6540 PetscCall(ISGetIndices(is,&rows)); 6541 PetscCall(MatZeroRowsLocal(mat,numRows,rows,diag,x,b)); 6542 PetscCall(ISRestoreIndices(is,&rows)); 6543 PetscFunctionReturn(0); 6544 } 6545 6546 /*@ 6547 MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal) 6548 of a set of rows and columns of a matrix; using local numbering of rows. 6549 6550 Collective on Mat 6551 6552 Input Parameters: 6553 + mat - the matrix 6554 . numRows - the number of rows to remove 6555 . rows - the global row indices 6556 . diag - value put in all diagonals of eliminated rows 6557 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6558 - b - optional vector of right hand side, that will be adjusted by provided solution 6559 6560 Notes: 6561 Before calling MatZeroRowsColumnsLocal(), the user must first set the 6562 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6563 6564 See `MatZeroRowsColumns()` for details on how this routine operates. 6565 6566 Level: intermediate 6567 6568 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6569 `MatZeroRows()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6570 @*/ 6571 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6572 { 6573 IS is, newis; 6574 const PetscInt *newRows; 6575 6576 PetscFunctionBegin; 6577 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6578 PetscValidType(mat,1); 6579 if (numRows) PetscValidIntPointer(rows,3); 6580 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6581 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6582 MatCheckPreallocated(mat,1); 6583 6584 PetscCheck(mat->cmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6585 PetscCall(ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is)); 6586 PetscCall(ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis)); 6587 PetscCall(ISGetIndices(newis,&newRows)); 6588 PetscCall((*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b)); 6589 PetscCall(ISRestoreIndices(newis,&newRows)); 6590 PetscCall(ISDestroy(&newis)); 6591 PetscCall(ISDestroy(&is)); 6592 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6593 PetscFunctionReturn(0); 6594 } 6595 6596 /*@ 6597 MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal) 6598 of a set of rows and columns of a matrix; using local numbering of rows. 6599 6600 Collective on Mat 6601 6602 Input Parameters: 6603 + mat - the matrix 6604 . is - index set of rows to remove 6605 . diag - value put in all diagonals of eliminated rows 6606 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6607 - b - optional vector of right hand side, that will be adjusted by provided solution 6608 6609 Notes: 6610 Before calling `MatZeroRowsColumnsLocalIS()`, the user must first set the 6611 local-to-global mapping by calling `MatSetLocalToGlobalMapping()`. 6612 6613 See `MatZeroRowsColumns()` for details on how this routine operates. 6614 6615 Level: intermediate 6616 6617 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6618 `MatZeroRowsColumnsLocal()`, `MatZeroRows()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6619 @*/ 6620 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6621 { 6622 PetscInt numRows; 6623 const PetscInt *rows; 6624 6625 PetscFunctionBegin; 6626 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6627 PetscValidType(mat,1); 6628 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6629 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6630 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6631 MatCheckPreallocated(mat,1); 6632 6633 PetscCall(ISGetLocalSize(is,&numRows)); 6634 PetscCall(ISGetIndices(is,&rows)); 6635 PetscCall(MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b)); 6636 PetscCall(ISRestoreIndices(is,&rows)); 6637 PetscFunctionReturn(0); 6638 } 6639 6640 /*@C 6641 MatGetSize - Returns the numbers of rows and columns in a matrix. 6642 6643 Not Collective 6644 6645 Input Parameter: 6646 . mat - the matrix 6647 6648 Output Parameters: 6649 + m - the number of global rows 6650 - n - the number of global columns 6651 6652 Note: both output parameters can be NULL on input. 6653 6654 Level: beginner 6655 6656 .seealso: `MatGetLocalSize()` 6657 @*/ 6658 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n) 6659 { 6660 PetscFunctionBegin; 6661 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6662 if (m) *m = mat->rmap->N; 6663 if (n) *n = mat->cmap->N; 6664 PetscFunctionReturn(0); 6665 } 6666 6667 /*@C 6668 MatGetLocalSize - For most matrix formats, excluding `MATELEMENTAL` and `MATSCALAPACK`, Returns the number of local rows and local columns 6669 of a matrix. For all matrices this is the local size of the left and right vectors as returned by MatCreateVecs(). 6670 6671 Not Collective 6672 6673 Input Parameter: 6674 . mat - the matrix 6675 6676 Output Parameters: 6677 + m - the number of local rows, use `NULL` to not obtain this value 6678 - n - the number of local columns, use `NULL` to not obtain this value 6679 6680 Level: beginner 6681 6682 .seealso: `MatGetSize()` 6683 @*/ 6684 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n) 6685 { 6686 PetscFunctionBegin; 6687 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6688 if (m) PetscValidIntPointer(m,2); 6689 if (n) PetscValidIntPointer(n,3); 6690 if (m) *m = mat->rmap->n; 6691 if (n) *n = mat->cmap->n; 6692 PetscFunctionReturn(0); 6693 } 6694 6695 /*@C 6696 MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies this matrix by that are owned by 6697 this processor. (The columns of the "diagonal block" for most sparse matrix formats). See :any:`<sec_matlayout>` for details on matrix layouts. 6698 6699 Not Collective, unless matrix has not been allocated, then collective on Mat 6700 6701 Input Parameter: 6702 . mat - the matrix 6703 6704 Output Parameters: 6705 + m - the global index of the first local column, use `NULL` to not obtain this value 6706 - n - one more than the global index of the last local column, use `NULL` to not obtain this value 6707 6708 Level: developer 6709 6710 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRanges()`, `MatGetOwnershipRangesColumn()`, `PetscLayout` 6711 6712 @*/ 6713 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n) 6714 { 6715 PetscFunctionBegin; 6716 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6717 PetscValidType(mat,1); 6718 if (m) PetscValidIntPointer(m,2); 6719 if (n) PetscValidIntPointer(n,3); 6720 MatCheckPreallocated(mat,1); 6721 if (m) *m = mat->cmap->rstart; 6722 if (n) *n = mat->cmap->rend; 6723 PetscFunctionReturn(0); 6724 } 6725 6726 /*@C 6727 MatGetOwnershipRange - For matrices that own values by row, excludes `MATELEMENTAL` and `MATSCALAPACK`, returns the range of matrix rows owned by 6728 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 6729 vector product with this matrix. See :any:`<sec_matlayout>` for details on matrix layouts 6730 6731 Not Collective 6732 6733 Input Parameter: 6734 . mat - the matrix 6735 6736 Output Parameters: 6737 + m - the global index of the first local row, use `NULL` to not obtain this value 6738 - n - one more than the global index of the last local row, use `NULL` to not obtain this value 6739 6740 Note: 6741 This function requires that the matrix be preallocated. If you have not preallocated, consider using 6742 `PetscSplitOwnership`(`MPI_Comm` comm, `PetscInt` *n, `PetscInt` *N) 6743 and then `MPI_Scan()` to calculate prefix sums of the local sizes. 6744 6745 Level: beginner 6746 6747 .seealso: `MatGetOwnershipRanges()`, `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRangesColumn()`, `PetscSplitOwnership()`, `PetscSplitOwnershipBlock()`, 6748 `PetscLayout` 6749 6750 @*/ 6751 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n) 6752 { 6753 PetscFunctionBegin; 6754 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6755 PetscValidType(mat,1); 6756 if (m) PetscValidIntPointer(m,2); 6757 if (n) PetscValidIntPointer(n,3); 6758 MatCheckPreallocated(mat,1); 6759 if (m) *m = mat->rmap->rstart; 6760 if (n) *n = mat->rmap->rend; 6761 PetscFunctionReturn(0); 6762 } 6763 6764 /*@C 6765 MatGetOwnershipRanges - For matrices that own values by row, excludes `MATELEMENTAL` and `MATSCALAPACK`, returns the range of matrix rows owned by 6766 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 6767 vector product with this matrix. See :any:`<sec_matlayout>` for details on matrix layouts 6768 6769 Not Collective, unless matrix has not been allocated, then collective on Mat 6770 6771 Input Parameters: 6772 . mat - the matrix 6773 6774 Output Parameters: 6775 . ranges - start of each processors portion plus one more than the total length at the end 6776 6777 Level: beginner 6778 6779 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRangesColumn()`, `PetscLayout` 6780 6781 @*/ 6782 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges) 6783 { 6784 PetscFunctionBegin; 6785 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6786 PetscValidType(mat,1); 6787 MatCheckPreallocated(mat,1); 6788 PetscCall(PetscLayoutGetRanges(mat->rmap,ranges)); 6789 PetscFunctionReturn(0); 6790 } 6791 6792 /*@C 6793 MatGetOwnershipRangesColumn - Returns the ranges of matrix columns associated with rows of a vector one multiplies this vector by that are owned by 6794 each processor. (The columns of the "diagonal blocks", for most sparse matrix formats). See :any:`<sec_matlayout>` for details on matrix layouts. 6795 6796 Not Collective, unless matrix has not been allocated, then collective on Mat 6797 6798 Input Parameters: 6799 . mat - the matrix 6800 6801 Output Parameters: 6802 . ranges - start of each processors portion plus one more then the total length at the end 6803 6804 Level: beginner 6805 6806 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRanges()` 6807 6808 @*/ 6809 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges) 6810 { 6811 PetscFunctionBegin; 6812 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6813 PetscValidType(mat,1); 6814 MatCheckPreallocated(mat,1); 6815 PetscCall(PetscLayoutGetRanges(mat->cmap,ranges)); 6816 PetscFunctionReturn(0); 6817 } 6818 6819 /*@C 6820 MatGetOwnershipIS - Get row and column ownership of a matrices' values as index sets. For most matrices, excluding `MATELEMENTAL` and `MATSCALAPACK`, this 6821 corresponds to values returned by `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`. For `MATELEMENTAL` and `MATSCALAPACK` the ownership 6822 is more complicated. See :any:`<sec_matlayout>` for details on matrix layouts. 6823 6824 Not Collective 6825 6826 Input Parameter: 6827 . A - matrix 6828 6829 Output Parameters: 6830 + rows - rows in which this process owns elements, , use `NULL` to not obtain this value 6831 - cols - columns in which this process owns elements, use `NULL` to not obtain this value 6832 6833 Level: intermediate 6834 6835 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`, `MatSetValues()`, ``MATELEMENTAL``, ``MATSCALAPACK`` 6836 @*/ 6837 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols) 6838 { 6839 PetscErrorCode (*f)(Mat,IS*,IS*); 6840 6841 PetscFunctionBegin; 6842 MatCheckPreallocated(A,1); 6843 PetscCall(PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f)); 6844 if (f) { 6845 PetscCall((*f)(A,rows,cols)); 6846 } else { /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */ 6847 if (rows) PetscCall(ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows)); 6848 if (cols) PetscCall(ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols)); 6849 } 6850 PetscFunctionReturn(0); 6851 } 6852 6853 /*@C 6854 MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix. 6855 Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric() 6856 to complete the factorization. 6857 6858 Collective on Mat 6859 6860 Input Parameters: 6861 + mat - the matrix 6862 . row - row permutation 6863 . column - column permutation 6864 - info - structure containing 6865 $ levels - number of levels of fill. 6866 $ expected fill - as ratio of original fill. 6867 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 6868 missing diagonal entries) 6869 6870 Output Parameters: 6871 . fact - new matrix that has been symbolically factored 6872 6873 Notes: 6874 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 6875 6876 Most users should employ the simplified KSP interface for linear solvers 6877 instead of working directly with matrix algebra routines such as this. 6878 See, e.g., KSPCreate(). 6879 6880 Level: developer 6881 6882 .seealso: `MatLUFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()` 6883 `MatGetOrdering()`, `MatFactorInfo` 6884 6885 Note: this uses the definition of level of fill as in Y. Saad, 2003 6886 6887 Developer Note: fortran interface is not autogenerated as the f90 6888 interface definition cannot be generated correctly [due to MatFactorInfo] 6889 6890 References: 6891 . * - Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6892 @*/ 6893 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 6894 { 6895 PetscFunctionBegin; 6896 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 6897 PetscValidType(mat,2); 6898 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,3); 6899 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,4); 6900 PetscValidPointer(info,5); 6901 PetscValidPointer(fact,1); 6902 PetscCheck(info->levels >= 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %" PetscInt_FMT,(PetscInt)info->levels); 6903 PetscCheck(info->fill >= 1.0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6904 if (!fact->ops->ilufactorsymbolic) { 6905 MatSolverType stype; 6906 PetscCall(MatFactorGetSolverType(fact,&stype)); 6907 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver type %s",((PetscObject)mat)->type_name,stype); 6908 } 6909 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6910 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6911 MatCheckPreallocated(mat,2); 6912 6913 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0)); 6914 PetscCall((fact->ops->ilufactorsymbolic)(fact,mat,row,col,info)); 6915 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0)); 6916 PetscFunctionReturn(0); 6917 } 6918 6919 /*@C 6920 MatICCFactorSymbolic - Performs symbolic incomplete 6921 Cholesky factorization for a symmetric matrix. Use 6922 MatCholeskyFactorNumeric() to complete the factorization. 6923 6924 Collective on Mat 6925 6926 Input Parameters: 6927 + mat - the matrix 6928 . perm - row and column permutation 6929 - info - structure containing 6930 $ levels - number of levels of fill. 6931 $ expected fill - as ratio of original fill. 6932 6933 Output Parameter: 6934 . fact - the factored matrix 6935 6936 Notes: 6937 Most users should employ the KSP interface for linear solvers 6938 instead of working directly with matrix algebra routines such as this. 6939 See, e.g., KSPCreate(). 6940 6941 Level: developer 6942 6943 .seealso: `MatCholeskyFactorNumeric()`, `MatCholeskyFactor()`, `MatFactorInfo` 6944 6945 Note: this uses the definition of level of fill as in Y. Saad, 2003 6946 6947 Developer Note: fortran interface is not autogenerated as the f90 6948 interface definition cannot be generated correctly [due to MatFactorInfo] 6949 6950 References: 6951 . * - Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6952 @*/ 6953 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 6954 { 6955 PetscFunctionBegin; 6956 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 6957 PetscValidType(mat,2); 6958 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,3); 6959 PetscValidPointer(info,4); 6960 PetscValidPointer(fact,1); 6961 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6962 PetscCheck(info->levels >= 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %" PetscInt_FMT,(PetscInt) info->levels); 6963 PetscCheck(info->fill >= 1.0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6964 if (!(fact)->ops->iccfactorsymbolic) { 6965 MatSolverType stype; 6966 PetscCall(MatFactorGetSolverType(fact,&stype)); 6967 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver type %s",((PetscObject)mat)->type_name,stype); 6968 } 6969 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6970 MatCheckPreallocated(mat,2); 6971 6972 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0)); 6973 PetscCall((fact->ops->iccfactorsymbolic)(fact,mat,perm,info)); 6974 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0)); 6975 PetscFunctionReturn(0); 6976 } 6977 6978 /*@C 6979 MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat 6980 points to an array of valid matrices, they may be reused to store the new 6981 submatrices. 6982 6983 Collective on Mat 6984 6985 Input Parameters: 6986 + mat - the matrix 6987 . n - the number of submatrixes to be extracted (on this processor, may be zero) 6988 . irow, icol - index sets of rows and columns to extract 6989 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6990 6991 Output Parameter: 6992 . submat - the array of submatrices 6993 6994 Notes: 6995 MatCreateSubMatrices() can extract ONLY sequential submatrices 6996 (from both sequential and parallel matrices). Use MatCreateSubMatrix() 6997 to extract a parallel submatrix. 6998 6999 Some matrix types place restrictions on the row and column 7000 indices, such as that they be sorted or that they be equal to each other. 7001 7002 The index sets may not have duplicate entries. 7003 7004 When extracting submatrices from a parallel matrix, each processor can 7005 form a different submatrix by setting the rows and columns of its 7006 individual index sets according to the local submatrix desired. 7007 7008 When finished using the submatrices, the user should destroy 7009 them with MatDestroySubMatrices(). 7010 7011 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 7012 original matrix has not changed from that last call to MatCreateSubMatrices(). 7013 7014 This routine creates the matrices in submat; you should NOT create them before 7015 calling it. It also allocates the array of matrix pointers submat. 7016 7017 For BAIJ matrices the index sets must respect the block structure, that is if they 7018 request one row/column in a block, they must request all rows/columns that are in 7019 that block. For example, if the block size is 2 you cannot request just row 0 and 7020 column 0. 7021 7022 Fortran Note: 7023 The Fortran interface is slightly different from that given below; it 7024 requires one to pass in as submat a Mat (integer) array of size at least n+1. 7025 7026 Level: advanced 7027 7028 .seealso: `MatDestroySubMatrices()`, `MatCreateSubMatrix()`, `MatGetRow()`, `MatGetDiagonal()`, `MatReuse` 7029 @*/ 7030 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 7031 { 7032 PetscInt i; 7033 PetscBool eq; 7034 7035 PetscFunctionBegin; 7036 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7037 PetscValidType(mat,1); 7038 if (n) { 7039 PetscValidPointer(irow,3); 7040 for (i=0; i<n; i++) PetscValidHeaderSpecific(irow[i],IS_CLASSID,3); 7041 PetscValidPointer(icol,4); 7042 for (i=0; i<n; i++) PetscValidHeaderSpecific(icol[i],IS_CLASSID,4); 7043 } 7044 PetscValidPointer(submat,6); 7045 if (n && scall == MAT_REUSE_MATRIX) { 7046 PetscValidPointer(*submat,6); 7047 for (i=0; i<n; i++) PetscValidHeaderSpecific((*submat)[i],MAT_CLASSID,6); 7048 } 7049 PetscCheck(mat->ops->createsubmatrices,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7050 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7051 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7052 MatCheckPreallocated(mat,1); 7053 PetscCall(PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0)); 7054 PetscCall((*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat)); 7055 PetscCall(PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0)); 7056 for (i=0; i<n; i++) { 7057 (*submat)[i]->factortype = MAT_FACTOR_NONE; /* in case in place factorization was previously done on submatrix */ 7058 PetscCall(ISEqualUnsorted(irow[i],icol[i],&eq)); 7059 if (eq) { 7060 PetscCall(MatPropagateSymmetryOptions(mat,(*submat)[i])); 7061 } 7062 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 7063 if (mat->boundtocpu && mat->bindingpropagates) { 7064 PetscCall(MatBindToCPU((*submat)[i],PETSC_TRUE)); 7065 PetscCall(MatSetBindingPropagates((*submat)[i],PETSC_TRUE)); 7066 } 7067 #endif 7068 } 7069 PetscFunctionReturn(0); 7070 } 7071 7072 /*@C 7073 MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms). 7074 7075 Collective on Mat 7076 7077 Input Parameters: 7078 + mat - the matrix 7079 . n - the number of submatrixes to be extracted 7080 . irow, icol - index sets of rows and columns to extract 7081 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 7082 7083 Output Parameter: 7084 . submat - the array of submatrices 7085 7086 Level: advanced 7087 7088 .seealso: `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRow()`, `MatGetDiagonal()`, `MatReuse` 7089 @*/ 7090 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 7091 { 7092 PetscInt i; 7093 PetscBool eq; 7094 7095 PetscFunctionBegin; 7096 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7097 PetscValidType(mat,1); 7098 if (n) { 7099 PetscValidPointer(irow,3); 7100 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 7101 PetscValidPointer(icol,4); 7102 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 7103 } 7104 PetscValidPointer(submat,6); 7105 if (n && scall == MAT_REUSE_MATRIX) { 7106 PetscValidPointer(*submat,6); 7107 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 7108 } 7109 PetscCheck(mat->ops->createsubmatricesmpi,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7110 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7111 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7112 MatCheckPreallocated(mat,1); 7113 7114 PetscCall(PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0)); 7115 PetscCall((*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat)); 7116 PetscCall(PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0)); 7117 for (i=0; i<n; i++) { 7118 PetscCall(ISEqualUnsorted(irow[i],icol[i],&eq)); 7119 if (eq) { 7120 PetscCall(MatPropagateSymmetryOptions(mat,(*submat)[i])); 7121 } 7122 } 7123 PetscFunctionReturn(0); 7124 } 7125 7126 /*@C 7127 MatDestroyMatrices - Destroys an array of matrices. 7128 7129 Collective on Mat 7130 7131 Input Parameters: 7132 + n - the number of local matrices 7133 - mat - the matrices (note that this is a pointer to the array of matrices) 7134 7135 Level: advanced 7136 7137 Notes: 7138 Frees not only the matrices, but also the array that contains the matrices 7139 In Fortran will not free the array. 7140 7141 .seealso: `MatCreateSubMatrices()` `MatDestroySubMatrices()` 7142 @*/ 7143 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[]) 7144 { 7145 PetscInt i; 7146 7147 PetscFunctionBegin; 7148 if (!*mat) PetscFunctionReturn(0); 7149 PetscCheck(n >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %" PetscInt_FMT,n); 7150 PetscValidPointer(mat,2); 7151 7152 for (i=0; i<n; i++) { 7153 PetscCall(MatDestroy(&(*mat)[i])); 7154 } 7155 7156 /* memory is allocated even if n = 0 */ 7157 PetscCall(PetscFree(*mat)); 7158 PetscFunctionReturn(0); 7159 } 7160 7161 /*@C 7162 MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices(). 7163 7164 Collective on Mat 7165 7166 Input Parameters: 7167 + n - the number of local matrices 7168 - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling 7169 sequence of MatCreateSubMatrices()) 7170 7171 Level: advanced 7172 7173 Notes: 7174 Frees not only the matrices, but also the array that contains the matrices 7175 In Fortran will not free the array. 7176 7177 .seealso: `MatCreateSubMatrices()` 7178 @*/ 7179 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[]) 7180 { 7181 Mat mat0; 7182 7183 PetscFunctionBegin; 7184 if (!*mat) PetscFunctionReturn(0); 7185 /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */ 7186 PetscCheck(n >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %" PetscInt_FMT,n); 7187 PetscValidPointer(mat,2); 7188 7189 mat0 = (*mat)[0]; 7190 if (mat0 && mat0->ops->destroysubmatrices) { 7191 PetscCall((mat0->ops->destroysubmatrices)(n,mat)); 7192 } else { 7193 PetscCall(MatDestroyMatrices(n,mat)); 7194 } 7195 PetscFunctionReturn(0); 7196 } 7197 7198 /*@C 7199 MatGetSeqNonzeroStructure - Extracts the nonzero structure from a matrix and stores it, in its entirety, on each process 7200 7201 Collective on Mat 7202 7203 Input Parameters: 7204 . mat - the matrix 7205 7206 Output Parameter: 7207 . matstruct - the sequential matrix with the nonzero structure of mat 7208 7209 Level: intermediate 7210 7211 .seealso: `MatDestroySeqNonzeroStructure()`, `MatCreateSubMatrices()`, `MatDestroyMatrices()` 7212 @*/ 7213 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct) 7214 { 7215 PetscFunctionBegin; 7216 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7217 PetscValidPointer(matstruct,2); 7218 7219 PetscValidType(mat,1); 7220 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7221 MatCheckPreallocated(mat,1); 7222 7223 PetscCheck(mat->ops->getseqnonzerostructure,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s",((PetscObject)mat)->type_name); 7224 PetscCall(PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0)); 7225 PetscCall((*mat->ops->getseqnonzerostructure)(mat,matstruct)); 7226 PetscCall(PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0)); 7227 PetscFunctionReturn(0); 7228 } 7229 7230 /*@C 7231 MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure(). 7232 7233 Collective on Mat 7234 7235 Input Parameters: 7236 . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling 7237 sequence of MatGetSequentialNonzeroStructure()) 7238 7239 Level: advanced 7240 7241 Notes: 7242 Frees not only the matrices, but also the array that contains the matrices 7243 7244 .seealso: `MatGetSeqNonzeroStructure()` 7245 @*/ 7246 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat) 7247 { 7248 PetscFunctionBegin; 7249 PetscValidPointer(mat,1); 7250 PetscCall(MatDestroy(mat)); 7251 PetscFunctionReturn(0); 7252 } 7253 7254 /*@ 7255 MatIncreaseOverlap - Given a set of submatrices indicated by index sets, 7256 replaces the index sets by larger ones that represent submatrices with 7257 additional overlap. 7258 7259 Collective on Mat 7260 7261 Input Parameters: 7262 + mat - the matrix 7263 . n - the number of index sets 7264 . is - the array of index sets (these index sets will changed during the call) 7265 - ov - the additional overlap requested 7266 7267 Options Database: 7268 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7269 7270 Level: developer 7271 7272 Developer Note: 7273 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. 7274 7275 .seealso: `MatCreateSubMatrices()` 7276 @*/ 7277 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov) 7278 { 7279 PetscInt i,bs,cbs; 7280 7281 PetscFunctionBegin; 7282 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7283 PetscValidType(mat,1); 7284 PetscValidLogicalCollectiveInt(mat,n,2); 7285 PetscCheck(n >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %" PetscInt_FMT,n); 7286 if (n) { 7287 PetscValidPointer(is,3); 7288 for (i = 0; i < n; i++) PetscValidHeaderSpecific(is[i],IS_CLASSID,3); 7289 } 7290 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7291 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7292 MatCheckPreallocated(mat,1); 7293 7294 if (!ov || !n) PetscFunctionReturn(0); 7295 PetscCheck(mat->ops->increaseoverlap,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7296 PetscCall(PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0)); 7297 PetscCall((*mat->ops->increaseoverlap)(mat,n,is,ov)); 7298 PetscCall(PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0)); 7299 PetscCall(MatGetBlockSizes(mat,&bs,&cbs)); 7300 if (bs == cbs) { 7301 for (i=0; i<n; i++) { 7302 PetscCall(ISSetBlockSize(is[i],bs)); 7303 } 7304 } 7305 PetscFunctionReturn(0); 7306 } 7307 7308 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt); 7309 7310 /*@ 7311 MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across 7312 a sub communicator, replaces the index sets by larger ones that represent submatrices with 7313 additional overlap. 7314 7315 Collective on Mat 7316 7317 Input Parameters: 7318 + mat - the matrix 7319 . n - the number of index sets 7320 . is - the array of index sets (these index sets will changed during the call) 7321 - ov - the additional overlap requested 7322 7323 Options Database: 7324 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7325 7326 Level: developer 7327 7328 .seealso: `MatCreateSubMatrices()` 7329 @*/ 7330 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov) 7331 { 7332 PetscInt i; 7333 7334 PetscFunctionBegin; 7335 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7336 PetscValidType(mat,1); 7337 PetscCheck(n >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %" PetscInt_FMT,n); 7338 if (n) { 7339 PetscValidPointer(is,3); 7340 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 7341 } 7342 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7343 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7344 MatCheckPreallocated(mat,1); 7345 if (!ov) PetscFunctionReturn(0); 7346 PetscCall(PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0)); 7347 for (i=0; i<n; i++) { 7348 PetscCall(MatIncreaseOverlapSplit_Single(mat,&is[i],ov)); 7349 } 7350 PetscCall(PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0)); 7351 PetscFunctionReturn(0); 7352 } 7353 7354 /*@ 7355 MatGetBlockSize - Returns the matrix block size. 7356 7357 Not Collective 7358 7359 Input Parameter: 7360 . mat - the matrix 7361 7362 Output Parameter: 7363 . bs - block size 7364 7365 Notes: 7366 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7367 7368 If the block size has not been set yet this routine returns 1. 7369 7370 Level: intermediate 7371 7372 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSizes()` 7373 @*/ 7374 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs) 7375 { 7376 PetscFunctionBegin; 7377 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7378 PetscValidIntPointer(bs,2); 7379 *bs = PetscAbs(mat->rmap->bs); 7380 PetscFunctionReturn(0); 7381 } 7382 7383 /*@ 7384 MatGetBlockSizes - Returns the matrix block row and column sizes. 7385 7386 Not Collective 7387 7388 Input Parameter: 7389 . mat - the matrix 7390 7391 Output Parameters: 7392 + rbs - row block size 7393 - cbs - column block size 7394 7395 Notes: 7396 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7397 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7398 7399 If a block size has not been set yet this routine returns 1. 7400 7401 Level: intermediate 7402 7403 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSize()`, `MatSetBlockSizes()` 7404 @*/ 7405 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs) 7406 { 7407 PetscFunctionBegin; 7408 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7409 if (rbs) PetscValidIntPointer(rbs,2); 7410 if (cbs) PetscValidIntPointer(cbs,3); 7411 if (rbs) *rbs = PetscAbs(mat->rmap->bs); 7412 if (cbs) *cbs = PetscAbs(mat->cmap->bs); 7413 PetscFunctionReturn(0); 7414 } 7415 7416 /*@ 7417 MatSetBlockSize - Sets the matrix block size. 7418 7419 Logically Collective on Mat 7420 7421 Input Parameters: 7422 + mat - the matrix 7423 - bs - block size 7424 7425 Notes: 7426 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7427 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7428 7429 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size 7430 is compatible with the matrix local sizes. 7431 7432 Level: intermediate 7433 7434 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`, `MatGetBlockSizes()` 7435 @*/ 7436 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs) 7437 { 7438 PetscFunctionBegin; 7439 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7440 PetscValidLogicalCollectiveInt(mat,bs,2); 7441 PetscCall(MatSetBlockSizes(mat,bs,bs)); 7442 PetscFunctionReturn(0); 7443 } 7444 7445 typedef struct { 7446 PetscInt n; 7447 IS *is; 7448 Mat *mat; 7449 PetscObjectState nonzerostate; 7450 Mat C; 7451 } EnvelopeData; 7452 7453 static PetscErrorCode EnvelopeDataDestroy(EnvelopeData *edata) 7454 { 7455 for (PetscInt i=0; i<edata->n; i++) { 7456 PetscCall(ISDestroy(&edata->is[i])); 7457 } 7458 PetscCall(PetscFree(edata->is)); 7459 PetscCall(PetscFree(edata)); 7460 return 0; 7461 } 7462 7463 /* 7464 MatComputeVariableBlockEnvelope - Given a matrix whose nonzeros are in blocks along the diagonal this computes and stores 7465 the sizes of these blocks in the matrix. An individual block may lie over several processes. 7466 7467 Collective on mat 7468 7469 Input Parameter: 7470 . mat - the matrix 7471 7472 Notes: 7473 There can be zeros within the blocks 7474 7475 The blocks can overlap between processes, including laying on more than two processes 7476 7477 */ 7478 static PetscErrorCode MatComputeVariableBlockEnvelope(Mat mat) 7479 { 7480 PetscInt n,*sizes,*starts,i = 0,env = 0, tbs = 0, lblocks = 0,rstart,II,ln = 0,cnt = 0,cstart,cend; 7481 PetscInt *diag,*odiag,sc; 7482 VecScatter scatter; 7483 PetscScalar *seqv; 7484 const PetscScalar *parv; 7485 const PetscInt *ia,*ja; 7486 PetscBool set,flag,done; 7487 Mat AA = mat,A; 7488 MPI_Comm comm; 7489 PetscMPIInt rank,size,tag; 7490 MPI_Status status; 7491 PetscContainer container; 7492 EnvelopeData *edata; 7493 Vec seq,par; 7494 IS isglobal; 7495 7496 PetscFunctionBegin; 7497 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7498 PetscCall(MatIsSymmetricKnown(mat,&set,&flag)); 7499 if (!set || !flag) { 7500 /* TOO: only needs nonzero structure of transpose */ 7501 PetscCall(MatTranspose(mat,MAT_INITIAL_MATRIX,&AA)); 7502 PetscCall(MatAXPY(AA,1.0,mat,DIFFERENT_NONZERO_PATTERN)); 7503 } 7504 PetscCall(MatAIJGetLocalMat(AA,&A)); 7505 PetscCall(MatGetRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ia,&ja,&done)); 7506 PetscCheck(done,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Unable to get IJ structure from matrix"); 7507 7508 PetscCall(MatGetLocalSize(mat,&n,NULL)); 7509 PetscCall(PetscObjectGetNewTag((PetscObject)mat,&tag)); 7510 PetscCall(PetscObjectGetComm((PetscObject)mat,&comm)); 7511 PetscCallMPI(MPI_Comm_size(comm,&size)); 7512 PetscCallMPI(MPI_Comm_rank(comm,&rank)); 7513 7514 PetscCall(PetscMalloc2(n,&sizes,n,&starts)); 7515 7516 if (rank > 0) { 7517 PetscCallMPI(MPI_Recv(&env,1,MPIU_INT,rank-1,tag,comm,&status)); 7518 PetscCallMPI(MPI_Recv(&tbs,1,MPIU_INT,rank-1,tag,comm,&status)); 7519 } 7520 PetscCall(MatGetOwnershipRange(mat,&rstart,NULL)); 7521 for (i=0; i<n; i++) { 7522 env = PetscMax(env,ja[ia[i+1]-1]); 7523 II = rstart + i; 7524 if (env == II) { 7525 starts[lblocks] = tbs; 7526 sizes[lblocks++] = 1 + II - tbs; 7527 tbs = 1 + II; 7528 } 7529 } 7530 if (rank < size-1) { 7531 PetscCallMPI(MPI_Send(&env,1,MPIU_INT,rank+1,tag,comm)); 7532 PetscCallMPI(MPI_Send(&tbs,1,MPIU_INT,rank+1,tag,comm)); 7533 } 7534 7535 PetscCall(MatRestoreRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ia,&ja,&done)); 7536 if (!set || !flag) { 7537 PetscCall(MatDestroy(&AA)); 7538 } 7539 PetscCall(MatDestroy(&A)); 7540 7541 PetscCall(PetscNew(&edata)); 7542 PetscCall(MatGetNonzeroState(mat,&edata->nonzerostate)); 7543 edata->n = lblocks; 7544 /* create IS needed for extracting blocks from the original matrix */ 7545 PetscCall(PetscMalloc1(lblocks,&edata->is)); 7546 for (PetscInt i=0; i<lblocks; i++) { 7547 PetscCall(ISCreateStride(PETSC_COMM_SELF,sizes[i],starts[i],1,&edata->is[i])); 7548 } 7549 7550 /* Create the resulting inverse matrix structure with preallocation information */ 7551 PetscCall(MatCreate(PetscObjectComm((PetscObject)mat),&edata->C)); 7552 PetscCall(MatSetSizes(edata->C,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N)); 7553 PetscCall(MatSetBlockSizesFromMats(edata->C,mat,mat)); 7554 PetscCall(MatSetType(edata->C,MATAIJ)); 7555 7556 /* Communicate the start and end of each row, from each block to the correct rank */ 7557 /* TODO: Use PetscSF instead of VecScatter */ 7558 for (PetscInt i=0; i<lblocks; i++) ln += sizes[i]; 7559 PetscCall(VecCreateSeq(PETSC_COMM_SELF,2*ln,&seq)); 7560 PetscCall(VecGetArrayWrite(seq,&seqv)); 7561 for (PetscInt i=0; i<lblocks; i++) { 7562 for (PetscInt j=0; j<sizes[i]; j++) { 7563 seqv[cnt] = starts[i]; 7564 seqv[cnt+1] = starts[i] + sizes[i]; 7565 cnt += 2; 7566 } 7567 } 7568 PetscCall(VecRestoreArrayWrite(seq,&seqv)); 7569 PetscCallMPI(MPI_Scan(&cnt,&sc,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat))); 7570 sc -= cnt; 7571 PetscCall(VecCreateMPI(PetscObjectComm((PetscObject)mat),2*mat->rmap->n,2*mat->rmap->N,&par)); 7572 PetscCall(ISCreateStride(PETSC_COMM_SELF,cnt,sc,1,&isglobal)); 7573 PetscCall(VecScatterCreate(seq, NULL ,par, isglobal,&scatter)); 7574 PetscCall(ISDestroy(&isglobal)); 7575 PetscCall(VecScatterBegin(scatter,seq,par,INSERT_VALUES,SCATTER_FORWARD)); 7576 PetscCall(VecScatterEnd(scatter,seq,par,INSERT_VALUES,SCATTER_FORWARD)); 7577 PetscCall(VecScatterDestroy(&scatter)); 7578 PetscCall(VecDestroy(&seq)); 7579 PetscCall(MatGetOwnershipRangeColumn(mat,&cstart,&cend)); 7580 PetscCall(PetscMalloc2(mat->rmap->n,&diag,mat->rmap->n,&odiag)); 7581 PetscCall(VecGetArrayRead(par,&parv)); 7582 cnt = 0; 7583 PetscCall(MatGetSize(mat,NULL,&n)); 7584 for (PetscInt i=0; i<mat->rmap->n; i++) { 7585 PetscInt start,end,d = 0,od = 0; 7586 7587 start = (PetscInt)PetscRealPart(parv[cnt]); 7588 end = (PetscInt)PetscRealPart(parv[cnt+1]); 7589 cnt += 2; 7590 7591 if (start < cstart) {od += cstart - start + n - cend; d += cend - cstart;} 7592 else if (start < cend) {od += n - cend; d += cend - start;} 7593 else od += n - start; 7594 if (end <= cstart) {od -= cstart - end + n - cend; d -= cend - cstart;} 7595 else if (end < cend) {od -= n - cend; d -= cend - end;} 7596 else od -= n - end; 7597 7598 odiag[i] = od; 7599 diag[i] = d; 7600 } 7601 PetscCall(VecRestoreArrayRead(par,&parv)); 7602 PetscCall(VecDestroy(&par)); 7603 PetscCall(MatXAIJSetPreallocation(edata->C,mat->rmap->bs,diag,odiag,NULL,NULL)); 7604 PetscCall(PetscFree2(diag,odiag)); 7605 PetscCall(PetscFree2(sizes,starts)); 7606 7607 PetscCall(PetscContainerCreate(PETSC_COMM_SELF,&container)); 7608 PetscCall(PetscContainerSetPointer(container,edata)); 7609 PetscCall(PetscContainerSetUserDestroy(container,(PetscErrorCode (*)(void*))EnvelopeDataDestroy)); 7610 PetscCall(PetscObjectCompose((PetscObject)mat,"EnvelopeData",(PetscObject)container)); 7611 PetscCall(PetscObjectDereference((PetscObject)container)); 7612 PetscFunctionReturn(0); 7613 } 7614 7615 /*@ 7616 MatInvertVariableBlockEnvelope - set matrix C to be the inverted block diagonal of matrix A 7617 7618 Collective on Mat 7619 7620 Input Parameters: 7621 . A - the matrix 7622 7623 Output Parameters: 7624 . C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set. 7625 7626 Notes: 7627 For efficiency the matrix A should have all the nonzero entries clustered in smallish blocks along the diagonal. 7628 7629 Level: advanced 7630 7631 .seealso: MatInvertBlockDiagonal(), MatComputeBlockDiagonal() 7632 @*/ 7633 PetscErrorCode MatInvertVariableBlockEnvelope(Mat A,MatReuse reuse, Mat *C) 7634 { 7635 PetscContainer container; 7636 EnvelopeData *edata; 7637 PetscObjectState nonzerostate; 7638 7639 PetscFunctionBegin; 7640 PetscCall(PetscObjectQuery((PetscObject)A,"EnvelopeData",(PetscObject*)&container)); 7641 if (!container) { 7642 PetscCall(MatComputeVariableBlockEnvelope(A)); 7643 PetscCall(PetscObjectQuery((PetscObject)A,"EnvelopeData",(PetscObject*)&container)); 7644 } 7645 PetscCall(PetscContainerGetPointer(container,(void**)&edata)); 7646 PetscCall(MatGetNonzeroState(A,&nonzerostate)); 7647 PetscCheck(nonzerostate <= edata->nonzerostate,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Cannot handle changes to matrix nonzero structure"); 7648 PetscCheck(reuse != MAT_REUSE_MATRIX || *C == edata->C,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C matrix must be the same as previously output"); 7649 7650 PetscCall(MatCreateSubMatrices(A,edata->n,edata->is,edata->is,MAT_INITIAL_MATRIX,&edata->mat)); 7651 *C = edata->C; 7652 7653 for (PetscInt i=0; i<edata->n; i++) { 7654 Mat D; 7655 PetscScalar *dvalues; 7656 7657 PetscCall(MatConvert(edata->mat[i], MATSEQDENSE,MAT_INITIAL_MATRIX,&D)); 7658 PetscCall(MatSetOption(*C,MAT_ROW_ORIENTED,PETSC_FALSE)); 7659 PetscCall(MatSeqDenseInvert(D)); 7660 PetscCall(MatDenseGetArray(D,&dvalues)); 7661 PetscCall(MatSetValuesIS(*C,edata->is[i],edata->is[i],dvalues,INSERT_VALUES)); 7662 PetscCall(MatDestroy(&D)); 7663 } 7664 PetscCall(MatDestroySubMatrices(edata->n,&edata->mat)); 7665 PetscCall(MatAssemblyBegin(*C,MAT_FINAL_ASSEMBLY)); 7666 PetscCall(MatAssemblyEnd(*C,MAT_FINAL_ASSEMBLY)); 7667 PetscFunctionReturn(0); 7668 } 7669 7670 /*@ 7671 MatSetVariableBlockSizes - Sets diagonal point-blocks of the matrix that need not be of the same size 7672 7673 Logically Collective on Mat 7674 7675 Input Parameters: 7676 + mat - the matrix 7677 . nblocks - the number of blocks on this process, each block can only exist on a single process 7678 - bsizes - the block sizes 7679 7680 Notes: 7681 Currently used by PCVPBJACOBI for AIJ matrices 7682 7683 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. 7684 7685 Level: intermediate 7686 7687 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`, `MatGetBlockSizes()`, `MatGetVariableBlockSizes()`, `MatComputeVariableBlockEnvelope()`, `PCVPBJACOBI` 7688 @*/ 7689 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes) 7690 { 7691 PetscInt i,ncnt = 0, nlocal; 7692 7693 PetscFunctionBegin; 7694 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7695 PetscCheck(nblocks >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero"); 7696 PetscCall(MatGetLocalSize(mat,&nlocal,NULL)); 7697 for (i=0; i<nblocks; i++) ncnt += bsizes[i]; 7698 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); 7699 PetscCall(PetscFree(mat->bsizes)); 7700 mat->nblocks = nblocks; 7701 PetscCall(PetscMalloc1(nblocks,&mat->bsizes)); 7702 PetscCall(PetscArraycpy(mat->bsizes,bsizes,nblocks)); 7703 PetscFunctionReturn(0); 7704 } 7705 7706 /*@C 7707 MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size 7708 7709 Logically Collective on Mat 7710 7711 Input Parameter: 7712 . mat - the matrix 7713 7714 Output Parameters: 7715 + nblocks - the number of blocks on this process 7716 - bsizes - the block sizes 7717 7718 Notes: Currently not supported from Fortran 7719 7720 Level: intermediate 7721 7722 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`, `MatGetBlockSizes()`, `MatSetVariableBlockSizes()`, `MatComputeVariableBlockEnvelope()` 7723 @*/ 7724 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes) 7725 { 7726 PetscFunctionBegin; 7727 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7728 *nblocks = mat->nblocks; 7729 *bsizes = mat->bsizes; 7730 PetscFunctionReturn(0); 7731 } 7732 7733 /*@ 7734 MatSetBlockSizes - Sets the matrix block row and column sizes. 7735 7736 Logically Collective on Mat 7737 7738 Input Parameters: 7739 + mat - the matrix 7740 . rbs - row block size 7741 - cbs - column block size 7742 7743 Notes: 7744 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7745 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7746 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7747 7748 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes 7749 are compatible with the matrix local sizes. 7750 7751 The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs(). 7752 7753 Level: intermediate 7754 7755 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSize()`, `MatGetBlockSizes()` 7756 @*/ 7757 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs) 7758 { 7759 PetscFunctionBegin; 7760 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7761 PetscValidLogicalCollectiveInt(mat,rbs,2); 7762 PetscValidLogicalCollectiveInt(mat,cbs,3); 7763 if (mat->ops->setblocksizes) PetscCall((*mat->ops->setblocksizes)(mat,rbs,cbs)); 7764 if (mat->rmap->refcnt) { 7765 ISLocalToGlobalMapping l2g = NULL; 7766 PetscLayout nmap = NULL; 7767 7768 PetscCall(PetscLayoutDuplicate(mat->rmap,&nmap)); 7769 if (mat->rmap->mapping) { 7770 PetscCall(ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g)); 7771 } 7772 PetscCall(PetscLayoutDestroy(&mat->rmap)); 7773 mat->rmap = nmap; 7774 mat->rmap->mapping = l2g; 7775 } 7776 if (mat->cmap->refcnt) { 7777 ISLocalToGlobalMapping l2g = NULL; 7778 PetscLayout nmap = NULL; 7779 7780 PetscCall(PetscLayoutDuplicate(mat->cmap,&nmap)); 7781 if (mat->cmap->mapping) { 7782 PetscCall(ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g)); 7783 } 7784 PetscCall(PetscLayoutDestroy(&mat->cmap)); 7785 mat->cmap = nmap; 7786 mat->cmap->mapping = l2g; 7787 } 7788 PetscCall(PetscLayoutSetBlockSize(mat->rmap,rbs)); 7789 PetscCall(PetscLayoutSetBlockSize(mat->cmap,cbs)); 7790 PetscFunctionReturn(0); 7791 } 7792 7793 /*@ 7794 MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices 7795 7796 Logically Collective on Mat 7797 7798 Input Parameters: 7799 + mat - the matrix 7800 . fromRow - matrix from which to copy row block size 7801 - fromCol - matrix from which to copy column block size (can be same as fromRow) 7802 7803 Level: developer 7804 7805 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()` 7806 @*/ 7807 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol) 7808 { 7809 PetscFunctionBegin; 7810 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7811 PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2); 7812 PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3); 7813 if (fromRow->rmap->bs > 0) PetscCall(PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs)); 7814 if (fromCol->cmap->bs > 0) PetscCall(PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs)); 7815 PetscFunctionReturn(0); 7816 } 7817 7818 /*@ 7819 MatResidual - Default routine to calculate the residual. 7820 7821 Collective on Mat 7822 7823 Input Parameters: 7824 + mat - the matrix 7825 . b - the right-hand-side 7826 - x - the approximate solution 7827 7828 Output Parameter: 7829 . r - location to store the residual 7830 7831 Level: developer 7832 7833 .seealso: `PCMGSetResidual()` 7834 @*/ 7835 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r) 7836 { 7837 PetscFunctionBegin; 7838 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7839 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 7840 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 7841 PetscValidHeaderSpecific(r,VEC_CLASSID,4); 7842 PetscValidType(mat,1); 7843 MatCheckPreallocated(mat,1); 7844 PetscCall(PetscLogEventBegin(MAT_Residual,mat,0,0,0)); 7845 if (!mat->ops->residual) { 7846 PetscCall(MatMult(mat,x,r)); 7847 PetscCall(VecAYPX(r,-1.0,b)); 7848 } else { 7849 PetscCall((*mat->ops->residual)(mat,b,x,r)); 7850 } 7851 PetscCall(PetscLogEventEnd(MAT_Residual,mat,0,0,0)); 7852 PetscFunctionReturn(0); 7853 } 7854 7855 /*@C 7856 MatGetRowIJ - Returns the compressed row storage i and j indices for the local rows of a sparse matrix 7857 7858 Collective on Mat 7859 7860 Input Parameters: 7861 + mat - the matrix 7862 . shift - 0 or 1 indicating we want the indices starting at 0 or 1 7863 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized 7864 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7865 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7866 always used. 7867 7868 Output Parameters: 7869 + n - number of local rows in the (possibly compressed) matrix 7870 . ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix 7871 . ja - the column indices 7872 - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers 7873 are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set 7874 7875 Level: developer 7876 7877 Notes: 7878 You CANNOT change any of the ia[] or ja[] values. 7879 7880 Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values. 7881 7882 Fortran Notes: 7883 In Fortran use 7884 $ 7885 $ PetscInt ia(1), ja(1) 7886 $ PetscOffset iia, jja 7887 $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr) 7888 $ ! Access the ith and jth entries via ia(iia + i) and ja(jja + j) 7889 7890 or 7891 $ 7892 $ PetscInt, pointer :: ia(:),ja(:) 7893 $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr) 7894 $ ! Access the ith and jth entries via ia(i) and ja(j) 7895 7896 .seealso: `MatGetColumnIJ()`, `MatRestoreRowIJ()`, `MatSeqAIJGetArray()` 7897 @*/ 7898 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7899 { 7900 PetscFunctionBegin; 7901 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7902 PetscValidType(mat,1); 7903 if (n) PetscValidIntPointer(n,5); 7904 if (ia) PetscValidPointer(ia,6); 7905 if (ja) PetscValidPointer(ja,7); 7906 if (done) PetscValidBoolPointer(done,8); 7907 MatCheckPreallocated(mat,1); 7908 if (!mat->ops->getrowij && done) *done = PETSC_FALSE; 7909 else { 7910 if (done) *done = PETSC_TRUE; 7911 PetscCall(PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0)); 7912 PetscCall((*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done)); 7913 PetscCall(PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0)); 7914 } 7915 PetscFunctionReturn(0); 7916 } 7917 7918 /*@C 7919 MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices. 7920 7921 Collective on Mat 7922 7923 Input Parameters: 7924 + mat - the matrix 7925 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7926 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7927 symmetrized 7928 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7929 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7930 always used. 7931 . n - number of columns in the (possibly compressed) matrix 7932 . ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix 7933 - ja - the row indices 7934 7935 Output Parameters: 7936 . done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned 7937 7938 Level: developer 7939 7940 .seealso: `MatGetRowIJ()`, `MatRestoreColumnIJ()` 7941 @*/ 7942 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7943 { 7944 PetscFunctionBegin; 7945 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7946 PetscValidType(mat,1); 7947 PetscValidIntPointer(n,5); 7948 if (ia) PetscValidPointer(ia,6); 7949 if (ja) PetscValidPointer(ja,7); 7950 PetscValidBoolPointer(done,8); 7951 MatCheckPreallocated(mat,1); 7952 if (!mat->ops->getcolumnij) *done = PETSC_FALSE; 7953 else { 7954 *done = PETSC_TRUE; 7955 PetscCall((*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done)); 7956 } 7957 PetscFunctionReturn(0); 7958 } 7959 7960 /*@C 7961 MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with 7962 MatGetRowIJ(). 7963 7964 Collective on Mat 7965 7966 Input Parameters: 7967 + mat - the matrix 7968 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7969 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7970 symmetrized 7971 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7972 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7973 always used. 7974 . n - size of (possibly compressed) matrix 7975 . ia - the row pointers 7976 - ja - the column indices 7977 7978 Output Parameters: 7979 . done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7980 7981 Note: 7982 This routine zeros out n, ia, and ja. This is to prevent accidental 7983 us of the array after it has been restored. If you pass NULL, it will 7984 not zero the pointers. Use of ia or ja after MatRestoreRowIJ() is invalid. 7985 7986 Level: developer 7987 7988 .seealso: `MatGetRowIJ()`, `MatRestoreColumnIJ()` 7989 @*/ 7990 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7991 { 7992 PetscFunctionBegin; 7993 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7994 PetscValidType(mat,1); 7995 if (ia) PetscValidPointer(ia,6); 7996 if (ja) PetscValidPointer(ja,7); 7997 if (done) PetscValidBoolPointer(done,8); 7998 MatCheckPreallocated(mat,1); 7999 8000 if (!mat->ops->restorerowij && done) *done = PETSC_FALSE; 8001 else { 8002 if (done) *done = PETSC_TRUE; 8003 PetscCall((*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done)); 8004 if (n) *n = 0; 8005 if (ia) *ia = NULL; 8006 if (ja) *ja = NULL; 8007 } 8008 PetscFunctionReturn(0); 8009 } 8010 8011 /*@C 8012 MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with 8013 MatGetColumnIJ(). 8014 8015 Collective on Mat 8016 8017 Input Parameters: 8018 + mat - the matrix 8019 . shift - 1 or zero indicating we want the indices starting at 0 or 1 8020 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 8021 symmetrized 8022 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 8023 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 8024 always used. 8025 8026 Output Parameters: 8027 + n - size of (possibly compressed) matrix 8028 . ia - the column pointers 8029 . ja - the row indices 8030 - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 8031 8032 Level: developer 8033 8034 .seealso: `MatGetColumnIJ()`, `MatRestoreRowIJ()` 8035 @*/ 8036 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 8037 { 8038 PetscFunctionBegin; 8039 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8040 PetscValidType(mat,1); 8041 if (ia) PetscValidPointer(ia,6); 8042 if (ja) PetscValidPointer(ja,7); 8043 PetscValidBoolPointer(done,8); 8044 MatCheckPreallocated(mat,1); 8045 8046 if (!mat->ops->restorecolumnij) *done = PETSC_FALSE; 8047 else { 8048 *done = PETSC_TRUE; 8049 PetscCall((*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done)); 8050 if (n) *n = 0; 8051 if (ia) *ia = NULL; 8052 if (ja) *ja = NULL; 8053 } 8054 PetscFunctionReturn(0); 8055 } 8056 8057 /*@C 8058 MatColoringPatch -Used inside matrix coloring routines that 8059 use MatGetRowIJ() and/or MatGetColumnIJ(). 8060 8061 Collective on Mat 8062 8063 Input Parameters: 8064 + mat - the matrix 8065 . ncolors - max color value 8066 . n - number of entries in colorarray 8067 - colorarray - array indicating color for each column 8068 8069 Output Parameters: 8070 . iscoloring - coloring generated using colorarray information 8071 8072 Level: developer 8073 8074 .seealso: `MatGetRowIJ()`, `MatGetColumnIJ()` 8075 8076 @*/ 8077 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring) 8078 { 8079 PetscFunctionBegin; 8080 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8081 PetscValidType(mat,1); 8082 PetscValidIntPointer(colorarray,4); 8083 PetscValidPointer(iscoloring,5); 8084 MatCheckPreallocated(mat,1); 8085 8086 if (!mat->ops->coloringpatch) { 8087 PetscCall(ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring)); 8088 } else { 8089 PetscCall((*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring)); 8090 } 8091 PetscFunctionReturn(0); 8092 } 8093 8094 /*@ 8095 MatSetUnfactored - Resets a factored matrix to be treated as unfactored. 8096 8097 Logically Collective on Mat 8098 8099 Input Parameter: 8100 . mat - the factored matrix to be reset 8101 8102 Notes: 8103 This routine should be used only with factored matrices formed by in-place 8104 factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE 8105 format). This option can save memory, for example, when solving nonlinear 8106 systems with a matrix-free Newton-Krylov method and a matrix-based, in-place 8107 ILU(0) preconditioner. 8108 8109 Note that one can specify in-place ILU(0) factorization by calling 8110 .vb 8111 PCType(pc,PCILU); 8112 PCFactorSeUseInPlace(pc); 8113 .ve 8114 or by using the options -pc_type ilu -pc_factor_in_place 8115 8116 In-place factorization ILU(0) can also be used as a local 8117 solver for the blocks within the block Jacobi or additive Schwarz 8118 methods (runtime option: -sub_pc_factor_in_place). See Users-Manual: ch_pc 8119 for details on setting local solver options. 8120 8121 Most users should employ the simplified KSP interface for linear solvers 8122 instead of working directly with matrix algebra routines such as this. 8123 See, e.g., KSPCreate(). 8124 8125 Level: developer 8126 8127 .seealso: `PCFactorSetUseInPlace()`, `PCFactorGetUseInPlace()` 8128 8129 @*/ 8130 PetscErrorCode MatSetUnfactored(Mat mat) 8131 { 8132 PetscFunctionBegin; 8133 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8134 PetscValidType(mat,1); 8135 MatCheckPreallocated(mat,1); 8136 mat->factortype = MAT_FACTOR_NONE; 8137 if (!mat->ops->setunfactored) PetscFunctionReturn(0); 8138 PetscCall((*mat->ops->setunfactored)(mat)); 8139 PetscFunctionReturn(0); 8140 } 8141 8142 /*MC 8143 MatDenseGetArrayF90 - Accesses a matrix array from Fortran90. 8144 8145 Synopsis: 8146 MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 8147 8148 Not collective 8149 8150 Input Parameter: 8151 . x - matrix 8152 8153 Output Parameters: 8154 + xx_v - the Fortran90 pointer to the array 8155 - ierr - error code 8156 8157 Example of Usage: 8158 .vb 8159 PetscScalar, pointer xx_v(:,:) 8160 .... 8161 call MatDenseGetArrayF90(x,xx_v,ierr) 8162 a = xx_v(3) 8163 call MatDenseRestoreArrayF90(x,xx_v,ierr) 8164 .ve 8165 8166 Level: advanced 8167 8168 .seealso: `MatDenseRestoreArrayF90()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatSeqAIJGetArrayF90()` 8169 8170 M*/ 8171 8172 /*MC 8173 MatDenseRestoreArrayF90 - Restores a matrix array that has been 8174 accessed with MatDenseGetArrayF90(). 8175 8176 Synopsis: 8177 MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 8178 8179 Not collective 8180 8181 Input Parameters: 8182 + x - matrix 8183 - xx_v - the Fortran90 pointer to the array 8184 8185 Output Parameter: 8186 . ierr - error code 8187 8188 Example of Usage: 8189 .vb 8190 PetscScalar, pointer xx_v(:,:) 8191 .... 8192 call MatDenseGetArrayF90(x,xx_v,ierr) 8193 a = xx_v(3) 8194 call MatDenseRestoreArrayF90(x,xx_v,ierr) 8195 .ve 8196 8197 Level: advanced 8198 8199 .seealso: `MatDenseGetArrayF90()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatSeqAIJRestoreArrayF90()` 8200 8201 M*/ 8202 8203 /*MC 8204 MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90. 8205 8206 Synopsis: 8207 MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 8208 8209 Not collective 8210 8211 Input Parameter: 8212 . x - matrix 8213 8214 Output Parameters: 8215 + xx_v - the Fortran90 pointer to the array 8216 - ierr - error code 8217 8218 Example of Usage: 8219 .vb 8220 PetscScalar, pointer xx_v(:) 8221 .... 8222 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 8223 a = xx_v(3) 8224 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 8225 .ve 8226 8227 Level: advanced 8228 8229 .seealso: `MatSeqAIJRestoreArrayF90()`, `MatSeqAIJGetArray()`, `MatSeqAIJRestoreArray()`, `MatDenseGetArrayF90()` 8230 8231 M*/ 8232 8233 /*MC 8234 MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been 8235 accessed with MatSeqAIJGetArrayF90(). 8236 8237 Synopsis: 8238 MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 8239 8240 Not collective 8241 8242 Input Parameters: 8243 + x - matrix 8244 - xx_v - the Fortran90 pointer to the array 8245 8246 Output Parameter: 8247 . ierr - error code 8248 8249 Example of Usage: 8250 .vb 8251 PetscScalar, pointer xx_v(:) 8252 .... 8253 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 8254 a = xx_v(3) 8255 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 8256 .ve 8257 8258 Level: advanced 8259 8260 .seealso: `MatSeqAIJGetArrayF90()`, `MatSeqAIJGetArray()`, `MatSeqAIJRestoreArray()`, `MatDenseRestoreArrayF90()` 8261 8262 M*/ 8263 8264 /*@ 8265 MatCreateSubMatrix - Gets a single submatrix on the same number of processors 8266 as the original matrix. 8267 8268 Collective on Mat 8269 8270 Input Parameters: 8271 + mat - the original matrix 8272 . isrow - parallel IS containing the rows this processor should obtain 8273 . 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. 8274 - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 8275 8276 Output Parameter: 8277 . newmat - the new submatrix, of the same type as the old 8278 8279 Level: advanced 8280 8281 Notes: 8282 The submatrix will be able to be multiplied with vectors using the same layout as iscol. 8283 8284 Some matrix types place restrictions on the row and column indices, such 8285 as that they be sorted or that they be equal to each other. 8286 8287 The index sets may not have duplicate entries. 8288 8289 The first time this is called you should use a cll of MAT_INITIAL_MATRIX, 8290 the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls 8291 to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX 8292 will reuse the matrix generated the first time. You should call MatDestroy() on newmat when 8293 you are finished using it. 8294 8295 The communicator of the newly obtained matrix is ALWAYS the same as the communicator of 8296 the input matrix. 8297 8298 If iscol is NULL then all columns are obtained (not supported in Fortran). 8299 8300 Example usage: 8301 Consider the following 8x8 matrix with 34 non-zero values, that is 8302 assembled across 3 processors. Let's assume that proc0 owns 3 rows, 8303 proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown 8304 as follows: 8305 8306 .vb 8307 1 2 0 | 0 3 0 | 0 4 8308 Proc0 0 5 6 | 7 0 0 | 8 0 8309 9 0 10 | 11 0 0 | 12 0 8310 ------------------------------------- 8311 13 0 14 | 15 16 17 | 0 0 8312 Proc1 0 18 0 | 19 20 21 | 0 0 8313 0 0 0 | 22 23 0 | 24 0 8314 ------------------------------------- 8315 Proc2 25 26 27 | 0 0 28 | 29 0 8316 30 0 0 | 31 32 33 | 0 34 8317 .ve 8318 8319 Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is 8320 8321 .vb 8322 2 0 | 0 3 0 | 0 8323 Proc0 5 6 | 7 0 0 | 8 8324 ------------------------------- 8325 Proc1 18 0 | 19 20 21 | 0 8326 ------------------------------- 8327 Proc2 26 27 | 0 0 28 | 29 8328 0 0 | 31 32 33 | 0 8329 .ve 8330 8331 .seealso: `MatCreateSubMatrices()`, `MatCreateSubMatricesMPI()`, `MatCreateSubMatrixVirtual()`, `MatSubMatrixVirtualUpdate()` 8332 @*/ 8333 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat) 8334 { 8335 PetscMPIInt size; 8336 Mat *local; 8337 IS iscoltmp; 8338 PetscBool flg; 8339 8340 PetscFunctionBegin; 8341 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8342 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 8343 if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 8344 PetscValidPointer(newmat,5); 8345 if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5); 8346 PetscValidType(mat,1); 8347 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8348 PetscCheck(cll != MAT_IGNORE_MATRIX,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX"); 8349 8350 MatCheckPreallocated(mat,1); 8351 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 8352 8353 if (!iscol || isrow == iscol) { 8354 PetscBool stride; 8355 PetscMPIInt grabentirematrix = 0,grab; 8356 PetscCall(PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride)); 8357 if (stride) { 8358 PetscInt first,step,n,rstart,rend; 8359 PetscCall(ISStrideGetInfo(isrow,&first,&step)); 8360 if (step == 1) { 8361 PetscCall(MatGetOwnershipRange(mat,&rstart,&rend)); 8362 if (rstart == first) { 8363 PetscCall(ISGetLocalSize(isrow,&n)); 8364 if (n == rend-rstart) { 8365 grabentirematrix = 1; 8366 } 8367 } 8368 } 8369 } 8370 PetscCall(MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat))); 8371 if (grab) { 8372 PetscCall(PetscInfo(mat,"Getting entire matrix as submatrix\n")); 8373 if (cll == MAT_INITIAL_MATRIX) { 8374 *newmat = mat; 8375 PetscCall(PetscObjectReference((PetscObject)mat)); 8376 } 8377 PetscFunctionReturn(0); 8378 } 8379 } 8380 8381 if (!iscol) { 8382 PetscCall(ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp)); 8383 } else { 8384 iscoltmp = iscol; 8385 } 8386 8387 /* if original matrix is on just one processor then use submatrix generated */ 8388 if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) { 8389 PetscCall(MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat)); 8390 goto setproperties; 8391 } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) { 8392 PetscCall(MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local)); 8393 *newmat = *local; 8394 PetscCall(PetscFree(local)); 8395 goto setproperties; 8396 } else if (!mat->ops->createsubmatrix) { 8397 /* Create a new matrix type that implements the operation using the full matrix */ 8398 PetscCall(PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0)); 8399 switch (cll) { 8400 case MAT_INITIAL_MATRIX: 8401 PetscCall(MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat)); 8402 break; 8403 case MAT_REUSE_MATRIX: 8404 PetscCall(MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp)); 8405 break; 8406 default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX"); 8407 } 8408 PetscCall(PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0)); 8409 goto setproperties; 8410 } 8411 8412 PetscCheck(mat->ops->createsubmatrix,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8413 PetscCall(PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0)); 8414 PetscCall((*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat)); 8415 PetscCall(PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0)); 8416 8417 setproperties: 8418 PetscCall(ISEqualUnsorted(isrow,iscoltmp,&flg)); 8419 if (flg) PetscCall(MatPropagateSymmetryOptions(mat,*newmat)); 8420 if (!iscol) PetscCall(ISDestroy(&iscoltmp)); 8421 if (*newmat && cll == MAT_INITIAL_MATRIX) PetscCall(PetscObjectStateIncrease((PetscObject)*newmat)); 8422 PetscFunctionReturn(0); 8423 } 8424 8425 /*@ 8426 MatPropagateSymmetryOptions - Propagates symmetry options set on a matrix to another matrix 8427 8428 Not Collective 8429 8430 Input Parameters: 8431 + A - the matrix we wish to propagate options from 8432 - B - the matrix we wish to propagate options to 8433 8434 Level: beginner 8435 8436 Notes: 8437 Propagates the options associated to `MAT_SYMMETRY_ETERNAL`, `MAT_STRUCTURALLY_SYMMETRIC`, `MAT_HERMITIAN`, `MAT_SPD`, `MAT_SYMMETRIC`, and `MAT_STRUCTURAL_SYMMETRY_ETERNAL` 8438 8439 .seealso: `MatSetOption()`, `MatIsSymmetricKnown()`, `MatIsSPDKnown()`, `MatIsHermitianKnown()`, MatIsStructurallySymmetricKnown()` 8440 @*/ 8441 PetscErrorCode MatPropagateSymmetryOptions(Mat A, Mat B) 8442 { 8443 PetscFunctionBegin; 8444 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8445 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 8446 B->symmetry_eternal = A->symmetry_eternal; 8447 B->structural_symmetry_eternal = A->structural_symmetry_eternal; 8448 B->symmetric = A->symmetric; 8449 B->structurally_symmetric = A->structurally_symmetric; 8450 B->spd = A->spd; 8451 B->hermitian = A->hermitian; 8452 PetscFunctionReturn(0); 8453 } 8454 8455 /*@ 8456 MatStashSetInitialSize - sets the sizes of the matrix stash, that is 8457 used during the assembly process to store values that belong to 8458 other processors. 8459 8460 Not Collective 8461 8462 Input Parameters: 8463 + mat - the matrix 8464 . size - the initial size of the stash. 8465 - bsize - the initial size of the block-stash(if used). 8466 8467 Options Database Keys: 8468 + -matstash_initial_size <size> or <size0,size1,...sizep-1> 8469 - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1> 8470 8471 Level: intermediate 8472 8473 Notes: 8474 The block-stash is used for values set with MatSetValuesBlocked() while 8475 the stash is used for values set with MatSetValues() 8476 8477 Run with the option -info and look for output of the form 8478 MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs. 8479 to determine the appropriate value, MM, to use for size and 8480 MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs. 8481 to determine the value, BMM to use for bsize 8482 8483 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `Mat`, `MatStashGetInfo()` 8484 8485 @*/ 8486 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize) 8487 { 8488 PetscFunctionBegin; 8489 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8490 PetscValidType(mat,1); 8491 PetscCall(MatStashSetInitialSize_Private(&mat->stash,size)); 8492 PetscCall(MatStashSetInitialSize_Private(&mat->bstash,bsize)); 8493 PetscFunctionReturn(0); 8494 } 8495 8496 /*@ 8497 MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 8498 the matrix 8499 8500 Neighbor-wise Collective on Mat 8501 8502 Input Parameters: 8503 + mat - the matrix 8504 . x,y - the vectors 8505 - w - where the result is stored 8506 8507 Level: intermediate 8508 8509 Notes: 8510 w may be the same vector as y. 8511 8512 This allows one to use either the restriction or interpolation (its transpose) 8513 matrix to do the interpolation 8514 8515 .seealso: `MatMultAdd()`, `MatMultTransposeAdd()`, `MatRestrict()` 8516 8517 @*/ 8518 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w) 8519 { 8520 PetscInt M,N,Ny; 8521 8522 PetscFunctionBegin; 8523 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8524 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8525 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8526 PetscValidHeaderSpecific(w,VEC_CLASSID,4); 8527 PetscCall(MatGetSize(A,&M,&N)); 8528 PetscCall(VecGetSize(y,&Ny)); 8529 if (M == Ny) { 8530 PetscCall(MatMultAdd(A,x,y,w)); 8531 } else { 8532 PetscCall(MatMultTransposeAdd(A,x,y,w)); 8533 } 8534 PetscFunctionReturn(0); 8535 } 8536 8537 /*@ 8538 MatInterpolate - y = A*x or A'*x depending on the shape of 8539 the matrix 8540 8541 Neighbor-wise Collective on Mat 8542 8543 Input Parameters: 8544 + mat - the matrix 8545 - x,y - the vectors 8546 8547 Level: intermediate 8548 8549 Notes: 8550 This allows one to use either the restriction or interpolation (its transpose) 8551 matrix to do the interpolation 8552 8553 .seealso: `MatMultAdd()`, `MatMultTransposeAdd()`, `MatRestrict()` 8554 8555 @*/ 8556 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y) 8557 { 8558 PetscInt M,N,Ny; 8559 8560 PetscFunctionBegin; 8561 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8562 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8563 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8564 PetscCall(MatGetSize(A,&M,&N)); 8565 PetscCall(VecGetSize(y,&Ny)); 8566 if (M == Ny) { 8567 PetscCall(MatMult(A,x,y)); 8568 } else { 8569 PetscCall(MatMultTranspose(A,x,y)); 8570 } 8571 PetscFunctionReturn(0); 8572 } 8573 8574 /*@ 8575 MatRestrict - y = A*x or A'*x 8576 8577 Neighbor-wise Collective on Mat 8578 8579 Input Parameters: 8580 + mat - the matrix 8581 - x,y - the vectors 8582 8583 Level: intermediate 8584 8585 Notes: 8586 This allows one to use either the restriction or interpolation (its transpose) 8587 matrix to do the restriction 8588 8589 .seealso: `MatMultAdd()`, `MatMultTransposeAdd()`, `MatInterpolate()` 8590 8591 @*/ 8592 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y) 8593 { 8594 PetscInt M,N,Ny; 8595 8596 PetscFunctionBegin; 8597 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8598 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8599 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8600 PetscCall(MatGetSize(A,&M,&N)); 8601 PetscCall(VecGetSize(y,&Ny)); 8602 if (M == Ny) { 8603 PetscCall(MatMult(A,x,y)); 8604 } else { 8605 PetscCall(MatMultTranspose(A,x,y)); 8606 } 8607 PetscFunctionReturn(0); 8608 } 8609 8610 /*@ 8611 MatMatInterpolateAdd - Y = W + A*X or W + A'*X 8612 8613 Neighbor-wise Collective on Mat 8614 8615 Input Parameters: 8616 + mat - the matrix 8617 - w, x - the input dense matrices 8618 8619 Output Parameters: 8620 . y - the output dense matrix 8621 8622 Level: intermediate 8623 8624 Notes: 8625 This allows one to use either the restriction or interpolation (its transpose) 8626 matrix to do the interpolation. y matrix can be reused if already created with the proper sizes, 8627 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8628 8629 .seealso: `MatInterpolateAdd()`, `MatMatInterpolate()`, `MatMatRestrict()` 8630 8631 @*/ 8632 PetscErrorCode MatMatInterpolateAdd(Mat A,Mat x,Mat w,Mat *y) 8633 { 8634 PetscInt M,N,Mx,Nx,Mo,My = 0,Ny = 0; 8635 PetscBool trans = PETSC_TRUE; 8636 MatReuse reuse = MAT_INITIAL_MATRIX; 8637 8638 PetscFunctionBegin; 8639 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8640 PetscValidHeaderSpecific(x,MAT_CLASSID,2); 8641 PetscValidType(x,2); 8642 if (w) PetscValidHeaderSpecific(w,MAT_CLASSID,3); 8643 if (*y) PetscValidHeaderSpecific(*y,MAT_CLASSID,4); 8644 PetscCall(MatGetSize(A,&M,&N)); 8645 PetscCall(MatGetSize(x,&Mx,&Nx)); 8646 if (N == Mx) trans = PETSC_FALSE; 8647 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); 8648 Mo = trans ? N : M; 8649 if (*y) { 8650 PetscCall(MatGetSize(*y,&My,&Ny)); 8651 if (Mo == My && Nx == Ny) { reuse = MAT_REUSE_MATRIX; } 8652 else { 8653 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); 8654 PetscCall(MatDestroy(y)); 8655 } 8656 } 8657 8658 if (w && *y == w) { /* this is to minimize changes in PCMG */ 8659 PetscBool flg; 8660 8661 PetscCall(PetscObjectQuery((PetscObject)*y,"__MatMatIntAdd_w",(PetscObject*)&w)); 8662 if (w) { 8663 PetscInt My,Ny,Mw,Nw; 8664 8665 PetscCall(PetscObjectTypeCompare((PetscObject)*y,((PetscObject)w)->type_name,&flg)); 8666 PetscCall(MatGetSize(*y,&My,&Ny)); 8667 PetscCall(MatGetSize(w,&Mw,&Nw)); 8668 if (!flg || My != Mw || Ny != Nw) w = NULL; 8669 } 8670 if (!w) { 8671 PetscCall(MatDuplicate(*y,MAT_COPY_VALUES,&w)); 8672 PetscCall(PetscObjectCompose((PetscObject)*y,"__MatMatIntAdd_w",(PetscObject)w)); 8673 PetscCall(PetscLogObjectParent((PetscObject)*y,(PetscObject)w)); 8674 PetscCall(PetscObjectDereference((PetscObject)w)); 8675 } else { 8676 PetscCall(MatCopy(*y,w,UNKNOWN_NONZERO_PATTERN)); 8677 } 8678 } 8679 if (!trans) { 8680 PetscCall(MatMatMult(A,x,reuse,PETSC_DEFAULT,y)); 8681 } else { 8682 PetscCall(MatTransposeMatMult(A,x,reuse,PETSC_DEFAULT,y)); 8683 } 8684 if (w) PetscCall(MatAXPY(*y,1.0,w,UNKNOWN_NONZERO_PATTERN)); 8685 PetscFunctionReturn(0); 8686 } 8687 8688 /*@ 8689 MatMatInterpolate - Y = A*X or A'*X 8690 8691 Neighbor-wise Collective on Mat 8692 8693 Input Parameters: 8694 + mat - the matrix 8695 - x - the input dense matrix 8696 8697 Output Parameters: 8698 . y - the output dense matrix 8699 8700 Level: intermediate 8701 8702 Notes: 8703 This allows one to use either the restriction or interpolation (its transpose) 8704 matrix to do the interpolation. y matrix can be reused if already created with the proper sizes, 8705 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8706 8707 .seealso: `MatInterpolate()`, `MatRestrict()`, `MatMatRestrict()` 8708 8709 @*/ 8710 PetscErrorCode MatMatInterpolate(Mat A,Mat x,Mat *y) 8711 { 8712 PetscFunctionBegin; 8713 PetscCall(MatMatInterpolateAdd(A,x,NULL,y)); 8714 PetscFunctionReturn(0); 8715 } 8716 8717 /*@ 8718 MatMatRestrict - Y = A*X or A'*X 8719 8720 Neighbor-wise Collective on Mat 8721 8722 Input Parameters: 8723 + mat - the matrix 8724 - x - the input dense matrix 8725 8726 Output Parameters: 8727 . y - the output dense matrix 8728 8729 Level: intermediate 8730 8731 Notes: 8732 This allows one to use either the restriction or interpolation (its transpose) 8733 matrix to do the restriction. y matrix can be reused if already created with the proper sizes, 8734 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8735 8736 .seealso: `MatRestrict()`, `MatInterpolate()`, `MatMatInterpolate()` 8737 @*/ 8738 PetscErrorCode MatMatRestrict(Mat A,Mat x,Mat *y) 8739 { 8740 PetscFunctionBegin; 8741 PetscCall(MatMatInterpolateAdd(A,x,NULL,y)); 8742 PetscFunctionReturn(0); 8743 } 8744 8745 /*@ 8746 MatGetNullSpace - retrieves the null space of a matrix. 8747 8748 Logically Collective on Mat 8749 8750 Input Parameters: 8751 + mat - the matrix 8752 - nullsp - the null space object 8753 8754 Level: developer 8755 8756 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatSetNullSpace()` 8757 @*/ 8758 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp) 8759 { 8760 PetscFunctionBegin; 8761 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8762 PetscValidPointer(nullsp,2); 8763 *nullsp = (mat->symmetric == PETSC_BOOL3_TRUE && !mat->nullsp) ? mat->transnullsp : mat->nullsp; 8764 PetscFunctionReturn(0); 8765 } 8766 8767 /*@ 8768 MatSetNullSpace - attaches a null space to a matrix. 8769 8770 Logically Collective on Mat 8771 8772 Input Parameters: 8773 + mat - the matrix 8774 - nullsp - the null space object 8775 8776 Level: advanced 8777 8778 Notes: 8779 This null space is used by the KSP linear solvers to solve singular systems. 8780 8781 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 8782 8783 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 8784 to zero but the linear system will still be solved in a least squares sense. 8785 8786 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8787 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). 8788 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 8789 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 8790 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). 8791 This \hat{b} can be obtained by calling MatNullSpaceRemove() with the null space of the transpose of the matrix. 8792 8793 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 8794 routine also automatically calls MatSetTransposeNullSpace(). 8795 8796 The user should call `MatNullSpaceDestroy()`. 8797 8798 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatGetNullSpace()`, `MatSetTransposeNullSpace()`, `MatGetTransposeNullSpace()`, `MatNullSpaceRemove()`, 8799 `KSPSetPCSide()` 8800 @*/ 8801 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp) 8802 { 8803 PetscFunctionBegin; 8804 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8805 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8806 if (nullsp) PetscCall(PetscObjectReference((PetscObject)nullsp)); 8807 PetscCall(MatNullSpaceDestroy(&mat->nullsp)); 8808 mat->nullsp = nullsp; 8809 if (mat->symmetric == PETSC_BOOL3_TRUE) { 8810 PetscCall(MatSetTransposeNullSpace(mat,nullsp)); 8811 } 8812 PetscFunctionReturn(0); 8813 } 8814 8815 /*@ 8816 MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix. 8817 8818 Logically Collective on Mat 8819 8820 Input Parameters: 8821 + mat - the matrix 8822 - nullsp - the null space object 8823 8824 Level: developer 8825 8826 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatSetTransposeNullSpace()`, `MatSetNullSpace()`, `MatGetNullSpace()` 8827 @*/ 8828 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp) 8829 { 8830 PetscFunctionBegin; 8831 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8832 PetscValidType(mat,1); 8833 PetscValidPointer(nullsp,2); 8834 *nullsp = (mat->symmetric == PETSC_BOOL3_TRUE && !mat->transnullsp) ? mat->nullsp : mat->transnullsp; 8835 PetscFunctionReturn(0); 8836 } 8837 8838 /*@ 8839 MatSetTransposeNullSpace - attaches the null space of a transpose of a matrix to the matrix 8840 8841 Logically Collective on Mat 8842 8843 Input Parameters: 8844 + mat - the matrix 8845 - nullsp - the null space object 8846 8847 Level: advanced 8848 8849 Notes: 8850 This allows solving singular linear systems defined by the transpose of the matrix using KSP solvers with left preconditioning. 8851 8852 See MatSetNullSpace() 8853 8854 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatGetNullSpace()`, `MatSetNullSpace()`, `MatGetTransposeNullSpace()`, `MatNullSpaceRemove()`, `KSPSetPCSide()` 8855 @*/ 8856 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp) 8857 { 8858 PetscFunctionBegin; 8859 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8860 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8861 if (nullsp) PetscCall(PetscObjectReference((PetscObject)nullsp)); 8862 PetscCall(MatNullSpaceDestroy(&mat->transnullsp)); 8863 mat->transnullsp = nullsp; 8864 PetscFunctionReturn(0); 8865 } 8866 8867 /*@ 8868 MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions 8869 This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix. 8870 8871 Logically Collective on Mat 8872 8873 Input Parameters: 8874 + mat - the matrix 8875 - nullsp - the null space object 8876 8877 Level: advanced 8878 8879 Notes: 8880 Overwrites any previous near null space that may have been attached 8881 8882 You can remove the null space by calling this routine with an nullsp of NULL 8883 8884 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNullSpace()`, `MatNullSpaceCreateRigidBody()`, `MatGetNearNullSpace()` 8885 @*/ 8886 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp) 8887 { 8888 PetscFunctionBegin; 8889 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8890 PetscValidType(mat,1); 8891 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8892 MatCheckPreallocated(mat,1); 8893 if (nullsp) PetscCall(PetscObjectReference((PetscObject)nullsp)); 8894 PetscCall(MatNullSpaceDestroy(&mat->nearnullsp)); 8895 mat->nearnullsp = nullsp; 8896 PetscFunctionReturn(0); 8897 } 8898 8899 /*@ 8900 MatGetNearNullSpace - Get null space attached with MatSetNearNullSpace() 8901 8902 Not Collective 8903 8904 Input Parameter: 8905 . mat - the matrix 8906 8907 Output Parameter: 8908 . nullsp - the null space object, NULL if not set 8909 8910 Level: developer 8911 8912 .seealso: `MatSetNearNullSpace()`, `MatGetNullSpace()`, `MatNullSpaceCreate()` 8913 @*/ 8914 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp) 8915 { 8916 PetscFunctionBegin; 8917 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8918 PetscValidType(mat,1); 8919 PetscValidPointer(nullsp,2); 8920 MatCheckPreallocated(mat,1); 8921 *nullsp = mat->nearnullsp; 8922 PetscFunctionReturn(0); 8923 } 8924 8925 /*@C 8926 MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix. 8927 8928 Collective on Mat 8929 8930 Input Parameters: 8931 + mat - the matrix 8932 . row - row/column permutation 8933 . fill - expected fill factor >= 1.0 8934 - level - level of fill, for ICC(k) 8935 8936 Notes: 8937 Probably really in-place only when level of fill is zero, otherwise allocates 8938 new space to store factored matrix and deletes previous memory. 8939 8940 Most users should employ the simplified KSP interface for linear solvers 8941 instead of working directly with matrix algebra routines such as this. 8942 See, e.g., KSPCreate(). 8943 8944 Level: developer 8945 8946 .seealso: `MatICCFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()` 8947 8948 Developer Note: fortran interface is not autogenerated as the f90 8949 interface definition cannot be generated correctly [due to MatFactorInfo] 8950 8951 @*/ 8952 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info) 8953 { 8954 PetscFunctionBegin; 8955 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8956 PetscValidType(mat,1); 8957 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 8958 PetscValidPointer(info,3); 8959 PetscCheck(mat->rmap->N == mat->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 8960 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8961 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8962 PetscCheck(mat->ops->iccfactor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8963 MatCheckPreallocated(mat,1); 8964 PetscCall((*mat->ops->iccfactor)(mat,row,info)); 8965 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 8966 PetscFunctionReturn(0); 8967 } 8968 8969 /*@ 8970 MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 8971 ghosted ones. 8972 8973 Not Collective 8974 8975 Input Parameters: 8976 + mat - the matrix 8977 - diag - the diagonal values, including ghost ones 8978 8979 Level: developer 8980 8981 Notes: 8982 Works only for MPIAIJ and MPIBAIJ matrices 8983 8984 .seealso: `MatDiagonalScale()` 8985 @*/ 8986 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag) 8987 { 8988 PetscMPIInt size; 8989 8990 PetscFunctionBegin; 8991 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8992 PetscValidHeaderSpecific(diag,VEC_CLASSID,2); 8993 PetscValidType(mat,1); 8994 8995 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled"); 8996 PetscCall(PetscLogEventBegin(MAT_Scale,mat,0,0,0)); 8997 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 8998 if (size == 1) { 8999 PetscInt n,m; 9000 PetscCall(VecGetSize(diag,&n)); 9001 PetscCall(MatGetSize(mat,NULL,&m)); 9002 if (m == n) { 9003 PetscCall(MatDiagonalScale(mat,NULL,diag)); 9004 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions"); 9005 } else { 9006 PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag)); 9007 } 9008 PetscCall(PetscLogEventEnd(MAT_Scale,mat,0,0,0)); 9009 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 9010 PetscFunctionReturn(0); 9011 } 9012 9013 /*@ 9014 MatGetInertia - Gets the inertia from a factored matrix 9015 9016 Collective on Mat 9017 9018 Input Parameter: 9019 . mat - the matrix 9020 9021 Output Parameters: 9022 + nneg - number of negative eigenvalues 9023 . nzero - number of zero eigenvalues 9024 - npos - number of positive eigenvalues 9025 9026 Level: advanced 9027 9028 Notes: 9029 Matrix must have been factored by MatCholeskyFactor() 9030 9031 @*/ 9032 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos) 9033 { 9034 PetscFunctionBegin; 9035 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9036 PetscValidType(mat,1); 9037 PetscCheck(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 9038 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled"); 9039 PetscCheck(mat->ops->getinertia,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 9040 PetscCall((*mat->ops->getinertia)(mat,nneg,nzero,npos)); 9041 PetscFunctionReturn(0); 9042 } 9043 9044 /* ----------------------------------------------------------------*/ 9045 /*@C 9046 MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors 9047 9048 Neighbor-wise Collective on Mats 9049 9050 Input Parameters: 9051 + mat - the factored matrix 9052 - b - the right-hand-side vectors 9053 9054 Output Parameter: 9055 . x - the result vectors 9056 9057 Notes: 9058 The vectors b and x cannot be the same. I.e., one cannot 9059 call MatSolves(A,x,x). 9060 9061 Notes: 9062 Most users should employ the simplified KSP interface for linear solvers 9063 instead of working directly with matrix algebra routines such as this. 9064 See, e.g., KSPCreate(). 9065 9066 Level: developer 9067 9068 .seealso: `MatSolveAdd()`, `MatSolveTranspose()`, `MatSolveTransposeAdd()`, `MatSolve()` 9069 @*/ 9070 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x) 9071 { 9072 PetscFunctionBegin; 9073 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9074 PetscValidType(mat,1); 9075 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 9076 PetscCheck(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 9077 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 9078 9079 PetscCheck(mat->ops->solves,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 9080 MatCheckPreallocated(mat,1); 9081 PetscCall(PetscLogEventBegin(MAT_Solves,mat,0,0,0)); 9082 PetscCall((*mat->ops->solves)(mat,b,x)); 9083 PetscCall(PetscLogEventEnd(MAT_Solves,mat,0,0,0)); 9084 PetscFunctionReturn(0); 9085 } 9086 9087 /*@ 9088 MatIsSymmetric - Test whether a matrix is symmetric 9089 9090 Collective on Mat 9091 9092 Input Parameters: 9093 + A - the matrix to test 9094 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose) 9095 9096 Output Parameters: 9097 . flg - the result 9098 9099 Notes: 9100 For real numbers MatIsSymmetric() and MatIsHermitian() return identical results 9101 9102 If the matrix does not yet know if it is symmetric or not this can be an expensive operation, also available `MatIsSymmetricKnown()` 9103 9104 Level: intermediate 9105 9106 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetricKnown()` 9107 @*/ 9108 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg) 9109 { 9110 PetscFunctionBegin; 9111 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9112 PetscValidBoolPointer(flg,3); 9113 9114 if (A->symmetric == PETSC_BOOL3_TRUE) *flg = PETSC_TRUE; 9115 else if (A->symmetric == PETSC_BOOL3_FALSE) *flg = PETSC_FALSE; 9116 else { 9117 if (!A->ops->issymmetric) { 9118 MatType mattype; 9119 PetscCall(MatGetType(A,&mattype)); 9120 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for symmetric",mattype); 9121 } 9122 PetscCall((*A->ops->issymmetric)(A,tol,flg)); 9123 if (!tol) PetscCall(MatSetOption(A,MAT_SYMMETRIC,*flg)); 9124 } 9125 PetscFunctionReturn(0); 9126 } 9127 9128 /*@ 9129 MatIsHermitian - Test whether a matrix is Hermitian 9130 9131 Collective on Mat 9132 9133 Input Parameters: 9134 + A - the matrix to test 9135 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian) 9136 9137 Output Parameters: 9138 . flg - the result 9139 9140 Level: intermediate 9141 9142 Notes: 9143 For real numbers MatIsSymmetric() and MatIsHermitian() return identical results 9144 9145 If the matrix does not yet know if it is hermitian or not this can be an expensive operation, also available `MatIsHermitianKnown()` 9146 9147 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitianKnown()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, 9148 `MatIsSymmetricKnown()`, `MatIsSymmetric()` 9149 @*/ 9150 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg) 9151 { 9152 PetscFunctionBegin; 9153 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9154 PetscValidBoolPointer(flg,3); 9155 9156 if (A->hermitian == PETSC_BOOL3_TRUE) *flg = PETSC_TRUE; 9157 else if (A->hermitian == PETSC_BOOL3_FALSE) *flg = PETSC_FALSE; 9158 else { 9159 if (!A->ops->ishermitian) { 9160 MatType mattype; 9161 PetscCall(MatGetType(A,&mattype)); 9162 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for hermitian",mattype); 9163 } 9164 PetscCall((*A->ops->ishermitian)(A,tol,flg)); 9165 if (!tol) PetscCall(MatSetOption(A,MAT_HERMITIAN,*flg)); 9166 } 9167 PetscFunctionReturn(0); 9168 } 9169 9170 /*@ 9171 MatIsSymmetricKnown - Checks if a matrix knows if it is symmetric or not and its symmetric state 9172 9173 Not Collective 9174 9175 Input Parameter: 9176 . A - the matrix to check 9177 9178 Output Parameters: 9179 + set - PETSC_TRUE if the matrix knows its symmetry state (this tells you if the next flag is valid) 9180 - flg - the result (only valid if set is PETSC_TRUE) 9181 9182 Level: advanced 9183 9184 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric() 9185 if you want it explicitly checked 9186 9187 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitianKnown()` 9188 @*/ 9189 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg) 9190 { 9191 PetscFunctionBegin; 9192 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9193 PetscValidBoolPointer(set,2); 9194 PetscValidBoolPointer(flg,3); 9195 if (A->symmetric != PETSC_BOOL3_UNKNOWN) { 9196 *set = PETSC_TRUE; 9197 *flg = PetscBool3ToBool(A->symmetric); 9198 } else { 9199 *set = PETSC_FALSE; 9200 } 9201 PetscFunctionReturn(0); 9202 } 9203 9204 /*@ 9205 MatIsSPDKnown - Checks if a matrix knows if it is symmetric positive definite or not and its symmetric positive definite state 9206 9207 Not Collective 9208 9209 Input Parameter: 9210 . A - the matrix to check 9211 9212 Output Parameters: 9213 + set - PETSC_TRUE if the matrix knows its symmetric positive definite state (this tells you if the next flag is valid) 9214 - flg - the result (only valid if set is PETSC_TRUE) 9215 9216 Level: advanced 9217 9218 Note: 9219 Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). 9220 9221 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitianKnown()` 9222 @*/ 9223 PetscErrorCode MatIsSPDKnown(Mat A,PetscBool *set,PetscBool *flg) 9224 { 9225 PetscFunctionBegin; 9226 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9227 PetscValidBoolPointer(set,2); 9228 PetscValidBoolPointer(flg,3); 9229 if (A->spd != PETSC_BOOL3_UNKNOWN) { 9230 *set = PETSC_TRUE; 9231 *flg = PetscBool3ToBool(A->spd); 9232 } else { 9233 *set = PETSC_FALSE; 9234 } 9235 PetscFunctionReturn(0); 9236 } 9237 9238 /*@ 9239 MatIsHermitianKnown - Checks if a matrix knows if it is Hermitian or not and its Hermitian state 9240 9241 Not Collective 9242 9243 Input Parameter: 9244 . A - the matrix to check 9245 9246 Output Parameters: 9247 + set - PETSC_TRUE if the matrix knows its Hermitian state (this tells you if the next flag is valid) 9248 - flg - the result (only valid if set is PETSC_TRUE) 9249 9250 Level: advanced 9251 9252 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian() 9253 if you want it explicitly checked 9254 9255 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()` 9256 @*/ 9257 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg) 9258 { 9259 PetscFunctionBegin; 9260 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9261 PetscValidBoolPointer(set,2); 9262 PetscValidBoolPointer(flg,3); 9263 if (A->hermitian != PETSC_BOOL3_UNKNOWN) { 9264 *set = PETSC_TRUE; 9265 *flg = PetscBool3ToBool(A->hermitian); 9266 } else { 9267 *set = PETSC_FALSE; 9268 } 9269 PetscFunctionReturn(0); 9270 } 9271 9272 /*@ 9273 MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric 9274 9275 Collective on Mat 9276 9277 Input Parameter: 9278 . A - the matrix to test 9279 9280 Output Parameters: 9281 . flg - the result 9282 9283 Notes: 9284 If the matrix does yet know it is structurally symmetric this can be an expensive operation, also available `MatIsStructurallySymmetricKnown()` 9285 9286 Level: intermediate 9287 9288 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsSymmetric()`, `MatSetOption()`, `MatIsStructurallySymmetricKnown()` 9289 @*/ 9290 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg) 9291 { 9292 PetscFunctionBegin; 9293 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9294 PetscValidBoolPointer(flg,2); 9295 if (A->structurally_symmetric != PETSC_BOOL3_UNKNOWN) { 9296 *flg = PetscBool3ToBool(A->structurally_symmetric); 9297 } else { 9298 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); 9299 PetscCall((*A->ops->isstructurallysymmetric)(A,flg)); 9300 PetscCall(MatSetOption(A,MAT_STRUCTURALLY_SYMMETRIC,*flg)); 9301 } 9302 PetscFunctionReturn(0); 9303 } 9304 9305 /*@ 9306 MatIsStructurallySymmetricKnown - Checks if a matrix knows if it is structurally symmetric or not and its structurally symmetric state 9307 9308 Not Collective 9309 9310 Input Parameter: 9311 . A - the matrix to check 9312 9313 Output Parameters: 9314 + set - PETSC_TRUE if the matrix knows its structurally symmetric state (this tells you if the next flag is valid) 9315 - flg - the result (only valid if set is PETSC_TRUE) 9316 9317 Level: advanced 9318 9319 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitianKnown()` 9320 @*/ 9321 PetscErrorCode MatIsStructurallySymmetricKnown(Mat A,PetscBool *set,PetscBool *flg) 9322 { 9323 PetscFunctionBegin; 9324 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9325 PetscValidBoolPointer(set,2); 9326 PetscValidBoolPointer(flg,3); 9327 if (A->structurally_symmetric != PETSC_BOOL3_UNKNOWN) { 9328 *set = PETSC_TRUE; 9329 *flg = PetscBool3ToBool(A->structurally_symmetric); 9330 } else { 9331 *set = PETSC_FALSE; 9332 } 9333 PetscFunctionReturn(0); 9334 } 9335 9336 /*@ 9337 MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need 9338 to be communicated to other processors during the MatAssemblyBegin/End() process 9339 9340 Not collective 9341 9342 Input Parameter: 9343 . vec - the vector 9344 9345 Output Parameters: 9346 + nstash - the size of the stash 9347 . reallocs - the number of additional mallocs incurred. 9348 . bnstash - the size of the block stash 9349 - breallocs - the number of additional mallocs incurred.in the block stash 9350 9351 Level: advanced 9352 9353 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `Mat`, `MatStashSetInitialSize()` 9354 9355 @*/ 9356 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs) 9357 { 9358 PetscFunctionBegin; 9359 PetscCall(MatStashGetInfo_Private(&mat->stash,nstash,reallocs)); 9360 PetscCall(MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs)); 9361 PetscFunctionReturn(0); 9362 } 9363 9364 /*@C 9365 MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same 9366 parallel layout 9367 9368 Collective on Mat 9369 9370 Input Parameter: 9371 . mat - the matrix 9372 9373 Output Parameters: 9374 + right - (optional) vector that the matrix can be multiplied against 9375 - left - (optional) vector that the matrix vector product can be stored in 9376 9377 Notes: 9378 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(). 9379 9380 Notes: 9381 These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed 9382 9383 Level: advanced 9384 9385 .seealso: `MatCreate()`, `VecDestroy()` 9386 @*/ 9387 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left) 9388 { 9389 PetscFunctionBegin; 9390 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9391 PetscValidType(mat,1); 9392 if (mat->ops->getvecs) { 9393 PetscCall((*mat->ops->getvecs)(mat,right,left)); 9394 } else { 9395 PetscInt rbs,cbs; 9396 PetscCall(MatGetBlockSizes(mat,&rbs,&cbs)); 9397 if (right) { 9398 PetscCheck(mat->cmap->n >= 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup"); 9399 PetscCall(VecCreate(PetscObjectComm((PetscObject)mat),right)); 9400 PetscCall(VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE)); 9401 PetscCall(VecSetBlockSize(*right,cbs)); 9402 PetscCall(VecSetType(*right,mat->defaultvectype)); 9403 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 9404 if (mat->boundtocpu && mat->bindingpropagates) { 9405 PetscCall(VecSetBindingPropagates(*right,PETSC_TRUE)); 9406 PetscCall(VecBindToCPU(*right,PETSC_TRUE)); 9407 } 9408 #endif 9409 PetscCall(PetscLayoutReference(mat->cmap,&(*right)->map)); 9410 } 9411 if (left) { 9412 PetscCheck(mat->rmap->n >= 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup"); 9413 PetscCall(VecCreate(PetscObjectComm((PetscObject)mat),left)); 9414 PetscCall(VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE)); 9415 PetscCall(VecSetBlockSize(*left,rbs)); 9416 PetscCall(VecSetType(*left,mat->defaultvectype)); 9417 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 9418 if (mat->boundtocpu && mat->bindingpropagates) { 9419 PetscCall(VecSetBindingPropagates(*left,PETSC_TRUE)); 9420 PetscCall(VecBindToCPU(*left,PETSC_TRUE)); 9421 } 9422 #endif 9423 PetscCall(PetscLayoutReference(mat->rmap,&(*left)->map)); 9424 } 9425 } 9426 PetscFunctionReturn(0); 9427 } 9428 9429 /*@C 9430 MatFactorInfoInitialize - Initializes a MatFactorInfo data structure 9431 with default values. 9432 9433 Not Collective 9434 9435 Input Parameters: 9436 . info - the MatFactorInfo data structure 9437 9438 Notes: 9439 The solvers are generally used through the KSP and PC objects, for example 9440 PCLU, PCILU, PCCHOLESKY, PCICC 9441 9442 Level: developer 9443 9444 .seealso: `MatFactorInfo` 9445 9446 Developer Note: fortran interface is not autogenerated as the f90 9447 interface definition cannot be generated correctly [due to MatFactorInfo] 9448 9449 @*/ 9450 9451 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info) 9452 { 9453 PetscFunctionBegin; 9454 PetscCall(PetscMemzero(info,sizeof(MatFactorInfo))); 9455 PetscFunctionReturn(0); 9456 } 9457 9458 /*@ 9459 MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed 9460 9461 Collective on Mat 9462 9463 Input Parameters: 9464 + mat - the factored matrix 9465 - is - the index set defining the Schur indices (0-based) 9466 9467 Notes: 9468 Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system. 9469 9470 You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call. 9471 9472 Level: developer 9473 9474 .seealso: `MatGetFactor()`, `MatFactorGetSchurComplement()`, `MatFactorRestoreSchurComplement()`, `MatFactorCreateSchurComplement()`, `MatFactorSolveSchurComplement()`, 9475 `MatFactorSolveSchurComplementTranspose()`, `MatFactorSolveSchurComplement()` 9476 9477 @*/ 9478 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is) 9479 { 9480 PetscErrorCode (*f)(Mat,IS); 9481 9482 PetscFunctionBegin; 9483 PetscValidType(mat,1); 9484 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9485 PetscValidType(is,2); 9486 PetscValidHeaderSpecific(is,IS_CLASSID,2); 9487 PetscCheckSameComm(mat,1,is,2); 9488 PetscCheck(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 9489 PetscCall(PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f)); 9490 PetscCheck(f,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"The selected MatSolverType does not support Schur complement computation. You should use MATSOLVERMUMPS or MATSOLVERMKL_PARDISO"); 9491 PetscCall(MatDestroy(&mat->schur)); 9492 PetscCall((*f)(mat,is)); 9493 PetscCheck(mat->schur,PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created"); 9494 PetscFunctionReturn(0); 9495 } 9496 9497 /*@ 9498 MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step 9499 9500 Logically Collective on Mat 9501 9502 Input Parameters: 9503 + F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface 9504 . S - location where to return the Schur complement, can be NULL 9505 - status - the status of the Schur complement matrix, can be NULL 9506 9507 Notes: 9508 You must call MatFactorSetSchurIS() before calling this routine. 9509 9510 The routine provides a copy of the Schur matrix stored within the solver data structures. 9511 The caller must destroy the object when it is no longer needed. 9512 If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse. 9513 9514 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) 9515 9516 Developer Notes: 9517 The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc 9518 matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix. 9519 9520 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 9521 9522 Level: advanced 9523 9524 References: 9525 9526 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorGetSchurComplement()`, `MatFactorSchurStatus` 9527 @*/ 9528 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 9529 { 9530 PetscFunctionBegin; 9531 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9532 if (S) PetscValidPointer(S,2); 9533 if (status) PetscValidPointer(status,3); 9534 if (S) { 9535 PetscErrorCode (*f)(Mat,Mat*); 9536 9537 PetscCall(PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f)); 9538 if (f) { 9539 PetscCall((*f)(F,S)); 9540 } else { 9541 PetscCall(MatDuplicate(F->schur,MAT_COPY_VALUES,S)); 9542 } 9543 } 9544 if (status) *status = F->schur_status; 9545 PetscFunctionReturn(0); 9546 } 9547 9548 /*@ 9549 MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix 9550 9551 Logically Collective on Mat 9552 9553 Input Parameters: 9554 + F - the factored matrix obtained by calling MatGetFactor() 9555 . *S - location where to return the Schur complement, can be NULL 9556 - status - the status of the Schur complement matrix, can be NULL 9557 9558 Notes: 9559 You must call MatFactorSetSchurIS() before calling this routine. 9560 9561 Schur complement mode is currently implemented for sequential matrices. 9562 The routine returns a the Schur Complement stored within the data strutures of the solver. 9563 If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement. 9564 The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed. 9565 9566 Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix 9567 9568 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 9569 9570 Level: advanced 9571 9572 References: 9573 9574 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorRestoreSchurComplement()`, `MatFactorCreateSchurComplement()`, `MatFactorSchurStatus` 9575 @*/ 9576 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 9577 { 9578 PetscFunctionBegin; 9579 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9580 if (S) PetscValidPointer(S,2); 9581 if (status) PetscValidPointer(status,3); 9582 if (S) *S = F->schur; 9583 if (status) *status = F->schur_status; 9584 PetscFunctionReturn(0); 9585 } 9586 9587 /*@ 9588 MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement 9589 9590 Logically Collective on Mat 9591 9592 Input Parameters: 9593 + F - the factored matrix obtained by calling MatGetFactor() 9594 . *S - location where the Schur complement is stored 9595 - status - the status of the Schur complement matrix (see MatFactorSchurStatus) 9596 9597 Notes: 9598 9599 Level: advanced 9600 9601 References: 9602 9603 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorRestoreSchurComplement()`, `MatFactorCreateSchurComplement()`, `MatFactorSchurStatus` 9604 @*/ 9605 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status) 9606 { 9607 PetscFunctionBegin; 9608 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9609 if (S) { 9610 PetscValidHeaderSpecific(*S,MAT_CLASSID,2); 9611 *S = NULL; 9612 } 9613 F->schur_status = status; 9614 PetscCall(MatFactorUpdateSchurStatus_Private(F)); 9615 PetscFunctionReturn(0); 9616 } 9617 9618 /*@ 9619 MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step 9620 9621 Logically Collective on Mat 9622 9623 Input Parameters: 9624 + F - the factored matrix obtained by calling MatGetFactor() 9625 . rhs - location where the right hand side of the Schur complement system is stored 9626 - sol - location where the solution of the Schur complement system has to be returned 9627 9628 Notes: 9629 The sizes of the vectors should match the size of the Schur complement 9630 9631 Must be called after MatFactorSetSchurIS() 9632 9633 Level: advanced 9634 9635 References: 9636 9637 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorSolveSchurComplement()` 9638 @*/ 9639 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol) 9640 { 9641 PetscFunctionBegin; 9642 PetscValidType(F,1); 9643 PetscValidType(rhs,2); 9644 PetscValidType(sol,3); 9645 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9646 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9647 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9648 PetscCheckSameComm(F,1,rhs,2); 9649 PetscCheckSameComm(F,1,sol,3); 9650 PetscCall(MatFactorFactorizeSchurComplement(F)); 9651 switch (F->schur_status) { 9652 case MAT_FACTOR_SCHUR_FACTORED: 9653 PetscCall(MatSolveTranspose(F->schur,rhs,sol)); 9654 break; 9655 case MAT_FACTOR_SCHUR_INVERTED: 9656 PetscCall(MatMultTranspose(F->schur,rhs,sol)); 9657 break; 9658 default: 9659 SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %d",F->schur_status); 9660 } 9661 PetscFunctionReturn(0); 9662 } 9663 9664 /*@ 9665 MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step 9666 9667 Logically Collective on Mat 9668 9669 Input Parameters: 9670 + F - the factored matrix obtained by calling MatGetFactor() 9671 . rhs - location where the right hand side of the Schur complement system is stored 9672 - sol - location where the solution of the Schur complement system has to be returned 9673 9674 Notes: 9675 The sizes of the vectors should match the size of the Schur complement 9676 9677 Must be called after MatFactorSetSchurIS() 9678 9679 Level: advanced 9680 9681 References: 9682 9683 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorSolveSchurComplementTranspose()` 9684 @*/ 9685 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol) 9686 { 9687 PetscFunctionBegin; 9688 PetscValidType(F,1); 9689 PetscValidType(rhs,2); 9690 PetscValidType(sol,3); 9691 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9692 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9693 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9694 PetscCheckSameComm(F,1,rhs,2); 9695 PetscCheckSameComm(F,1,sol,3); 9696 PetscCall(MatFactorFactorizeSchurComplement(F)); 9697 switch (F->schur_status) { 9698 case MAT_FACTOR_SCHUR_FACTORED: 9699 PetscCall(MatSolve(F->schur,rhs,sol)); 9700 break; 9701 case MAT_FACTOR_SCHUR_INVERTED: 9702 PetscCall(MatMult(F->schur,rhs,sol)); 9703 break; 9704 default: 9705 SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %d",F->schur_status); 9706 } 9707 PetscFunctionReturn(0); 9708 } 9709 9710 /*@ 9711 MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step 9712 9713 Logically Collective on Mat 9714 9715 Input Parameters: 9716 . F - the factored matrix obtained by calling MatGetFactor() 9717 9718 Notes: 9719 Must be called after MatFactorSetSchurIS(). 9720 9721 Call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it. 9722 9723 Level: advanced 9724 9725 References: 9726 9727 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorGetSchurComplement()`, `MatFactorCreateSchurComplement()` 9728 @*/ 9729 PetscErrorCode MatFactorInvertSchurComplement(Mat F) 9730 { 9731 PetscFunctionBegin; 9732 PetscValidType(F,1); 9733 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9734 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0); 9735 PetscCall(MatFactorFactorizeSchurComplement(F)); 9736 PetscCall(MatFactorInvertSchurComplement_Private(F)); 9737 F->schur_status = MAT_FACTOR_SCHUR_INVERTED; 9738 PetscFunctionReturn(0); 9739 } 9740 9741 /*@ 9742 MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step 9743 9744 Logically Collective on Mat 9745 9746 Input Parameters: 9747 . F - the factored matrix obtained by calling MatGetFactor() 9748 9749 Notes: 9750 Must be called after MatFactorSetSchurIS(). 9751 9752 Level: advanced 9753 9754 References: 9755 9756 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorInvertSchurComplement()` 9757 @*/ 9758 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F) 9759 { 9760 PetscFunctionBegin; 9761 PetscValidType(F,1); 9762 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9763 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0); 9764 PetscCall(MatFactorFactorizeSchurComplement_Private(F)); 9765 F->schur_status = MAT_FACTOR_SCHUR_FACTORED; 9766 PetscFunctionReturn(0); 9767 } 9768 9769 /*@ 9770 MatPtAP - Creates the matrix product C = P^T * A * P 9771 9772 Neighbor-wise Collective on Mat 9773 9774 Input Parameters: 9775 + A - the matrix 9776 . P - the projection matrix 9777 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9778 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate 9779 if the result is a dense matrix this is irrelevant 9780 9781 Output Parameters: 9782 . C - the product matrix 9783 9784 Notes: 9785 C will be created and must be destroyed by the user with MatDestroy(). 9786 9787 For matrix types without special implementation the function fallbacks to MatMatMult() followed by MatTransposeMatMult(). 9788 9789 Level: intermediate 9790 9791 .seealso: `MatMatMult()`, `MatRARt()` 9792 @*/ 9793 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 9794 { 9795 PetscFunctionBegin; 9796 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*C,5); 9797 PetscCheck(scall != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9798 9799 if (scall == MAT_INITIAL_MATRIX) { 9800 PetscCall(MatProductCreate(A,P,NULL,C)); 9801 PetscCall(MatProductSetType(*C,MATPRODUCT_PtAP)); 9802 PetscCall(MatProductSetAlgorithm(*C,"default")); 9803 PetscCall(MatProductSetFill(*C,fill)); 9804 9805 (*C)->product->api_user = PETSC_TRUE; 9806 PetscCall(MatProductSetFromOptions(*C)); 9807 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); 9808 PetscCall(MatProductSymbolic(*C)); 9809 } else { /* scall == MAT_REUSE_MATRIX */ 9810 PetscCall(MatProductReplaceMats(A,P,NULL,*C)); 9811 } 9812 9813 PetscCall(MatProductNumeric(*C)); 9814 (*C)->symmetric = A->symmetric; 9815 (*C)->spd = A->spd; 9816 PetscFunctionReturn(0); 9817 } 9818 9819 /*@ 9820 MatRARt - Creates the matrix product C = R * A * R^T 9821 9822 Neighbor-wise Collective on Mat 9823 9824 Input Parameters: 9825 + A - the matrix 9826 . R - the projection matrix 9827 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9828 - fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate 9829 if the result is a dense matrix this is irrelevant 9830 9831 Output Parameters: 9832 . C - the product matrix 9833 9834 Notes: 9835 C will be created and must be destroyed by the user with MatDestroy(). 9836 9837 This routine is currently only implemented for pairs of AIJ matrices and classes 9838 which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes, 9839 parallel MatRARt is implemented via explicit transpose of R, which could be very expensive. 9840 We recommend using MatPtAP(). 9841 9842 Level: intermediate 9843 9844 .seealso: `MatMatMult()`, `MatPtAP()` 9845 @*/ 9846 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C) 9847 { 9848 PetscFunctionBegin; 9849 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*C,5); 9850 PetscCheck(scall != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9851 9852 if (scall == MAT_INITIAL_MATRIX) { 9853 PetscCall(MatProductCreate(A,R,NULL,C)); 9854 PetscCall(MatProductSetType(*C,MATPRODUCT_RARt)); 9855 PetscCall(MatProductSetAlgorithm(*C,"default")); 9856 PetscCall(MatProductSetFill(*C,fill)); 9857 9858 (*C)->product->api_user = PETSC_TRUE; 9859 PetscCall(MatProductSetFromOptions(*C)); 9860 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); 9861 PetscCall(MatProductSymbolic(*C)); 9862 } else { /* scall == MAT_REUSE_MATRIX */ 9863 PetscCall(MatProductReplaceMats(A,R,NULL,*C)); 9864 } 9865 9866 PetscCall(MatProductNumeric(*C)); 9867 if (A->symmetric == PETSC_BOOL3_TRUE) { 9868 PetscCall(MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE)); 9869 } 9870 PetscFunctionReturn(0); 9871 } 9872 9873 static PetscErrorCode MatProduct_Private(Mat A,Mat B,MatReuse scall,PetscReal fill,MatProductType ptype, Mat *C) 9874 { 9875 PetscFunctionBegin; 9876 PetscCheck(scall != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9877 9878 if (scall == MAT_INITIAL_MATRIX) { 9879 PetscCall(PetscInfo(A,"Calling MatProduct API with MAT_INITIAL_MATRIX and product type %s\n",MatProductTypes[ptype])); 9880 PetscCall(MatProductCreate(A,B,NULL,C)); 9881 PetscCall(MatProductSetType(*C,ptype)); 9882 PetscCall(MatProductSetAlgorithm(*C,MATPRODUCTALGORITHMDEFAULT)); 9883 PetscCall(MatProductSetFill(*C,fill)); 9884 9885 (*C)->product->api_user = PETSC_TRUE; 9886 PetscCall(MatProductSetFromOptions(*C)); 9887 PetscCall(MatProductSymbolic(*C)); 9888 } else { /* scall == MAT_REUSE_MATRIX */ 9889 Mat_Product *product = (*C)->product; 9890 PetscBool isdense; 9891 9892 PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)(*C),&isdense,MATSEQDENSE,MATMPIDENSE,"")); 9893 if (isdense && product && product->type != ptype) { 9894 PetscCall(MatProductClear(*C)); 9895 product = NULL; 9896 } 9897 PetscCall(PetscInfo(A,"Calling MatProduct API with MAT_REUSE_MATRIX %s product present and product type %s\n",product ? "with" : "without",MatProductTypes[ptype])); 9898 if (!product) { /* user provide the dense matrix *C without calling MatProductCreate() or reusing it from previous calls */ 9899 if (isdense) { 9900 PetscCall(MatProductCreate_Private(A,B,NULL,*C)); 9901 product = (*C)->product; 9902 product->fill = fill; 9903 product->api_user = PETSC_TRUE; 9904 product->clear = PETSC_TRUE; 9905 9906 PetscCall(MatProductSetType(*C,ptype)); 9907 PetscCall(MatProductSetFromOptions(*C)); 9908 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); 9909 PetscCall(MatProductSymbolic(*C)); 9910 } else SETERRQ(PetscObjectComm((PetscObject)(*C)),PETSC_ERR_SUP,"Call MatProductCreate() first"); 9911 } else { /* user may change input matrices A or B when REUSE */ 9912 PetscCall(MatProductReplaceMats(A,B,NULL,*C)); 9913 } 9914 } 9915 PetscCall(MatProductNumeric(*C)); 9916 PetscFunctionReturn(0); 9917 } 9918 9919 /*@ 9920 MatMatMult - Performs Matrix-Matrix Multiplication C=A*B. 9921 9922 Neighbor-wise Collective on Mat 9923 9924 Input Parameters: 9925 + A - the left matrix 9926 . B - the right matrix 9927 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9928 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate 9929 if the result is a dense matrix this is irrelevant 9930 9931 Output Parameters: 9932 . C - the product matrix 9933 9934 Notes: 9935 Unless scall is MAT_REUSE_MATRIX C will be created. 9936 9937 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 9938 call to this function with MAT_INITIAL_MATRIX. 9939 9940 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value actually needed. 9941 9942 If you have many matrices with the same non-zero structure to multiply, you should use MatProductCreate()/MatProductSymbolic()/MatProductReplaceMats(), and call MatProductNumeric() repeatedly. 9943 9944 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. 9945 9946 Example of Usage: 9947 .vb 9948 MatProductCreate(A,B,NULL,&C); 9949 MatProductSetType(C,MATPRODUCT_AB); 9950 MatProductSymbolic(C); 9951 MatProductNumeric(C); // compute C=A * B 9952 MatProductReplaceMats(A1,B1,NULL,C); // compute C=A1 * B1 9953 MatProductNumeric(C); 9954 MatProductReplaceMats(A2,NULL,NULL,C); // compute C=A2 * B1 9955 MatProductNumeric(C); 9956 .ve 9957 9958 Level: intermediate 9959 9960 .seealso: `MatTransposeMatMult()`, `MatMatTransposeMult()`, `MatPtAP()`, `MatProductCreate()`, `MatProductSymbolic()`, `MatProductReplaceMats()`, `MatProductNumeric()` 9961 @*/ 9962 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9963 { 9964 PetscFunctionBegin; 9965 PetscCall(MatProduct_Private(A,B,scall,fill,MATPRODUCT_AB,C)); 9966 PetscFunctionReturn(0); 9967 } 9968 9969 /*@ 9970 MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T. 9971 9972 Neighbor-wise Collective on Mat 9973 9974 Input Parameters: 9975 + A - the left matrix 9976 . B - the right matrix 9977 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9978 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9979 9980 Output Parameters: 9981 . C - the product matrix 9982 9983 Notes: 9984 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9985 9986 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9987 9988 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9989 actually needed. 9990 9991 This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class, 9992 and for pairs of MPIDense matrices. 9993 9994 Options Database Keys: 9995 . -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorithms for MPIDense matrices: the 9996 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity; 9997 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity. 9998 9999 Level: intermediate 10000 10001 .seealso: `MatMatMult()`, `MatTransposeMatMult()` `MatPtAP()` 10002 @*/ 10003 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 10004 { 10005 PetscFunctionBegin; 10006 PetscCall(MatProduct_Private(A,B,scall,fill,MATPRODUCT_ABt,C)); 10007 if (A == B) { 10008 PetscCall(MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE)); 10009 } 10010 PetscFunctionReturn(0); 10011 } 10012 10013 /*@ 10014 MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B. 10015 10016 Neighbor-wise Collective on Mat 10017 10018 Input Parameters: 10019 + A - the left matrix 10020 . B - the right matrix 10021 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10022 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 10023 10024 Output Parameters: 10025 . C - the product matrix 10026 10027 Notes: 10028 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 10029 10030 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call. 10031 10032 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 10033 actually needed. 10034 10035 This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes 10036 which inherit from SeqAIJ. C will be of the same type as the input matrices. 10037 10038 Level: intermediate 10039 10040 .seealso: `MatMatMult()`, `MatMatTransposeMult()`, `MatPtAP()` 10041 @*/ 10042 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 10043 { 10044 PetscFunctionBegin; 10045 PetscCall(MatProduct_Private(A,B,scall,fill,MATPRODUCT_AtB,C)); 10046 PetscFunctionReturn(0); 10047 } 10048 10049 /*@ 10050 MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C. 10051 10052 Neighbor-wise Collective on Mat 10053 10054 Input Parameters: 10055 + A - the left matrix 10056 . B - the middle matrix 10057 . C - the right matrix 10058 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10059 - 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 10060 if the result is a dense matrix this is irrelevant 10061 10062 Output Parameters: 10063 . D - the product matrix 10064 10065 Notes: 10066 Unless scall is MAT_REUSE_MATRIX D will be created. 10067 10068 MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call 10069 10070 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 10071 actually needed. 10072 10073 If you have many matrices with the same non-zero structure to multiply, you 10074 should use MAT_REUSE_MATRIX in all calls but the first 10075 10076 Level: intermediate 10077 10078 .seealso: `MatMatMult`, `MatPtAP()`, `MatMatTransposeMult()`, `MatTransposeMatMult()` 10079 @*/ 10080 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D) 10081 { 10082 PetscFunctionBegin; 10083 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*D,6); 10084 PetscCheck(scall != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 10085 10086 if (scall == MAT_INITIAL_MATRIX) { 10087 PetscCall(MatProductCreate(A,B,C,D)); 10088 PetscCall(MatProductSetType(*D,MATPRODUCT_ABC)); 10089 PetscCall(MatProductSetAlgorithm(*D,"default")); 10090 PetscCall(MatProductSetFill(*D,fill)); 10091 10092 (*D)->product->api_user = PETSC_TRUE; 10093 PetscCall(MatProductSetFromOptions(*D)); 10094 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); 10095 PetscCall(MatProductSymbolic(*D)); 10096 } else { /* user may change input matrices when REUSE */ 10097 PetscCall(MatProductReplaceMats(A,B,C,*D)); 10098 } 10099 PetscCall(MatProductNumeric(*D)); 10100 PetscFunctionReturn(0); 10101 } 10102 10103 /*@ 10104 MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators. 10105 10106 Collective on Mat 10107 10108 Input Parameters: 10109 + mat - the matrix 10110 . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices) 10111 . subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used) 10112 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10113 10114 Output Parameter: 10115 . matredundant - redundant matrix 10116 10117 Notes: 10118 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 10119 original matrix has not changed from that last call to MatCreateRedundantMatrix(). 10120 10121 This routine creates the duplicated matrices in the subcommunicators; you should NOT create them before 10122 calling it. 10123 10124 Level: advanced 10125 10126 .seealso: `MatDestroy()` 10127 @*/ 10128 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant) 10129 { 10130 MPI_Comm comm; 10131 PetscMPIInt size; 10132 PetscInt mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs; 10133 Mat_Redundant *redund=NULL; 10134 PetscSubcomm psubcomm=NULL; 10135 MPI_Comm subcomm_in=subcomm; 10136 Mat *matseq; 10137 IS isrow,iscol; 10138 PetscBool newsubcomm=PETSC_FALSE; 10139 10140 PetscFunctionBegin; 10141 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10142 if (nsubcomm && reuse == MAT_REUSE_MATRIX) { 10143 PetscValidPointer(*matredundant,5); 10144 PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5); 10145 } 10146 10147 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 10148 if (size == 1 || nsubcomm == 1) { 10149 if (reuse == MAT_INITIAL_MATRIX) { 10150 PetscCall(MatDuplicate(mat,MAT_COPY_VALUES,matredundant)); 10151 } else { 10152 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"); 10153 PetscCall(MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN)); 10154 } 10155 PetscFunctionReturn(0); 10156 } 10157 10158 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10159 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10160 MatCheckPreallocated(mat,1); 10161 10162 PetscCall(PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0)); 10163 if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */ 10164 /* create psubcomm, then get subcomm */ 10165 PetscCall(PetscObjectGetComm((PetscObject)mat,&comm)); 10166 PetscCallMPI(MPI_Comm_size(comm,&size)); 10167 PetscCheck(nsubcomm >= 1 && nsubcomm <= size,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %d",size); 10168 10169 PetscCall(PetscSubcommCreate(comm,&psubcomm)); 10170 PetscCall(PetscSubcommSetNumber(psubcomm,nsubcomm)); 10171 PetscCall(PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS)); 10172 PetscCall(PetscSubcommSetFromOptions(psubcomm)); 10173 PetscCall(PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL)); 10174 newsubcomm = PETSC_TRUE; 10175 PetscCall(PetscSubcommDestroy(&psubcomm)); 10176 } 10177 10178 /* get isrow, iscol and a local sequential matrix matseq[0] */ 10179 if (reuse == MAT_INITIAL_MATRIX) { 10180 mloc_sub = PETSC_DECIDE; 10181 nloc_sub = PETSC_DECIDE; 10182 if (bs < 1) { 10183 PetscCall(PetscSplitOwnership(subcomm,&mloc_sub,&M)); 10184 PetscCall(PetscSplitOwnership(subcomm,&nloc_sub,&N)); 10185 } else { 10186 PetscCall(PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M)); 10187 PetscCall(PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N)); 10188 } 10189 PetscCallMPI(MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm)); 10190 rstart = rend - mloc_sub; 10191 PetscCall(ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow)); 10192 PetscCall(ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol)); 10193 } else { /* reuse == MAT_REUSE_MATRIX */ 10194 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"); 10195 /* retrieve subcomm */ 10196 PetscCall(PetscObjectGetComm((PetscObject)(*matredundant),&subcomm)); 10197 redund = (*matredundant)->redundant; 10198 isrow = redund->isrow; 10199 iscol = redund->iscol; 10200 matseq = redund->matseq; 10201 } 10202 PetscCall(MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq)); 10203 10204 /* get matredundant over subcomm */ 10205 if (reuse == MAT_INITIAL_MATRIX) { 10206 PetscCall(MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant)); 10207 10208 /* create a supporting struct and attach it to C for reuse */ 10209 PetscCall(PetscNewLog(*matredundant,&redund)); 10210 (*matredundant)->redundant = redund; 10211 redund->isrow = isrow; 10212 redund->iscol = iscol; 10213 redund->matseq = matseq; 10214 if (newsubcomm) { 10215 redund->subcomm = subcomm; 10216 } else { 10217 redund->subcomm = MPI_COMM_NULL; 10218 } 10219 } else { 10220 PetscCall(MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant)); 10221 } 10222 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 10223 if (matseq[0]->boundtocpu && matseq[0]->bindingpropagates) { 10224 PetscCall(MatBindToCPU(*matredundant,PETSC_TRUE)); 10225 PetscCall(MatSetBindingPropagates(*matredundant,PETSC_TRUE)); 10226 } 10227 #endif 10228 PetscCall(PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0)); 10229 PetscFunctionReturn(0); 10230 } 10231 10232 /*@C 10233 MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from 10234 a given 'mat' object. Each submatrix can span multiple procs. 10235 10236 Collective on Mat 10237 10238 Input Parameters: 10239 + mat - the matrix 10240 . subcomm - the subcommunicator obtained by com_split(comm) 10241 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10242 10243 Output Parameter: 10244 . subMat - 'parallel submatrices each spans a given subcomm 10245 10246 Notes: 10247 The submatrix partition across processors is dictated by 'subComm' a 10248 communicator obtained by MPI_comm_split(). The subComm 10249 is not restriced to be grouped with consecutive original ranks. 10250 10251 Due the MPI_Comm_split() usage, the parallel layout of the submatrices 10252 map directly to the layout of the original matrix [wrt the local 10253 row,col partitioning]. So the original 'DiagonalMat' naturally maps 10254 into the 'DiagonalMat' of the subMat, hence it is used directly from 10255 the subMat. However the offDiagMat looses some columns - and this is 10256 reconstructed with MatSetValues() 10257 10258 Level: advanced 10259 10260 .seealso: `MatCreateSubMatrices()` 10261 @*/ 10262 PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat) 10263 { 10264 PetscMPIInt commsize,subCommSize; 10265 10266 PetscFunctionBegin; 10267 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize)); 10268 PetscCallMPI(MPI_Comm_size(subComm,&subCommSize)); 10269 PetscCheck(subCommSize <= commsize,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %d < SubCommZize %d",commsize,subCommSize); 10270 10271 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"); 10272 PetscCall(PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0)); 10273 PetscCall((*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat)); 10274 PetscCall(PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0)); 10275 PetscFunctionReturn(0); 10276 } 10277 10278 /*@ 10279 MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering 10280 10281 Not Collective 10282 10283 Input Parameters: 10284 + mat - matrix to extract local submatrix from 10285 . isrow - local row indices for submatrix 10286 - iscol - local column indices for submatrix 10287 10288 Output Parameter: 10289 . submat - the submatrix 10290 10291 Level: intermediate 10292 10293 Notes: 10294 The submat should be returned with MatRestoreLocalSubMatrix(). 10295 10296 Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be 10297 the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's. 10298 10299 The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then 10300 MatSetValuesBlockedLocal() will also be implemented. 10301 10302 The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that 10303 matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided. 10304 10305 .seealso: `MatRestoreLocalSubMatrix()`, `MatCreateLocalRef()`, `MatSetLocalToGlobalMapping()` 10306 @*/ 10307 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10308 { 10309 PetscFunctionBegin; 10310 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10311 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10312 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10313 PetscCheckSameComm(isrow,2,iscol,3); 10314 PetscValidPointer(submat,4); 10315 PetscCheck(mat->rmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call"); 10316 10317 if (mat->ops->getlocalsubmatrix) { 10318 PetscCall((*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat)); 10319 } else { 10320 PetscCall(MatCreateLocalRef(mat,isrow,iscol,submat)); 10321 } 10322 PetscFunctionReturn(0); 10323 } 10324 10325 /*@ 10326 MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering 10327 10328 Not Collective 10329 10330 Input Parameters: 10331 + mat - matrix to extract local submatrix from 10332 . isrow - local row indices for submatrix 10333 . iscol - local column indices for submatrix 10334 - submat - the submatrix 10335 10336 Level: intermediate 10337 10338 .seealso: `MatGetLocalSubMatrix()` 10339 @*/ 10340 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10341 { 10342 PetscFunctionBegin; 10343 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10344 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10345 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10346 PetscCheckSameComm(isrow,2,iscol,3); 10347 PetscValidPointer(submat,4); 10348 if (*submat) { 10349 PetscValidHeaderSpecific(*submat,MAT_CLASSID,4); 10350 } 10351 10352 if (mat->ops->restorelocalsubmatrix) { 10353 PetscCall((*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat)); 10354 } else { 10355 PetscCall(MatDestroy(submat)); 10356 } 10357 *submat = NULL; 10358 PetscFunctionReturn(0); 10359 } 10360 10361 /* --------------------------------------------------------*/ 10362 /*@ 10363 MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix 10364 10365 Collective on Mat 10366 10367 Input Parameter: 10368 . mat - the matrix 10369 10370 Output Parameter: 10371 . is - if any rows have zero diagonals this contains the list of them 10372 10373 Level: developer 10374 10375 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 10376 @*/ 10377 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is) 10378 { 10379 PetscFunctionBegin; 10380 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10381 PetscValidType(mat,1); 10382 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10383 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10384 10385 if (!mat->ops->findzerodiagonals) { 10386 Vec diag; 10387 const PetscScalar *a; 10388 PetscInt *rows; 10389 PetscInt rStart, rEnd, r, nrow = 0; 10390 10391 PetscCall(MatCreateVecs(mat, &diag, NULL)); 10392 PetscCall(MatGetDiagonal(mat, diag)); 10393 PetscCall(MatGetOwnershipRange(mat, &rStart, &rEnd)); 10394 PetscCall(VecGetArrayRead(diag, &a)); 10395 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow; 10396 PetscCall(PetscMalloc1(nrow, &rows)); 10397 nrow = 0; 10398 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart; 10399 PetscCall(VecRestoreArrayRead(diag, &a)); 10400 PetscCall(VecDestroy(&diag)); 10401 PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is)); 10402 } else { 10403 PetscCall((*mat->ops->findzerodiagonals)(mat, is)); 10404 } 10405 PetscFunctionReturn(0); 10406 } 10407 10408 /*@ 10409 MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size) 10410 10411 Collective on Mat 10412 10413 Input Parameter: 10414 . mat - the matrix 10415 10416 Output Parameter: 10417 . is - contains the list of rows with off block diagonal entries 10418 10419 Level: developer 10420 10421 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 10422 @*/ 10423 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is) 10424 { 10425 PetscFunctionBegin; 10426 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10427 PetscValidType(mat,1); 10428 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10429 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10430 10431 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); 10432 PetscCall((*mat->ops->findoffblockdiagonalentries)(mat,is)); 10433 PetscFunctionReturn(0); 10434 } 10435 10436 /*@C 10437 MatInvertBlockDiagonal - Inverts the block diagonal entries. 10438 10439 Collective on Mat 10440 10441 Input Parameters: 10442 . mat - the matrix 10443 10444 Output Parameters: 10445 . values - the block inverses in column major order (FORTRAN-like) 10446 10447 Note: 10448 The size of the blocks is determined by the block size of the matrix. 10449 10450 Fortran Note: 10451 This routine is not available from Fortran. 10452 10453 Level: advanced 10454 10455 .seealso: `MatInvertVariableBlockEnvelope()`, `MatInvertBlockDiagonalMat()` 10456 @*/ 10457 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values) 10458 { 10459 PetscFunctionBegin; 10460 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10461 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10462 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10463 PetscCheck(mat->ops->invertblockdiagonal,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for type %s",((PetscObject)mat)->type_name); 10464 PetscCall((*mat->ops->invertblockdiagonal)(mat,values)); 10465 PetscFunctionReturn(0); 10466 } 10467 10468 /*@C 10469 MatInvertVariableBlockDiagonal - Inverts the point block diagonal entries. 10470 10471 Collective on Mat 10472 10473 Input Parameters: 10474 + mat - the matrix 10475 . nblocks - the number of blocks on the process, set with MatSetVariableBlockSizes() 10476 - bsizes - the size of each block on the process, set with MatSetVariableBlockSizes() 10477 10478 Output Parameters: 10479 . values - the block inverses in column major order (FORTRAN-like) 10480 10481 Note: 10482 This routine is not available from Fortran. 10483 10484 Level: advanced 10485 10486 .seealso: `MatInvertBlockDiagonal()`, `MatSetVariableBlockSizes()`, `MatInvertVariableBlockEnvelope()` 10487 @*/ 10488 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values) 10489 { 10490 PetscFunctionBegin; 10491 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10492 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10493 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10494 PetscCheck(mat->ops->invertvariableblockdiagonal,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for type %s",((PetscObject)mat)->type_name); 10495 PetscCall((*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values)); 10496 PetscFunctionReturn(0); 10497 } 10498 10499 /*@ 10500 MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A 10501 10502 Collective on Mat 10503 10504 Input Parameters: 10505 . A - the matrix 10506 10507 Output Parameters: 10508 . C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set. 10509 10510 Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C 10511 10512 Level: advanced 10513 10514 .seealso: `MatInvertBlockDiagonal()` 10515 @*/ 10516 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C) 10517 { 10518 const PetscScalar *vals; 10519 PetscInt *dnnz; 10520 PetscInt m,rstart,rend,bs,i,j; 10521 10522 PetscFunctionBegin; 10523 PetscCall(MatInvertBlockDiagonal(A,&vals)); 10524 PetscCall(MatGetBlockSize(A,&bs)); 10525 PetscCall(MatGetLocalSize(A,&m,NULL)); 10526 PetscCall(MatSetLayouts(C,A->rmap,A->cmap)); 10527 PetscCall(PetscMalloc1(m/bs,&dnnz)); 10528 for (j = 0; j < m/bs; j++) dnnz[j] = 1; 10529 PetscCall(MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL)); 10530 PetscCall(PetscFree(dnnz)); 10531 PetscCall(MatGetOwnershipRange(C,&rstart,&rend)); 10532 PetscCall(MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE)); 10533 for (i = rstart/bs; i < rend/bs; i++) { 10534 PetscCall(MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES)); 10535 } 10536 PetscCall(MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY)); 10537 PetscCall(MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY)); 10538 PetscCall(MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE)); 10539 PetscFunctionReturn(0); 10540 } 10541 10542 /*@C 10543 MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created 10544 via MatTransposeColoringCreate(). 10545 10546 Collective on MatTransposeColoring 10547 10548 Input Parameter: 10549 . c - coloring context 10550 10551 Level: intermediate 10552 10553 .seealso: `MatTransposeColoringCreate()` 10554 @*/ 10555 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c) 10556 { 10557 MatTransposeColoring matcolor=*c; 10558 10559 PetscFunctionBegin; 10560 if (!matcolor) PetscFunctionReturn(0); 10561 if (--((PetscObject)matcolor)->refct > 0) {matcolor = NULL; PetscFunctionReturn(0);} 10562 10563 PetscCall(PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow)); 10564 PetscCall(PetscFree(matcolor->rows)); 10565 PetscCall(PetscFree(matcolor->den2sp)); 10566 PetscCall(PetscFree(matcolor->colorforcol)); 10567 PetscCall(PetscFree(matcolor->columns)); 10568 if (matcolor->brows>0) PetscCall(PetscFree(matcolor->lstart)); 10569 PetscCall(PetscHeaderDestroy(c)); 10570 PetscFunctionReturn(0); 10571 } 10572 10573 /*@C 10574 MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which 10575 a MatTransposeColoring context has been created, computes a dense B^T by Apply 10576 MatTransposeColoring to sparse B. 10577 10578 Collective on MatTransposeColoring 10579 10580 Input Parameters: 10581 + B - sparse matrix B 10582 . Btdense - symbolic dense matrix B^T 10583 - coloring - coloring context created with MatTransposeColoringCreate() 10584 10585 Output Parameter: 10586 . Btdense - dense matrix B^T 10587 10588 Level: advanced 10589 10590 Notes: 10591 These are used internally for some implementations of MatRARt() 10592 10593 .seealso: `MatTransposeColoringCreate()`, `MatTransposeColoringDestroy()`, `MatTransColoringApplyDenToSp()` 10594 10595 @*/ 10596 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense) 10597 { 10598 PetscFunctionBegin; 10599 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 10600 PetscValidHeaderSpecific(Btdense,MAT_CLASSID,3); 10601 PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,1); 10602 10603 PetscCheck(B->ops->transcoloringapplysptoden,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name); 10604 PetscCall((B->ops->transcoloringapplysptoden)(coloring,B,Btdense)); 10605 PetscFunctionReturn(0); 10606 } 10607 10608 /*@C 10609 MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which 10610 a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense 10611 in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix 10612 Csp from Cden. 10613 10614 Collective on MatTransposeColoring 10615 10616 Input Parameters: 10617 + coloring - coloring context created with MatTransposeColoringCreate() 10618 - Cden - matrix product of a sparse matrix and a dense matrix Btdense 10619 10620 Output Parameter: 10621 . Csp - sparse matrix 10622 10623 Level: advanced 10624 10625 Notes: 10626 These are used internally for some implementations of MatRARt() 10627 10628 .seealso: `MatTransposeColoringCreate()`, `MatTransposeColoringDestroy()`, `MatTransColoringApplySpToDen()` 10629 10630 @*/ 10631 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp) 10632 { 10633 PetscFunctionBegin; 10634 PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1); 10635 PetscValidHeaderSpecific(Cden,MAT_CLASSID,2); 10636 PetscValidHeaderSpecific(Csp,MAT_CLASSID,3); 10637 10638 PetscCheck(Csp->ops->transcoloringapplydentosp,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name); 10639 PetscCall((Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp)); 10640 PetscCall(MatAssemblyBegin(Csp,MAT_FINAL_ASSEMBLY)); 10641 PetscCall(MatAssemblyEnd(Csp,MAT_FINAL_ASSEMBLY)); 10642 PetscFunctionReturn(0); 10643 } 10644 10645 /*@C 10646 MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T. 10647 10648 Collective on Mat 10649 10650 Input Parameters: 10651 + mat - the matrix product C 10652 - iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring() 10653 10654 Output Parameter: 10655 . color - the new coloring context 10656 10657 Level: intermediate 10658 10659 .seealso: `MatTransposeColoringDestroy()`, `MatTransColoringApplySpToDen()`, 10660 `MatTransColoringApplyDenToSp()` 10661 @*/ 10662 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color) 10663 { 10664 MatTransposeColoring c; 10665 MPI_Comm comm; 10666 10667 PetscFunctionBegin; 10668 PetscCall(PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0)); 10669 PetscCall(PetscObjectGetComm((PetscObject)mat,&comm)); 10670 PetscCall(PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL)); 10671 10672 c->ctype = iscoloring->ctype; 10673 if (mat->ops->transposecoloringcreate) { 10674 PetscCall((*mat->ops->transposecoloringcreate)(mat,iscoloring,c)); 10675 } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for matrix type %s",((PetscObject)mat)->type_name); 10676 10677 *color = c; 10678 PetscCall(PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0)); 10679 PetscFunctionReturn(0); 10680 } 10681 10682 /*@ 10683 MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the 10684 matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the 10685 same, otherwise it will be larger 10686 10687 Not Collective 10688 10689 Input Parameter: 10690 . A - the matrix 10691 10692 Output Parameter: 10693 . state - the current state 10694 10695 Notes: 10696 You can only compare states from two different calls to the SAME matrix, you cannot compare calls between 10697 different matrices 10698 10699 Level: intermediate 10700 10701 .seealso: `PetscObjectStateGet()` 10702 @*/ 10703 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state) 10704 { 10705 PetscFunctionBegin; 10706 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10707 *state = mat->nonzerostate; 10708 PetscFunctionReturn(0); 10709 } 10710 10711 /*@ 10712 MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential 10713 matrices from each processor 10714 10715 Collective 10716 10717 Input Parameters: 10718 + comm - the communicators the parallel matrix will live on 10719 . seqmat - the input sequential matrices 10720 . n - number of local columns (or PETSC_DECIDE) 10721 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10722 10723 Output Parameter: 10724 . mpimat - the parallel matrix generated 10725 10726 Level: advanced 10727 10728 Notes: 10729 The number of columns of the matrix in EACH processor MUST be the same. 10730 10731 @*/ 10732 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat) 10733 { 10734 PetscMPIInt size; 10735 10736 PetscFunctionBegin; 10737 PetscCallMPI(MPI_Comm_size(comm,&size)); 10738 if (size == 1) { 10739 if (reuse == MAT_INITIAL_MATRIX) { 10740 PetscCall(MatDuplicate(seqmat,MAT_COPY_VALUES,mpimat)); 10741 } else { 10742 PetscCall(MatCopy(seqmat,*mpimat,SAME_NONZERO_PATTERN)); 10743 } 10744 PetscFunctionReturn(0); 10745 } 10746 10747 PetscCheck(seqmat->ops->creatempimatconcatenateseqmat,PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name); 10748 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"); 10749 10750 PetscCall(PetscLogEventBegin(MAT_Merge,seqmat,0,0,0)); 10751 PetscCall((*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat)); 10752 PetscCall(PetscLogEventEnd(MAT_Merge,seqmat,0,0,0)); 10753 PetscFunctionReturn(0); 10754 } 10755 10756 /*@ 10757 MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent 10758 ranks' ownership ranges. 10759 10760 Collective on A 10761 10762 Input Parameters: 10763 + A - the matrix to create subdomains from 10764 - N - requested number of subdomains 10765 10766 Output Parameters: 10767 + n - number of subdomains resulting on this rank 10768 - iss - IS list with indices of subdomains on this rank 10769 10770 Level: advanced 10771 10772 Notes: 10773 number of subdomains must be smaller than the communicator size 10774 @*/ 10775 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[]) 10776 { 10777 MPI_Comm comm,subcomm; 10778 PetscMPIInt size,rank,color; 10779 PetscInt rstart,rend,k; 10780 10781 PetscFunctionBegin; 10782 PetscCall(PetscObjectGetComm((PetscObject)A,&comm)); 10783 PetscCallMPI(MPI_Comm_size(comm,&size)); 10784 PetscCallMPI(MPI_Comm_rank(comm,&rank)); 10785 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); 10786 *n = 1; 10787 k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */ 10788 color = rank/k; 10789 PetscCallMPI(MPI_Comm_split(comm,color,rank,&subcomm)); 10790 PetscCall(PetscMalloc1(1,iss)); 10791 PetscCall(MatGetOwnershipRange(A,&rstart,&rend)); 10792 PetscCall(ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0])); 10793 PetscCallMPI(MPI_Comm_free(&subcomm)); 10794 PetscFunctionReturn(0); 10795 } 10796 10797 /*@ 10798 MatGalerkin - Constructs the coarse grid problem via Galerkin projection. 10799 10800 If the interpolation and restriction operators are the same, uses MatPtAP. 10801 If they are not the same, use MatMatMatMult. 10802 10803 Once the coarse grid problem is constructed, correct for interpolation operators 10804 that are not of full rank, which can legitimately happen in the case of non-nested 10805 geometric multigrid. 10806 10807 Input Parameters: 10808 + restrct - restriction operator 10809 . dA - fine grid matrix 10810 . interpolate - interpolation operator 10811 . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10812 - fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate 10813 10814 Output Parameters: 10815 . A - the Galerkin coarse matrix 10816 10817 Options Database Key: 10818 . -pc_mg_galerkin <both,pmat,mat,none> - for what matrices the Galerkin process should be used 10819 10820 Level: developer 10821 10822 .seealso: `MatPtAP()`, `MatMatMatMult()` 10823 @*/ 10824 PetscErrorCode MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A) 10825 { 10826 IS zerorows; 10827 Vec diag; 10828 10829 PetscFunctionBegin; 10830 PetscCheck(reuse != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 10831 /* Construct the coarse grid matrix */ 10832 if (interpolate == restrct) { 10833 PetscCall(MatPtAP(dA,interpolate,reuse,fill,A)); 10834 } else { 10835 PetscCall(MatMatMatMult(restrct,dA,interpolate,reuse,fill,A)); 10836 } 10837 10838 /* If the interpolation matrix is not of full rank, A will have zero rows. 10839 This can legitimately happen in the case of non-nested geometric multigrid. 10840 In that event, we set the rows of the matrix to the rows of the identity, 10841 ignoring the equations (as the RHS will also be zero). */ 10842 10843 PetscCall(MatFindZeroRows(*A, &zerorows)); 10844 10845 if (zerorows != NULL) { /* if there are any zero rows */ 10846 PetscCall(MatCreateVecs(*A, &diag, NULL)); 10847 PetscCall(MatGetDiagonal(*A, diag)); 10848 PetscCall(VecISSet(diag, zerorows, 1.0)); 10849 PetscCall(MatDiagonalSet(*A, diag, INSERT_VALUES)); 10850 PetscCall(VecDestroy(&diag)); 10851 PetscCall(ISDestroy(&zerorows)); 10852 } 10853 PetscFunctionReturn(0); 10854 } 10855 10856 /*@C 10857 MatSetOperation - Allows user to set a matrix operation for any matrix type 10858 10859 Logically Collective on Mat 10860 10861 Input Parameters: 10862 + mat - the matrix 10863 . op - the name of the operation 10864 - f - the function that provides the operation 10865 10866 Level: developer 10867 10868 Usage: 10869 $ extern PetscErrorCode usermult(Mat,Vec,Vec); 10870 $ PetscCall(MatCreateXXX(comm,...&A); 10871 $ PetscCall(MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult); 10872 10873 Notes: 10874 See the file include/petscmat.h for a complete list of matrix 10875 operations, which all have the form MATOP_<OPERATION>, where 10876 <OPERATION> is the name (in all capital letters) of the 10877 user interface routine (e.g., MatMult() -> MATOP_MULT). 10878 10879 All user-provided functions (except for MATOP_DESTROY) should have the same calling 10880 sequence as the usual matrix interface routines, since they 10881 are intended to be accessed via the usual matrix interface 10882 routines, e.g., 10883 $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 10884 10885 In particular each function MUST return an error code of 0 on success and 10886 nonzero on failure. 10887 10888 This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type. 10889 10890 .seealso: `MatGetOperation()`, `MatCreateShell()`, `MatShellSetContext()`, `MatShellSetOperation()` 10891 @*/ 10892 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void)) 10893 { 10894 PetscFunctionBegin; 10895 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10896 if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) { 10897 mat->ops->viewnative = mat->ops->view; 10898 } 10899 (((void(**)(void))mat->ops)[op]) = f; 10900 PetscFunctionReturn(0); 10901 } 10902 10903 /*@C 10904 MatGetOperation - Gets a matrix operation for any matrix type. 10905 10906 Not Collective 10907 10908 Input Parameters: 10909 + mat - the matrix 10910 - op - the name of the operation 10911 10912 Output Parameter: 10913 . f - the function that provides the operation 10914 10915 Level: developer 10916 10917 Usage: 10918 $ PetscErrorCode (*usermult)(Mat,Vec,Vec); 10919 $ MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult); 10920 10921 Notes: 10922 See the file include/petscmat.h for a complete list of matrix 10923 operations, which all have the form MATOP_<OPERATION>, where 10924 <OPERATION> is the name (in all capital letters) of the 10925 user interface routine (e.g., MatMult() -> MATOP_MULT). 10926 10927 This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type. 10928 10929 .seealso: `MatSetOperation()`, `MatCreateShell()`, `MatShellGetContext()`, `MatShellGetOperation()` 10930 @*/ 10931 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void)) 10932 { 10933 PetscFunctionBegin; 10934 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10935 *f = (((void (**)(void))mat->ops)[op]); 10936 PetscFunctionReturn(0); 10937 } 10938 10939 /*@ 10940 MatHasOperation - Determines whether the given matrix supports the particular 10941 operation. 10942 10943 Not Collective 10944 10945 Input Parameters: 10946 + mat - the matrix 10947 - op - the operation, for example, MATOP_GET_DIAGONAL 10948 10949 Output Parameter: 10950 . has - either PETSC_TRUE or PETSC_FALSE 10951 10952 Level: advanced 10953 10954 Notes: 10955 See the file include/petscmat.h for a complete list of matrix 10956 operations, which all have the form MATOP_<OPERATION>, where 10957 <OPERATION> is the name (in all capital letters) of the 10958 user-level routine. E.g., MatNorm() -> MATOP_NORM. 10959 10960 .seealso: `MatCreateShell()` 10961 @*/ 10962 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has) 10963 { 10964 PetscFunctionBegin; 10965 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10966 PetscValidBoolPointer(has,3); 10967 if (mat->ops->hasoperation) { 10968 PetscCall((*mat->ops->hasoperation)(mat,op,has)); 10969 } else { 10970 if (((void**)mat->ops)[op]) *has = PETSC_TRUE; 10971 else { 10972 *has = PETSC_FALSE; 10973 if (op == MATOP_CREATE_SUBMATRIX) { 10974 PetscMPIInt size; 10975 10976 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 10977 if (size == 1) { 10978 PetscCall(MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has)); 10979 } 10980 } 10981 } 10982 } 10983 PetscFunctionReturn(0); 10984 } 10985 10986 /*@ 10987 MatHasCongruentLayouts - Determines whether the rows and columns layouts 10988 of the matrix are congruent 10989 10990 Collective on mat 10991 10992 Input Parameters: 10993 . mat - the matrix 10994 10995 Output Parameter: 10996 . cong - either PETSC_TRUE or PETSC_FALSE 10997 10998 Level: beginner 10999 11000 Notes: 11001 11002 .seealso: `MatCreate()`, `MatSetSizes()` 11003 @*/ 11004 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong) 11005 { 11006 PetscFunctionBegin; 11007 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 11008 PetscValidType(mat,1); 11009 PetscValidBoolPointer(cong,2); 11010 if (!mat->rmap || !mat->cmap) { 11011 *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE; 11012 PetscFunctionReturn(0); 11013 } 11014 if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */ 11015 PetscCall(PetscLayoutSetUp(mat->rmap)); 11016 PetscCall(PetscLayoutSetUp(mat->cmap)); 11017 PetscCall(PetscLayoutCompare(mat->rmap,mat->cmap,cong)); 11018 if (*cong) mat->congruentlayouts = 1; 11019 else mat->congruentlayouts = 0; 11020 } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE; 11021 PetscFunctionReturn(0); 11022 } 11023 11024 PetscErrorCode MatSetInf(Mat A) 11025 { 11026 PetscFunctionBegin; 11027 PetscCheck(A->ops->setinf,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"No support for this operation for this matrix type"); 11028 PetscCall((*A->ops->setinf)(A)); 11029 PetscFunctionReturn(0); 11030 } 11031 11032 /*C 11033 MatCreateGraph - create a scalar matrix, for use in graph algorithms 11034 11035 Collective on mat 11036 11037 Input Parameters: 11038 + A - the matrix 11039 - sym - PETSC_TRUE indicates that the graph will be symmetrized 11040 . scale - PETSC_TRUE indicates that the graph will be scaled with the diagonal 11041 11042 Output Parameter: 11043 . graph - the resulting graph 11044 11045 Level: advanced 11046 11047 Notes: 11048 11049 .seealso: `MatCreate()`, `MatFilter()` 11050 */ 11051 PETSC_EXTERN PetscErrorCode MatCreateGraph(Mat A, PetscBool sym, PetscBool scale, Mat *graph) 11052 { 11053 PetscFunctionBegin; 11054 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 11055 PetscValidType(A,1); 11056 PetscValidPointer(graph,3); 11057 PetscCheck(A->ops->creategraph,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"No support for this operation for this matrix type"); 11058 PetscCall((*A->ops->creategraph)(A,sym,scale,graph)); 11059 PetscFunctionReturn(0); 11060 } 11061 11062 /*C 11063 MatFilter - filters a Mat values with an absolut value equal to or below a give threshold 11064 11065 Collective on mat 11066 11067 Input Parameter: 11068 . value - filter value - < 0: does nothing; == 0: removes only 0.0 entries; otherwise: removes entries <= value 11069 11070 Input/Output Parameter: 11071 . A - the Mat to filter in place 11072 11073 Level: advanced 11074 11075 Notes: 11076 11077 .seealso: `MatCreate()`, `MatCreateGraph()` 11078 */ 11079 PETSC_EXTERN PetscErrorCode MatFilter(Mat G,PetscReal value,Mat *F) 11080 { 11081 PetscFunctionBegin; 11082 PetscValidHeaderSpecific(G,MAT_CLASSID,1); 11083 PetscValidType(G,1); 11084 PetscValidPointer(F,3); 11085 if (value >= 0.0) { 11086 PetscCheck(G->ops->filter,PetscObjectComm((PetscObject)G),PETSC_ERR_SUP,"No support for this operation for this matrix type"); 11087 PetscCall((G->ops->filter)(G,value,F)); 11088 } 11089 PetscFunctionReturn(0); 11090 } 11091