1 /* 2 This is where the abstract matrix operations are defined 3 */ 4 5 #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/ 6 #include <petsc/private/isimpl.h> 7 #include <petsc/private/vecimpl.h> 8 9 /* Logging support */ 10 PetscClassId MAT_CLASSID; 11 PetscClassId MAT_COLORING_CLASSID; 12 PetscClassId MAT_FDCOLORING_CLASSID; 13 PetscClassId MAT_TRANSPOSECOLORING_CLASSID; 14 15 PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultAdd, MAT_MultTranspose; 16 PetscLogEvent MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve,MAT_MatTrSolve; 17 PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic; 18 PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor; 19 PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin; 20 PetscLogEvent MAT_QRFactorNumeric, MAT_QRFactorSymbolic, MAT_QRFactor; 21 PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_CreateSubMats, MAT_GetOrdering, MAT_RedundantMat, MAT_GetSeqNonzeroStructure; 22 PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_PartitioningND, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate; 23 PetscLogEvent MAT_FDColoringSetUp, MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction, MAT_CreateSubMat; 24 PetscLogEvent MAT_TransposeColoringCreate; 25 PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric; 26 PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric; 27 PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric; 28 PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric; 29 PetscLogEvent MAT_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric; 30 PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd; 31 PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_GetBrowsOfAcols; 32 PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym; 33 PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure; 34 PetscLogEvent MAT_GetMultiProcBlock; 35 PetscLogEvent MAT_CUSPARSECopyToGPU, MAT_CUSPARSECopyFromGPU, MAT_CUSPARSEGenerateTranspose, MAT_CUSPARSESolveAnalysis; 36 PetscLogEvent MAT_PreallCOO, MAT_SetVCOO; 37 PetscLogEvent MAT_SetValuesBatch; 38 PetscLogEvent MAT_ViennaCLCopyToGPU; 39 PetscLogEvent MAT_DenseCopyToGPU, MAT_DenseCopyFromGPU; 40 PetscLogEvent MAT_Merge,MAT_Residual,MAT_SetRandom; 41 PetscLogEvent MAT_FactorFactS,MAT_FactorInvS; 42 PetscLogEvent MATCOLORING_Apply,MATCOLORING_Comm,MATCOLORING_Local,MATCOLORING_ISCreate,MATCOLORING_SetUp,MATCOLORING_Weights; 43 PetscLogEvent MAT_H2Opus_Build,MAT_H2Opus_Compress,MAT_H2Opus_Orthog,MAT_H2Opus_LR; 44 45 const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","QR","MatFactorType","MAT_FACTOR_",NULL}; 46 47 /*@ 48 MatSetRandom - Sets all components of a matrix to random numbers. For sparse matrices that have been preallocated but not been assembled it randomly selects appropriate locations, 49 for sparse matrices that already have locations it fills the locations with random numbers 50 51 Logically Collective on Mat 52 53 Input Parameters: 54 + x - the matrix 55 - rctx - the random number context, formed by `PetscRandomCreate()`, or NULL and 56 it will create one internally. 57 58 Output Parameter: 59 . x - the matrix 60 61 Example of Usage: 62 .vb 63 PetscRandomCreate(PETSC_COMM_WORLD,&rctx); 64 MatSetRandom(x,rctx); 65 PetscRandomDestroy(rctx); 66 .ve 67 68 Level: intermediate 69 70 .seealso: `MatZeroEntries()`, `MatSetValues()`, `PetscRandomCreate()`, `PetscRandomDestroy()` 71 @*/ 72 PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx) 73 { 74 PetscRandom randObj = NULL; 75 76 PetscFunctionBegin; 77 PetscValidHeaderSpecific(x,MAT_CLASSID,1); 78 if (rctx) PetscValidHeaderSpecific(rctx,PETSC_RANDOM_CLASSID,2); 79 PetscValidType(x,1); 80 MatCheckPreallocated(x,1); 81 82 PetscCheck(x->ops->setrandom,PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Mat type %s",((PetscObject)x)->type_name); 83 84 if (!rctx) { 85 MPI_Comm comm; 86 PetscCall(PetscObjectGetComm((PetscObject)x,&comm)); 87 PetscCall(PetscRandomCreate(comm,&randObj)); 88 PetscCall(PetscRandomSetFromOptions(randObj)); 89 rctx = randObj; 90 } 91 PetscCall(PetscLogEventBegin(MAT_SetRandom,x,rctx,0,0)); 92 PetscCall((*x->ops->setrandom)(x,rctx)); 93 PetscCall(PetscLogEventEnd(MAT_SetRandom,x,rctx,0,0)); 94 95 PetscCall(MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY)); 96 PetscCall(MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY)); 97 PetscCall(PetscRandomDestroy(&randObj)); 98 PetscFunctionReturn(0); 99 } 100 101 /*@ 102 MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in 103 104 Logically Collective on Mat 105 106 Input Parameter: 107 . mat - the factored matrix 108 109 Output Parameters: 110 + pivot - the pivot value computed 111 - row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes 112 the share the matrix 113 114 Level: advanced 115 116 Notes: 117 This routine does not work for factorizations done with external packages. 118 119 This routine should only be called if `MatGetFactorError()` returns a value of `MAT_FACTOR_NUMERIC_ZEROPIVOT` 120 121 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 122 123 .seealso: `MatZeroEntries()`, `MatFactor()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()`, `MatFactorClearError()`, `MatFactorGetErrorZeroPivot()` 124 @*/ 125 PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row) 126 { 127 PetscFunctionBegin; 128 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 129 PetscValidRealPointer(pivot,2); 130 PetscValidIntPointer(row,3); 131 *pivot = mat->factorerror_zeropivot_value; 132 *row = mat->factorerror_zeropivot_row; 133 PetscFunctionReturn(0); 134 } 135 136 /*@ 137 MatFactorGetError - gets the error code from a factorization 138 139 Logically Collective on Mat 140 141 Input Parameters: 142 . mat - the factored matrix 143 144 Output Parameter: 145 . err - the error code 146 147 Level: advanced 148 149 Notes: 150 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 151 152 .seealso: `MatZeroEntries()`, `MatFactor()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()`, `MatFactorClearError()`, `MatFactorGetErrorZeroPivot()`, 153 `MatErrorCode` 154 @*/ 155 PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err) 156 { 157 PetscFunctionBegin; 158 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 159 PetscValidPointer(err,2); 160 *err = mat->factorerrortype; 161 PetscFunctionReturn(0); 162 } 163 164 /*@ 165 MatFactorClearError - clears the error code in a factorization 166 167 Logically Collective on Mat 168 169 Input Parameter: 170 . mat - the factored matrix 171 172 Level: developer 173 174 Notes: 175 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 176 177 .seealso: `MatZeroEntries()`, `MatFactor()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()`, `MatFactorGetError()`, `MatFactorGetErrorZeroPivot()`, 178 `MatGetErrorCode()`, `MatErrorCode` 179 @*/ 180 PetscErrorCode MatFactorClearError(Mat mat) 181 { 182 PetscFunctionBegin; 183 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 184 mat->factorerrortype = MAT_FACTOR_NOERROR; 185 mat->factorerror_zeropivot_value = 0.0; 186 mat->factorerror_zeropivot_row = 0; 187 PetscFunctionReturn(0); 188 } 189 190 PETSC_INTERN PetscErrorCode MatFindNonzeroRowsOrCols_Basic(Mat mat,PetscBool cols,PetscReal tol,IS *nonzero) 191 { 192 Vec r,l; 193 const PetscScalar *al; 194 PetscInt i,nz,gnz,N,n; 195 196 PetscFunctionBegin; 197 PetscCall(MatCreateVecs(mat,&r,&l)); 198 if (!cols) { /* nonzero rows */ 199 PetscCall(MatGetSize(mat,&N,NULL)); 200 PetscCall(MatGetLocalSize(mat,&n,NULL)); 201 PetscCall(VecSet(l,0.0)); 202 PetscCall(VecSetRandom(r,NULL)); 203 PetscCall(MatMult(mat,r,l)); 204 PetscCall(VecGetArrayRead(l,&al)); 205 } else { /* nonzero columns */ 206 PetscCall(MatGetSize(mat,NULL,&N)); 207 PetscCall(MatGetLocalSize(mat,NULL,&n)); 208 PetscCall(VecSet(r,0.0)); 209 PetscCall(VecSetRandom(l,NULL)); 210 PetscCall(MatMultTranspose(mat,l,r)); 211 PetscCall(VecGetArrayRead(r,&al)); 212 } 213 if (tol <= 0.0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++; } 214 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nz++; } 215 PetscCall(MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat))); 216 if (gnz != N) { 217 PetscInt *nzr; 218 PetscCall(PetscMalloc1(nz,&nzr)); 219 if (nz) { 220 if (tol < 0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; } 221 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nzr[nz++] = i; } 222 } 223 PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,nonzero)); 224 } else *nonzero = NULL; 225 if (!cols) { /* nonzero rows */ 226 PetscCall(VecRestoreArrayRead(l,&al)); 227 } else { 228 PetscCall(VecRestoreArrayRead(r,&al)); 229 } 230 PetscCall(VecDestroy(&l)); 231 PetscCall(VecDestroy(&r)); 232 PetscFunctionReturn(0); 233 } 234 235 /*@ 236 MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix 237 238 Input Parameter: 239 . A - the matrix 240 241 Output Parameter: 242 . keptrows - the rows that are not completely zero 243 244 Notes: 245 keptrows is set to NULL if all rows are nonzero. 246 247 Level: intermediate 248 249 @*/ 250 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows) 251 { 252 PetscFunctionBegin; 253 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 254 PetscValidType(mat,1); 255 PetscValidPointer(keptrows,2); 256 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 257 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 258 if (mat->ops->findnonzerorows) { 259 PetscCall((*mat->ops->findnonzerorows)(mat,keptrows)); 260 } else { 261 PetscCall(MatFindNonzeroRowsOrCols_Basic(mat,PETSC_FALSE,0.0,keptrows)); 262 } 263 PetscFunctionReturn(0); 264 } 265 266 /*@ 267 MatFindZeroRows - Locate all rows that are completely zero in the matrix 268 269 Input Parameter: 270 . A - the matrix 271 272 Output Parameter: 273 . zerorows - the rows that are completely zero 274 275 Notes: 276 zerorows is set to NULL if no rows are zero. 277 278 Level: intermediate 279 280 @*/ 281 PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows) 282 { 283 IS keptrows; 284 PetscInt m, n; 285 286 PetscFunctionBegin; 287 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 288 PetscValidType(mat,1); 289 PetscValidPointer(zerorows,2); 290 PetscCall(MatFindNonzeroRows(mat, &keptrows)); 291 /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows. 292 In keeping with this convention, we set zerorows to NULL if there are no zero 293 rows. */ 294 if (keptrows == NULL) { 295 *zerorows = NULL; 296 } else { 297 PetscCall(MatGetOwnershipRange(mat,&m,&n)); 298 PetscCall(ISComplement(keptrows,m,n,zerorows)); 299 PetscCall(ISDestroy(&keptrows)); 300 } 301 PetscFunctionReturn(0); 302 } 303 304 /*@ 305 MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling 306 307 Not Collective 308 309 Input Parameters: 310 . A - the matrix 311 312 Output Parameters: 313 . a - the diagonal part (which is a SEQUENTIAL matrix) 314 315 Notes: 316 See the manual page for `MatCreateAIJ()` for more information on the "diagonal part" of the matrix. 317 318 Use caution, as the reference count on the returned matrix is not incremented and it is used as part of the containing MPI Mat's normal operation. 319 320 Level: advanced 321 322 .seelaso: `MatCreateAIJ()` 323 @*/ 324 PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a) 325 { 326 PetscFunctionBegin; 327 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 328 PetscValidType(A,1); 329 PetscValidPointer(a,2); 330 PetscCheck(!A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 331 if (A->ops->getdiagonalblock) { 332 PetscCall((*A->ops->getdiagonalblock)(A,a)); 333 } else { 334 PetscMPIInt size; 335 336 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)A),&size)); 337 PetscCheck(size == 1,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not for parallel matrix type %s",((PetscObject)A)->type_name); 338 *a = A; 339 } 340 PetscFunctionReturn(0); 341 } 342 343 /*@ 344 MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries. 345 346 Collective on Mat 347 348 Input Parameters: 349 . mat - the matrix 350 351 Output Parameter: 352 . trace - the sum of the diagonal entries 353 354 Level: advanced 355 356 @*/ 357 PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace) 358 { 359 Vec diag; 360 361 PetscFunctionBegin; 362 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 363 PetscValidScalarPointer(trace,2); 364 PetscCall(MatCreateVecs(mat,&diag,NULL)); 365 PetscCall(MatGetDiagonal(mat,diag)); 366 PetscCall(VecSum(diag,trace)); 367 PetscCall(VecDestroy(&diag)); 368 PetscFunctionReturn(0); 369 } 370 371 /*@ 372 MatRealPart - Zeros out the imaginary part of the matrix 373 374 Logically Collective on Mat 375 376 Input Parameters: 377 . mat - the matrix 378 379 Level: advanced 380 381 .seealso: `MatImaginaryPart()` 382 @*/ 383 PetscErrorCode MatRealPart(Mat mat) 384 { 385 PetscFunctionBegin; 386 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 387 PetscValidType(mat,1); 388 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 389 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 390 PetscCheck(mat->ops->realpart,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 391 MatCheckPreallocated(mat,1); 392 PetscCall((*mat->ops->realpart)(mat)); 393 PetscFunctionReturn(0); 394 } 395 396 /*@C 397 MatGetGhosts - Get the global indices of all ghost nodes defined by the sparse matrix 398 399 Collective on Mat 400 401 Input Parameter: 402 . mat - the matrix 403 404 Output Parameters: 405 + nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block) 406 - ghosts - the global indices of the ghost points 407 408 Notes: 409 the nghosts and ghosts are suitable to pass into `VecCreateGhost()` 410 411 Level: advanced 412 413 @*/ 414 PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[]) 415 { 416 PetscFunctionBegin; 417 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 418 PetscValidType(mat,1); 419 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 420 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 421 if (mat->ops->getghosts) { 422 PetscCall((*mat->ops->getghosts)(mat,nghosts,ghosts)); 423 } else { 424 if (nghosts) *nghosts = 0; 425 if (ghosts) *ghosts = NULL; 426 } 427 PetscFunctionReturn(0); 428 } 429 430 /*@ 431 MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part 432 433 Logically Collective on Mat 434 435 Input Parameters: 436 . mat - the matrix 437 438 Level: advanced 439 440 .seealso: `MatRealPart()` 441 @*/ 442 PetscErrorCode MatImaginaryPart(Mat mat) 443 { 444 PetscFunctionBegin; 445 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 446 PetscValidType(mat,1); 447 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 448 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 449 PetscCheck(mat->ops->imaginarypart,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 450 MatCheckPreallocated(mat,1); 451 PetscCall((*mat->ops->imaginarypart)(mat)); 452 PetscFunctionReturn(0); 453 } 454 455 /*@ 456 MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices) 457 458 Not Collective 459 460 Input Parameter: 461 . mat - the matrix 462 463 Output Parameters: 464 + missing - is any diagonal missing 465 - dd - first diagonal entry that is missing (optional) on this process 466 467 Level: advanced 468 469 .seealso: `MatRealPart()` 470 @*/ 471 PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd) 472 { 473 PetscFunctionBegin; 474 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 475 PetscValidType(mat,1); 476 PetscValidBoolPointer(missing,2); 477 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix %s",((PetscObject)mat)->type_name); 478 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 479 PetscCheck(mat->ops->missingdiagonal,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 480 PetscCall((*mat->ops->missingdiagonal)(mat,missing,dd)); 481 PetscFunctionReturn(0); 482 } 483 484 /*@C 485 MatGetRow - Gets a row of a matrix. You MUST call `MatRestoreRow()` 486 for each row that you get to ensure that your application does 487 not bleed memory. 488 489 Not Collective 490 491 Input Parameters: 492 + mat - the matrix 493 - row - the row to get 494 495 Output Parameters: 496 + ncols - if not NULL, the number of nonzeros in the row 497 . cols - if not NULL, the column numbers 498 - vals - if not NULL, the values 499 500 Notes: 501 This routine is provided for people who need to have direct access 502 to the structure of a matrix. We hope that we provide enough 503 high-level matrix routines that few users will need it. 504 505 `MatGetRow()` always returns 0-based column indices, regardless of 506 whether the internal representation is 0-based (default) or 1-based. 507 508 For better efficiency, set cols and/or vals to NULL if you do 509 not wish to extract these quantities. 510 511 The user can only examine the values extracted with `MatGetRow()`; 512 the values cannot be altered. To change the matrix entries, one 513 must use `MatSetValues()`. 514 515 You can only have one call to `MatGetRow()` outstanding for a particular 516 matrix at a time, per processor. `MatGetRow()` can only obtain rows 517 associated with the given processor, it cannot get rows from the 518 other processors; for that we suggest using `MatCreateSubMatrices()`, then 519 MatGetRow() on the submatrix. The row index passed to `MatGetRow()` 520 is in the global number of rows. 521 522 Use `MatGetRowIJ()` and `MatRestoreRowIJ()` to access all the local indices of the sparse matrix. 523 524 Use `MatSeqAIJGetArray()` and similar functions to access the numerical values for certain matrix types directly. 525 526 Fortran Notes: 527 The calling sequence from Fortran is 528 .vb 529 MatGetRow(matrix,row,ncols,cols,values,ierr) 530 Mat matrix (input) 531 integer row (input) 532 integer ncols (output) 533 integer cols(maxcols) (output) 534 double precision (or double complex) values(maxcols) output 535 .ve 536 where maxcols >= maximum nonzeros in any row of the matrix. 537 538 Caution: 539 Do not try to change the contents of the output arrays (cols and vals). 540 In some cases, this may corrupt the matrix. 541 542 Level: advanced 543 544 .seealso: `MatRestoreRow()`, `MatSetValues()`, `MatGetValues()`, `MatCreateSubMatrices()`, `MatGetDiagonal()`, `MatGetRowIJ()`, `MatRestoreRowIJ()` 545 @*/ 546 PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 547 { 548 PetscInt incols; 549 550 PetscFunctionBegin; 551 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 552 PetscValidType(mat,1); 553 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 554 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 555 PetscCheck(mat->ops->getrow,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 556 MatCheckPreallocated(mat,1); 557 PetscCheck(row >= mat->rmap->rstart && row < mat->rmap->rend,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Only for local rows, %" PetscInt_FMT " not in [%" PetscInt_FMT ",%" PetscInt_FMT ")",row,mat->rmap->rstart,mat->rmap->rend); 558 PetscCall(PetscLogEventBegin(MAT_GetRow,mat,0,0,0)); 559 PetscCall((*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals)); 560 if (ncols) *ncols = incols; 561 PetscCall(PetscLogEventEnd(MAT_GetRow,mat,0,0,0)); 562 PetscFunctionReturn(0); 563 } 564 565 /*@ 566 MatConjugate - replaces the matrix values with their complex conjugates 567 568 Logically Collective on Mat 569 570 Input Parameters: 571 . mat - the matrix 572 573 Level: advanced 574 575 .seealso: `VecConjugate()`, `MatTranspose()` 576 @*/ 577 PetscErrorCode MatConjugate(Mat mat) 578 { 579 PetscFunctionBegin; 580 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 581 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 582 if (PetscDefined(USE_COMPLEX) && mat->hermitian != PETSC_BOOL3_TRUE) { 583 PetscCheck(mat->ops->conjugate,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not provided for matrix type %s, send email to petsc-maint@mcs.anl.gov",((PetscObject)mat)->type_name); 584 PetscCall((*mat->ops->conjugate)(mat)); 585 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 586 } 587 PetscFunctionReturn(0); 588 } 589 590 /*@C 591 MatRestoreRow - Frees any temporary space allocated by `MatGetRow()`. 592 593 Not Collective 594 595 Input Parameters: 596 + mat - the matrix 597 . row - the row to get 598 . ncols, cols - the number of nonzeros and their columns 599 - vals - if nonzero the column values 600 601 Notes: 602 This routine should be called after you have finished examining the entries. 603 604 This routine zeros out ncols, cols, and vals. This is to prevent accidental 605 us of the array after it has been restored. If you pass NULL, it will 606 not zero the pointers. Use of cols or vals after `MatRestoreRow()` is invalid. 607 608 Fortran Notes: 609 The calling sequence from Fortran is 610 .vb 611 MatRestoreRow(matrix,row,ncols,cols,values,ierr) 612 Mat matrix (input) 613 integer row (input) 614 integer ncols (output) 615 integer cols(maxcols) (output) 616 double precision (or double complex) values(maxcols) output 617 .ve 618 Where maxcols >= maximum nonzeros in any row of the matrix. 619 620 In Fortran `MatRestoreRow()` MUST be called after `MatGetRow()` 621 before another call to `MatGetRow()` can be made. 622 623 Level: advanced 624 625 .seealso: `MatGetRow()` 626 @*/ 627 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 628 { 629 PetscFunctionBegin; 630 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 631 if (ncols) PetscValidIntPointer(ncols,3); 632 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 633 if (!mat->ops->restorerow) PetscFunctionReturn(0); 634 PetscCall((*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals)); 635 if (ncols) *ncols = 0; 636 if (cols) *cols = NULL; 637 if (vals) *vals = NULL; 638 PetscFunctionReturn(0); 639 } 640 641 /*@ 642 MatGetRowUpperTriangular - Sets a flag to enable calls to `MatGetRow()` for matrix in `MATSBAIJ` format. 643 You should call `MatRestoreRowUpperTriangular()` after calling` MatGetRow()` and `MatRestoreRow()` to disable the flag. 644 645 Not Collective 646 647 Input Parameters: 648 . mat - the matrix 649 650 Notes: 651 The flag is to ensure that users are aware of `MatGetRow()` only provides the upper triangular part of the row for the matrices in `MATSBAIJ` format. 652 653 Level: advanced 654 655 .seealso: `MatRestoreRowUpperTriangular()` 656 @*/ 657 PetscErrorCode MatGetRowUpperTriangular(Mat mat) 658 { 659 PetscFunctionBegin; 660 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 661 PetscValidType(mat,1); 662 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 663 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 664 MatCheckPreallocated(mat,1); 665 if (!mat->ops->getrowuppertriangular) PetscFunctionReturn(0); 666 PetscCall((*mat->ops->getrowuppertriangular)(mat)); 667 PetscFunctionReturn(0); 668 } 669 670 /*@ 671 MatRestoreRowUpperTriangular - Disable calls to `MatGetRow()` for matrix in `MATSBAIJ` format. 672 673 Not Collective 674 675 Input Parameters: 676 . mat - the matrix 677 678 Notes: 679 This routine should be called after you have finished calls to `MatGetRow()` and `MatRestoreRow()`. 680 681 Level: advanced 682 683 .seealso: `MatGetRowUpperTriangular()` 684 @*/ 685 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat) 686 { 687 PetscFunctionBegin; 688 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 689 PetscValidType(mat,1); 690 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 691 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 692 MatCheckPreallocated(mat,1); 693 if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0); 694 PetscCall((*mat->ops->restorerowuppertriangular)(mat)); 695 PetscFunctionReturn(0); 696 } 697 698 /*@C 699 MatSetOptionsPrefix - Sets the prefix used for searching for all 700 Mat options in the database. 701 702 Logically Collective on Mat 703 704 Input Parameters: 705 + A - the Mat context 706 - prefix - the prefix to prepend to all option names 707 708 Notes: 709 A hyphen (-) must NOT be given at the beginning of the prefix name. 710 The first character of all runtime options is AUTOMATICALLY the hyphen. 711 712 This is NOT used for options for the factorization of the matrix. Normally the 713 prefix is automatically passed in from the PC calling the factorization. To set 714 it directly use `MatSetOptionsPrefixFactor()` 715 716 Level: advanced 717 718 .seealso: `MatSetFromOptions()`, `MatSetOptionsPrefixFactor()` 719 @*/ 720 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[]) 721 { 722 PetscFunctionBegin; 723 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 724 PetscCall(PetscObjectSetOptionsPrefix((PetscObject)A,prefix)); 725 PetscFunctionReturn(0); 726 } 727 728 /*@C 729 MatSetOptionsPrefixFactor - Sets the prefix used for searching for all Mat factor options in the database for 730 for matrices created with `MatGetFactor()` 731 732 Logically Collective on Mat 733 734 Input Parameters: 735 + A - the Mat context 736 - prefix - the prefix to prepend to all option names for the factored matrix 737 738 Notes: 739 A hyphen (-) must NOT be given at the beginning of the prefix name. 740 The first character of all runtime options is AUTOMATICALLY the hyphen. 741 742 Normally the prefix is automatically passed in from the PC calling the factorization. To set 743 it directly when not using `KSP`/`PC` use `MatSetOptionsPrefixFactor()` 744 745 Level: developer 746 747 .seealso: `MatSetFromOptions()`, `MatSetOptionsPrefix()`, `MatAppendOptionsPrefixFactor()` 748 @*/ 749 PetscErrorCode MatSetOptionsPrefixFactor(Mat A,const char prefix[]) 750 { 751 PetscFunctionBegin; 752 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 753 if (prefix) { 754 PetscValidCharPointer(prefix,2); 755 PetscCheck(prefix[0] != '-',PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Options prefix should not begin with a hyphen"); 756 if (prefix != A->factorprefix) { 757 PetscCall(PetscFree(A->factorprefix)); 758 PetscCall(PetscStrallocpy(prefix,&A->factorprefix)); 759 } 760 } else PetscCall(PetscFree(A->factorprefix)); 761 PetscFunctionReturn(0); 762 } 763 764 /*@C 765 MatAppendOptionsPrefixFactor - Appends to the prefix used for searching for all Mat factor options in the database for 766 for matrices created with `MatGetFactor()` 767 768 Logically Collective on Mat 769 770 Input Parameters: 771 + A - the Mat context 772 - prefix - the prefix to prepend to all option names for the factored matrix 773 774 Notes: 775 A hyphen (-) must NOT be given at the beginning of the prefix name. 776 The first character of all runtime options is AUTOMATICALLY the hyphen. 777 778 Normally the prefix is automatically passed in from the PC calling the factorization. To set 779 it directly when not using `KSP`/`PC` use `MatAppendOptionsPrefixFactor()` 780 781 Level: developer 782 .seealso: `PetscOptionsCreate()`, `PetscOptionsDestroy()`, `PetscObjectSetOptionsPrefix()`, `PetscObjectPrependOptionsPrefix()`, 783 `PetscObjectGetOptionsPrefix()`, `TSAppendOptionsPrefix()`, `SNESAppendOptionsPrefix()`, `KSPAppendOptionsPrefix()`, `MatSetOptionsPrefixFactor()`, 784 `MatSetOptionsPrefix()` 785 @*/ 786 PetscErrorCode MatAppendOptionsPrefixFactor(Mat A,const char prefix[]) 787 { 788 char *buf = A->factorprefix; 789 size_t len1,len2; 790 791 PetscFunctionBegin; 792 PetscValidHeader(A,1); 793 if (!prefix) PetscFunctionReturn(0); 794 if (!buf) { 795 PetscCall(MatSetOptionsPrefixFactor(A,prefix)); 796 PetscFunctionReturn(0); 797 } 798 PetscCheck(prefix[0] != '-',PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Options prefix should not begin with a hyphen"); 799 800 PetscCall(PetscStrlen(prefix,&len1)); 801 PetscCall(PetscStrlen(buf,&len2)); 802 PetscCall(PetscMalloc1(1+len1+len2,&A->factorprefix)); 803 PetscCall(PetscStrcpy(A->factorprefix,buf)); 804 PetscCall(PetscStrcat(A->factorprefix,prefix)); 805 PetscCall(PetscFree(buf)); 806 PetscFunctionReturn(0); 807 } 808 809 /*@C 810 MatAppendOptionsPrefix - Appends to the prefix used for searching for all 811 Mat options in the database. 812 813 Logically Collective on Mat 814 815 Input Parameters: 816 + A - the Mat context 817 - prefix - the prefix to prepend to all option names 818 819 Notes: 820 A hyphen (-) must NOT be given at the beginning of the prefix name. 821 The first character of all runtime options is AUTOMATICALLY the hyphen. 822 823 Level: advanced 824 825 .seealso: `MatGetOptionsPrefix()` 826 @*/ 827 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[]) 828 { 829 PetscFunctionBegin; 830 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 831 PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)A,prefix)); 832 PetscFunctionReturn(0); 833 } 834 835 /*@C 836 MatGetOptionsPrefix - Gets the prefix used for searching for all 837 Mat options in the database. 838 839 Not Collective 840 841 Input Parameter: 842 . A - the Mat context 843 844 Output Parameter: 845 . prefix - pointer to the prefix string used 846 847 Notes: 848 On the fortran side, the user should pass in a string 'prefix' of 849 sufficient length to hold the prefix. 850 851 Level: advanced 852 853 .seealso: `MatAppendOptionsPrefix()` 854 @*/ 855 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[]) 856 { 857 PetscFunctionBegin; 858 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 859 PetscValidPointer(prefix,2); 860 PetscCall(PetscObjectGetOptionsPrefix((PetscObject)A,prefix)); 861 PetscFunctionReturn(0); 862 } 863 864 /*@ 865 MatResetPreallocation - Reset mat to use the original nonzero pattern provided by users. 866 867 Collective on Mat 868 869 Input Parameters: 870 . A - the Mat context 871 872 Notes: 873 The allocated memory will be shrunk after calling `MatAssemblyBegin()` and `MatAssemblyEnd()` with `MAT_FINAL_ASSEMBLY`. 874 875 Users can reset the preallocation to access the original memory. 876 877 Currently only supported for `MATMPIAIJ` and `MATSEQAIJ` matrices. 878 879 Level: beginner 880 881 .seealso: `MatSeqAIJSetPreallocation()`, `MatMPIAIJSetPreallocation()`, `MatXAIJSetPreallocation()` 882 @*/ 883 PetscErrorCode MatResetPreallocation(Mat A) 884 { 885 PetscFunctionBegin; 886 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 887 PetscValidType(A,1); 888 PetscUseMethod(A,"MatResetPreallocation_C",(Mat),(A)); 889 PetscFunctionReturn(0); 890 } 891 892 /*@ 893 MatSetUp - Sets up the internal matrix data structures for later use. 894 895 Collective on Mat 896 897 Input Parameters: 898 . A - the Mat context 899 900 Notes: 901 If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used. 902 903 If a suitable preallocation routine is used, this function does not need to be called. 904 905 See the Performance chapter of the PETSc users manual for how to preallocate matrices 906 907 Level: beginner 908 909 .seealso: `MatCreate()`, `MatDestroy()` 910 @*/ 911 PetscErrorCode MatSetUp(Mat A) 912 { 913 PetscFunctionBegin; 914 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 915 if (!((PetscObject)A)->type_name) { 916 PetscMPIInt size; 917 918 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)A), &size)); 919 PetscCall(MatSetType(A, size == 1 ? MATSEQAIJ : MATMPIAIJ)); 920 } 921 if (!A->preallocated && A->ops->setup) { 922 PetscCall(PetscInfo(A,"Warning not preallocating matrix storage\n")); 923 PetscCall((*A->ops->setup)(A)); 924 } 925 PetscCall(PetscLayoutSetUp(A->rmap)); 926 PetscCall(PetscLayoutSetUp(A->cmap)); 927 A->preallocated = PETSC_TRUE; 928 PetscFunctionReturn(0); 929 } 930 931 #if defined(PETSC_HAVE_SAWS) 932 #include <petscviewersaws.h> 933 #endif 934 935 /*@C 936 MatViewFromOptions - View from Options 937 938 Collective on Mat 939 940 Input Parameters: 941 + A - the Mat context 942 . obj - Optional object 943 - name - command line option 944 945 Level: intermediate 946 .seealso: `Mat`, `MatView`, `PetscObjectViewFromOptions()`, `MatCreate()` 947 @*/ 948 PetscErrorCode MatViewFromOptions(Mat A,PetscObject obj,const char name[]) 949 { 950 PetscFunctionBegin; 951 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 952 PetscCall(PetscObjectViewFromOptions((PetscObject)A,obj,name)); 953 PetscFunctionReturn(0); 954 } 955 956 /*@C 957 MatView - Visualizes a matrix object. 958 959 Collective on Mat 960 961 Input Parameters: 962 + mat - the matrix 963 - viewer - visualization context 964 965 Notes: 966 The available visualization contexts include 967 + `PETSC_VIEWER_STDOUT_SELF` - for sequential matrices 968 . `PETSC_VIEWER_STDOUT_WORLD` - for parallel matrices created on `PETSC_COMM_WORLD` 969 . `PETSC_VIEWER_STDOUT_`(comm) - for matrices created on MPI communicator comm 970 - `PETSC_VIEWER_DRAW_WORLD` - graphical display of nonzero structure 971 972 The user can open alternative visualization contexts with 973 + `PetscViewerASCIIOpen()` - Outputs matrix to a specified file 974 . `PetscViewerBinaryOpen()` - Outputs matrix in binary to a 975 specified file; corresponding input uses MatLoad() 976 . `PetscViewerDrawOpen()` - Outputs nonzero matrix structure to 977 an X window display 978 - `PetscViewerSocketOpen()` - Outputs matrix to Socket viewer. 979 Currently only the sequential dense and AIJ 980 matrix types support the Socket viewer. 981 982 The user can call `PetscViewerPushFormat()` to specify the output 983 format of ASCII printed objects (when using `PETSC_VIEWER_STDOUT_SELF`, 984 `PETSC_VIEWER_STDOUT_WORLD` and `PetscViewerASCIIOpen()`). Available formats include 985 + `PETSC_VIEWER_DEFAULT` - default, prints matrix contents 986 . `PETSC_VIEWER_ASCII_MATLAB` - prints matrix contents in Matlab format 987 . `PETSC_VIEWER_ASCII_DENSE` - prints entire matrix including zeros 988 . `PETSC_VIEWER_ASCII_COMMON` - prints matrix contents, using a sparse 989 format common among all matrix types 990 . `PETSC_VIEWER_ASCII_IMPL` - prints matrix contents, using an implementation-specific 991 format (which is in many cases the same as the default) 992 . `PETSC_VIEWER_ASCII_INFO` - prints basic information about the matrix 993 size and structure (not the matrix entries) 994 - `PETSC_VIEWER_ASCII_INFO_DETAIL` - prints more detailed information about 995 the matrix structure 996 997 Options Database Keys: 998 + -mat_view ::ascii_info - Prints info on matrix at conclusion of `MatAssemblyEnd()` 999 . -mat_view ::ascii_info_detail - Prints more detailed info 1000 . -mat_view - Prints matrix in ASCII format 1001 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 1002 . -mat_view draw - PetscDraws nonzero structure of matrix, using `MatView()` and `PetscDrawOpenX()`. 1003 . -display <name> - Sets display name (default is host) 1004 . -draw_pause <sec> - Sets number of seconds to pause after display 1005 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details) 1006 . -viewer_socket_machine <machine> - 1007 . -viewer_socket_port <port> - 1008 . -mat_view binary - save matrix to file in binary format 1009 - -viewer_binary_filename <name> - 1010 1011 Level: beginner 1012 1013 Notes: 1014 The ASCII viewers are only recommended for small matrices on at most a moderate number of processes, 1015 the program will seemingly hang and take hours for larger matrices, for larger matrices one should use the binary format. 1016 1017 In the debugger you can do "call MatView(mat,0)" to display the matrix. (The same holds for any PETSc object viewer). 1018 1019 See the manual page for `MatLoad()` for the exact format of the binary file when the binary 1020 viewer is used. 1021 1022 See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary 1023 viewer is used and lib/petsc/bin/PetscBinaryIO.py for loading them into Python. 1024 1025 One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure, 1026 and then use the following mouse functions. 1027 .vb 1028 left mouse: zoom in 1029 middle mouse: zoom out 1030 right mouse: continue with the simulation 1031 .ve 1032 1033 .seealso: `PetscViewerPushFormat()`, `PetscViewerASCIIOpen()`, `PetscViewerDrawOpen()`, 1034 `PetscViewerSocketOpen()`, `PetscViewerBinaryOpen()`, `MatLoad()` 1035 @*/ 1036 PetscErrorCode MatView(Mat mat,PetscViewer viewer) 1037 { 1038 PetscInt rows,cols,rbs,cbs; 1039 PetscBool isascii,isstring,issaws; 1040 PetscViewerFormat format; 1041 PetscMPIInt size; 1042 1043 PetscFunctionBegin; 1044 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1045 PetscValidType(mat,1); 1046 if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer)); 1047 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1048 PetscCheckSameComm(mat,1,viewer,2); 1049 MatCheckPreallocated(mat,1); 1050 1051 PetscCall(PetscViewerGetFormat(viewer,&format)); 1052 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 1053 if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0); 1054 1055 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring)); 1056 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii)); 1057 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws)); 1058 if ((!isascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) { 1059 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detail"); 1060 } 1061 1062 PetscCall(PetscLogEventBegin(MAT_View,mat,viewer,0,0)); 1063 if (isascii) { 1064 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix"); 1065 PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer)); 1066 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1067 MatNullSpace nullsp,transnullsp; 1068 1069 PetscCall(PetscViewerASCIIPushTab(viewer)); 1070 PetscCall(MatGetSize(mat,&rows,&cols)); 1071 PetscCall(MatGetBlockSizes(mat,&rbs,&cbs)); 1072 if (rbs != 1 || cbs != 1) { 1073 if (rbs != cbs) PetscCall(PetscViewerASCIIPrintf(viewer,"rows=%" PetscInt_FMT ", cols=%" PetscInt_FMT ", rbs=%" PetscInt_FMT ", cbs=%" PetscInt_FMT "\n",rows,cols,rbs,cbs)); 1074 else PetscCall(PetscViewerASCIIPrintf(viewer,"rows=%" PetscInt_FMT ", cols=%" PetscInt_FMT ", bs=%" PetscInt_FMT "\n",rows,cols,rbs)); 1075 } else PetscCall(PetscViewerASCIIPrintf(viewer,"rows=%" PetscInt_FMT ", cols=%" PetscInt_FMT "\n",rows,cols)); 1076 if (mat->factortype) { 1077 MatSolverType solver; 1078 PetscCall(MatFactorGetSolverType(mat,&solver)); 1079 PetscCall(PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver)); 1080 } 1081 if (mat->ops->getinfo) { 1082 MatInfo info; 1083 PetscCall(MatGetInfo(mat,MAT_GLOBAL_SUM,&info)); 1084 PetscCall(PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated)); 1085 if (!mat->factortype) PetscCall(PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls=%" PetscInt_FMT "\n",(PetscInt)info.mallocs)); 1086 } 1087 PetscCall(MatGetNullSpace(mat,&nullsp)); 1088 PetscCall(MatGetTransposeNullSpace(mat,&transnullsp)); 1089 if (nullsp) PetscCall(PetscViewerASCIIPrintf(viewer," has attached null space\n")); 1090 if (transnullsp && transnullsp != nullsp) PetscCall(PetscViewerASCIIPrintf(viewer," has attached transposed null space\n")); 1091 PetscCall(MatGetNearNullSpace(mat,&nullsp)); 1092 if (nullsp) PetscCall(PetscViewerASCIIPrintf(viewer," has attached near null space\n")); 1093 PetscCall(PetscViewerASCIIPushTab(viewer)); 1094 PetscCall(MatProductView(mat,viewer)); 1095 PetscCall(PetscViewerASCIIPopTab(viewer)); 1096 } 1097 } else if (issaws) { 1098 #if defined(PETSC_HAVE_SAWS) 1099 PetscMPIInt rank; 1100 1101 PetscCall(PetscObjectName((PetscObject)mat)); 1102 PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD,&rank)); 1103 if (!((PetscObject)mat)->amsmem && rank == 0) { 1104 PetscCall(PetscObjectViewSAWs((PetscObject)mat,viewer)); 1105 } 1106 #endif 1107 } else if (isstring) { 1108 const char *type; 1109 PetscCall(MatGetType(mat,&type)); 1110 PetscCall(PetscViewerStringSPrintf(viewer," MatType: %-7.7s",type)); 1111 if (mat->ops->view) PetscCall((*mat->ops->view)(mat,viewer)); 1112 } 1113 if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) { 1114 PetscCall(PetscViewerASCIIPushTab(viewer)); 1115 PetscCall((*mat->ops->viewnative)(mat,viewer)); 1116 PetscCall(PetscViewerASCIIPopTab(viewer)); 1117 } else if (mat->ops->view) { 1118 PetscCall(PetscViewerASCIIPushTab(viewer)); 1119 PetscCall((*mat->ops->view)(mat,viewer)); 1120 PetscCall(PetscViewerASCIIPopTab(viewer)); 1121 } 1122 if (isascii) { 1123 PetscCall(PetscViewerGetFormat(viewer,&format)); 1124 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1125 PetscCall(PetscViewerASCIIPopTab(viewer)); 1126 } 1127 } 1128 PetscCall(PetscLogEventEnd(MAT_View,mat,viewer,0,0)); 1129 PetscFunctionReturn(0); 1130 } 1131 1132 #if defined(PETSC_USE_DEBUG) 1133 #include <../src/sys/totalview/tv_data_display.h> 1134 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat) 1135 { 1136 TV_add_row("Local rows", "int", &mat->rmap->n); 1137 TV_add_row("Local columns", "int", &mat->cmap->n); 1138 TV_add_row("Global rows", "int", &mat->rmap->N); 1139 TV_add_row("Global columns", "int", &mat->cmap->N); 1140 TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name); 1141 return TV_format_OK; 1142 } 1143 #endif 1144 1145 /*@C 1146 MatLoad - Loads a matrix that has been stored in binary/HDF5 format 1147 with `MatView()`. The matrix format is determined from the options database. 1148 Generates a parallel MPI matrix if the communicator has more than one 1149 processor. The default matrix type is AIJ. 1150 1151 Collective on PetscViewer 1152 1153 Input Parameters: 1154 + mat - the newly loaded matrix, this needs to have been created with `MatCreate()` 1155 or some related function before a call to `MatLoad()` 1156 - viewer - binary/HDF5 file viewer 1157 1158 Options Database Keys: 1159 Used with block matrix formats (`MATSEQBAIJ`, ...) to specify 1160 block size 1161 . -matload_block_size <bs> - set block size 1162 1163 Level: beginner 1164 1165 Notes: 1166 If the Mat type has not yet been given then `MATAIJ` is used, call `MatSetFromOptions()` on the 1167 Mat before calling this routine if you wish to set it from the options database. 1168 1169 `MatLoad()` automatically loads into the options database any options 1170 given in the file filename.info where filename is the name of the file 1171 that was passed to the `PetscViewerBinaryOpen()`. The options in the info 1172 file will be ignored if you use the -viewer_binary_skip_info option. 1173 1174 If the type or size of mat is not set before a call to `MatLoad()`, PETSc 1175 sets the default matrix type AIJ and sets the local and global sizes. 1176 If type and/or size is already set, then the same are used. 1177 1178 In parallel, each processor can load a subset of rows (or the 1179 entire matrix). This routine is especially useful when a large 1180 matrix is stored on disk and only part of it is desired on each 1181 processor. For example, a parallel solver may access only some of 1182 the rows from each processor. The algorithm used here reads 1183 relatively small blocks of data rather than reading the entire 1184 matrix and then subsetting it. 1185 1186 Viewer's `PetscViewerType` must be either `PETSCVIEWERBINARY` or `PETSCVIEWERHDF5`. 1187 Such viewer can be created using `PetscViewerBinaryOpen()` or `PetscViewerHDF5Open()`, 1188 or the sequence like 1189 .vb 1190 `PetscViewer` v; 1191 `PetscViewerCreate`(`PETSC_COMM_WORLD`,&v); 1192 `PetscViewerSetType`(v,`PETSCVIEWERBINARY`); 1193 `PetscViewerSetFromOptions`(v); 1194 `PetscViewerFileSetMode`(v,`FILE_MODE_READ`); 1195 `PetscViewerFileSetName`(v,"datafile"); 1196 .ve 1197 The optional `PetscViewerSetFromOptions()` call allows overriding `PetscViewerSetType()` using the option 1198 $ -viewer_type {binary,hdf5} 1199 1200 See the example src/ksp/ksp/tutorials/ex27.c with the first approach, 1201 and src/mat/tutorials/ex10.c with the second approach. 1202 1203 Notes about the PETSc binary format: 1204 In case of `PETSCVIEWERBINARY`, a native PETSc binary format is used. Each of the blocks 1205 is read onto rank 0 and then shipped to its destination rank, one after another. 1206 Multiple objects, both matrices and vectors, can be stored within the same file. 1207 Their PetscObject name is ignored; they are loaded in the order of their storage. 1208 1209 Most users should not need to know the details of the binary storage 1210 format, since `MatLoad()` and `MatView()` completely hide these details. 1211 But for anyone who's interested, the standard binary matrix storage 1212 format is 1213 1214 $ PetscInt MAT_FILE_CLASSID 1215 $ PetscInt number of rows 1216 $ PetscInt number of columns 1217 $ PetscInt total number of nonzeros 1218 $ PetscInt *number nonzeros in each row 1219 $ PetscInt *column indices of all nonzeros (starting index is zero) 1220 $ PetscScalar *values of all nonzeros 1221 1222 PETSc automatically does the byte swapping for 1223 machines that store the bytes reversed, e.g. DEC alpha, freebsd, 1224 Linux, Microsoft Windows and the Intel Paragon; thus if you write your own binary 1225 read/write routines you have to swap the bytes; see `PetscBinaryRead()` 1226 and `PetscBinaryWrite()` to see how this may be done. 1227 1228 Notes about the HDF5 (MATLAB MAT-File Version 7.3) format: 1229 In case of `PETSCVIEWERHDF5`, a parallel HDF5 reader is used. 1230 Each processor's chunk is loaded independently by its owning rank. 1231 Multiple objects, both matrices and vectors, can be stored within the same file. 1232 They are looked up by their PetscObject name. 1233 1234 As the MATLAB MAT-File Version 7.3 format is also a HDF5 flavor, we decided to use 1235 by default the same structure and naming of the AIJ arrays and column count 1236 within the HDF5 file. This means that a MAT file saved with -v7.3 flag, e.g. 1237 $ save example.mat A b -v7.3 1238 can be directly read by this routine (see Reference 1 for details). 1239 Note that depending on your MATLAB version, this format might be a default, 1240 otherwise you can set it as default in Preferences. 1241 1242 Unless -nocompression flag is used to save the file in MATLAB, 1243 PETSc must be configured with ZLIB package. 1244 1245 See also examples src/mat/tutorials/ex10.c and src/ksp/ksp/tutorials/ex27.c 1246 1247 Current HDF5 (MAT-File) limitations: 1248 This reader currently supports only real `MATSEQAIJ`, `MATMPIAIJ`, `MATSEQDENSE` and `MATMPIDENSE` matrices. 1249 1250 Corresponding `MatView()` is not yet implemented. 1251 1252 The loaded matrix is actually a transpose of the original one in MATLAB, 1253 unless you push `PETSC_VIEWER_HDF5_MAT` format (see examples above). 1254 With this format, matrix is automatically transposed by PETSc, 1255 unless the matrix is marked as SPD or symmetric 1256 (see `MatSetOption()`, `MAT_SPD`, `MAT_SYMMETRIC`). 1257 1258 References: 1259 . * - MATLAB(R) Documentation, manual page of save(), https://www.mathworks.com/help/matlab/ref/save.html#btox10b-1-version 1260 1261 .seealso: `PetscViewerBinaryOpen()`, `PetscViewerSetType()`, `MatView()`, `VecLoad()` 1262 1263 @*/ 1264 PetscErrorCode MatLoad(Mat mat,PetscViewer viewer) 1265 { 1266 PetscBool flg; 1267 1268 PetscFunctionBegin; 1269 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1270 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1271 1272 if (!((PetscObject)mat)->type_name) PetscCall(MatSetType(mat,MATAIJ)); 1273 1274 flg = PETSC_FALSE; 1275 PetscCall(PetscOptionsGetBool(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matload_symmetric",&flg,NULL)); 1276 if (flg) { 1277 PetscCall(MatSetOption(mat,MAT_SYMMETRIC,PETSC_TRUE)); 1278 PetscCall(MatSetOption(mat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE)); 1279 } 1280 flg = PETSC_FALSE; 1281 PetscCall(PetscOptionsGetBool(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matload_spd",&flg,NULL)); 1282 if (flg) PetscCall(MatSetOption(mat,MAT_SPD,PETSC_TRUE)); 1283 1284 PetscCheck(mat->ops->load,PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type %s",((PetscObject)mat)->type_name); 1285 PetscCall(PetscLogEventBegin(MAT_Load,mat,viewer,0,0)); 1286 PetscCall((*mat->ops->load)(mat,viewer)); 1287 PetscCall(PetscLogEventEnd(MAT_Load,mat,viewer,0,0)); 1288 PetscFunctionReturn(0); 1289 } 1290 1291 static PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant) 1292 { 1293 Mat_Redundant *redund = *redundant; 1294 1295 PetscFunctionBegin; 1296 if (redund) { 1297 if (redund->matseq) { /* via MatCreateSubMatrices() */ 1298 PetscCall(ISDestroy(&redund->isrow)); 1299 PetscCall(ISDestroy(&redund->iscol)); 1300 PetscCall(MatDestroySubMatrices(1,&redund->matseq)); 1301 } else { 1302 PetscCall(PetscFree2(redund->send_rank,redund->recv_rank)); 1303 PetscCall(PetscFree(redund->sbuf_j)); 1304 PetscCall(PetscFree(redund->sbuf_a)); 1305 for (PetscInt i=0; i<redund->nrecvs; i++) { 1306 PetscCall(PetscFree(redund->rbuf_j[i])); 1307 PetscCall(PetscFree(redund->rbuf_a[i])); 1308 } 1309 PetscCall(PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a)); 1310 } 1311 1312 if (redund->subcomm) PetscCall(PetscCommDestroy(&redund->subcomm)); 1313 PetscCall(PetscFree(redund)); 1314 } 1315 PetscFunctionReturn(0); 1316 } 1317 1318 /*@C 1319 MatDestroy - Frees space taken by a matrix. 1320 1321 Collective on Mat 1322 1323 Input Parameter: 1324 . A - the matrix 1325 1326 Level: beginner 1327 1328 Developer Notes: 1329 Some special arrays of matrices are not destroyed in this routine but instead by the routines called by 1330 `MatDestroySubMatrices()`. Thus one must be sure that any changes here must also be made in those routines. 1331 MatHeaderMerge() and MatHeaderReplace() also manipulate the data in the `Mat` object and likely need changes 1332 if changes are needed here. 1333 @*/ 1334 PetscErrorCode MatDestroy(Mat *A) 1335 { 1336 PetscFunctionBegin; 1337 if (!*A) PetscFunctionReturn(0); 1338 PetscValidHeaderSpecific(*A,MAT_CLASSID,1); 1339 if (--((PetscObject)(*A))->refct > 0) {*A = NULL; PetscFunctionReturn(0);} 1340 1341 /* if memory was published with SAWs then destroy it */ 1342 PetscCall(PetscObjectSAWsViewOff((PetscObject)*A)); 1343 if ((*A)->ops->destroy) PetscCall((*(*A)->ops->destroy)(*A)); 1344 1345 PetscCall(PetscFree((*A)->factorprefix)); 1346 PetscCall(PetscFree((*A)->defaultvectype)); 1347 PetscCall(PetscFree((*A)->bsizes)); 1348 PetscCall(PetscFree((*A)->solvertype)); 1349 for (PetscInt i=0; i<MAT_FACTOR_NUM_TYPES; i++) PetscCall(PetscFree((*A)->preferredordering[i])); 1350 if ((*A)->redundant && (*A)->redundant->matseq[0] == *A) (*A)->redundant->matseq[0] = NULL; 1351 PetscCall(MatDestroy_Redundant(&(*A)->redundant)); 1352 PetscCall(MatProductClear(*A)); 1353 PetscCall(MatNullSpaceDestroy(&(*A)->nullsp)); 1354 PetscCall(MatNullSpaceDestroy(&(*A)->transnullsp)); 1355 PetscCall(MatNullSpaceDestroy(&(*A)->nearnullsp)); 1356 PetscCall(MatDestroy(&(*A)->schur)); 1357 PetscCall(PetscLayoutDestroy(&(*A)->rmap)); 1358 PetscCall(PetscLayoutDestroy(&(*A)->cmap)); 1359 PetscCall(PetscHeaderDestroy(A)); 1360 PetscFunctionReturn(0); 1361 } 1362 1363 /*@C 1364 MatSetValues - Inserts or adds a block of values into a matrix. 1365 These values may be cached, so `MatAssemblyBegin()` and `MatAssemblyEnd()` 1366 MUST be called after all calls to `MatSetValues()` have been completed. 1367 1368 Not Collective 1369 1370 Input Parameters: 1371 + mat - the matrix 1372 . v - a logically two-dimensional array of values 1373 . m, idxm - the number of rows and their global indices 1374 . n, idxn - the number of columns and their global indices 1375 - addv - either `ADD_VALUES` or `INSERT_VALUES`, where 1376 `ADD_VALUES` adds values to any existing entries, and 1377 `INSERT_VALUES` replaces existing entries with new values 1378 1379 Notes: 1380 If you create the matrix yourself (that is not with a call to `DMCreateMatrix()`) then you MUST call MatXXXXSetPreallocation() or 1381 `MatSetUp()` before using this routine 1382 1383 By default the values, v, are row-oriented. See `MatSetOption()` for other options. 1384 1385 Calls to `MatSetValues()` with the `INSERT_VALUES` and `ADD_VALUES` 1386 options cannot be mixed without intervening calls to the assembly 1387 routines. 1388 1389 `MatSetValues()` uses 0-based row and column numbers in Fortran 1390 as well as in C. 1391 1392 Negative indices may be passed in idxm and idxn, these rows and columns are 1393 simply ignored. This allows easily inserting element stiffness matrices 1394 with homogeneous Dirchlet boundary conditions that you don't want represented 1395 in the matrix. 1396 1397 Efficiency Alert: 1398 The routine `MatSetValuesBlocked()` may offer much better efficiency 1399 for users of block sparse formats (`MATSEQBAIJ` and `MATMPIBAIJ`). 1400 1401 Level: beginner 1402 1403 Developer Notes: 1404 This is labeled with C so does not automatically generate Fortran stubs and interfaces 1405 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 1406 1407 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 1408 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES` 1409 @*/ 1410 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1411 { 1412 PetscFunctionBeginHot; 1413 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1414 PetscValidType(mat,1); 1415 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1416 PetscValidIntPointer(idxm,3); 1417 PetscValidIntPointer(idxn,5); 1418 MatCheckPreallocated(mat,1); 1419 1420 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 1421 else PetscCheck(mat->insertmode == addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1422 1423 if (PetscDefined(USE_DEBUG)) { 1424 PetscInt i,j; 1425 1426 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1427 PetscCheck(mat->ops->setvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1428 1429 for (i=0; i<m; i++) { 1430 for (j=0; j<n; j++) { 1431 if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j])) 1432 #if defined(PETSC_USE_COMPLEX) 1433 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g+i%g at matrix entry (%" PetscInt_FMT ",%" PetscInt_FMT ")",(double)PetscRealPart(v[i*n+j]),(double)PetscImaginaryPart(v[i*n+j]),idxm[i],idxn[j]); 1434 #else 1435 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%" PetscInt_FMT ",%" PetscInt_FMT ")",(double)v[i*n+j],idxm[i],idxn[j]); 1436 #endif 1437 } 1438 } 1439 for (i=0; i<m; i++) PetscCheck(idxm[i] < mat->rmap->N,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Cannot insert in row %" PetscInt_FMT ", maximum is %" PetscInt_FMT,idxm[i],mat->rmap->N-1); 1440 for (i=0; i<n; i++) PetscCheck(idxn[i] < mat->cmap->N,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Cannot insert in column %" PetscInt_FMT ", maximum is %" PetscInt_FMT,idxn[i],mat->cmap->N-1); 1441 } 1442 1443 if (mat->assembled) { 1444 mat->was_assembled = PETSC_TRUE; 1445 mat->assembled = PETSC_FALSE; 1446 } 1447 PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 1448 PetscCall((*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv)); 1449 PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 1450 PetscFunctionReturn(0); 1451 } 1452 1453 /*@C 1454 MatSetValuesIS - Inserts or adds a block of values into a matrix using IS to indicate the rows and columns 1455 These values may be cached, so `MatAssemblyBegin()` and `MatAssemblyEnd()` 1456 MUST be called after all calls to `MatSetValues()` have been completed. 1457 1458 Not Collective 1459 1460 Input Parameters: 1461 + mat - the matrix 1462 . v - a logically two-dimensional array of values 1463 . ism - the rows to provide 1464 . isn - the columns to provide 1465 - addv - either `ADD_VALUES` or `INSERT_VALUES`, where 1466 `ADD_VALUES` adds values to any existing entries, and 1467 `INSERT_VALUES` replaces existing entries with new values 1468 1469 Notes: 1470 If you create the matrix yourself (that is not with a call to `DMCreateMatrix()`) then you MUST call MatXXXXSetPreallocation() or 1471 `MatSetUp()` before using this routine 1472 1473 By default the values, v, are row-oriented. See `MatSetOption()` for other options. 1474 1475 Calls to `MatSetValues()` with the `INSERT_VALUES` and `ADD_VALUES` 1476 options cannot be mixed without intervening calls to the assembly 1477 routines. 1478 1479 MatSetValues() uses 0-based row and column numbers in Fortran 1480 as well as in C. 1481 1482 Negative indices may be passed in ism and isn, these rows and columns are 1483 simply ignored. This allows easily inserting element stiffness matrices 1484 with homogeneous Dirchlet boundary conditions that you don't want represented 1485 in the matrix. 1486 1487 Efficiency Alert: 1488 The routine `MatSetValuesBlocked()` may offer much better efficiency 1489 for users of block sparse formats (`MATSEQBAIJ` and `MATMPIBAIJ`). 1490 1491 Level: beginner 1492 1493 Developer Notes: 1494 This is labeled with C so does not automatically generate Fortran stubs and interfaces 1495 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 1496 1497 This is currently not optimized for any particular IS type 1498 1499 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 1500 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()` 1501 @*/ 1502 PetscErrorCode MatSetValuesIS(Mat mat,IS ism,IS isn,const PetscScalar v[],InsertMode addv) 1503 { 1504 PetscInt m,n; 1505 const PetscInt *rows,*cols; 1506 1507 PetscFunctionBeginHot; 1508 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1509 PetscCall(ISGetIndices(ism,&rows)); 1510 PetscCall(ISGetIndices(isn,&cols)); 1511 PetscCall(ISGetLocalSize(ism,&m)); 1512 PetscCall(ISGetLocalSize(isn,&n)); 1513 PetscCall(MatSetValues(mat,m,rows,n,cols,v,addv)); 1514 PetscCall(ISRestoreIndices(ism,&rows)); 1515 PetscCall(ISRestoreIndices(isn,&cols)); 1516 PetscFunctionReturn(0); 1517 } 1518 1519 /*@ 1520 MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero 1521 values into a matrix 1522 1523 Not Collective 1524 1525 Input Parameters: 1526 + mat - the matrix 1527 . row - the (block) row to set 1528 - v - a logically two-dimensional array of values 1529 1530 Notes: 1531 By the values, v, are column-oriented (for the block version) and sorted 1532 1533 All the nonzeros in the row must be provided 1534 1535 The matrix must have previously had its column indices set 1536 1537 The row must belong to this process 1538 1539 Level: intermediate 1540 1541 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 1542 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()`, `MatSetValuesRow()`, `MatSetLocalToGlobalMapping()` 1543 @*/ 1544 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[]) 1545 { 1546 PetscInt globalrow; 1547 1548 PetscFunctionBegin; 1549 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1550 PetscValidType(mat,1); 1551 PetscValidScalarPointer(v,3); 1552 PetscCall(ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow)); 1553 PetscCall(MatSetValuesRow(mat,globalrow,v)); 1554 PetscFunctionReturn(0); 1555 } 1556 1557 /*@ 1558 MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero 1559 values into a matrix 1560 1561 Not Collective 1562 1563 Input Parameters: 1564 + mat - the matrix 1565 . row - the (block) row to set 1566 - v - a logically two-dimensional (column major) array of values for block matrices with blocksize larger than one, otherwise a one dimensional array of values 1567 1568 Notes: 1569 The values, v, are column-oriented for the block version. 1570 1571 All the nonzeros in the row must be provided 1572 1573 THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually `MatSetValues()` is used. 1574 1575 The row must belong to this process 1576 1577 Level: advanced 1578 1579 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 1580 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()` 1581 @*/ 1582 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[]) 1583 { 1584 PetscFunctionBeginHot; 1585 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1586 PetscValidType(mat,1); 1587 MatCheckPreallocated(mat,1); 1588 PetscValidScalarPointer(v,3); 1589 PetscCheck(mat->insertmode != ADD_VALUES,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values"); 1590 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1591 mat->insertmode = INSERT_VALUES; 1592 1593 if (mat->assembled) { 1594 mat->was_assembled = PETSC_TRUE; 1595 mat->assembled = PETSC_FALSE; 1596 } 1597 PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 1598 PetscCheck(mat->ops->setvaluesrow,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1599 PetscCall((*mat->ops->setvaluesrow)(mat,row,v)); 1600 PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 1601 PetscFunctionReturn(0); 1602 } 1603 1604 /*@ 1605 MatSetValuesStencil - Inserts or adds a block of values into a matrix. 1606 Using structured grid indexing 1607 1608 Not Collective 1609 1610 Input Parameters: 1611 + mat - the matrix 1612 . m - number of rows being entered 1613 . idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered 1614 . n - number of columns being entered 1615 . idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered 1616 . v - a logically two-dimensional array of values 1617 - addv - either ADD_VALUES or INSERT_VALUES, where 1618 ADD_VALUES adds values to any existing entries, and 1619 INSERT_VALUES replaces existing entries with new values 1620 1621 Notes: 1622 By default the values, v, are row-oriented. See `MatSetOption()` for other options. 1623 1624 Calls to `MatSetValuesStencil()` with the `INSERT_VALUES` and `ADD_VALUES` 1625 options cannot be mixed without intervening calls to the assembly 1626 routines. 1627 1628 The grid coordinates are across the entire grid, not just the local portion 1629 1630 `MatSetValuesStencil()` uses 0-based row and column numbers in Fortran 1631 as well as in C. 1632 1633 For setting/accessing vector values via array coordinates you can use the `DMDAVecGetArray()` routine 1634 1635 In order to use this routine you must either obtain the matrix with `DMCreateMatrix()` 1636 or call `MatSetLocalToGlobalMapping()` and `MatSetStencil()` first. 1637 1638 The columns and rows in the stencil passed in MUST be contained within the 1639 ghost region of the given process as set with DMDACreateXXX() or `MatSetStencil()`. For example, 1640 if you create a `DMDA` with an overlap of one grid level and on a particular process its first 1641 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1642 first i index you can use in your column and row indices in `MatSetStencil()` is 5. 1643 1644 In Fortran idxm and idxn should be declared as 1645 $ MatStencil idxm(4,m),idxn(4,n) 1646 and the values inserted using 1647 $ idxm(MatStencil_i,1) = i 1648 $ idxm(MatStencil_j,1) = j 1649 $ idxm(MatStencil_k,1) = k 1650 $ idxm(MatStencil_c,1) = c 1651 etc 1652 1653 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 1654 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 1655 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 1656 `DM_BOUNDARY_PERIODIC` boundary type. 1657 1658 For indices that don't mean anything for your case (like the k index when working in 2d) or the c index when you have 1659 a single value per point) you can skip filling those indices. 1660 1661 Inspired by the structured grid interface to the HYPRE package 1662 (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods) 1663 1664 Efficiency Alert: 1665 The routine `MatSetValuesBlockedStencil()` may offer much better efficiency 1666 for users of block sparse formats (`MATSEQBAIJ` and `MATMPIBAIJ`). 1667 1668 Level: beginner 1669 1670 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()` 1671 `MatSetValues()`, `MatSetValuesBlockedStencil()`, `MatSetStencil()`, `DMCreateMatrix()`, `DMDAVecGetArray()`, `MatStencil` 1672 @*/ 1673 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1674 { 1675 PetscInt buf[8192],*bufm=NULL,*bufn=NULL,*jdxm,*jdxn; 1676 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1677 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1678 1679 PetscFunctionBegin; 1680 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1681 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1682 PetscValidType(mat,1); 1683 PetscValidPointer(idxm,3); 1684 PetscValidPointer(idxn,5); 1685 1686 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1687 jdxm = buf; jdxn = buf+m; 1688 } else { 1689 PetscCall(PetscMalloc2(m,&bufm,n,&bufn)); 1690 jdxm = bufm; jdxn = bufn; 1691 } 1692 for (i=0; i<m; i++) { 1693 for (j=0; j<3-sdim; j++) dxm++; 1694 tmp = *dxm++ - starts[0]; 1695 for (j=0; j<dim-1; j++) { 1696 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1697 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1698 } 1699 if (mat->stencil.noc) dxm++; 1700 jdxm[i] = tmp; 1701 } 1702 for (i=0; i<n; i++) { 1703 for (j=0; j<3-sdim; j++) dxn++; 1704 tmp = *dxn++ - starts[0]; 1705 for (j=0; j<dim-1; j++) { 1706 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1707 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1708 } 1709 if (mat->stencil.noc) dxn++; 1710 jdxn[i] = tmp; 1711 } 1712 PetscCall(MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv)); 1713 PetscCall(PetscFree2(bufm,bufn)); 1714 PetscFunctionReturn(0); 1715 } 1716 1717 /*@ 1718 MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix. 1719 Using structured grid indexing 1720 1721 Not Collective 1722 1723 Input Parameters: 1724 + mat - the matrix 1725 . m - number of rows being entered 1726 . idxm - grid coordinates for matrix rows being entered 1727 . n - number of columns being entered 1728 . idxn - grid coordinates for matrix columns being entered 1729 . v - a logically two-dimensional array of values 1730 - addv - either ADD_VALUES or INSERT_VALUES, where 1731 ADD_VALUES adds values to any existing entries, and 1732 INSERT_VALUES replaces existing entries with new values 1733 1734 Notes: 1735 By default the values, v, are row-oriented and unsorted. 1736 See MatSetOption() for other options. 1737 1738 Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES 1739 options cannot be mixed without intervening calls to the assembly 1740 routines. 1741 1742 The grid coordinates are across the entire grid, not just the local portion 1743 1744 MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran 1745 as well as in C. 1746 1747 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine 1748 1749 In order to use this routine you must either obtain the matrix with DMCreateMatrix() 1750 or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first. 1751 1752 The columns and rows in the stencil passed in MUST be contained within the 1753 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example, 1754 if you create a DMDA with an overlap of one grid level and on a particular process its first 1755 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1756 first i index you can use in your column and row indices in MatSetStencil() is 5. 1757 1758 In Fortran idxm and idxn should be declared as 1759 $ MatStencil idxm(4,m),idxn(4,n) 1760 and the values inserted using 1761 $ idxm(MatStencil_i,1) = i 1762 $ idxm(MatStencil_j,1) = j 1763 $ idxm(MatStencil_k,1) = k 1764 etc 1765 1766 Negative indices may be passed in idxm and idxn, these rows and columns are 1767 simply ignored. This allows easily inserting element stiffness matrices 1768 with homogeneous Dirchlet boundary conditions that you don't want represented 1769 in the matrix. 1770 1771 Inspired by the structured grid interface to the HYPRE package 1772 (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods) 1773 1774 Level: beginner 1775 1776 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()` 1777 `MatSetValues()`, `MatSetValuesStencil()`, `MatSetStencil()`, `DMCreateMatrix()`, `DMDAVecGetArray()`, `MatStencil`, 1778 `MatSetBlockSize()`, `MatSetLocalToGlobalMapping()` 1779 @*/ 1780 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1781 { 1782 PetscInt buf[8192],*bufm=NULL,*bufn=NULL,*jdxm,*jdxn; 1783 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1784 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1785 1786 PetscFunctionBegin; 1787 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1788 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1789 PetscValidType(mat,1); 1790 PetscValidPointer(idxm,3); 1791 PetscValidPointer(idxn,5); 1792 PetscValidScalarPointer(v,6); 1793 1794 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1795 jdxm = buf; jdxn = buf+m; 1796 } else { 1797 PetscCall(PetscMalloc2(m,&bufm,n,&bufn)); 1798 jdxm = bufm; jdxn = bufn; 1799 } 1800 for (i=0; i<m; i++) { 1801 for (j=0; j<3-sdim; j++) dxm++; 1802 tmp = *dxm++ - starts[0]; 1803 for (j=0; j<sdim-1; j++) { 1804 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1805 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1806 } 1807 dxm++; 1808 jdxm[i] = tmp; 1809 } 1810 for (i=0; i<n; i++) { 1811 for (j=0; j<3-sdim; j++) dxn++; 1812 tmp = *dxn++ - starts[0]; 1813 for (j=0; j<sdim-1; j++) { 1814 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1815 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1816 } 1817 dxn++; 1818 jdxn[i] = tmp; 1819 } 1820 PetscCall(MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv)); 1821 PetscCall(PetscFree2(bufm,bufn)); 1822 PetscFunctionReturn(0); 1823 } 1824 1825 /*@ 1826 MatSetStencil - Sets the grid information for setting values into a matrix via 1827 MatSetValuesStencil() 1828 1829 Not Collective 1830 1831 Input Parameters: 1832 + mat - the matrix 1833 . dim - dimension of the grid 1, 2, or 3 1834 . dims - number of grid points in x, y, and z direction, including ghost points on your processor 1835 . starts - starting point of ghost nodes on your processor in x, y, and z direction 1836 - dof - number of degrees of freedom per node 1837 1838 Inspired by the structured grid interface to the HYPRE package 1839 (www.llnl.gov/CASC/hyper) 1840 1841 For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the 1842 user. 1843 1844 Level: beginner 1845 1846 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()` 1847 `MatSetValues()`, `MatSetValuesBlockedStencil()`, `MatSetValuesStencil()` 1848 @*/ 1849 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof) 1850 { 1851 PetscFunctionBegin; 1852 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1853 PetscValidIntPointer(dims,3); 1854 PetscValidIntPointer(starts,4); 1855 1856 mat->stencil.dim = dim + (dof > 1); 1857 for (PetscInt i=0; i<dim; i++) { 1858 mat->stencil.dims[i] = dims[dim-i-1]; /* copy the values in backwards */ 1859 mat->stencil.starts[i] = starts[dim-i-1]; 1860 } 1861 mat->stencil.dims[dim] = dof; 1862 mat->stencil.starts[dim] = 0; 1863 mat->stencil.noc = (PetscBool)(dof == 1); 1864 PetscFunctionReturn(0); 1865 } 1866 1867 /*@C 1868 MatSetValuesBlocked - Inserts or adds a block of values into a matrix. 1869 1870 Not Collective 1871 1872 Input Parameters: 1873 + mat - the matrix 1874 . v - a logically two-dimensional array of values 1875 . m, idxm - the number of block rows and their global block indices 1876 . n, idxn - the number of block columns and their global block indices 1877 - addv - either ADD_VALUES or INSERT_VALUES, where 1878 ADD_VALUES adds values to any existing entries, and 1879 INSERT_VALUES replaces existing entries with new values 1880 1881 Notes: 1882 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call 1883 MatXXXXSetPreallocation() or MatSetUp() before using this routine. 1884 1885 The m and n count the NUMBER of blocks in the row direction and column direction, 1886 NOT the total number of rows/columns; for example, if the block size is 2 and 1887 you are passing in values for rows 2,3,4,5 then m would be 2 (not 4). 1888 The values in idxm would be 1 2; that is the first index for each block divided by 1889 the block size. 1890 1891 Note that you must call MatSetBlockSize() when constructing this matrix (before 1892 preallocating it). 1893 1894 By default the values, v, are row-oriented, so the layout of 1895 v is the same as for MatSetValues(). See MatSetOption() for other options. 1896 1897 Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES 1898 options cannot be mixed without intervening calls to the assembly 1899 routines. 1900 1901 MatSetValuesBlocked() uses 0-based row and column numbers in Fortran 1902 as well as in C. 1903 1904 Negative indices may be passed in idxm and idxn, these rows and columns are 1905 simply ignored. This allows easily inserting element stiffness matrices 1906 with homogeneous Dirchlet boundary conditions that you don't want represented 1907 in the matrix. 1908 1909 Each time an entry is set within a sparse matrix via MatSetValues(), 1910 internal searching must be done to determine where to place the 1911 data in the matrix storage space. By instead inserting blocks of 1912 entries via MatSetValuesBlocked(), the overhead of matrix assembly is 1913 reduced. 1914 1915 Example: 1916 $ Suppose m=n=2 and block size(bs) = 2 The array is 1917 $ 1918 $ 1 2 | 3 4 1919 $ 5 6 | 7 8 1920 $ - - - | - - - 1921 $ 9 10 | 11 12 1922 $ 13 14 | 15 16 1923 $ 1924 $ v[] should be passed in like 1925 $ v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] 1926 $ 1927 $ If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then 1928 $ v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16] 1929 1930 Level: intermediate 1931 1932 .seealso: `MatSetBlockSize()`, `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetValuesBlockedLocal()` 1933 @*/ 1934 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1935 { 1936 PetscFunctionBeginHot; 1937 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1938 PetscValidType(mat,1); 1939 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1940 PetscValidIntPointer(idxm,3); 1941 PetscValidIntPointer(idxn,5); 1942 MatCheckPreallocated(mat,1); 1943 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 1944 else PetscCheck(mat->insertmode == addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1945 if (PetscDefined(USE_DEBUG)) { 1946 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1947 PetscCheck(mat->ops->setvaluesblocked || mat->ops->setvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1948 } 1949 if (PetscDefined(USE_DEBUG)) { 1950 PetscInt rbs,cbs,M,N,i; 1951 PetscCall(MatGetBlockSizes(mat,&rbs,&cbs)); 1952 PetscCall(MatGetSize(mat,&M,&N)); 1953 for (i=0; i<m; i++) PetscCheck(idxm[i]*rbs < M,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row block index %" PetscInt_FMT " (index %" PetscInt_FMT ") greater than row length %" PetscInt_FMT,i,idxm[i],M); 1954 for (i=0; i<n; i++) PetscCheck(idxn[i]*cbs < N,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column block index %" PetscInt_FMT " (index %" PetscInt_FMT ") great than column length %" PetscInt_FMT,i,idxn[i],N); 1955 } 1956 if (mat->assembled) { 1957 mat->was_assembled = PETSC_TRUE; 1958 mat->assembled = PETSC_FALSE; 1959 } 1960 PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 1961 if (mat->ops->setvaluesblocked) { 1962 PetscCall((*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv)); 1963 } else { 1964 PetscInt buf[8192],*bufr=NULL,*bufc=NULL,*iidxm,*iidxn; 1965 PetscInt i,j,bs,cbs; 1966 1967 PetscCall(MatGetBlockSizes(mat,&bs,&cbs)); 1968 if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1969 iidxm = buf; 1970 iidxn = buf + m*bs; 1971 } else { 1972 PetscCall(PetscMalloc2(m*bs,&bufr,n*cbs,&bufc)); 1973 iidxm = bufr; 1974 iidxn = bufc; 1975 } 1976 for (i=0; i<m; i++) { 1977 for (j=0; j<bs; j++) { 1978 iidxm[i*bs+j] = bs*idxm[i] + j; 1979 } 1980 } 1981 if (m != n || bs != cbs || idxm != idxn) { 1982 for (i=0; i<n; i++) { 1983 for (j=0; j<cbs; j++) { 1984 iidxn[i*cbs+j] = cbs*idxn[i] + j; 1985 } 1986 } 1987 } else iidxn = iidxm; 1988 PetscCall(MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv)); 1989 PetscCall(PetscFree2(bufr,bufc)); 1990 } 1991 PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 1992 PetscFunctionReturn(0); 1993 } 1994 1995 /*@C 1996 MatGetValues - Gets a block of values from a matrix. 1997 1998 Not Collective; can only return values that are owned by the give process 1999 2000 Input Parameters: 2001 + mat - the matrix 2002 . v - a logically two-dimensional array for storing the values 2003 . m, idxm - the number of rows and their global indices 2004 - n, idxn - the number of columns and their global indices 2005 2006 Notes: 2007 The user must allocate space (m*n PetscScalars) for the values, v. 2008 The values, v, are then returned in a row-oriented format, 2009 analogous to that used by default in MatSetValues(). 2010 2011 MatGetValues() uses 0-based row and column numbers in 2012 Fortran as well as in C. 2013 2014 MatGetValues() requires that the matrix has been assembled 2015 with MatAssemblyBegin()/MatAssemblyEnd(). Thus, calls to 2016 MatSetValues() and MatGetValues() CANNOT be made in succession 2017 without intermediate matrix assembly. 2018 2019 Negative row or column indices will be ignored and those locations in v[] will be 2020 left unchanged. 2021 2022 For the standard row-based matrix formats, idxm[] can only contain rows owned by the requesting MPI rank. 2023 That is, rows with global index greater than or equal to rstart and less than rend where rstart and rend are obtainable 2024 from MatGetOwnershipRange(mat,&rstart,&rend). 2025 2026 Level: advanced 2027 2028 .seealso: `MatGetRow()`, `MatCreateSubMatrices()`, `MatSetValues()`, `MatGetOwnershipRange()`, `MatGetValuesLocal()`, `MatGetValue()` 2029 @*/ 2030 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[]) 2031 { 2032 PetscFunctionBegin; 2033 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2034 PetscValidType(mat,1); 2035 if (!m || !n) PetscFunctionReturn(0); 2036 PetscValidIntPointer(idxm,3); 2037 PetscValidIntPointer(idxn,5); 2038 PetscValidScalarPointer(v,6); 2039 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2040 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2041 PetscCheck(mat->ops->getvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2042 MatCheckPreallocated(mat,1); 2043 2044 PetscCall(PetscLogEventBegin(MAT_GetValues,mat,0,0,0)); 2045 PetscCall((*mat->ops->getvalues)(mat,m,idxm,n,idxn,v)); 2046 PetscCall(PetscLogEventEnd(MAT_GetValues,mat,0,0,0)); 2047 PetscFunctionReturn(0); 2048 } 2049 2050 /*@C 2051 MatGetValuesLocal - retrieves values from certain locations in a matrix using the local numbering of the indices 2052 defined previously by MatSetLocalToGlobalMapping() 2053 2054 Not Collective 2055 2056 Input Parameters: 2057 + mat - the matrix 2058 . nrow, irow - number of rows and their local indices 2059 - ncol, icol - number of columns and their local indices 2060 2061 Output Parameter: 2062 . y - a logically two-dimensional array of values 2063 2064 Notes: 2065 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine. 2066 2067 This routine can only return values that are owned by the requesting MPI rank. That is, for standard matrix formats, rows that, in the global numbering, 2068 are greater than or equal to rstart and less than rend where rstart and rend are obtainable from MatGetOwnershipRange(mat,&rstart,&rend). One can 2069 determine if the resulting global row associated with the local row r is owned by the requesting MPI rank by applying the ISLocalToGlobalMapping set 2070 with MatSetLocalToGlobalMapping(). 2071 2072 Developer Notes: 2073 This is labelled with C so does not automatically generate Fortran stubs and interfaces 2074 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2075 2076 Level: advanced 2077 2078 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetLocalToGlobalMapping()`, 2079 `MatSetValuesLocal()`, `MatGetValues()` 2080 @*/ 2081 PetscErrorCode MatGetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],PetscScalar y[]) 2082 { 2083 PetscFunctionBeginHot; 2084 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2085 PetscValidType(mat,1); 2086 MatCheckPreallocated(mat,1); 2087 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to retrieve */ 2088 PetscValidIntPointer(irow,3); 2089 PetscValidIntPointer(icol,5); 2090 if (PetscDefined(USE_DEBUG)) { 2091 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2092 PetscCheck(mat->ops->getvalueslocal || mat->ops->getvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2093 } 2094 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2095 PetscCall(PetscLogEventBegin(MAT_GetValues,mat,0,0,0)); 2096 if (mat->ops->getvalueslocal) { 2097 PetscCall((*mat->ops->getvalueslocal)(mat,nrow,irow,ncol,icol,y)); 2098 } else { 2099 PetscInt buf[8192],*bufr=NULL,*bufc=NULL,*irowm,*icolm; 2100 if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2101 irowm = buf; icolm = buf+nrow; 2102 } else { 2103 PetscCall(PetscMalloc2(nrow,&bufr,ncol,&bufc)); 2104 irowm = bufr; icolm = bufc; 2105 } 2106 PetscCheck(mat->rmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MatGetValuesLocal() cannot proceed without local-to-global row mapping (See MatSetLocalToGlobalMapping())."); 2107 PetscCheck(mat->cmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MatGetValuesLocal() cannot proceed without local-to-global column mapping (See MatSetLocalToGlobalMapping())."); 2108 PetscCall(ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm)); 2109 PetscCall(ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm)); 2110 PetscCall(MatGetValues(mat,nrow,irowm,ncol,icolm,y)); 2111 PetscCall(PetscFree2(bufr,bufc)); 2112 } 2113 PetscCall(PetscLogEventEnd(MAT_GetValues,mat,0,0,0)); 2114 PetscFunctionReturn(0); 2115 } 2116 2117 /*@ 2118 MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and 2119 the same size. Currently, this can only be called once and creates the given matrix. 2120 2121 Not Collective 2122 2123 Input Parameters: 2124 + mat - the matrix 2125 . nb - the number of blocks 2126 . bs - the number of rows (and columns) in each block 2127 . rows - a concatenation of the rows for each block 2128 - v - a concatenation of logically two-dimensional arrays of values 2129 2130 Notes: 2131 In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix. 2132 2133 Level: advanced 2134 2135 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 2136 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()` 2137 @*/ 2138 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[]) 2139 { 2140 PetscFunctionBegin; 2141 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2142 PetscValidType(mat,1); 2143 PetscValidIntPointer(rows,4); 2144 PetscValidScalarPointer(v,5); 2145 PetscAssert(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2146 2147 PetscCall(PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0)); 2148 if (mat->ops->setvaluesbatch) { 2149 PetscCall((*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v)); 2150 } else { 2151 for (PetscInt b = 0; b < nb; ++b) PetscCall(MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES)); 2152 } 2153 PetscCall(PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0)); 2154 PetscFunctionReturn(0); 2155 } 2156 2157 /*@ 2158 MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by 2159 the routine MatSetValuesLocal() to allow users to insert matrix entries 2160 using a local (per-processor) numbering. 2161 2162 Not Collective 2163 2164 Input Parameters: 2165 + x - the matrix 2166 . rmapping - row mapping created with ISLocalToGlobalMappingCreate() or ISLocalToGlobalMappingCreateIS() 2167 - cmapping - column mapping 2168 2169 Level: intermediate 2170 2171 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetValuesLocal()`, `MatGetValuesLocal()` 2172 @*/ 2173 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 2174 { 2175 PetscFunctionBegin; 2176 PetscValidHeaderSpecific(x,MAT_CLASSID,1); 2177 PetscValidType(x,1); 2178 if (rmapping) PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2); 2179 if (cmapping) PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3); 2180 if (x->ops->setlocaltoglobalmapping) { 2181 PetscCall((*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping)); 2182 } else { 2183 PetscCall(PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping)); 2184 PetscCall(PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping)); 2185 } 2186 PetscFunctionReturn(0); 2187 } 2188 2189 /*@ 2190 MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping() 2191 2192 Not Collective 2193 2194 Input Parameter: 2195 . A - the matrix 2196 2197 Output Parameters: 2198 + rmapping - row mapping 2199 - cmapping - column mapping 2200 2201 Level: advanced 2202 2203 .seealso: `MatSetValuesLocal()` 2204 @*/ 2205 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping) 2206 { 2207 PetscFunctionBegin; 2208 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2209 PetscValidType(A,1); 2210 if (rmapping) { 2211 PetscValidPointer(rmapping,2); 2212 *rmapping = A->rmap->mapping; 2213 } 2214 if (cmapping) { 2215 PetscValidPointer(cmapping,3); 2216 *cmapping = A->cmap->mapping; 2217 } 2218 PetscFunctionReturn(0); 2219 } 2220 2221 /*@ 2222 MatSetLayouts - Sets the PetscLayout objects for rows and columns of a matrix 2223 2224 Logically Collective on A 2225 2226 Input Parameters: 2227 + A - the matrix 2228 . rmap - row layout 2229 - cmap - column layout 2230 2231 Level: advanced 2232 2233 .seealso: `MatCreateVecs()`, `MatGetLocalToGlobalMapping()`, `MatGetLayouts()` 2234 @*/ 2235 PetscErrorCode MatSetLayouts(Mat A,PetscLayout rmap,PetscLayout cmap) 2236 { 2237 PetscFunctionBegin; 2238 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2239 PetscCall(PetscLayoutReference(rmap,&A->rmap)); 2240 PetscCall(PetscLayoutReference(cmap,&A->cmap)); 2241 PetscFunctionReturn(0); 2242 } 2243 2244 /*@ 2245 MatGetLayouts - Gets the PetscLayout objects for rows and columns 2246 2247 Not Collective 2248 2249 Input Parameter: 2250 . A - the matrix 2251 2252 Output Parameters: 2253 + rmap - row layout 2254 - cmap - column layout 2255 2256 Level: advanced 2257 2258 .seealso: `MatCreateVecs()`, `MatGetLocalToGlobalMapping()`, `MatSetLayouts()` 2259 @*/ 2260 PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap) 2261 { 2262 PetscFunctionBegin; 2263 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2264 PetscValidType(A,1); 2265 if (rmap) { 2266 PetscValidPointer(rmap,2); 2267 *rmap = A->rmap; 2268 } 2269 if (cmap) { 2270 PetscValidPointer(cmap,3); 2271 *cmap = A->cmap; 2272 } 2273 PetscFunctionReturn(0); 2274 } 2275 2276 /*@C 2277 MatSetValuesLocal - Inserts or adds values into certain locations of a matrix, 2278 using a local numbering of the nodes. 2279 2280 Not Collective 2281 2282 Input Parameters: 2283 + mat - the matrix 2284 . nrow, irow - number of rows and their local indices 2285 . ncol, icol - number of columns and their local indices 2286 . y - a logically two-dimensional array of values 2287 - addv - either INSERT_VALUES or ADD_VALUES, where 2288 ADD_VALUES adds values to any existing entries, and 2289 INSERT_VALUES replaces existing entries with new values 2290 2291 Notes: 2292 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2293 MatSetUp() before using this routine 2294 2295 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine 2296 2297 Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES 2298 options cannot be mixed without intervening calls to the assembly 2299 routines. 2300 2301 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2302 MUST be called after all calls to MatSetValuesLocal() have been completed. 2303 2304 Level: intermediate 2305 2306 Developer Notes: 2307 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2308 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2309 2310 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetLocalToGlobalMapping()`, 2311 `MatSetValueLocal()`, `MatGetValuesLocal()` 2312 @*/ 2313 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2314 { 2315 PetscFunctionBeginHot; 2316 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2317 PetscValidType(mat,1); 2318 MatCheckPreallocated(mat,1); 2319 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2320 PetscValidIntPointer(irow,3); 2321 PetscValidIntPointer(icol,5); 2322 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 2323 else PetscCheck(mat->insertmode == addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2324 if (PetscDefined(USE_DEBUG)) { 2325 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2326 PetscCheck(mat->ops->setvalueslocal || mat->ops->setvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2327 } 2328 2329 if (mat->assembled) { 2330 mat->was_assembled = PETSC_TRUE; 2331 mat->assembled = PETSC_FALSE; 2332 } 2333 PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 2334 if (mat->ops->setvalueslocal) { 2335 PetscCall((*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv)); 2336 } else { 2337 PetscInt buf[8192],*bufr=NULL,*bufc=NULL; 2338 const PetscInt *irowm,*icolm; 2339 2340 if ((!mat->rmap->mapping && !mat->cmap->mapping) || (nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2341 bufr = buf; 2342 bufc = buf + nrow; 2343 irowm = bufr; 2344 icolm = bufc; 2345 } else { 2346 PetscCall(PetscMalloc2(nrow,&bufr,ncol,&bufc)); 2347 irowm = bufr; 2348 icolm = bufc; 2349 } 2350 if (mat->rmap->mapping) PetscCall(ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,bufr)); 2351 else irowm = irow; 2352 if (mat->cmap->mapping) { 2353 if (mat->cmap->mapping != mat->rmap->mapping || ncol != nrow || icol != irow) { 2354 PetscCall(ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,bufc)); 2355 } else icolm = irowm; 2356 } else icolm = icol; 2357 PetscCall(MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv)); 2358 if (bufr != buf) PetscCall(PetscFree2(bufr,bufc)); 2359 } 2360 PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 2361 PetscFunctionReturn(0); 2362 } 2363 2364 /*@C 2365 MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix, 2366 using a local ordering of the nodes a block at a time. 2367 2368 Not Collective 2369 2370 Input Parameters: 2371 + x - the matrix 2372 . nrow, irow - number of rows and their local indices 2373 . ncol, icol - number of columns and their local indices 2374 . y - a logically two-dimensional array of values 2375 - addv - either INSERT_VALUES or ADD_VALUES, where 2376 ADD_VALUES adds values to any existing entries, and 2377 INSERT_VALUES replaces existing entries with new values 2378 2379 Notes: 2380 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2381 MatSetUp() before using this routine 2382 2383 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping() 2384 before using this routineBefore calling MatSetValuesLocal(), the user must first set the 2385 2386 Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES 2387 options cannot be mixed without intervening calls to the assembly 2388 routines. 2389 2390 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2391 MUST be called after all calls to MatSetValuesBlockedLocal() have been completed. 2392 2393 Level: intermediate 2394 2395 Developer Notes: 2396 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2397 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2398 2399 .seealso: `MatSetBlockSize()`, `MatSetLocalToGlobalMapping()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, 2400 `MatSetValuesLocal()`, `MatSetValuesBlocked()` 2401 @*/ 2402 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2403 { 2404 PetscFunctionBeginHot; 2405 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2406 PetscValidType(mat,1); 2407 MatCheckPreallocated(mat,1); 2408 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2409 PetscValidIntPointer(irow,3); 2410 PetscValidIntPointer(icol,5); 2411 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 2412 else PetscCheck(mat->insertmode == addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2413 if (PetscDefined(USE_DEBUG)) { 2414 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2415 PetscCheck(mat->ops->setvaluesblockedlocal || mat->ops->setvaluesblocked || mat->ops->setvalueslocal || mat->ops->setvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2416 } 2417 2418 if (mat->assembled) { 2419 mat->was_assembled = PETSC_TRUE; 2420 mat->assembled = PETSC_FALSE; 2421 } 2422 if (PetscUnlikelyDebug(mat->rmap->mapping)) { /* Condition on the mapping existing, because MatSetValuesBlockedLocal_IS does not require it to be set. */ 2423 PetscInt irbs, rbs; 2424 PetscCall(MatGetBlockSizes(mat, &rbs, NULL)); 2425 PetscCall(ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&irbs)); 2426 PetscCheck(rbs == irbs,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different row block sizes! mat %" PetscInt_FMT ", row l2g map %" PetscInt_FMT,rbs,irbs); 2427 } 2428 if (PetscUnlikelyDebug(mat->cmap->mapping)) { 2429 PetscInt icbs, cbs; 2430 PetscCall(MatGetBlockSizes(mat,NULL,&cbs)); 2431 PetscCall(ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&icbs)); 2432 PetscCheck(cbs == icbs,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different col block sizes! mat %" PetscInt_FMT ", col l2g map %" PetscInt_FMT,cbs,icbs); 2433 } 2434 PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 2435 if (mat->ops->setvaluesblockedlocal) { 2436 PetscCall((*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv)); 2437 } else { 2438 PetscInt buf[8192],*bufr=NULL,*bufc=NULL; 2439 const PetscInt *irowm,*icolm; 2440 2441 if ((!mat->rmap->mapping && !mat->cmap->mapping) || (nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2442 bufr = buf; 2443 bufc = buf + nrow; 2444 irowm = bufr; 2445 icolm = bufc; 2446 } else { 2447 PetscCall(PetscMalloc2(nrow,&bufr,ncol,&bufc)); 2448 irowm = bufr; 2449 icolm = bufc; 2450 } 2451 if (mat->rmap->mapping) PetscCall(ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,bufr)); 2452 else irowm = irow; 2453 if (mat->cmap->mapping) { 2454 if (mat->cmap->mapping != mat->rmap->mapping || ncol != nrow || icol != irow) { 2455 PetscCall(ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,bufc)); 2456 } else icolm = irowm; 2457 } else icolm = icol; 2458 PetscCall(MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv)); 2459 if (bufr != buf) PetscCall(PetscFree2(bufr,bufc)); 2460 } 2461 PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 2462 PetscFunctionReturn(0); 2463 } 2464 2465 /*@ 2466 MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal 2467 2468 Collective on Mat 2469 2470 Input Parameters: 2471 + mat - the matrix 2472 - x - the vector to be multiplied 2473 2474 Output Parameters: 2475 . y - the result 2476 2477 Notes: 2478 The vectors x and y cannot be the same. I.e., one cannot 2479 call MatMult(A,y,y). 2480 2481 Level: developer 2482 2483 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 2484 @*/ 2485 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y) 2486 { 2487 PetscFunctionBegin; 2488 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2489 PetscValidType(mat,1); 2490 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2491 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2492 2493 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2494 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2495 PetscCheck(x != y,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2496 MatCheckPreallocated(mat,1); 2497 2498 PetscCheck(mat->ops->multdiagonalblock,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a multiply defined",((PetscObject)mat)->type_name); 2499 PetscCall((*mat->ops->multdiagonalblock)(mat,x,y)); 2500 PetscCall(PetscObjectStateIncrease((PetscObject)y)); 2501 PetscFunctionReturn(0); 2502 } 2503 2504 /* --------------------------------------------------------*/ 2505 /*@ 2506 MatMult - Computes the matrix-vector product, y = Ax. 2507 2508 Neighbor-wise Collective on Mat 2509 2510 Input Parameters: 2511 + mat - the matrix 2512 - x - the vector to be multiplied 2513 2514 Output Parameters: 2515 . y - the result 2516 2517 Notes: 2518 The vectors x and y cannot be the same. I.e., one cannot 2519 call MatMult(A,y,y). 2520 2521 Level: beginner 2522 2523 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 2524 @*/ 2525 PetscErrorCode MatMult(Mat mat,Vec x,Vec y) 2526 { 2527 PetscFunctionBegin; 2528 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2529 PetscValidType(mat,1); 2530 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2531 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2532 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2533 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2534 PetscCheck(x != y,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2535 PetscCheck(mat->cmap->N == x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,x->map->N); 2536 PetscCheck(mat->rmap->N == y->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,y->map->N); 2537 PetscCheck(mat->cmap->n == x->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->n,x->map->n); 2538 PetscCheck(mat->rmap->n == y->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,y->map->n); 2539 PetscCall(VecSetErrorIfLocked(y,3)); 2540 if (mat->erroriffailure) PetscCall(VecValidValues(x,2,PETSC_TRUE)); 2541 MatCheckPreallocated(mat,1); 2542 2543 PetscCall(VecLockReadPush(x)); 2544 PetscCheck(mat->ops->mult,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a multiply defined",((PetscObject)mat)->type_name); 2545 PetscCall(PetscLogEventBegin(MAT_Mult,mat,x,y,0)); 2546 PetscCall((*mat->ops->mult)(mat,x,y)); 2547 PetscCall(PetscLogEventEnd(MAT_Mult,mat,x,y,0)); 2548 if (mat->erroriffailure) PetscCall(VecValidValues(y,3,PETSC_FALSE)); 2549 PetscCall(VecLockReadPop(x)); 2550 PetscFunctionReturn(0); 2551 } 2552 2553 /*@ 2554 MatMultTranspose - Computes matrix transpose times a vector y = A^T * x. 2555 2556 Neighbor-wise Collective on Mat 2557 2558 Input Parameters: 2559 + mat - the matrix 2560 - x - the vector to be multiplied 2561 2562 Output Parameters: 2563 . y - the result 2564 2565 Notes: 2566 The vectors x and y cannot be the same. I.e., one cannot 2567 call MatMultTranspose(A,y,y). 2568 2569 For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple, 2570 use MatMultHermitianTranspose() 2571 2572 Level: beginner 2573 2574 .seealso: `MatMult()`, `MatMultAdd()`, `MatMultTransposeAdd()`, `MatMultHermitianTranspose()`, `MatTranspose()` 2575 @*/ 2576 PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y) 2577 { 2578 PetscErrorCode (*op)(Mat,Vec,Vec) = NULL; 2579 2580 PetscFunctionBegin; 2581 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2582 PetscValidType(mat,1); 2583 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2584 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2585 2586 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2587 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2588 PetscCheck(x != y,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2589 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); 2590 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); 2591 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); 2592 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); 2593 if (mat->erroriffailure) PetscCall(VecValidValues(x,2,PETSC_TRUE)); 2594 MatCheckPreallocated(mat,1); 2595 2596 if (!mat->ops->multtranspose) { 2597 if (mat->symmetric == PETSC_BOOL3_TRUE && mat->ops->mult) op = mat->ops->mult; 2598 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); 2599 } else op = mat->ops->multtranspose; 2600 PetscCall(PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0)); 2601 PetscCall(VecLockReadPush(x)); 2602 PetscCall((*op)(mat,x,y)); 2603 PetscCall(VecLockReadPop(x)); 2604 PetscCall(PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0)); 2605 PetscCall(PetscObjectStateIncrease((PetscObject)y)); 2606 if (mat->erroriffailure) PetscCall(VecValidValues(y,3,PETSC_FALSE)); 2607 PetscFunctionReturn(0); 2608 } 2609 2610 /*@ 2611 MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector. 2612 2613 Neighbor-wise Collective on Mat 2614 2615 Input Parameters: 2616 + mat - the matrix 2617 - x - the vector to be multilplied 2618 2619 Output Parameters: 2620 . y - the result 2621 2622 Notes: 2623 The vectors x and y cannot be the same. I.e., one cannot 2624 call MatMultHermitianTranspose(A,y,y). 2625 2626 Also called the conjugate transpose, complex conjugate transpose, or adjoint. 2627 2628 For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical. 2629 2630 Level: beginner 2631 2632 .seealso: `MatMult()`, `MatMultAdd()`, `MatMultHermitianTransposeAdd()`, `MatMultTranspose()` 2633 @*/ 2634 PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y) 2635 { 2636 PetscFunctionBegin; 2637 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2638 PetscValidType(mat,1); 2639 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2640 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2641 2642 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2643 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2644 PetscCheck(x != y,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2645 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); 2646 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); 2647 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); 2648 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); 2649 MatCheckPreallocated(mat,1); 2650 2651 PetscCall(PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0)); 2652 #if defined(PETSC_USE_COMPLEX) 2653 if (mat->ops->multhermitiantranspose || (mat->hermitian == PETSC_BOOL3_TRUE && mat->ops->mult)) { 2654 PetscCall(VecLockReadPush(x)); 2655 if (mat->ops->multhermitiantranspose) { 2656 PetscCall((*mat->ops->multhermitiantranspose)(mat,x,y)); 2657 } else { 2658 PetscCall((*mat->ops->mult)(mat,x,y)); 2659 } 2660 PetscCall(VecLockReadPop(x)); 2661 } else { 2662 Vec w; 2663 PetscCall(VecDuplicate(x,&w)); 2664 PetscCall(VecCopy(x,w)); 2665 PetscCall(VecConjugate(w)); 2666 PetscCall(MatMultTranspose(mat,w,y)); 2667 PetscCall(VecDestroy(&w)); 2668 PetscCall(VecConjugate(y)); 2669 } 2670 PetscCall(PetscObjectStateIncrease((PetscObject)y)); 2671 #else 2672 PetscCall(MatMultTranspose(mat,x,y)); 2673 #endif 2674 PetscCall(PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0)); 2675 PetscFunctionReturn(0); 2676 } 2677 2678 /*@ 2679 MatMultAdd - Computes v3 = v2 + A * v1. 2680 2681 Neighbor-wise Collective on Mat 2682 2683 Input Parameters: 2684 + mat - the matrix 2685 - v1, v2 - the vectors 2686 2687 Output Parameters: 2688 . v3 - the result 2689 2690 Notes: 2691 The vectors v1 and v3 cannot be the same. I.e., one cannot 2692 call MatMultAdd(A,v1,v2,v1). 2693 2694 Level: beginner 2695 2696 .seealso: `MatMultTranspose()`, `MatMult()`, `MatMultTransposeAdd()` 2697 @*/ 2698 PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2699 { 2700 PetscFunctionBegin; 2701 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2702 PetscValidType(mat,1); 2703 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2704 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2705 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2706 2707 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2708 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2709 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); 2710 /* 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); 2711 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); */ 2712 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); 2713 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); 2714 PetscCheck(v1 != v3,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2715 MatCheckPreallocated(mat,1); 2716 2717 PetscCheck(mat->ops->multadd,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type %s",((PetscObject)mat)->type_name); 2718 PetscCall(PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3)); 2719 PetscCall(VecLockReadPush(v1)); 2720 PetscCall((*mat->ops->multadd)(mat,v1,v2,v3)); 2721 PetscCall(VecLockReadPop(v1)); 2722 PetscCall(PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3)); 2723 PetscCall(PetscObjectStateIncrease((PetscObject)v3)); 2724 PetscFunctionReturn(0); 2725 } 2726 2727 /*@ 2728 MatMultTransposeAdd - Computes v3 = v2 + A' * v1. 2729 2730 Neighbor-wise Collective on Mat 2731 2732 Input Parameters: 2733 + mat - the matrix 2734 - v1, v2 - the vectors 2735 2736 Output Parameters: 2737 . v3 - the result 2738 2739 Notes: 2740 The vectors v1 and v3 cannot be the same. I.e., one cannot 2741 call MatMultTransposeAdd(A,v1,v2,v1). 2742 2743 Level: beginner 2744 2745 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMult()` 2746 @*/ 2747 PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2748 { 2749 PetscErrorCode (*op)(Mat,Vec,Vec,Vec) = (!mat->ops->multtransposeadd && mat->symmetric) ? mat->ops->multadd : mat->ops->multtransposeadd; 2750 2751 PetscFunctionBegin; 2752 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2753 PetscValidType(mat,1); 2754 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2755 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2756 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2757 2758 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2759 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2760 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); 2761 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); 2762 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); 2763 PetscCheck(v1 != v3,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2764 PetscCheck(op,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2765 MatCheckPreallocated(mat,1); 2766 2767 PetscCall(PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3)); 2768 PetscCall(VecLockReadPush(v1)); 2769 PetscCall((*op)(mat,v1,v2,v3)); 2770 PetscCall(VecLockReadPop(v1)); 2771 PetscCall(PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3)); 2772 PetscCall(PetscObjectStateIncrease((PetscObject)v3)); 2773 PetscFunctionReturn(0); 2774 } 2775 2776 /*@ 2777 MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1. 2778 2779 Neighbor-wise Collective on Mat 2780 2781 Input Parameters: 2782 + mat - the matrix 2783 - v1, v2 - the vectors 2784 2785 Output Parameters: 2786 . v3 - the result 2787 2788 Notes: 2789 The vectors v1 and v3 cannot be the same. I.e., one cannot 2790 call MatMultHermitianTransposeAdd(A,v1,v2,v1). 2791 2792 Level: beginner 2793 2794 .seealso: `MatMultHermitianTranspose()`, `MatMultTranspose()`, `MatMultAdd()`, `MatMult()` 2795 @*/ 2796 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2797 { 2798 PetscFunctionBegin; 2799 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2800 PetscValidType(mat,1); 2801 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2802 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2803 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2804 2805 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2806 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2807 PetscCheck(v1 != v3,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2808 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); 2809 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); 2810 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); 2811 MatCheckPreallocated(mat,1); 2812 2813 PetscCall(PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3)); 2814 PetscCall(VecLockReadPush(v1)); 2815 if (mat->ops->multhermitiantransposeadd) { 2816 PetscCall((*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3)); 2817 } else { 2818 Vec w,z; 2819 PetscCall(VecDuplicate(v1,&w)); 2820 PetscCall(VecCopy(v1,w)); 2821 PetscCall(VecConjugate(w)); 2822 PetscCall(VecDuplicate(v3,&z)); 2823 PetscCall(MatMultTranspose(mat,w,z)); 2824 PetscCall(VecDestroy(&w)); 2825 PetscCall(VecConjugate(z)); 2826 if (v2 != v3) { 2827 PetscCall(VecWAXPY(v3,1.0,v2,z)); 2828 } else { 2829 PetscCall(VecAXPY(v3,1.0,z)); 2830 } 2831 PetscCall(VecDestroy(&z)); 2832 } 2833 PetscCall(VecLockReadPop(v1)); 2834 PetscCall(PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3)); 2835 PetscCall(PetscObjectStateIncrease((PetscObject)v3)); 2836 PetscFunctionReturn(0); 2837 } 2838 2839 /*@C 2840 MatGetFactorType - gets the type of factorization it is 2841 2842 Not Collective 2843 2844 Input Parameters: 2845 . mat - the matrix 2846 2847 Output Parameters: 2848 . t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT 2849 2850 Level: intermediate 2851 2852 .seealso: `MatFactorType`, `MatGetFactor()`, `MatSetFactorType()` 2853 @*/ 2854 PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t) 2855 { 2856 PetscFunctionBegin; 2857 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2858 PetscValidType(mat,1); 2859 PetscValidPointer(t,2); 2860 *t = mat->factortype; 2861 PetscFunctionReturn(0); 2862 } 2863 2864 /*@C 2865 MatSetFactorType - sets the type of factorization it is 2866 2867 Logically Collective on Mat 2868 2869 Input Parameters: 2870 + mat - the matrix 2871 - t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT 2872 2873 Level: intermediate 2874 2875 .seealso: `MatFactorType`, `MatGetFactor()`, `MatGetFactorType()` 2876 @*/ 2877 PetscErrorCode MatSetFactorType(Mat mat, MatFactorType t) 2878 { 2879 PetscFunctionBegin; 2880 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2881 PetscValidType(mat,1); 2882 mat->factortype = t; 2883 PetscFunctionReturn(0); 2884 } 2885 2886 /* ------------------------------------------------------------*/ 2887 /*@C 2888 MatGetInfo - Returns information about matrix storage (number of 2889 nonzeros, memory, etc.). 2890 2891 Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag 2892 2893 Input Parameter: 2894 . mat - the matrix 2895 2896 Output Parameters: 2897 + flag - flag indicating the type of parameters to be returned 2898 (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors, 2899 MAT_GLOBAL_SUM - sum over all processors) 2900 - info - matrix information context 2901 2902 Notes: 2903 The MatInfo context contains a variety of matrix data, including 2904 number of nonzeros allocated and used, number of mallocs during 2905 matrix assembly, etc. Additional information for factored matrices 2906 is provided (such as the fill ratio, number of mallocs during 2907 factorization, etc.). Much of this info is printed to PETSC_STDOUT 2908 when using the runtime options 2909 $ -info -mat_view ::ascii_info 2910 2911 Example for C/C++ Users: 2912 See the file ${PETSC_DIR}/include/petscmat.h for a complete list of 2913 data within the MatInfo context. For example, 2914 .vb 2915 MatInfo info; 2916 Mat A; 2917 double mal, nz_a, nz_u; 2918 2919 MatGetInfo(A,MAT_LOCAL,&info); 2920 mal = info.mallocs; 2921 nz_a = info.nz_allocated; 2922 .ve 2923 2924 Example for Fortran Users: 2925 Fortran users should declare info as a double precision 2926 array of dimension MAT_INFO_SIZE, and then extract the parameters 2927 of interest. See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h 2928 a complete list of parameter names. 2929 .vb 2930 double precision info(MAT_INFO_SIZE) 2931 double precision mal, nz_a 2932 Mat A 2933 integer ierr 2934 2935 call MatGetInfo(A,MAT_LOCAL,info,ierr) 2936 mal = info(MAT_INFO_MALLOCS) 2937 nz_a = info(MAT_INFO_NZ_ALLOCATED) 2938 .ve 2939 2940 Level: intermediate 2941 2942 Developer Note: fortran interface is not autogenerated as the f90 2943 interface definition cannot be generated correctly [due to MatInfo] 2944 2945 .seealso: `MatStashGetInfo()` 2946 2947 @*/ 2948 PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info) 2949 { 2950 PetscFunctionBegin; 2951 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2952 PetscValidType(mat,1); 2953 PetscValidPointer(info,3); 2954 PetscCheck(mat->ops->getinfo,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2955 MatCheckPreallocated(mat,1); 2956 PetscCall((*mat->ops->getinfo)(mat,flag,info)); 2957 PetscFunctionReturn(0); 2958 } 2959 2960 /* 2961 This is used by external packages where it is not easy to get the info from the actual 2962 matrix factorization. 2963 */ 2964 PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info) 2965 { 2966 PetscFunctionBegin; 2967 PetscCall(PetscMemzero(info,sizeof(MatInfo))); 2968 PetscFunctionReturn(0); 2969 } 2970 2971 /* ----------------------------------------------------------*/ 2972 2973 /*@C 2974 MatLUFactor - Performs in-place LU factorization of matrix. 2975 2976 Collective on Mat 2977 2978 Input Parameters: 2979 + mat - the matrix 2980 . row - row permutation 2981 . col - column permutation 2982 - info - options for factorization, includes 2983 $ fill - expected fill as ratio of original fill. 2984 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 2985 $ Run with the option -info to determine an optimal value to use 2986 2987 Notes: 2988 Most users should employ the simplified KSP interface for linear solvers 2989 instead of working directly with matrix algebra routines such as this. 2990 See, e.g., KSPCreate(). 2991 2992 This changes the state of the matrix to a factored matrix; it cannot be used 2993 for example with MatSetValues() unless one first calls MatSetUnfactored(). 2994 2995 Level: developer 2996 2997 .seealso: `MatLUFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()`, 2998 `MatGetOrdering()`, `MatSetUnfactored()`, `MatFactorInfo`, `MatGetFactor()` 2999 3000 Developer Note: fortran interface is not autogenerated as the f90 3001 interface definition cannot be generated correctly [due to MatFactorInfo] 3002 3003 @*/ 3004 PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 3005 { 3006 MatFactorInfo tinfo; 3007 3008 PetscFunctionBegin; 3009 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3010 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 3011 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 3012 if (info) PetscValidPointer(info,4); 3013 PetscValidType(mat,1); 3014 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3015 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3016 PetscCheck(mat->ops->lufactor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3017 MatCheckPreallocated(mat,1); 3018 if (!info) { 3019 PetscCall(MatFactorInfoInitialize(&tinfo)); 3020 info = &tinfo; 3021 } 3022 3023 PetscCall(PetscLogEventBegin(MAT_LUFactor,mat,row,col,0)); 3024 PetscCall((*mat->ops->lufactor)(mat,row,col,info)); 3025 PetscCall(PetscLogEventEnd(MAT_LUFactor,mat,row,col,0)); 3026 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 3027 PetscFunctionReturn(0); 3028 } 3029 3030 /*@C 3031 MatILUFactor - Performs in-place ILU factorization of matrix. 3032 3033 Collective on Mat 3034 3035 Input Parameters: 3036 + mat - the matrix 3037 . row - row permutation 3038 . col - column permutation 3039 - info - structure containing 3040 $ levels - number of levels of fill. 3041 $ expected fill - as ratio of original fill. 3042 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 3043 missing diagonal entries) 3044 3045 Notes: 3046 Probably really in-place only when level of fill is zero, otherwise allocates 3047 new space to store factored matrix and deletes previous memory. 3048 3049 Most users should employ the simplified KSP interface for linear solvers 3050 instead of working directly with matrix algebra routines such as this. 3051 See, e.g., KSPCreate(). 3052 3053 Level: developer 3054 3055 .seealso: `MatILUFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()`, `MatFactorInfo` 3056 3057 Developer Note: fortran interface is not autogenerated as the f90 3058 interface definition cannot be generated correctly [due to MatFactorInfo] 3059 3060 @*/ 3061 PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 3062 { 3063 PetscFunctionBegin; 3064 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3065 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 3066 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 3067 PetscValidPointer(info,4); 3068 PetscValidType(mat,1); 3069 PetscCheck(mat->rmap->N == mat->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 3070 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3071 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3072 PetscCheck(mat->ops->ilufactor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3073 MatCheckPreallocated(mat,1); 3074 3075 PetscCall(PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0)); 3076 PetscCall((*mat->ops->ilufactor)(mat,row,col,info)); 3077 PetscCall(PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0)); 3078 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 3079 PetscFunctionReturn(0); 3080 } 3081 3082 /*@C 3083 MatLUFactorSymbolic - Performs symbolic LU factorization of matrix. 3084 Call this routine before calling MatLUFactorNumeric(). 3085 3086 Collective on Mat 3087 3088 Input Parameters: 3089 + fact - the factor matrix obtained with MatGetFactor() 3090 . mat - the matrix 3091 . row, col - row and column permutations 3092 - info - options for factorization, includes 3093 $ fill - expected fill as ratio of original fill. 3094 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3095 $ Run with the option -info to determine an optimal value to use 3096 3097 Notes: 3098 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 3099 3100 Most users should employ the simplified KSP interface for linear solvers 3101 instead of working directly with matrix algebra routines such as this. 3102 See, e.g., KSPCreate(). 3103 3104 Level: developer 3105 3106 .seealso: `MatLUFactor()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()`, `MatFactorInfo`, `MatFactorInfoInitialize()` 3107 3108 Developer Note: fortran interface is not autogenerated as the f90 3109 interface definition cannot be generated correctly [due to MatFactorInfo] 3110 3111 @*/ 3112 PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 3113 { 3114 MatFactorInfo tinfo; 3115 3116 PetscFunctionBegin; 3117 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3118 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,3); 3119 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,4); 3120 if (info) PetscValidPointer(info,5); 3121 PetscValidType(mat,2); 3122 PetscValidPointer(fact,1); 3123 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3124 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3125 if (!(fact)->ops->lufactorsymbolic) { 3126 MatSolverType stype; 3127 PetscCall(MatFactorGetSolverType(fact,&stype)); 3128 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,stype); 3129 } 3130 MatCheckPreallocated(mat,2); 3131 if (!info) { 3132 PetscCall(MatFactorInfoInitialize(&tinfo)); 3133 info = &tinfo; 3134 } 3135 3136 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0)); 3137 PetscCall((fact->ops->lufactorsymbolic)(fact,mat,row,col,info)); 3138 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0)); 3139 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3140 PetscFunctionReturn(0); 3141 } 3142 3143 /*@C 3144 MatLUFactorNumeric - Performs numeric LU factorization of a matrix. 3145 Call this routine after first calling MatLUFactorSymbolic(). 3146 3147 Collective on Mat 3148 3149 Input Parameters: 3150 + fact - the factor matrix obtained with MatGetFactor() 3151 . mat - the matrix 3152 - info - options for factorization 3153 3154 Notes: 3155 See MatLUFactor() for in-place factorization. See 3156 MatCholeskyFactorNumeric() for the symmetric, positive definite case. 3157 3158 Most users should employ the simplified KSP interface for linear solvers 3159 instead of working directly with matrix algebra routines such as this. 3160 See, e.g., KSPCreate(). 3161 3162 Level: developer 3163 3164 .seealso: `MatLUFactorSymbolic()`, `MatLUFactor()`, `MatCholeskyFactor()` 3165 3166 Developer Note: fortran interface is not autogenerated as the f90 3167 interface definition cannot be generated correctly [due to MatFactorInfo] 3168 3169 @*/ 3170 PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3171 { 3172 MatFactorInfo tinfo; 3173 3174 PetscFunctionBegin; 3175 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3176 PetscValidType(mat,2); 3177 PetscValidPointer(fact,1); 3178 PetscValidHeaderSpecific(fact,MAT_CLASSID,1); 3179 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3180 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); 3181 3182 PetscCheck((fact)->ops->lufactornumeric,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name); 3183 MatCheckPreallocated(mat,2); 3184 if (!info) { 3185 PetscCall(MatFactorInfoInitialize(&tinfo)); 3186 info = &tinfo; 3187 } 3188 3189 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0)); 3190 else PetscCall(PetscLogEventBegin(MAT_LUFactor,mat,fact,0,0)); 3191 PetscCall((fact->ops->lufactornumeric)(fact,mat,info)); 3192 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0)); 3193 else PetscCall(PetscLogEventEnd(MAT_LUFactor,mat,fact,0,0)); 3194 PetscCall(MatViewFromOptions(fact,NULL,"-mat_factor_view")); 3195 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3196 PetscFunctionReturn(0); 3197 } 3198 3199 /*@C 3200 MatCholeskyFactor - Performs in-place Cholesky factorization of a 3201 symmetric matrix. 3202 3203 Collective on Mat 3204 3205 Input Parameters: 3206 + mat - the matrix 3207 . perm - row and column permutations 3208 - f - expected fill as ratio of original fill 3209 3210 Notes: 3211 See MatLUFactor() for the nonsymmetric case. See also 3212 MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric(). 3213 3214 Most users should employ the simplified KSP interface for linear solvers 3215 instead of working directly with matrix algebra routines such as this. 3216 See, e.g., KSPCreate(). 3217 3218 Level: developer 3219 3220 .seealso: `MatLUFactor()`, `MatCholeskyFactorSymbolic()`, `MatCholeskyFactorNumeric()` 3221 `MatGetOrdering()` 3222 3223 Developer Note: fortran interface is not autogenerated as the f90 3224 interface definition cannot be generated correctly [due to MatFactorInfo] 3225 3226 @*/ 3227 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info) 3228 { 3229 MatFactorInfo tinfo; 3230 3231 PetscFunctionBegin; 3232 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3233 PetscValidType(mat,1); 3234 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2); 3235 if (info) PetscValidPointer(info,3); 3236 PetscCheck(mat->rmap->N == mat->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square"); 3237 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3238 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3239 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); 3240 MatCheckPreallocated(mat,1); 3241 if (!info) { 3242 PetscCall(MatFactorInfoInitialize(&tinfo)); 3243 info = &tinfo; 3244 } 3245 3246 PetscCall(PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0)); 3247 PetscCall((*mat->ops->choleskyfactor)(mat,perm,info)); 3248 PetscCall(PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0)); 3249 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 3250 PetscFunctionReturn(0); 3251 } 3252 3253 /*@C 3254 MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization 3255 of a symmetric matrix. 3256 3257 Collective on Mat 3258 3259 Input Parameters: 3260 + fact - the factor matrix obtained with MatGetFactor() 3261 . mat - the matrix 3262 . perm - row and column permutations 3263 - info - options for factorization, includes 3264 $ fill - expected fill as ratio of original fill. 3265 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3266 $ Run with the option -info to determine an optimal value to use 3267 3268 Notes: 3269 See MatLUFactorSymbolic() for the nonsymmetric case. See also 3270 MatCholeskyFactor() and MatCholeskyFactorNumeric(). 3271 3272 Most users should employ the simplified KSP interface for linear solvers 3273 instead of working directly with matrix algebra routines such as this. 3274 See, e.g., KSPCreate(). 3275 3276 Level: developer 3277 3278 .seealso: `MatLUFactorSymbolic()`, `MatCholeskyFactor()`, `MatCholeskyFactorNumeric()` 3279 `MatGetOrdering()` 3280 3281 Developer Note: fortran interface is not autogenerated as the f90 3282 interface definition cannot be generated correctly [due to MatFactorInfo] 3283 3284 @*/ 3285 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 3286 { 3287 MatFactorInfo tinfo; 3288 3289 PetscFunctionBegin; 3290 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3291 PetscValidType(mat,2); 3292 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,3); 3293 if (info) PetscValidPointer(info,4); 3294 PetscValidPointer(fact,1); 3295 PetscCheck(mat->rmap->N == mat->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square"); 3296 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3297 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3298 if (!(fact)->ops->choleskyfactorsymbolic) { 3299 MatSolverType stype; 3300 PetscCall(MatFactorGetSolverType(fact,&stype)); 3301 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,stype); 3302 } 3303 MatCheckPreallocated(mat,2); 3304 if (!info) { 3305 PetscCall(MatFactorInfoInitialize(&tinfo)); 3306 info = &tinfo; 3307 } 3308 3309 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0)); 3310 PetscCall((fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info)); 3311 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0)); 3312 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3313 PetscFunctionReturn(0); 3314 } 3315 3316 /*@C 3317 MatCholeskyFactorNumeric - Performs numeric Cholesky factorization 3318 of a symmetric matrix. Call this routine after first calling 3319 MatCholeskyFactorSymbolic(). 3320 3321 Collective on Mat 3322 3323 Input Parameters: 3324 + fact - the factor matrix obtained with MatGetFactor() 3325 . mat - the initial matrix 3326 . info - options for factorization 3327 - fact - the symbolic factor of mat 3328 3329 Notes: 3330 Most users should employ the simplified KSP interface for linear solvers 3331 instead of working directly with matrix algebra routines such as this. 3332 See, e.g., KSPCreate(). 3333 3334 Level: developer 3335 3336 .seealso: `MatCholeskyFactorSymbolic()`, `MatCholeskyFactor()`, `MatLUFactorNumeric()` 3337 3338 Developer Note: fortran interface is not autogenerated as the f90 3339 interface definition cannot be generated correctly [due to MatFactorInfo] 3340 3341 @*/ 3342 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3343 { 3344 MatFactorInfo tinfo; 3345 3346 PetscFunctionBegin; 3347 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3348 PetscValidType(mat,2); 3349 PetscValidPointer(fact,1); 3350 PetscValidHeaderSpecific(fact,MAT_CLASSID,1); 3351 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3352 PetscCheck((fact)->ops->choleskyfactornumeric,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name); 3353 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); 3354 MatCheckPreallocated(mat,2); 3355 if (!info) { 3356 PetscCall(MatFactorInfoInitialize(&tinfo)); 3357 info = &tinfo; 3358 } 3359 3360 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0)); 3361 else PetscCall(PetscLogEventBegin(MAT_CholeskyFactor,mat,fact,0,0)); 3362 PetscCall((fact->ops->choleskyfactornumeric)(fact,mat,info)); 3363 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0)); 3364 else PetscCall(PetscLogEventEnd(MAT_CholeskyFactor,mat,fact,0,0)); 3365 PetscCall(MatViewFromOptions(fact,NULL,"-mat_factor_view")); 3366 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3367 PetscFunctionReturn(0); 3368 } 3369 3370 /*@ 3371 MatQRFactor - Performs in-place QR factorization of matrix. 3372 3373 Collective on Mat 3374 3375 Input Parameters: 3376 + mat - the matrix 3377 . col - column permutation 3378 - info - options for factorization, includes 3379 $ fill - expected fill as ratio of original fill. 3380 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3381 $ Run with the option -info to determine an optimal value to use 3382 3383 Notes: 3384 Most users should employ the simplified KSP interface for linear solvers 3385 instead of working directly with matrix algebra routines such as this. 3386 See, e.g., KSPCreate(). 3387 3388 This changes the state of the matrix to a factored matrix; it cannot be used 3389 for example with MatSetValues() unless one first calls MatSetUnfactored(). 3390 3391 Level: developer 3392 3393 .seealso: `MatQRFactorSymbolic()`, `MatQRFactorNumeric()`, `MatLUFactor()`, 3394 `MatSetUnfactored()`, `MatFactorInfo`, `MatGetFactor()` 3395 3396 Developer Note: fortran interface is not autogenerated as the f90 3397 interface definition cannot be generated correctly [due to MatFactorInfo] 3398 3399 @*/ 3400 PetscErrorCode MatQRFactor(Mat mat, IS col, const MatFactorInfo *info) 3401 { 3402 PetscFunctionBegin; 3403 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3404 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,2); 3405 if (info) PetscValidPointer(info,3); 3406 PetscValidType(mat,1); 3407 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3408 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3409 MatCheckPreallocated(mat,1); 3410 PetscCall(PetscLogEventBegin(MAT_QRFactor,mat,col,0,0)); 3411 PetscUseMethod(mat,"MatQRFactor_C", (Mat,IS,const MatFactorInfo*), (mat, col, info)); 3412 PetscCall(PetscLogEventEnd(MAT_QRFactor,mat,col,0,0)); 3413 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 3414 PetscFunctionReturn(0); 3415 } 3416 3417 /*@ 3418 MatQRFactorSymbolic - Performs symbolic QR factorization of matrix. 3419 Call this routine before calling MatQRFactorNumeric(). 3420 3421 Collective on Mat 3422 3423 Input Parameters: 3424 + fact - the factor matrix obtained with MatGetFactor() 3425 . mat - the matrix 3426 . col - column permutation 3427 - info - options for factorization, includes 3428 $ fill - expected fill as ratio of original fill. 3429 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3430 $ Run with the option -info to determine an optimal value to use 3431 3432 Most users should employ the simplified KSP interface for linear solvers 3433 instead of working directly with matrix algebra routines such as this. 3434 See, e.g., KSPCreate(). 3435 3436 Level: developer 3437 3438 .seealso: `MatQRFactor()`, `MatQRFactorNumeric()`, `MatLUFactor()`, `MatFactorInfo`, `MatFactorInfoInitialize()` 3439 3440 Developer Note: fortran interface is not autogenerated as the f90 3441 interface definition cannot be generated correctly [due to MatFactorInfo] 3442 3443 @*/ 3444 PetscErrorCode MatQRFactorSymbolic(Mat fact,Mat mat,IS col,const MatFactorInfo *info) 3445 { 3446 MatFactorInfo tinfo; 3447 3448 PetscFunctionBegin; 3449 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3450 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 3451 if (info) PetscValidPointer(info,4); 3452 PetscValidType(mat,2); 3453 PetscValidPointer(fact,1); 3454 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3455 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3456 MatCheckPreallocated(mat,2); 3457 if (!info) { 3458 PetscCall(MatFactorInfoInitialize(&tinfo)); 3459 info = &tinfo; 3460 } 3461 3462 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_QRFactorSymbolic,fact,mat,col,0)); 3463 PetscUseMethod(fact,"MatQRFactorSymbolic_C", (Mat,Mat,IS,const MatFactorInfo*), (fact, mat, col, info)); 3464 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_QRFactorSymbolic,fact,mat,col,0)); 3465 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3466 PetscFunctionReturn(0); 3467 } 3468 3469 /*@ 3470 MatQRFactorNumeric - Performs numeric QR factorization of a matrix. 3471 Call this routine after first calling MatQRFactorSymbolic(). 3472 3473 Collective on Mat 3474 3475 Input Parameters: 3476 + fact - the factor matrix obtained with MatGetFactor() 3477 . mat - the matrix 3478 - info - options for factorization 3479 3480 Notes: 3481 See MatQRFactor() for in-place factorization. 3482 3483 Most users should employ the simplified KSP interface for linear solvers 3484 instead of working directly with matrix algebra routines such as this. 3485 See, e.g., KSPCreate(). 3486 3487 Level: developer 3488 3489 .seealso: `MatQRFactorSymbolic()`, `MatLUFactor()` 3490 3491 Developer Note: fortran interface is not autogenerated as the f90 3492 interface definition cannot be generated correctly [due to MatFactorInfo] 3493 3494 @*/ 3495 PetscErrorCode MatQRFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3496 { 3497 MatFactorInfo tinfo; 3498 3499 PetscFunctionBegin; 3500 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3501 PetscValidType(mat,2); 3502 PetscValidPointer(fact,1); 3503 PetscValidHeaderSpecific(fact,MAT_CLASSID,1); 3504 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3505 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); 3506 3507 MatCheckPreallocated(mat,2); 3508 if (!info) { 3509 PetscCall(MatFactorInfoInitialize(&tinfo)); 3510 info = &tinfo; 3511 } 3512 3513 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_QRFactorNumeric,mat,fact,0,0)); 3514 else PetscCall(PetscLogEventBegin(MAT_QRFactor,mat,fact,0,0)); 3515 PetscUseMethod(fact,"MatQRFactorNumeric_C", (Mat,Mat,const MatFactorInfo*), (fact, mat, info)); 3516 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_QRFactorNumeric,mat,fact,0,0)); 3517 else PetscCall(PetscLogEventEnd(MAT_QRFactor,mat,fact,0,0)); 3518 PetscCall(MatViewFromOptions(fact,NULL,"-mat_factor_view")); 3519 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3520 PetscFunctionReturn(0); 3521 } 3522 3523 /* ----------------------------------------------------------------*/ 3524 /*@ 3525 MatSolve - Solves A x = b, given a factored matrix. 3526 3527 Neighbor-wise Collective on Mat 3528 3529 Input Parameters: 3530 + mat - the factored matrix 3531 - b - the right-hand-side vector 3532 3533 Output Parameter: 3534 . x - the result vector 3535 3536 Notes: 3537 The vectors b and x cannot be the same. I.e., one cannot 3538 call MatSolve(A,x,x). 3539 3540 Notes: 3541 Most users should employ the simplified KSP interface for linear solvers 3542 instead of working directly with matrix algebra routines such as this. 3543 See, e.g., KSPCreate(). 3544 3545 Level: developer 3546 3547 .seealso: `MatSolveAdd()`, `MatSolveTranspose()`, `MatSolveTransposeAdd()` 3548 @*/ 3549 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x) 3550 { 3551 PetscFunctionBegin; 3552 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3553 PetscValidType(mat,1); 3554 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3555 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3556 PetscCheckSameComm(mat,1,b,2); 3557 PetscCheckSameComm(mat,1,x,3); 3558 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3559 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); 3560 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); 3561 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); 3562 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3563 MatCheckPreallocated(mat,1); 3564 3565 PetscCall(PetscLogEventBegin(MAT_Solve,mat,b,x,0)); 3566 if (mat->factorerrortype) { 3567 PetscCall(PetscInfo(mat,"MatFactorError %d\n",mat->factorerrortype)); 3568 PetscCall(VecSetInf(x)); 3569 } else { 3570 PetscCheck(mat->ops->solve,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3571 PetscCall((*mat->ops->solve)(mat,b,x)); 3572 } 3573 PetscCall(PetscLogEventEnd(MAT_Solve,mat,b,x,0)); 3574 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3575 PetscFunctionReturn(0); 3576 } 3577 3578 static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X,PetscBool trans) 3579 { 3580 Vec b,x; 3581 PetscInt N,i; 3582 PetscErrorCode (*f)(Mat,Vec,Vec); 3583 PetscBool Abound,Bneedconv = PETSC_FALSE,Xneedconv = PETSC_FALSE; 3584 3585 PetscFunctionBegin; 3586 if (A->factorerrortype) { 3587 PetscCall(PetscInfo(A,"MatFactorError %d\n",A->factorerrortype)); 3588 PetscCall(MatSetInf(X)); 3589 PetscFunctionReturn(0); 3590 } 3591 f = (!trans || (!A->ops->solvetranspose && A->symmetric)) ? A->ops->solve : A->ops->solvetranspose; 3592 PetscCheck(f,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 3593 PetscCall(MatBoundToCPU(A,&Abound)); 3594 if (!Abound) { 3595 PetscCall(PetscObjectTypeCompareAny((PetscObject)B,&Bneedconv,MATSEQDENSE,MATMPIDENSE,"")); 3596 PetscCall(PetscObjectTypeCompareAny((PetscObject)X,&Xneedconv,MATSEQDENSE,MATMPIDENSE,"")); 3597 } 3598 if (Bneedconv) { 3599 PetscCall(MatConvert(B,MATDENSECUDA,MAT_INPLACE_MATRIX,&B)); 3600 } 3601 if (Xneedconv) { 3602 PetscCall(MatConvert(X,MATDENSECUDA,MAT_INPLACE_MATRIX,&X)); 3603 } 3604 PetscCall(MatGetSize(B,NULL,&N)); 3605 for (i=0; i<N; i++) { 3606 PetscCall(MatDenseGetColumnVecRead(B,i,&b)); 3607 PetscCall(MatDenseGetColumnVecWrite(X,i,&x)); 3608 PetscCall((*f)(A,b,x)); 3609 PetscCall(MatDenseRestoreColumnVecWrite(X,i,&x)); 3610 PetscCall(MatDenseRestoreColumnVecRead(B,i,&b)); 3611 } 3612 if (Bneedconv) { 3613 PetscCall(MatConvert(B,MATDENSE,MAT_INPLACE_MATRIX,&B)); 3614 } 3615 if (Xneedconv) { 3616 PetscCall(MatConvert(X,MATDENSE,MAT_INPLACE_MATRIX,&X)); 3617 } 3618 PetscFunctionReturn(0); 3619 } 3620 3621 /*@ 3622 MatMatSolve - Solves A X = B, given a factored matrix. 3623 3624 Neighbor-wise Collective on Mat 3625 3626 Input Parameters: 3627 + A - the factored matrix 3628 - B - the right-hand-side matrix MATDENSE (or sparse -- when using MUMPS) 3629 3630 Output Parameter: 3631 . X - the result matrix (dense matrix) 3632 3633 Notes: 3634 If B is a MATDENSE matrix then one can call MatMatSolve(A,B,B) except with MKL_CPARDISO; 3635 otherwise, B and X cannot be the same. 3636 3637 Notes: 3638 Most users should usually employ the simplified KSP interface for linear solvers 3639 instead of working directly with matrix algebra routines such as this. 3640 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3641 at a time. 3642 3643 Level: developer 3644 3645 .seealso: `MatMatSolveTranspose()`, `MatLUFactor()`, `MatCholeskyFactor()` 3646 @*/ 3647 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X) 3648 { 3649 PetscFunctionBegin; 3650 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3651 PetscValidType(A,1); 3652 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3653 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3654 PetscCheckSameComm(A,1,B,2); 3655 PetscCheckSameComm(A,1,X,3); 3656 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); 3657 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); 3658 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"); 3659 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3660 PetscCheck(A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3661 MatCheckPreallocated(A,1); 3662 3663 PetscCall(PetscLogEventBegin(MAT_MatSolve,A,B,X,0)); 3664 if (!A->ops->matsolve) { 3665 PetscCall(PetscInfo(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name)); 3666 PetscCall(MatMatSolve_Basic(A,B,X,PETSC_FALSE)); 3667 } else { 3668 PetscCall((*A->ops->matsolve)(A,B,X)); 3669 } 3670 PetscCall(PetscLogEventEnd(MAT_MatSolve,A,B,X,0)); 3671 PetscCall(PetscObjectStateIncrease((PetscObject)X)); 3672 PetscFunctionReturn(0); 3673 } 3674 3675 /*@ 3676 MatMatSolveTranspose - Solves A^T X = B, given a factored matrix. 3677 3678 Neighbor-wise Collective on Mat 3679 3680 Input Parameters: 3681 + A - the factored matrix 3682 - B - the right-hand-side matrix (dense matrix) 3683 3684 Output Parameter: 3685 . X - the result matrix (dense matrix) 3686 3687 Notes: 3688 The matrices B and X cannot be the same. I.e., one cannot 3689 call MatMatSolveTranspose(A,X,X). 3690 3691 Notes: 3692 Most users should usually employ the simplified KSP interface for linear solvers 3693 instead of working directly with matrix algebra routines such as this. 3694 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3695 at a time. 3696 3697 When using SuperLU_Dist or MUMPS as a parallel solver, PETSc will use their functionality to solve multiple right hand sides simultaneously. 3698 3699 Level: developer 3700 3701 .seealso: `MatMatSolve()`, `MatLUFactor()`, `MatCholeskyFactor()` 3702 @*/ 3703 PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X) 3704 { 3705 PetscFunctionBegin; 3706 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3707 PetscValidType(A,1); 3708 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3709 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3710 PetscCheckSameComm(A,1,B,2); 3711 PetscCheckSameComm(A,1,X,3); 3712 PetscCheck(X != B,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3713 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); 3714 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); 3715 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); 3716 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"); 3717 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3718 PetscCheck(A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3719 MatCheckPreallocated(A,1); 3720 3721 PetscCall(PetscLogEventBegin(MAT_MatSolve,A,B,X,0)); 3722 if (!A->ops->matsolvetranspose) { 3723 PetscCall(PetscInfo(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name)); 3724 PetscCall(MatMatSolve_Basic(A,B,X,PETSC_TRUE)); 3725 } else { 3726 PetscCall((*A->ops->matsolvetranspose)(A,B,X)); 3727 } 3728 PetscCall(PetscLogEventEnd(MAT_MatSolve,A,B,X,0)); 3729 PetscCall(PetscObjectStateIncrease((PetscObject)X)); 3730 PetscFunctionReturn(0); 3731 } 3732 3733 /*@ 3734 MatMatTransposeSolve - Solves A X = B^T, given a factored matrix. 3735 3736 Neighbor-wise Collective on Mat 3737 3738 Input Parameters: 3739 + A - the factored matrix 3740 - Bt - the transpose of right-hand-side matrix 3741 3742 Output Parameter: 3743 . X - the result matrix (dense matrix) 3744 3745 Notes: 3746 Most users should usually employ the simplified KSP interface for linear solvers 3747 instead of working directly with matrix algebra routines such as this. 3748 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3749 at a time. 3750 3751 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(). 3752 3753 Level: developer 3754 3755 .seealso: `MatMatSolve()`, `MatMatSolveTranspose()`, `MatLUFactor()`, `MatCholeskyFactor()` 3756 @*/ 3757 PetscErrorCode MatMatTransposeSolve(Mat A,Mat Bt,Mat X) 3758 { 3759 PetscFunctionBegin; 3760 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3761 PetscValidType(A,1); 3762 PetscValidHeaderSpecific(Bt,MAT_CLASSID,2); 3763 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3764 PetscCheckSameComm(A,1,Bt,2); 3765 PetscCheckSameComm(A,1,X,3); 3766 3767 PetscCheck(X != Bt,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3768 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); 3769 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); 3770 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"); 3771 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3772 PetscCheck(A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3773 MatCheckPreallocated(A,1); 3774 3775 PetscCheck(A->ops->mattransposesolve,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 3776 PetscCall(PetscLogEventBegin(MAT_MatTrSolve,A,Bt,X,0)); 3777 PetscCall((*A->ops->mattransposesolve)(A,Bt,X)); 3778 PetscCall(PetscLogEventEnd(MAT_MatTrSolve,A,Bt,X,0)); 3779 PetscCall(PetscObjectStateIncrease((PetscObject)X)); 3780 PetscFunctionReturn(0); 3781 } 3782 3783 /*@ 3784 MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or 3785 U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U, 3786 3787 Neighbor-wise Collective on Mat 3788 3789 Input Parameters: 3790 + mat - the factored matrix 3791 - b - the right-hand-side vector 3792 3793 Output Parameter: 3794 . x - the result vector 3795 3796 Notes: 3797 MatSolve() should be used for most applications, as it performs 3798 a forward solve followed by a backward solve. 3799 3800 The vectors b and x cannot be the same, i.e., one cannot 3801 call MatForwardSolve(A,x,x). 3802 3803 For matrix in seqsbaij format with block size larger than 1, 3804 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3805 MatForwardSolve() solves U^T*D y = b, and 3806 MatBackwardSolve() solves U x = y. 3807 Thus they do not provide a symmetric preconditioner. 3808 3809 Most users should employ the simplified KSP interface for linear solvers 3810 instead of working directly with matrix algebra routines such as this. 3811 See, e.g., KSPCreate(). 3812 3813 Level: developer 3814 3815 .seealso: `MatSolve()`, `MatBackwardSolve()` 3816 @*/ 3817 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x) 3818 { 3819 PetscFunctionBegin; 3820 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3821 PetscValidType(mat,1); 3822 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3823 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3824 PetscCheckSameComm(mat,1,b,2); 3825 PetscCheckSameComm(mat,1,x,3); 3826 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3827 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); 3828 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); 3829 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); 3830 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3831 MatCheckPreallocated(mat,1); 3832 3833 PetscCheck(mat->ops->forwardsolve,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3834 PetscCall(PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0)); 3835 PetscCall((*mat->ops->forwardsolve)(mat,b,x)); 3836 PetscCall(PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0)); 3837 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3838 PetscFunctionReturn(0); 3839 } 3840 3841 /*@ 3842 MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU. 3843 D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U, 3844 3845 Neighbor-wise Collective on Mat 3846 3847 Input Parameters: 3848 + mat - the factored matrix 3849 - b - the right-hand-side vector 3850 3851 Output Parameter: 3852 . x - the result vector 3853 3854 Notes: 3855 MatSolve() should be used for most applications, as it performs 3856 a forward solve followed by a backward solve. 3857 3858 The vectors b and x cannot be the same. I.e., one cannot 3859 call MatBackwardSolve(A,x,x). 3860 3861 For matrix in seqsbaij format with block size larger than 1, 3862 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3863 MatForwardSolve() solves U^T*D y = b, and 3864 MatBackwardSolve() solves U x = y. 3865 Thus they do not provide a symmetric preconditioner. 3866 3867 Most users should employ the simplified KSP interface for linear solvers 3868 instead of working directly with matrix algebra routines such as this. 3869 See, e.g., KSPCreate(). 3870 3871 Level: developer 3872 3873 .seealso: `MatSolve()`, `MatForwardSolve()` 3874 @*/ 3875 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x) 3876 { 3877 PetscFunctionBegin; 3878 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3879 PetscValidType(mat,1); 3880 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3881 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3882 PetscCheckSameComm(mat,1,b,2); 3883 PetscCheckSameComm(mat,1,x,3); 3884 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3885 PetscCheck(mat->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); 3886 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); 3887 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); 3888 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3889 MatCheckPreallocated(mat,1); 3890 3891 PetscCheck(mat->ops->backwardsolve,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3892 PetscCall(PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0)); 3893 PetscCall((*mat->ops->backwardsolve)(mat,b,x)); 3894 PetscCall(PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0)); 3895 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3896 PetscFunctionReturn(0); 3897 } 3898 3899 /*@ 3900 MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix. 3901 3902 Neighbor-wise Collective on Mat 3903 3904 Input Parameters: 3905 + mat - the factored matrix 3906 . b - the right-hand-side vector 3907 - y - the vector to be added to 3908 3909 Output Parameter: 3910 . x - the result vector 3911 3912 Notes: 3913 The vectors b and x cannot be the same. I.e., one cannot 3914 call MatSolveAdd(A,x,y,x). 3915 3916 Most users should employ the simplified KSP interface for linear solvers 3917 instead of working directly with matrix algebra routines such as this. 3918 See, e.g., KSPCreate(). 3919 3920 Level: developer 3921 3922 .seealso: `MatSolve()`, `MatSolveTranspose()`, `MatSolveTransposeAdd()` 3923 @*/ 3924 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x) 3925 { 3926 PetscScalar one = 1.0; 3927 Vec tmp; 3928 3929 PetscFunctionBegin; 3930 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3931 PetscValidType(mat,1); 3932 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 3933 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3934 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 3935 PetscCheckSameComm(mat,1,b,2); 3936 PetscCheckSameComm(mat,1,y,3); 3937 PetscCheckSameComm(mat,1,x,4); 3938 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3939 PetscCheck(mat->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); 3940 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); 3941 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); 3942 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); 3943 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); 3944 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3945 MatCheckPreallocated(mat,1); 3946 3947 PetscCall(PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y)); 3948 if (mat->factorerrortype) { 3949 3950 PetscCall(PetscInfo(mat,"MatFactorError %d\n",mat->factorerrortype)); 3951 PetscCall(VecSetInf(x)); 3952 } else if (mat->ops->solveadd) { 3953 PetscCall((*mat->ops->solveadd)(mat,b,y,x)); 3954 } else { 3955 /* do the solve then the add manually */ 3956 if (x != y) { 3957 PetscCall(MatSolve(mat,b,x)); 3958 PetscCall(VecAXPY(x,one,y)); 3959 } else { 3960 PetscCall(VecDuplicate(x,&tmp)); 3961 PetscCall(PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp)); 3962 PetscCall(VecCopy(x,tmp)); 3963 PetscCall(MatSolve(mat,b,x)); 3964 PetscCall(VecAXPY(x,one,tmp)); 3965 PetscCall(VecDestroy(&tmp)); 3966 } 3967 } 3968 PetscCall(PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y)); 3969 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3970 PetscFunctionReturn(0); 3971 } 3972 3973 /*@ 3974 MatSolveTranspose - Solves A' x = b, given a factored matrix. 3975 3976 Neighbor-wise Collective on Mat 3977 3978 Input Parameters: 3979 + mat - the factored matrix 3980 - b - the right-hand-side vector 3981 3982 Output Parameter: 3983 . x - the result vector 3984 3985 Notes: 3986 The vectors b and x cannot be the same. I.e., one cannot 3987 call MatSolveTranspose(A,x,x). 3988 3989 Most users should employ the simplified KSP interface for linear solvers 3990 instead of working directly with matrix algebra routines such as this. 3991 See, e.g., KSPCreate(). 3992 3993 Level: developer 3994 3995 .seealso: `MatSolve()`, `MatSolveAdd()`, `MatSolveTransposeAdd()` 3996 @*/ 3997 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x) 3998 { 3999 PetscErrorCode (*f)(Mat,Vec,Vec) = (!mat->ops->solvetranspose && mat->symmetric) ? mat->ops->solve : mat->ops->solvetranspose; 4000 4001 PetscFunctionBegin; 4002 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4003 PetscValidType(mat,1); 4004 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 4005 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 4006 PetscCheckSameComm(mat,1,b,2); 4007 PetscCheckSameComm(mat,1,x,3); 4008 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 4009 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); 4010 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); 4011 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 4012 MatCheckPreallocated(mat,1); 4013 PetscCall(PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0)); 4014 if (mat->factorerrortype) { 4015 PetscCall(PetscInfo(mat,"MatFactorError %d\n",mat->factorerrortype)); 4016 PetscCall(VecSetInf(x)); 4017 } else { 4018 PetscCheck(f,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name); 4019 PetscCall((*f)(mat,b,x)); 4020 } 4021 PetscCall(PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0)); 4022 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 4023 PetscFunctionReturn(0); 4024 } 4025 4026 /*@ 4027 MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a 4028 factored matrix. 4029 4030 Neighbor-wise Collective on Mat 4031 4032 Input Parameters: 4033 + mat - the factored matrix 4034 . b - the right-hand-side vector 4035 - y - the vector to be added to 4036 4037 Output Parameter: 4038 . x - the result vector 4039 4040 Notes: 4041 The vectors b and x cannot be the same. I.e., one cannot 4042 call MatSolveTransposeAdd(A,x,y,x). 4043 4044 Most users should employ the simplified KSP interface for linear solvers 4045 instead of working directly with matrix algebra routines such as this. 4046 See, e.g., KSPCreate(). 4047 4048 Level: developer 4049 4050 .seealso: `MatSolve()`, `MatSolveAdd()`, `MatSolveTranspose()` 4051 @*/ 4052 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x) 4053 { 4054 PetscScalar one = 1.0; 4055 Vec tmp; 4056 PetscErrorCode (*f)(Mat,Vec,Vec,Vec) = (!mat->ops->solvetransposeadd && mat->symmetric) ? mat->ops->solveadd : mat->ops->solvetransposeadd; 4057 4058 PetscFunctionBegin; 4059 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4060 PetscValidType(mat,1); 4061 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 4062 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 4063 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 4064 PetscCheckSameComm(mat,1,b,2); 4065 PetscCheckSameComm(mat,1,y,3); 4066 PetscCheckSameComm(mat,1,x,4); 4067 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 4068 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); 4069 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); 4070 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); 4071 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); 4072 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 4073 MatCheckPreallocated(mat,1); 4074 4075 PetscCall(PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y)); 4076 if (mat->factorerrortype) { 4077 PetscCall(PetscInfo(mat,"MatFactorError %d\n",mat->factorerrortype)); 4078 PetscCall(VecSetInf(x)); 4079 } else if (f) { 4080 PetscCall((*f)(mat,b,y,x)); 4081 } else { 4082 /* do the solve then the add manually */ 4083 if (x != y) { 4084 PetscCall(MatSolveTranspose(mat,b,x)); 4085 PetscCall(VecAXPY(x,one,y)); 4086 } else { 4087 PetscCall(VecDuplicate(x,&tmp)); 4088 PetscCall(PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp)); 4089 PetscCall(VecCopy(x,tmp)); 4090 PetscCall(MatSolveTranspose(mat,b,x)); 4091 PetscCall(VecAXPY(x,one,tmp)); 4092 PetscCall(VecDestroy(&tmp)); 4093 } 4094 } 4095 PetscCall(PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y)); 4096 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 4097 PetscFunctionReturn(0); 4098 } 4099 /* ----------------------------------------------------------------*/ 4100 4101 /*@ 4102 MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps. 4103 4104 Neighbor-wise Collective on Mat 4105 4106 Input Parameters: 4107 + mat - the matrix 4108 . b - the right hand side 4109 . omega - the relaxation factor 4110 . flag - flag indicating the type of SOR (see below) 4111 . shift - diagonal shift 4112 . its - the number of iterations 4113 - lits - the number of local iterations 4114 4115 Output Parameter: 4116 . x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess) 4117 4118 SOR Flags: 4119 + SOR_FORWARD_SWEEP - forward SOR 4120 . SOR_BACKWARD_SWEEP - backward SOR 4121 . SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR) 4122 . SOR_LOCAL_FORWARD_SWEEP - local forward SOR 4123 . SOR_LOCAL_BACKWARD_SWEEP - local forward SOR 4124 . SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR 4125 . SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies 4126 upper/lower triangular part of matrix to 4127 vector (with omega) 4128 - SOR_ZERO_INITIAL_GUESS - zero initial guess 4129 4130 Notes: 4131 SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and 4132 SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings 4133 on each processor. 4134 4135 Application programmers will not generally use MatSOR() directly, 4136 but instead will employ the KSP/PC interface. 4137 4138 Notes: 4139 for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing 4140 4141 Notes for Advanced Users: 4142 The flags are implemented as bitwise inclusive or operations. 4143 For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP) 4144 to specify a zero initial guess for SSOR. 4145 4146 Most users should employ the simplified KSP interface for linear solvers 4147 instead of working directly with matrix algebra routines such as this. 4148 See, e.g., KSPCreate(). 4149 4150 Vectors x and b CANNOT be the same 4151 4152 Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes 4153 4154 Level: developer 4155 4156 @*/ 4157 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x) 4158 { 4159 PetscFunctionBegin; 4160 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4161 PetscValidType(mat,1); 4162 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 4163 PetscValidHeaderSpecific(x,VEC_CLASSID,8); 4164 PetscCheckSameComm(mat,1,b,2); 4165 PetscCheckSameComm(mat,1,x,8); 4166 PetscCheck(mat->ops->sor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4167 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4168 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4169 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); 4170 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); 4171 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); 4172 PetscCheck(its > 0,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %" PetscInt_FMT " positive",its); 4173 PetscCheck(lits > 0,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %" PetscInt_FMT " positive",lits); 4174 PetscCheck(b != x,PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same"); 4175 4176 MatCheckPreallocated(mat,1); 4177 PetscCall(PetscLogEventBegin(MAT_SOR,mat,b,x,0)); 4178 PetscCall((*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x)); 4179 PetscCall(PetscLogEventEnd(MAT_SOR,mat,b,x,0)); 4180 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 4181 PetscFunctionReturn(0); 4182 } 4183 4184 /* 4185 Default matrix copy routine. 4186 */ 4187 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str) 4188 { 4189 PetscInt i,rstart = 0,rend = 0,nz; 4190 const PetscInt *cwork; 4191 const PetscScalar *vwork; 4192 4193 PetscFunctionBegin; 4194 if (B->assembled) PetscCall(MatZeroEntries(B)); 4195 if (str == SAME_NONZERO_PATTERN) { 4196 PetscCall(MatGetOwnershipRange(A,&rstart,&rend)); 4197 for (i=rstart; i<rend; i++) { 4198 PetscCall(MatGetRow(A,i,&nz,&cwork,&vwork)); 4199 PetscCall(MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES)); 4200 PetscCall(MatRestoreRow(A,i,&nz,&cwork,&vwork)); 4201 } 4202 } else { 4203 PetscCall(MatAYPX(B,0.0,A,str)); 4204 } 4205 PetscCall(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY)); 4206 PetscCall(MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY)); 4207 PetscFunctionReturn(0); 4208 } 4209 4210 /*@ 4211 MatCopy - Copies a matrix to another matrix. 4212 4213 Collective on Mat 4214 4215 Input Parameters: 4216 + A - the matrix 4217 - str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN 4218 4219 Output Parameter: 4220 . B - where the copy is put 4221 4222 Notes: 4223 If you use SAME_NONZERO_PATTERN then the two matrices must have the same nonzero pattern or the routine will crash. 4224 4225 MatCopy() copies the matrix entries of a matrix to another existing 4226 matrix (after first zeroing the second matrix). A related routine is 4227 MatConvert(), which first creates a new matrix and then copies the data. 4228 4229 Level: intermediate 4230 4231 .seealso: `MatConvert()`, `MatDuplicate()` 4232 @*/ 4233 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str) 4234 { 4235 PetscInt i; 4236 4237 PetscFunctionBegin; 4238 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4239 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4240 PetscValidType(A,1); 4241 PetscValidType(B,2); 4242 PetscCheckSameComm(A,1,B,2); 4243 MatCheckPreallocated(B,2); 4244 PetscCheck(A->assembled,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4245 PetscCheck(!A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4246 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); 4247 MatCheckPreallocated(A,1); 4248 if (A == B) PetscFunctionReturn(0); 4249 4250 PetscCall(PetscLogEventBegin(MAT_Copy,A,B,0,0)); 4251 if (A->ops->copy) { 4252 PetscCall((*A->ops->copy)(A,B,str)); 4253 } else { /* generic conversion */ 4254 PetscCall(MatCopy_Basic(A,B,str)); 4255 } 4256 4257 B->stencil.dim = A->stencil.dim; 4258 B->stencil.noc = A->stencil.noc; 4259 for (i=0; i<=A->stencil.dim; i++) { 4260 B->stencil.dims[i] = A->stencil.dims[i]; 4261 B->stencil.starts[i] = A->stencil.starts[i]; 4262 } 4263 4264 PetscCall(PetscLogEventEnd(MAT_Copy,A,B,0,0)); 4265 PetscCall(PetscObjectStateIncrease((PetscObject)B)); 4266 PetscFunctionReturn(0); 4267 } 4268 4269 /*@C 4270 MatConvert - Converts a matrix to another matrix, either of the same 4271 or different type. 4272 4273 Collective on Mat 4274 4275 Input Parameters: 4276 + mat - the matrix 4277 . newtype - new matrix type. Use MATSAME to create a new matrix of the 4278 same type as the original matrix. 4279 - reuse - denotes if the destination matrix is to be created or reused. 4280 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 4281 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). 4282 4283 Output Parameter: 4284 . M - pointer to place new matrix 4285 4286 Notes: 4287 MatConvert() first creates a new matrix and then copies the data from 4288 the first matrix. A related routine is MatCopy(), which copies the matrix 4289 entries of one matrix to another already existing matrix context. 4290 4291 Cannot be used to convert a sequential matrix to parallel or parallel to sequential, 4292 the MPI communicator of the generated matrix is always the same as the communicator 4293 of the input matrix. 4294 4295 Level: intermediate 4296 4297 .seealso: `MatCopy()`, `MatDuplicate()` 4298 @*/ 4299 PetscErrorCode MatConvert(Mat mat,MatType newtype,MatReuse reuse,Mat *M) 4300 { 4301 PetscBool sametype,issame,flg; 4302 PetscBool3 issymmetric,ishermitian; 4303 char convname[256],mtype[256]; 4304 Mat B; 4305 4306 PetscFunctionBegin; 4307 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4308 PetscValidType(mat,1); 4309 PetscValidPointer(M,4); 4310 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4311 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4312 MatCheckPreallocated(mat,1); 4313 4314 PetscCall(PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,sizeof(mtype),&flg)); 4315 if (flg) newtype = mtype; 4316 4317 PetscCall(PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype)); 4318 PetscCall(PetscStrcmp(newtype,"same",&issame)); 4319 PetscCheck(!(reuse == MAT_INPLACE_MATRIX) || !(mat != *M),PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix"); 4320 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"); 4321 4322 if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) { 4323 PetscCall(PetscInfo(mat,"Early return for inplace %s %d %d\n",((PetscObject)mat)->type_name,sametype,issame)); 4324 PetscFunctionReturn(0); 4325 } 4326 4327 /* Cache Mat options because some converters use MatHeaderReplace */ 4328 issymmetric = mat->symmetric; 4329 ishermitian = mat->hermitian; 4330 4331 if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) { 4332 PetscCall(PetscInfo(mat,"Calling duplicate for initial matrix %s %d %d\n",((PetscObject)mat)->type_name,sametype,issame)); 4333 PetscCall((*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M)); 4334 } else { 4335 PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL; 4336 const char *prefix[3] = {"seq","mpi",""}; 4337 PetscInt i; 4338 /* 4339 Order of precedence: 4340 0) See if newtype is a superclass of the current matrix. 4341 1) See if a specialized converter is known to the current matrix. 4342 2) See if a specialized converter is known to the desired matrix class. 4343 3) See if a good general converter is registered for the desired class 4344 (as of 6/27/03 only MATMPIADJ falls into this category). 4345 4) See if a good general converter is known for the current matrix. 4346 5) Use a really basic converter. 4347 */ 4348 4349 /* 0) See if newtype is a superclass of the current matrix. 4350 i.e mat is mpiaij and newtype is aij */ 4351 for (i=0; i<2; i++) { 4352 PetscCall(PetscStrncpy(convname,prefix[i],sizeof(convname))); 4353 PetscCall(PetscStrlcat(convname,newtype,sizeof(convname))); 4354 PetscCall(PetscStrcmp(convname,((PetscObject)mat)->type_name,&flg)); 4355 PetscCall(PetscInfo(mat,"Check superclass %s %s -> %d\n",convname,((PetscObject)mat)->type_name,flg)); 4356 if (flg) { 4357 if (reuse == MAT_INPLACE_MATRIX) { 4358 PetscCall(PetscInfo(mat,"Early return\n")); 4359 PetscFunctionReturn(0); 4360 } else if (reuse == MAT_INITIAL_MATRIX && mat->ops->duplicate) { 4361 PetscCall(PetscInfo(mat,"Calling MatDuplicate\n")); 4362 PetscCall((*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M)); 4363 PetscFunctionReturn(0); 4364 } else if (reuse == MAT_REUSE_MATRIX && mat->ops->copy) { 4365 PetscCall(PetscInfo(mat,"Calling MatCopy\n")); 4366 PetscCall(MatCopy(mat,*M,SAME_NONZERO_PATTERN)); 4367 PetscFunctionReturn(0); 4368 } 4369 } 4370 } 4371 /* 1) See if a specialized converter is known to the current matrix and the desired class */ 4372 for (i=0; i<3; i++) { 4373 PetscCall(PetscStrncpy(convname,"MatConvert_",sizeof(convname))); 4374 PetscCall(PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname))); 4375 PetscCall(PetscStrlcat(convname,"_",sizeof(convname))); 4376 PetscCall(PetscStrlcat(convname,prefix[i],sizeof(convname))); 4377 PetscCall(PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname))); 4378 PetscCall(PetscStrlcat(convname,"_C",sizeof(convname))); 4379 PetscCall(PetscObjectQueryFunction((PetscObject)mat,convname,&conv)); 4380 PetscCall(PetscInfo(mat,"Check specialized (1) %s (%s) -> %d\n",convname,((PetscObject)mat)->type_name,!!conv)); 4381 if (conv) goto foundconv; 4382 } 4383 4384 /* 2) See if a specialized converter is known to the desired matrix class. */ 4385 PetscCall(MatCreate(PetscObjectComm((PetscObject)mat),&B)); 4386 PetscCall(MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N)); 4387 PetscCall(MatSetType(B,newtype)); 4388 for (i=0; i<3; i++) { 4389 PetscCall(PetscStrncpy(convname,"MatConvert_",sizeof(convname))); 4390 PetscCall(PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname))); 4391 PetscCall(PetscStrlcat(convname,"_",sizeof(convname))); 4392 PetscCall(PetscStrlcat(convname,prefix[i],sizeof(convname))); 4393 PetscCall(PetscStrlcat(convname,newtype,sizeof(convname))); 4394 PetscCall(PetscStrlcat(convname,"_C",sizeof(convname))); 4395 PetscCall(PetscObjectQueryFunction((PetscObject)B,convname,&conv)); 4396 PetscCall(PetscInfo(mat,"Check specialized (2) %s (%s) -> %d\n",convname,((PetscObject)B)->type_name,!!conv)); 4397 if (conv) { 4398 PetscCall(MatDestroy(&B)); 4399 goto foundconv; 4400 } 4401 } 4402 4403 /* 3) See if a good general converter is registered for the desired class */ 4404 conv = B->ops->convertfrom; 4405 PetscCall(PetscInfo(mat,"Check convertfrom (%s) -> %d\n",((PetscObject)B)->type_name,!!conv)); 4406 PetscCall(MatDestroy(&B)); 4407 if (conv) goto foundconv; 4408 4409 /* 4) See if a good general converter is known for the current matrix */ 4410 if (mat->ops->convert) conv = mat->ops->convert; 4411 PetscCall(PetscInfo(mat,"Check general convert (%s) -> %d\n",((PetscObject)mat)->type_name,!!conv)); 4412 if (conv) goto foundconv; 4413 4414 /* 5) Use a really basic converter. */ 4415 PetscCall(PetscInfo(mat,"Using MatConvert_Basic\n")); 4416 conv = MatConvert_Basic; 4417 4418 foundconv: 4419 PetscCall(PetscLogEventBegin(MAT_Convert,mat,0,0,0)); 4420 PetscCall((*conv)(mat,newtype,reuse,M)); 4421 if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) { 4422 /* the block sizes must be same if the mappings are copied over */ 4423 (*M)->rmap->bs = mat->rmap->bs; 4424 (*M)->cmap->bs = mat->cmap->bs; 4425 PetscCall(PetscObjectReference((PetscObject)mat->rmap->mapping)); 4426 PetscCall(PetscObjectReference((PetscObject)mat->cmap->mapping)); 4427 (*M)->rmap->mapping = mat->rmap->mapping; 4428 (*M)->cmap->mapping = mat->cmap->mapping; 4429 } 4430 (*M)->stencil.dim = mat->stencil.dim; 4431 (*M)->stencil.noc = mat->stencil.noc; 4432 for (i=0; i<=mat->stencil.dim; i++) { 4433 (*M)->stencil.dims[i] = mat->stencil.dims[i]; 4434 (*M)->stencil.starts[i] = mat->stencil.starts[i]; 4435 } 4436 PetscCall(PetscLogEventEnd(MAT_Convert,mat,0,0,0)); 4437 } 4438 PetscCall(PetscObjectStateIncrease((PetscObject)*M)); 4439 4440 /* Copy Mat options */ 4441 if (issymmetric == PETSC_BOOL3_TRUE) PetscCall(MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE)); 4442 else if (issymmetric == PETSC_BOOL3_FALSE) PetscCall(MatSetOption(*M,MAT_SYMMETRIC,PETSC_FALSE)); 4443 if (ishermitian == PETSC_BOOL3_TRUE) PetscCall(MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE)); 4444 else if (ishermitian == PETSC_BOOL3_FALSE) PetscCall(MatSetOption(*M,MAT_HERMITIAN,PETSC_FALSE)); 4445 PetscFunctionReturn(0); 4446 } 4447 4448 /*@C 4449 MatFactorGetSolverType - Returns name of the package providing the factorization routines 4450 4451 Not Collective 4452 4453 Input Parameter: 4454 . mat - the matrix, must be a factored matrix 4455 4456 Output Parameter: 4457 . type - the string name of the package (do not free this string) 4458 4459 Notes: 4460 In Fortran you pass in a empty string and the package name will be copied into it. 4461 (Make sure the string is long enough) 4462 4463 Level: intermediate 4464 4465 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()` 4466 @*/ 4467 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type) 4468 { 4469 PetscErrorCode (*conv)(Mat,MatSolverType*); 4470 4471 PetscFunctionBegin; 4472 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4473 PetscValidType(mat,1); 4474 PetscValidPointer(type,2); 4475 PetscCheck(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 4476 PetscCall(PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv)); 4477 if (conv) PetscCall((*conv)(mat,type)); 4478 else *type = MATSOLVERPETSC; 4479 PetscFunctionReturn(0); 4480 } 4481 4482 typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType; 4483 struct _MatSolverTypeForSpecifcType { 4484 MatType mtype; 4485 /* no entry for MAT_FACTOR_NONE */ 4486 PetscErrorCode (*createfactor[MAT_FACTOR_NUM_TYPES-1])(Mat,MatFactorType,Mat*); 4487 MatSolverTypeForSpecifcType next; 4488 }; 4489 4490 typedef struct _MatSolverTypeHolder* MatSolverTypeHolder; 4491 struct _MatSolverTypeHolder { 4492 char *name; 4493 MatSolverTypeForSpecifcType handlers; 4494 MatSolverTypeHolder next; 4495 }; 4496 4497 static MatSolverTypeHolder MatSolverTypeHolders = NULL; 4498 4499 /*@C 4500 MatSolverTypeRegister - Registers a MatSolverType that works for a particular matrix type 4501 4502 Input Parameters: 4503 + package - name of the package, for example petsc or superlu 4504 . mtype - the matrix type that works with this package 4505 . ftype - the type of factorization supported by the package 4506 - createfactor - routine that will create the factored matrix ready to be used 4507 4508 Level: intermediate 4509 4510 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()` 4511 @*/ 4512 PetscErrorCode MatSolverTypeRegister(MatSolverType package,MatType mtype,MatFactorType ftype,PetscErrorCode (*createfactor)(Mat,MatFactorType,Mat*)) 4513 { 4514 MatSolverTypeHolder next = MatSolverTypeHolders,prev = NULL; 4515 PetscBool flg; 4516 MatSolverTypeForSpecifcType inext,iprev = NULL; 4517 4518 PetscFunctionBegin; 4519 PetscCall(MatInitializePackage()); 4520 if (!next) { 4521 PetscCall(PetscNew(&MatSolverTypeHolders)); 4522 PetscCall(PetscStrallocpy(package,&MatSolverTypeHolders->name)); 4523 PetscCall(PetscNew(&MatSolverTypeHolders->handlers)); 4524 PetscCall(PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype)); 4525 MatSolverTypeHolders->handlers->createfactor[(int)ftype-1] = createfactor; 4526 PetscFunctionReturn(0); 4527 } 4528 while (next) { 4529 PetscCall(PetscStrcasecmp(package,next->name,&flg)); 4530 if (flg) { 4531 PetscCheck(next->handlers,PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers"); 4532 inext = next->handlers; 4533 while (inext) { 4534 PetscCall(PetscStrcasecmp(mtype,inext->mtype,&flg)); 4535 if (flg) { 4536 inext->createfactor[(int)ftype-1] = createfactor; 4537 PetscFunctionReturn(0); 4538 } 4539 iprev = inext; 4540 inext = inext->next; 4541 } 4542 PetscCall(PetscNew(&iprev->next)); 4543 PetscCall(PetscStrallocpy(mtype,(char **)&iprev->next->mtype)); 4544 iprev->next->createfactor[(int)ftype-1] = createfactor; 4545 PetscFunctionReturn(0); 4546 } 4547 prev = next; 4548 next = next->next; 4549 } 4550 PetscCall(PetscNew(&prev->next)); 4551 PetscCall(PetscStrallocpy(package,&prev->next->name)); 4552 PetscCall(PetscNew(&prev->next->handlers)); 4553 PetscCall(PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype)); 4554 prev->next->handlers->createfactor[(int)ftype-1] = createfactor; 4555 PetscFunctionReturn(0); 4556 } 4557 4558 /*@C 4559 MatSolverTypeGet - Gets the function that creates the factor matrix if it exist 4560 4561 Input Parameters: 4562 + type - name of the package, for example petsc or superlu 4563 . ftype - the type of factorization supported by the type 4564 - mtype - the matrix type that works with this type 4565 4566 Output Parameters: 4567 + foundtype - PETSC_TRUE if the type was registered 4568 . foundmtype - PETSC_TRUE if the type supports the requested mtype 4569 - createfactor - routine that will create the factored matrix ready to be used or NULL if not found 4570 4571 Level: intermediate 4572 4573 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatSolverTypeRegister()`, `MatGetFactor()` 4574 @*/ 4575 PetscErrorCode MatSolverTypeGet(MatSolverType type,MatType mtype,MatFactorType ftype,PetscBool *foundtype,PetscBool *foundmtype,PetscErrorCode (**createfactor)(Mat,MatFactorType,Mat*)) 4576 { 4577 MatSolverTypeHolder next = MatSolverTypeHolders; 4578 PetscBool flg; 4579 MatSolverTypeForSpecifcType inext; 4580 4581 PetscFunctionBegin; 4582 if (foundtype) *foundtype = PETSC_FALSE; 4583 if (foundmtype) *foundmtype = PETSC_FALSE; 4584 if (createfactor) *createfactor = NULL; 4585 4586 if (type) { 4587 while (next) { 4588 PetscCall(PetscStrcasecmp(type,next->name,&flg)); 4589 if (flg) { 4590 if (foundtype) *foundtype = PETSC_TRUE; 4591 inext = next->handlers; 4592 while (inext) { 4593 PetscCall(PetscStrbeginswith(mtype,inext->mtype,&flg)); 4594 if (flg) { 4595 if (foundmtype) *foundmtype = PETSC_TRUE; 4596 if (createfactor) *createfactor = inext->createfactor[(int)ftype-1]; 4597 PetscFunctionReturn(0); 4598 } 4599 inext = inext->next; 4600 } 4601 } 4602 next = next->next; 4603 } 4604 } else { 4605 while (next) { 4606 inext = next->handlers; 4607 while (inext) { 4608 PetscCall(PetscStrcmp(mtype,inext->mtype,&flg)); 4609 if (flg && inext->createfactor[(int)ftype-1]) { 4610 if (foundtype) *foundtype = PETSC_TRUE; 4611 if (foundmtype) *foundmtype = PETSC_TRUE; 4612 if (createfactor) *createfactor = inext->createfactor[(int)ftype-1]; 4613 PetscFunctionReturn(0); 4614 } 4615 inext = inext->next; 4616 } 4617 next = next->next; 4618 } 4619 /* try with base classes inext->mtype */ 4620 next = MatSolverTypeHolders; 4621 while (next) { 4622 inext = next->handlers; 4623 while (inext) { 4624 PetscCall(PetscStrbeginswith(mtype,inext->mtype,&flg)); 4625 if (flg && inext->createfactor[(int)ftype-1]) { 4626 if (foundtype) *foundtype = PETSC_TRUE; 4627 if (foundmtype) *foundmtype = PETSC_TRUE; 4628 if (createfactor) *createfactor = inext->createfactor[(int)ftype-1]; 4629 PetscFunctionReturn(0); 4630 } 4631 inext = inext->next; 4632 } 4633 next = next->next; 4634 } 4635 } 4636 PetscFunctionReturn(0); 4637 } 4638 4639 PetscErrorCode MatSolverTypeDestroy(void) 4640 { 4641 MatSolverTypeHolder next = MatSolverTypeHolders,prev; 4642 MatSolverTypeForSpecifcType inext,iprev; 4643 4644 PetscFunctionBegin; 4645 while (next) { 4646 PetscCall(PetscFree(next->name)); 4647 inext = next->handlers; 4648 while (inext) { 4649 PetscCall(PetscFree(inext->mtype)); 4650 iprev = inext; 4651 inext = inext->next; 4652 PetscCall(PetscFree(iprev)); 4653 } 4654 prev = next; 4655 next = next->next; 4656 PetscCall(PetscFree(prev)); 4657 } 4658 MatSolverTypeHolders = NULL; 4659 PetscFunctionReturn(0); 4660 } 4661 4662 /*@C 4663 MatFactorGetCanUseOrdering - Indicates if the factorization can use the ordering provided in MatLUFactorSymbolic(), MatCholeskyFactorSymbolic() 4664 4665 Logically Collective on Mat 4666 4667 Input Parameters: 4668 . mat - the matrix 4669 4670 Output Parameters: 4671 . flg - PETSC_TRUE if uses the ordering 4672 4673 Notes: 4674 Most internal PETSc factorizations use the ordering passed to the factorization routine but external 4675 packages do not, thus we want to skip generating the ordering when it is not needed or used. 4676 4677 Level: developer 4678 4679 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()` 4680 @*/ 4681 PetscErrorCode MatFactorGetCanUseOrdering(Mat mat, PetscBool *flg) 4682 { 4683 PetscFunctionBegin; 4684 *flg = mat->canuseordering; 4685 PetscFunctionReturn(0); 4686 } 4687 4688 /*@C 4689 MatFactorGetPreferredOrdering - The preferred ordering for a particular matrix factor object 4690 4691 Logically Collective on Mat 4692 4693 Input Parameters: 4694 . mat - the matrix 4695 4696 Output Parameters: 4697 . otype - the preferred type 4698 4699 Level: developer 4700 4701 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()` 4702 @*/ 4703 PetscErrorCode MatFactorGetPreferredOrdering(Mat mat, MatFactorType ftype, MatOrderingType *otype) 4704 { 4705 PetscFunctionBegin; 4706 *otype = mat->preferredordering[ftype]; 4707 PetscCheck(*otype,PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatFactor did not have a preferred ordering"); 4708 PetscFunctionReturn(0); 4709 } 4710 4711 /*@C 4712 MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic() 4713 4714 Collective on Mat 4715 4716 Input Parameters: 4717 + mat - the matrix 4718 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4719 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4720 4721 Output Parameters: 4722 . f - the factor matrix used with MatXXFactorSymbolic() calls 4723 4724 Options Database Key: 4725 . -mat_factor_bind_factorization <host, device> - Where to do matrix factorization? Default is device (might consume more device memory. 4726 One can choose host to save device memory). Currently only supported with SEQAIJCUSPARSE matrices. 4727 4728 Notes: 4729 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4730 such as pastix, superlu, mumps etc. 4731 4732 PETSc must have been ./configure to use the external solver, using the option --download-package 4733 4734 Some of the packages have options for controlling the factorization, these are in the form -prefix_mat_packagename_packageoption 4735 where prefix is normally obtained from the calling `KSP`/`PC`. If `MatGetFactor()` is called directly one can set 4736 call `MatSetOptionsPrefixFactor()` on the originating matrix or `MatSetOptionsPrefix()` on the resulting factor matrix. 4737 4738 Developer Notes: 4739 This should actually be called MatCreateFactor() since it creates a new factor object 4740 4741 Level: intermediate 4742 4743 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatFactorGetCanUseOrdering()`, `MatSolverTypeRegister()` 4744 @*/ 4745 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f) 4746 { 4747 PetscBool foundtype,foundmtype; 4748 PetscErrorCode (*conv)(Mat,MatFactorType,Mat*); 4749 4750 PetscFunctionBegin; 4751 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4752 PetscValidType(mat,1); 4753 4754 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4755 MatCheckPreallocated(mat,1); 4756 4757 PetscCall(MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundtype,&foundmtype,&conv)); 4758 if (!foundtype) { 4759 if (type) { 4760 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); 4761 } else { 4762 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); 4763 } 4764 } 4765 PetscCheck(foundmtype,PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name); 4766 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); 4767 4768 PetscCall((*conv)(mat,ftype,f)); 4769 if (mat->factorprefix) PetscCall(MatSetOptionsPrefix(*f,mat->factorprefix)); 4770 PetscFunctionReturn(0); 4771 } 4772 4773 /*@C 4774 MatGetFactorAvailable - Returns a a flag if matrix supports particular type and factor type 4775 4776 Not Collective 4777 4778 Input Parameters: 4779 + mat - the matrix 4780 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4781 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4782 4783 Output Parameter: 4784 . flg - PETSC_TRUE if the factorization is available 4785 4786 Notes: 4787 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4788 such as pastix, superlu, mumps etc. 4789 4790 PETSc must have been ./configure to use the external solver, using the option --download-package 4791 4792 Developer Notes: 4793 This should actually be called MatCreateFactorAvailable() since MatGetFactor() creates a new factor object 4794 4795 Level: intermediate 4796 4797 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactor()`, `MatSolverTypeRegister()` 4798 @*/ 4799 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool *flg) 4800 { 4801 PetscErrorCode (*gconv)(Mat,MatFactorType,Mat*); 4802 4803 PetscFunctionBegin; 4804 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4805 PetscValidType(mat,1); 4806 PetscValidBoolPointer(flg,4); 4807 4808 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4809 MatCheckPreallocated(mat,1); 4810 4811 PetscCall(MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv)); 4812 *flg = gconv ? PETSC_TRUE : PETSC_FALSE; 4813 PetscFunctionReturn(0); 4814 } 4815 4816 /*@ 4817 MatDuplicate - Duplicates a matrix including the non-zero structure. 4818 4819 Collective on Mat 4820 4821 Input Parameters: 4822 + mat - the matrix 4823 - op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN. 4824 See the manual page for MatDuplicateOption for an explanation of these options. 4825 4826 Output Parameter: 4827 . M - pointer to place new matrix 4828 4829 Level: intermediate 4830 4831 Notes: 4832 You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN. 4833 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. 4834 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. 4835 4836 .seealso: `MatCopy()`, `MatConvert()`, `MatDuplicateOption` 4837 @*/ 4838 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M) 4839 { 4840 Mat B; 4841 VecType vtype; 4842 PetscInt i; 4843 PetscObject dm; 4844 void (*viewf)(void); 4845 4846 PetscFunctionBegin; 4847 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4848 PetscValidType(mat,1); 4849 PetscValidPointer(M,3); 4850 PetscCheck(op != MAT_COPY_VALUES || mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix"); 4851 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4852 MatCheckPreallocated(mat,1); 4853 4854 *M = NULL; 4855 PetscCheck(mat->ops->duplicate,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for matrix type %s",((PetscObject)mat)->type_name); 4856 PetscCall(PetscLogEventBegin(MAT_Convert,mat,0,0,0)); 4857 PetscCall((*mat->ops->duplicate)(mat,op,M)); 4858 PetscCall(PetscLogEventEnd(MAT_Convert,mat,0,0,0)); 4859 B = *M; 4860 4861 PetscCall(MatGetOperation(mat,MATOP_VIEW,&viewf)); 4862 if (viewf) PetscCall(MatSetOperation(B,MATOP_VIEW,viewf)); 4863 PetscCall(MatGetVecType(mat,&vtype)); 4864 PetscCall(MatSetVecType(B,vtype)); 4865 4866 B->stencil.dim = mat->stencil.dim; 4867 B->stencil.noc = mat->stencil.noc; 4868 for (i=0; i<=mat->stencil.dim; i++) { 4869 B->stencil.dims[i] = mat->stencil.dims[i]; 4870 B->stencil.starts[i] = mat->stencil.starts[i]; 4871 } 4872 4873 B->nooffproczerorows = mat->nooffproczerorows; 4874 B->nooffprocentries = mat->nooffprocentries; 4875 4876 PetscCall(PetscObjectQuery((PetscObject) mat, "__PETSc_dm", &dm)); 4877 if (dm) { 4878 PetscCall(PetscObjectCompose((PetscObject) B, "__PETSc_dm", dm)); 4879 } 4880 PetscCall(PetscObjectStateIncrease((PetscObject)B)); 4881 PetscFunctionReturn(0); 4882 } 4883 4884 /*@ 4885 MatGetDiagonal - Gets the diagonal of a matrix. 4886 4887 Logically Collective on Mat 4888 4889 Input Parameters: 4890 + mat - the matrix 4891 - v - the vector for storing the diagonal 4892 4893 Output Parameter: 4894 . v - the diagonal of the matrix 4895 4896 Level: intermediate 4897 4898 Note: 4899 Currently only correct in parallel for square matrices. 4900 4901 .seealso: `MatGetRow()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMaxAbs()` 4902 @*/ 4903 PetscErrorCode MatGetDiagonal(Mat mat,Vec v) 4904 { 4905 PetscFunctionBegin; 4906 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4907 PetscValidType(mat,1); 4908 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4909 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4910 PetscCheck(mat->ops->getdiagonal,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4911 MatCheckPreallocated(mat,1); 4912 4913 PetscCall((*mat->ops->getdiagonal)(mat,v)); 4914 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 4915 PetscFunctionReturn(0); 4916 } 4917 4918 /*@C 4919 MatGetRowMin - Gets the minimum value (of the real part) of each 4920 row of the matrix 4921 4922 Logically Collective on Mat 4923 4924 Input Parameter: 4925 . mat - the matrix 4926 4927 Output Parameters: 4928 + v - the vector for storing the maximums 4929 - idx - the indices of the column found for each row (optional) 4930 4931 Level: intermediate 4932 4933 Notes: 4934 The result of this call are the same as if one converted the matrix to dense format 4935 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4936 4937 This code is only implemented for a couple of matrix formats. 4938 4939 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMaxAbs()`, 4940 `MatGetRowMax()` 4941 @*/ 4942 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[]) 4943 { 4944 PetscFunctionBegin; 4945 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4946 PetscValidType(mat,1); 4947 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4948 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4949 4950 if (!mat->cmap->N) { 4951 PetscCall(VecSet(v,PETSC_MAX_REAL)); 4952 if (idx) { 4953 PetscInt i,m = mat->rmap->n; 4954 for (i=0; i<m; i++) idx[i] = -1; 4955 } 4956 } else { 4957 PetscCheck(mat->ops->getrowmin,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4958 MatCheckPreallocated(mat,1); 4959 } 4960 PetscCall((*mat->ops->getrowmin)(mat,v,idx)); 4961 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 4962 PetscFunctionReturn(0); 4963 } 4964 4965 /*@C 4966 MatGetRowMinAbs - Gets the minimum value (in absolute value) of each 4967 row of the matrix 4968 4969 Logically Collective on Mat 4970 4971 Input Parameter: 4972 . mat - the matrix 4973 4974 Output Parameters: 4975 + v - the vector for storing the minimums 4976 - idx - the indices of the column found for each row (or NULL if not needed) 4977 4978 Level: intermediate 4979 4980 Notes: 4981 if a row is completely empty or has only 0.0 values then the idx[] value for that 4982 row is 0 (the first column). 4983 4984 This code is only implemented for a couple of matrix formats. 4985 4986 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMax()`, `MatGetRowMaxAbs()`, `MatGetRowMin()` 4987 @*/ 4988 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[]) 4989 { 4990 PetscFunctionBegin; 4991 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4992 PetscValidType(mat,1); 4993 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4994 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4995 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4996 4997 if (!mat->cmap->N) { 4998 PetscCall(VecSet(v,0.0)); 4999 if (idx) { 5000 PetscInt i,m = mat->rmap->n; 5001 for (i=0; i<m; i++) idx[i] = -1; 5002 } 5003 } else { 5004 PetscCheck(mat->ops->getrowminabs,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5005 MatCheckPreallocated(mat,1); 5006 if (idx) PetscCall(PetscArrayzero(idx,mat->rmap->n)); 5007 PetscCall((*mat->ops->getrowminabs)(mat,v,idx)); 5008 } 5009 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 5010 PetscFunctionReturn(0); 5011 } 5012 5013 /*@C 5014 MatGetRowMax - Gets the maximum value (of the real part) of each 5015 row of the matrix 5016 5017 Logically Collective on Mat 5018 5019 Input Parameter: 5020 . mat - the matrix 5021 5022 Output Parameters: 5023 + v - the vector for storing the maximums 5024 - idx - the indices of the column found for each row (optional) 5025 5026 Level: intermediate 5027 5028 Notes: 5029 The result of this call are the same as if one converted the matrix to dense format 5030 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 5031 5032 This code is only implemented for a couple of matrix formats. 5033 5034 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMaxAbs()`, `MatGetRowMin()` 5035 @*/ 5036 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[]) 5037 { 5038 PetscFunctionBegin; 5039 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5040 PetscValidType(mat,1); 5041 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 5042 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5043 5044 if (!mat->cmap->N) { 5045 PetscCall(VecSet(v,PETSC_MIN_REAL)); 5046 if (idx) { 5047 PetscInt i,m = mat->rmap->n; 5048 for (i=0; i<m; i++) idx[i] = -1; 5049 } 5050 } else { 5051 PetscCheck(mat->ops->getrowmax,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5052 MatCheckPreallocated(mat,1); 5053 PetscCall((*mat->ops->getrowmax)(mat,v,idx)); 5054 } 5055 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 5056 PetscFunctionReturn(0); 5057 } 5058 5059 /*@C 5060 MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each 5061 row of the matrix 5062 5063 Logically Collective on Mat 5064 5065 Input Parameter: 5066 . mat - the matrix 5067 5068 Output Parameters: 5069 + v - the vector for storing the maximums 5070 - idx - the indices of the column found for each row (or NULL if not needed) 5071 5072 Level: intermediate 5073 5074 Notes: 5075 if a row is completely empty or has only 0.0 values then the idx[] value for that 5076 row is 0 (the first column). 5077 5078 This code is only implemented for a couple of matrix formats. 5079 5080 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMax()`, `MatGetRowMin()` 5081 @*/ 5082 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[]) 5083 { 5084 PetscFunctionBegin; 5085 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5086 PetscValidType(mat,1); 5087 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 5088 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5089 5090 if (!mat->cmap->N) { 5091 PetscCall(VecSet(v,0.0)); 5092 if (idx) { 5093 PetscInt i,m = mat->rmap->n; 5094 for (i=0; i<m; i++) idx[i] = -1; 5095 } 5096 } else { 5097 PetscCheck(mat->ops->getrowmaxabs,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5098 MatCheckPreallocated(mat,1); 5099 if (idx) PetscCall(PetscArrayzero(idx,mat->rmap->n)); 5100 PetscCall((*mat->ops->getrowmaxabs)(mat,v,idx)); 5101 } 5102 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 5103 PetscFunctionReturn(0); 5104 } 5105 5106 /*@ 5107 MatGetRowSum - Gets the sum of each row of the matrix 5108 5109 Logically or Neighborhood Collective on Mat 5110 5111 Input Parameters: 5112 . mat - the matrix 5113 5114 Output Parameter: 5115 . v - the vector for storing the sum of rows 5116 5117 Level: intermediate 5118 5119 Notes: 5120 This code is slow since it is not currently specialized for different formats 5121 5122 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMax()`, `MatGetRowMin()` 5123 @*/ 5124 PetscErrorCode MatGetRowSum(Mat mat, Vec v) 5125 { 5126 Vec ones; 5127 5128 PetscFunctionBegin; 5129 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5130 PetscValidType(mat,1); 5131 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 5132 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5133 MatCheckPreallocated(mat,1); 5134 PetscCall(MatCreateVecs(mat,&ones,NULL)); 5135 PetscCall(VecSet(ones,1.)); 5136 PetscCall(MatMult(mat,ones,v)); 5137 PetscCall(VecDestroy(&ones)); 5138 PetscFunctionReturn(0); 5139 } 5140 5141 /*@ 5142 MatTransposeSetPrecursor - Set the matrix from which the second matrix will receive numerical transpose data with a call to `MatTranspose`(A,`MAT_REUSE_MATRIX`,&B) 5143 when B was not obtained with `MatTranspose`(A,`MAT_INITIAL_MATRIX`,&B) 5144 5145 Collective on Mat 5146 5147 Input Parameter: 5148 . mat - the matrix to provide the transpose 5149 5150 Output Parameter: 5151 . 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 5152 5153 Level: advanced 5154 5155 Note: 5156 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 5157 routine allows bypassing that call. 5158 5159 .seealso: `MatTransposeSymbolic()`, `MatTranspose()`, `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse`, `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, `MAT_INPLACE_MATRIX` 5160 @*/ 5161 PetscErrorCode MatTransposeSetPrecursor(Mat mat,Mat B) 5162 { 5163 PetscContainer rB = NULL; 5164 MatParentState *rb = NULL; 5165 5166 PetscFunctionBegin; 5167 PetscCall(PetscNew(&rb)); 5168 rb->id = ((PetscObject)mat)->id; 5169 rb->state = 0; 5170 PetscCall(MatGetNonzeroState(mat,&rb->nonzerostate)); 5171 PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)B),&rB)); 5172 PetscCall(PetscContainerSetPointer(rB,rb)); 5173 PetscCall(PetscContainerSetUserDestroy(rB,PetscContainerUserDestroyDefault)); 5174 PetscCall(PetscObjectCompose((PetscObject)B,"MatTransposeParent",(PetscObject)rB)); 5175 PetscCall(PetscObjectDereference((PetscObject)rB)); 5176 PetscFunctionReturn(0); 5177 } 5178 5179 /*@ 5180 MatTranspose - Computes an in-place or out-of-place transpose of a matrix. 5181 5182 Collective on Mat 5183 5184 Input Parameters: 5185 + mat - the matrix to transpose 5186 - reuse - either `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, or `MAT_INPLACE_MATRIX` 5187 5188 Output Parameter: 5189 . B - the transpose 5190 5191 Notes: 5192 If you use `MAT_INPLACE_MATRIX` then you must pass in &mat for B 5193 5194 `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 5195 transpose, call `MatTransposeSetPrecursor`(mat,B) before calling this routine. 5196 5197 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. 5198 5199 Consider using `MatCreateTranspose()` instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed. 5200 5201 If mat is unchanged from the last call this function returns immediately without recomputing the result 5202 5203 If you only need the symbolic transpose, and not the numerical values, use `MatTransposeSymbolic()` 5204 5205 Level: intermediate 5206 5207 .seealso: `MatTransposeSetPrecursor()`, `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse`, `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, `MAT_INPLACE_MATRIX`, 5208 `MatTransposeSymbolic()` 5209 @*/ 5210 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B) 5211 { 5212 PetscContainer rB = NULL; 5213 MatParentState *rb = NULL; 5214 5215 PetscFunctionBegin; 5216 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5217 PetscValidType(mat,1); 5218 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5219 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5220 PetscCheck(mat->ops->transpose,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5221 PetscCheck(reuse != MAT_INPLACE_MATRIX || mat == *B,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first"); 5222 PetscCheck(reuse != MAT_REUSE_MATRIX || mat != *B,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX"); 5223 MatCheckPreallocated(mat,1); 5224 if (reuse == MAT_REUSE_MATRIX) { 5225 PetscCall(PetscObjectQuery((PetscObject)*B,"MatTransposeParent",(PetscObject*)&rB)); 5226 PetscCheck(rB,PetscObjectComm((PetscObject)*B),PETSC_ERR_ARG_WRONG,"Reuse matrix used was not generated from call to MatTranspose(). Suggest MatTransposeSetPrecursor()."); 5227 PetscCall(PetscContainerGetPointer(rB,(void**)&rb)); 5228 PetscCheck(rb->id == ((PetscObject)mat)->id,PetscObjectComm((PetscObject)*B),PETSC_ERR_ARG_WRONG,"Reuse matrix used was not generated from input matrix"); 5229 if (rb->state == ((PetscObject)mat)->state) PetscFunctionReturn(0); 5230 } 5231 5232 PetscCall(PetscLogEventBegin(MAT_Transpose,mat,0,0,0)); 5233 if (reuse != MAT_INPLACE_MATRIX || mat->symmetric != PETSC_BOOL3_TRUE) { 5234 PetscCall((*mat->ops->transpose)(mat,reuse,B)); 5235 PetscCall(PetscObjectStateIncrease((PetscObject)*B)); 5236 } 5237 PetscCall(PetscLogEventEnd(MAT_Transpose,mat,0,0,0)); 5238 5239 if (reuse == MAT_INITIAL_MATRIX) PetscCall(MatTransposeSetPrecursor(mat,*B)); 5240 if (reuse != MAT_INPLACE_MATRIX) { 5241 PetscCall(PetscObjectQuery((PetscObject)*B,"MatTransposeParent",(PetscObject*)&rB)); 5242 PetscCall(PetscContainerGetPointer(rB,(void**)&rb)); 5243 rb->state = ((PetscObject)mat)->state; 5244 rb->nonzerostate = mat->nonzerostate; 5245 } 5246 PetscFunctionReturn(0); 5247 } 5248 5249 /*@ 5250 MatTransposeSymbolic - Computes the symbolic part of the transpose of a matrix. 5251 5252 Collective on Mat 5253 5254 Input Parameters: 5255 . A - the matrix to transpose 5256 5257 Output Parameter: 5258 . 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 5259 numerical portion. 5260 5261 Level: intermediate 5262 5263 Note: 5264 This is not supported for many matrix types, use `MatTranspose()` in those cases 5265 5266 .seealso: `MatTransposeSetPrecursor()`, `MatTranspose()`, `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse`, `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, `MAT_INPLACE_MATRIX` 5267 @*/ 5268 PetscErrorCode MatTransposeSymbolic(Mat A,Mat *B) 5269 { 5270 PetscFunctionBegin; 5271 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5272 PetscValidType(A,1); 5273 PetscCheck(A->assembled,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5274 PetscCheck(!A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5275 PetscCheck(A->ops->transposesymbolic,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 5276 PetscCall(PetscLogEventBegin(MAT_Transpose,A,0,0,0)); 5277 PetscCall((*A->ops->transposesymbolic)(A,B)); 5278 PetscCall(PetscLogEventEnd(MAT_Transpose,A,0,0,0)); 5279 5280 PetscCall(MatTransposeSetPrecursor(A,*B)); 5281 PetscFunctionReturn(0); 5282 } 5283 5284 PetscErrorCode MatTransposeCheckNonzeroState_Private(Mat A,Mat B) 5285 { 5286 PetscContainer rB; 5287 MatParentState *rb; 5288 5289 PetscFunctionBegin; 5290 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5291 PetscValidType(A,1); 5292 PetscCheck(A->assembled,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5293 PetscCheck(!A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5294 PetscCall(PetscObjectQuery((PetscObject)B,"MatTransposeParent",(PetscObject*)&rB)); 5295 PetscCheck(rB,PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONG,"Reuse matrix used was not generated from call to MatTranspose()"); 5296 PetscCall(PetscContainerGetPointer(rB,(void**)&rb)); 5297 PetscCheck(rb->id == ((PetscObject)A)->id,PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONG,"Reuse matrix used was not generated from input matrix"); 5298 PetscCheck(rb->nonzerostate == A->nonzerostate,PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Reuse matrix has changed nonzero structure"); 5299 PetscFunctionReturn(0); 5300 } 5301 5302 /*@ 5303 MatIsTranspose - Test whether a matrix is another one's transpose, 5304 or its own, in which case it tests symmetry. 5305 5306 Collective on Mat 5307 5308 Input Parameters: 5309 + A - the matrix to test 5310 - B - the matrix to test against, this can equal the first parameter 5311 5312 Output Parameters: 5313 . flg - the result 5314 5315 Notes: 5316 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 5317 has a running time of the order of the number of nonzeros; the parallel 5318 test involves parallel copies of the block-offdiagonal parts of the matrix. 5319 5320 Level: intermediate 5321 5322 .seealso: `MatTranspose()`, `MatIsSymmetric()`, `MatIsHermitian()` 5323 @*/ 5324 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 5325 { 5326 PetscErrorCode (*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 5327 5328 PetscFunctionBegin; 5329 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5330 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5331 PetscValidBoolPointer(flg,4); 5332 PetscCall(PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f)); 5333 PetscCall(PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g)); 5334 *flg = PETSC_FALSE; 5335 if (f && g) { 5336 PetscCheck(f == g,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test"); 5337 PetscCall((*f)(A,B,tol,flg)); 5338 } else { 5339 MatType mattype; 5340 5341 PetscCall(MatGetType(f ? B : A,&mattype)); 5342 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for transpose",mattype); 5343 } 5344 PetscFunctionReturn(0); 5345 } 5346 5347 /*@ 5348 MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate. 5349 5350 Collective on Mat 5351 5352 Input Parameters: 5353 + mat - the matrix to transpose and complex conjugate 5354 - reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX 5355 5356 Output Parameter: 5357 . B - the Hermitian 5358 5359 Level: intermediate 5360 5361 .seealso: `MatTranspose()`, `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse` 5362 @*/ 5363 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B) 5364 { 5365 PetscFunctionBegin; 5366 PetscCall(MatTranspose(mat,reuse,B)); 5367 #if defined(PETSC_USE_COMPLEX) 5368 PetscCall(MatConjugate(*B)); 5369 #endif 5370 PetscFunctionReturn(0); 5371 } 5372 5373 /*@ 5374 MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose, 5375 5376 Collective on Mat 5377 5378 Input Parameters: 5379 + A - the matrix to test 5380 - B - the matrix to test against, this can equal the first parameter 5381 5382 Output Parameters: 5383 . flg - the result 5384 5385 Notes: 5386 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 5387 has a running time of the order of the number of nonzeros; the parallel 5388 test involves parallel copies of the block-offdiagonal parts of the matrix. 5389 5390 Level: intermediate 5391 5392 .seealso: `MatTranspose()`, `MatIsSymmetric()`, `MatIsHermitian()`, `MatIsTranspose()` 5393 @*/ 5394 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 5395 { 5396 PetscErrorCode (*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 5397 5398 PetscFunctionBegin; 5399 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5400 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5401 PetscValidBoolPointer(flg,4); 5402 PetscCall(PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f)); 5403 PetscCall(PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g)); 5404 if (f && g) { 5405 PetscCheck(f != g,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test"); 5406 PetscCall((*f)(A,B,tol,flg)); 5407 } 5408 PetscFunctionReturn(0); 5409 } 5410 5411 /*@ 5412 MatPermute - Creates a new matrix with rows and columns permuted from the 5413 original. 5414 5415 Collective on Mat 5416 5417 Input Parameters: 5418 + mat - the matrix to permute 5419 . row - row permutation, each processor supplies only the permutation for its rows 5420 - col - column permutation, each processor supplies only the permutation for its columns 5421 5422 Output Parameters: 5423 . B - the permuted matrix 5424 5425 Level: advanced 5426 5427 Note: 5428 The index sets map from row/col of permuted matrix to row/col of original matrix. 5429 The index sets should be on the same communicator as Mat and have the same local sizes. 5430 5431 Developer Note: 5432 If you want to implement MatPermute for a matrix type, and your approach doesn't 5433 exploit the fact that row and col are permutations, consider implementing the 5434 more general MatCreateSubMatrix() instead. 5435 5436 .seealso: `MatGetOrdering()`, `ISAllGather()` 5437 5438 @*/ 5439 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B) 5440 { 5441 PetscFunctionBegin; 5442 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5443 PetscValidType(mat,1); 5444 PetscValidHeaderSpecific(row,IS_CLASSID,2); 5445 PetscValidHeaderSpecific(col,IS_CLASSID,3); 5446 PetscValidPointer(B,4); 5447 PetscCheckSameComm(mat,1,row,2); 5448 if (row != col) PetscCheckSameComm(row,2,col,3); 5449 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5450 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5451 PetscCheck(mat->ops->permute || mat->ops->createsubmatrix,PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name); 5452 MatCheckPreallocated(mat,1); 5453 5454 if (mat->ops->permute) { 5455 PetscCall((*mat->ops->permute)(mat,row,col,B)); 5456 PetscCall(PetscObjectStateIncrease((PetscObject)*B)); 5457 } else { 5458 PetscCall(MatCreateSubMatrix(mat, row, col, MAT_INITIAL_MATRIX, B)); 5459 } 5460 PetscFunctionReturn(0); 5461 } 5462 5463 /*@ 5464 MatEqual - Compares two matrices. 5465 5466 Collective on Mat 5467 5468 Input Parameters: 5469 + A - the first matrix 5470 - B - the second matrix 5471 5472 Output Parameter: 5473 . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise. 5474 5475 Level: intermediate 5476 5477 @*/ 5478 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool *flg) 5479 { 5480 PetscFunctionBegin; 5481 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5482 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5483 PetscValidType(A,1); 5484 PetscValidType(B,2); 5485 PetscValidBoolPointer(flg,3); 5486 PetscCheckSameComm(A,1,B,2); 5487 MatCheckPreallocated(A,1); 5488 MatCheckPreallocated(B,2); 5489 PetscCheck(A->assembled,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5490 PetscCheck(B->assembled,PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5491 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); 5492 if (A->ops->equal && A->ops->equal == B->ops->equal) { 5493 PetscCall((*A->ops->equal)(A,B,flg)); 5494 } else { 5495 PetscCall(MatMultEqual(A,B,10,flg)); 5496 } 5497 PetscFunctionReturn(0); 5498 } 5499 5500 /*@ 5501 MatDiagonalScale - Scales a matrix on the left and right by diagonal 5502 matrices that are stored as vectors. Either of the two scaling 5503 matrices can be NULL. 5504 5505 Collective on Mat 5506 5507 Input Parameters: 5508 + mat - the matrix to be scaled 5509 . l - the left scaling vector (or NULL) 5510 - r - the right scaling vector (or NULL) 5511 5512 Notes: 5513 MatDiagonalScale() computes A = LAR, where 5514 L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector) 5515 The L scales the rows of the matrix, the R scales the columns of the matrix. 5516 5517 Level: intermediate 5518 5519 .seealso: `MatScale()`, `MatShift()`, `MatDiagonalSet()` 5520 @*/ 5521 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r) 5522 { 5523 PetscFunctionBegin; 5524 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5525 PetscValidType(mat,1); 5526 if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);} 5527 if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);} 5528 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5529 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5530 MatCheckPreallocated(mat,1); 5531 if (!l && !r) PetscFunctionReturn(0); 5532 5533 PetscCheck(mat->ops->diagonalscale,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5534 PetscCall(PetscLogEventBegin(MAT_Scale,mat,0,0,0)); 5535 PetscCall((*mat->ops->diagonalscale)(mat,l,r)); 5536 PetscCall(PetscLogEventEnd(MAT_Scale,mat,0,0,0)); 5537 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5538 if (l != r) mat->symmetric = PETSC_BOOL3_FALSE; 5539 PetscFunctionReturn(0); 5540 } 5541 5542 /*@ 5543 MatScale - Scales all elements of a matrix by a given number. 5544 5545 Logically Collective on Mat 5546 5547 Input Parameters: 5548 + mat - the matrix to be scaled 5549 - a - the scaling value 5550 5551 Output Parameter: 5552 . mat - the scaled matrix 5553 5554 Level: intermediate 5555 5556 .seealso: `MatDiagonalScale()` 5557 @*/ 5558 PetscErrorCode MatScale(Mat mat,PetscScalar a) 5559 { 5560 PetscFunctionBegin; 5561 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5562 PetscValidType(mat,1); 5563 PetscCheck(a == (PetscScalar)1.0 || mat->ops->scale,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5564 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5565 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5566 PetscValidLogicalCollectiveScalar(mat,a,2); 5567 MatCheckPreallocated(mat,1); 5568 5569 PetscCall(PetscLogEventBegin(MAT_Scale,mat,0,0,0)); 5570 if (a != (PetscScalar)1.0) { 5571 PetscCall((*mat->ops->scale)(mat,a)); 5572 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5573 } 5574 PetscCall(PetscLogEventEnd(MAT_Scale,mat,0,0,0)); 5575 PetscFunctionReturn(0); 5576 } 5577 5578 /*@ 5579 MatNorm - Calculates various norms of a matrix. 5580 5581 Collective on Mat 5582 5583 Input Parameters: 5584 + mat - the matrix 5585 - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY 5586 5587 Output Parameter: 5588 . nrm - the resulting norm 5589 5590 Level: intermediate 5591 5592 @*/ 5593 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm) 5594 { 5595 PetscFunctionBegin; 5596 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5597 PetscValidType(mat,1); 5598 PetscValidRealPointer(nrm,3); 5599 5600 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5601 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5602 PetscCheck(mat->ops->norm,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5603 MatCheckPreallocated(mat,1); 5604 5605 PetscCall((*mat->ops->norm)(mat,type,nrm)); 5606 PetscFunctionReturn(0); 5607 } 5608 5609 /* 5610 This variable is used to prevent counting of MatAssemblyBegin() that 5611 are called from within a MatAssemblyEnd(). 5612 */ 5613 static PetscInt MatAssemblyEnd_InUse = 0; 5614 /*@ 5615 MatAssemblyBegin - Begins assembling the matrix. This routine should 5616 be called after completing all calls to MatSetValues(). 5617 5618 Collective on Mat 5619 5620 Input Parameters: 5621 + mat - the matrix 5622 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5623 5624 Notes: 5625 MatSetValues() generally caches the values. The matrix is ready to 5626 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5627 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5628 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5629 using the matrix. 5630 5631 ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the 5632 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 5633 a global collective operation requring all processes that share the matrix. 5634 5635 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5636 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5637 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5638 5639 Level: beginner 5640 5641 .seealso: `MatAssemblyEnd()`, `MatSetValues()`, `MatAssembled()` 5642 @*/ 5643 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type) 5644 { 5645 PetscFunctionBegin; 5646 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5647 PetscValidType(mat,1); 5648 MatCheckPreallocated(mat,1); 5649 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?"); 5650 if (mat->assembled) { 5651 mat->was_assembled = PETSC_TRUE; 5652 mat->assembled = PETSC_FALSE; 5653 } 5654 5655 if (!MatAssemblyEnd_InUse) { 5656 PetscCall(PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0)); 5657 if (mat->ops->assemblybegin) PetscCall((*mat->ops->assemblybegin)(mat,type)); 5658 PetscCall(PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0)); 5659 } else if (mat->ops->assemblybegin) PetscCall((*mat->ops->assemblybegin)(mat,type)); 5660 PetscFunctionReturn(0); 5661 } 5662 5663 /*@ 5664 MatAssembled - Indicates if a matrix has been assembled and is ready for 5665 use; for example, in matrix-vector product. 5666 5667 Not Collective 5668 5669 Input Parameter: 5670 . mat - the matrix 5671 5672 Output Parameter: 5673 . assembled - PETSC_TRUE or PETSC_FALSE 5674 5675 Level: advanced 5676 5677 .seealso: `MatAssemblyEnd()`, `MatSetValues()`, `MatAssemblyBegin()` 5678 @*/ 5679 PetscErrorCode MatAssembled(Mat mat,PetscBool *assembled) 5680 { 5681 PetscFunctionBegin; 5682 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5683 PetscValidBoolPointer(assembled,2); 5684 *assembled = mat->assembled; 5685 PetscFunctionReturn(0); 5686 } 5687 5688 /*@ 5689 MatAssemblyEnd - Completes assembling the matrix. This routine should 5690 be called after MatAssemblyBegin(). 5691 5692 Collective on Mat 5693 5694 Input Parameters: 5695 + mat - the matrix 5696 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5697 5698 Options Database Keys: 5699 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly() 5700 . -mat_view ::ascii_info_detail - Prints more detailed info 5701 . -mat_view - Prints matrix in ASCII format 5702 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 5703 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 5704 . -display <name> - Sets display name (default is host) 5705 . -draw_pause <sec> - Sets number of seconds to pause after display 5706 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab) 5707 . -viewer_socket_machine <machine> - Machine to use for socket 5708 . -viewer_socket_port <port> - Port number to use for socket 5709 - -mat_view binary:filename[:append] - Save matrix to file in binary format 5710 5711 Notes: 5712 MatSetValues() generally caches the values. The matrix is ready to 5713 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5714 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5715 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5716 using the matrix. 5717 5718 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5719 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5720 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5721 5722 Level: beginner 5723 5724 .seealso: `MatAssemblyBegin()`, `MatSetValues()`, `PetscDrawOpenX()`, `PetscDrawCreate()`, `MatView()`, `MatAssembled()`, `PetscViewerSocketOpen()` 5725 @*/ 5726 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type) 5727 { 5728 static PetscInt inassm = 0; 5729 PetscBool flg = PETSC_FALSE; 5730 5731 PetscFunctionBegin; 5732 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5733 PetscValidType(mat,1); 5734 5735 inassm++; 5736 MatAssemblyEnd_InUse++; 5737 if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */ 5738 PetscCall(PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0)); 5739 if (mat->ops->assemblyend) PetscCall((*mat->ops->assemblyend)(mat,type)); 5740 PetscCall(PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0)); 5741 } else if (mat->ops->assemblyend) PetscCall((*mat->ops->assemblyend)(mat,type)); 5742 5743 /* Flush assembly is not a true assembly */ 5744 if (type != MAT_FLUSH_ASSEMBLY) { 5745 if (mat->num_ass) { 5746 if (!mat->symmetry_eternal) { 5747 mat->symmetric = PETSC_BOOL3_UNKNOWN; 5748 mat->hermitian = PETSC_BOOL3_UNKNOWN; 5749 } 5750 if (!mat->structural_symmetry_eternal && mat->ass_nonzerostate != mat->nonzerostate) { 5751 mat->structurally_symmetric = PETSC_BOOL3_UNKNOWN; 5752 } 5753 if (!mat->spd_eternal) mat->spd = PETSC_BOOL3_UNKNOWN; 5754 } 5755 mat->num_ass++; 5756 mat->assembled = PETSC_TRUE; 5757 mat->ass_nonzerostate = mat->nonzerostate; 5758 } 5759 5760 mat->insertmode = NOT_SET_VALUES; 5761 MatAssemblyEnd_InUse--; 5762 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5763 if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) { 5764 PetscCall(MatViewFromOptions(mat,NULL,"-mat_view")); 5765 5766 if (mat->checksymmetryonassembly) { 5767 PetscCall(MatIsSymmetric(mat,mat->checksymmetrytol,&flg)); 5768 if (flg) { 5769 PetscCall(PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol)); 5770 } else { 5771 PetscCall(PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol)); 5772 } 5773 } 5774 if (mat->nullsp && mat->checknullspaceonassembly) { 5775 PetscCall(MatNullSpaceTest(mat->nullsp,mat,NULL)); 5776 } 5777 } 5778 inassm--; 5779 PetscFunctionReturn(0); 5780 } 5781 5782 /*@ 5783 MatSetOption - Sets a parameter option for a matrix. Some options 5784 may be specific to certain storage formats. Some options 5785 determine how values will be inserted (or added). Sorted, 5786 row-oriented input will generally assemble the fastest. The default 5787 is row-oriented. 5788 5789 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5790 5791 Input Parameters: 5792 + mat - the matrix 5793 . option - the option, one of those listed below (and possibly others), 5794 - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5795 5796 Options Describing Matrix Structure: 5797 + MAT_SPD - symmetric positive definite 5798 . MAT_SYMMETRIC - symmetric in terms of both structure and value 5799 . MAT_HERMITIAN - transpose is the complex conjugation 5800 . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure 5801 . MAT_SYMMETRY_ETERNAL - indicates the symmetry (or Hermitian structure) or its absence will persist through any changes to the matrix 5802 . MAT_STRUCTURAL_SYMMETRY_ETERNAL - indicates the structural symmetry or its absence will persist through any changes to the matrix 5803 - MAT_SPD_ETERNAL - indicates the value of MAT_SPD (true or false) will persist through any changes to the matrix 5804 5805 These are not really options of the matrix, they are knowledge about the structure of the matrix that users may provide so that they 5806 do not need to be computed (usually at a high cost) 5807 5808 Options For Use with MatSetValues(): 5809 Insert a logically dense subblock, which can be 5810 . MAT_ROW_ORIENTED - row-oriented (default) 5811 5812 Note these options reflect the data you pass in with MatSetValues(); it has 5813 nothing to do with how the data is stored internally in the matrix 5814 data structure. 5815 5816 When (re)assembling a matrix, we can restrict the input for 5817 efficiency/debugging purposes. These options include 5818 + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow) 5819 . MAT_FORCE_DIAGONAL_ENTRIES - forces diagonal entries to be allocated 5820 . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries 5821 . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry 5822 . MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly 5823 . MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if 5824 any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves 5825 performance for very large process counts. 5826 - MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset 5827 of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly 5828 functions, instead sending only neighbor messages. 5829 5830 Notes: 5831 Except for MAT_UNUSED_NONZERO_LOCATION_ERR and MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg! 5832 5833 Some options are relevant only for particular matrix types and 5834 are thus ignored by others. Other options are not supported by 5835 certain matrix types and will generate an error message if set. 5836 5837 If using a Fortran 77 module to compute a matrix, one may need to 5838 use the column-oriented option (or convert to the row-oriented 5839 format). 5840 5841 MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion 5842 that would generate a new entry in the nonzero structure is instead 5843 ignored. Thus, if memory has not alredy been allocated for this particular 5844 data, then the insertion is ignored. For dense matrices, in which 5845 the entire array is allocated, no entries are ever ignored. 5846 Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5847 5848 MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5849 that would generate a new entry in the nonzero structure instead produces 5850 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 5851 5852 MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5853 that would generate a new entry that has not been preallocated will 5854 instead produce an error. (Currently supported for AIJ and BAIJ formats 5855 only.) This is a useful flag when debugging matrix memory preallocation. 5856 If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5857 5858 MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for 5859 other processors should be dropped, rather than stashed. 5860 This is useful if you know that the "owning" processor is also 5861 always generating the correct matrix entries, so that PETSc need 5862 not transfer duplicate entries generated on another processor. 5863 5864 MAT_USE_HASH_TABLE indicates that a hash table be used to improve the 5865 searches during matrix assembly. When this flag is set, the hash table 5866 is created during the first Matrix Assembly. This hash table is 5867 used the next time through, during MatSetVaules()/MatSetVaulesBlocked() 5868 to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag 5869 should be used with MAT_USE_HASH_TABLE flag. This option is currently 5870 supported by MATMPIBAIJ format only. 5871 5872 MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries 5873 are kept in the nonzero structure 5874 5875 MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating 5876 a zero location in the matrix 5877 5878 MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types 5879 5880 MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the 5881 zero row routines and thus improves performance for very large process counts. 5882 5883 MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular 5884 part of the matrix (since they should match the upper triangular part). 5885 5886 MAT_SORTED_FULL - each process provides exactly its local rows; all column indices for a given row are passed in a 5887 single call to MatSetValues(), preallocation is perfect, row oriented, INSERT_VALUES is used. Common 5888 with finite difference schemes with non-periodic boundary conditions. 5889 5890 Developer Note: 5891 MAT_SYMMETRY_ETERNAL, MAT_STRUCTURAL_SYMMETRY_ETERNAL, and MAT_SPD_ETERNAL are used by MatAssemblyEnd() and in other 5892 places where otherwise the value of MAT_SYMMETRIC, MAT_STRUCTURAL_SYMMETRIC or MAT_SPD would need to be changed back 5893 to PETSC_BOOL3_UNKNOWN because the matrix values had changed so the code cannot be certain that the related property had 5894 not changed. 5895 5896 Level: intermediate 5897 5898 .seealso: `MatOption`, `Mat`, `MatGetOption()` 5899 5900 @*/ 5901 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg) 5902 { 5903 PetscFunctionBegin; 5904 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5905 if (op > 0) { 5906 PetscValidLogicalCollectiveEnum(mat,op,2); 5907 PetscValidLogicalCollectiveBool(mat,flg,3); 5908 } 5909 5910 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); 5911 5912 switch (op) { 5913 case MAT_FORCE_DIAGONAL_ENTRIES: 5914 mat->force_diagonals = flg; 5915 PetscFunctionReturn(0); 5916 case MAT_NO_OFF_PROC_ENTRIES: 5917 mat->nooffprocentries = flg; 5918 PetscFunctionReturn(0); 5919 case MAT_SUBSET_OFF_PROC_ENTRIES: 5920 mat->assembly_subset = flg; 5921 if (!mat->assembly_subset) { /* See the same logic in VecAssembly wrt VEC_SUBSET_OFF_PROC_ENTRIES */ 5922 #if !defined(PETSC_HAVE_MPIUNI) 5923 PetscCall(MatStashScatterDestroy_BTS(&mat->stash)); 5924 #endif 5925 mat->stash.first_assembly_done = PETSC_FALSE; 5926 } 5927 PetscFunctionReturn(0); 5928 case MAT_NO_OFF_PROC_ZERO_ROWS: 5929 mat->nooffproczerorows = flg; 5930 PetscFunctionReturn(0); 5931 case MAT_SPD: 5932 if (flg) { 5933 mat->spd = PETSC_BOOL3_TRUE; 5934 mat->symmetric = PETSC_BOOL3_TRUE; 5935 mat->structurally_symmetric = PETSC_BOOL3_TRUE; 5936 } else { 5937 mat->spd = PETSC_BOOL3_FALSE; 5938 } 5939 break; 5940 case MAT_SYMMETRIC: 5941 mat->symmetric = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5942 if (flg) mat->structurally_symmetric = PETSC_BOOL3_TRUE; 5943 #if !defined(PETSC_USE_COMPLEX) 5944 mat->hermitian = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5945 #endif 5946 break; 5947 case MAT_HERMITIAN: 5948 mat->hermitian = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5949 if (flg) mat->structurally_symmetric = PETSC_BOOL3_TRUE; 5950 #if !defined(PETSC_USE_COMPLEX) 5951 mat->symmetric = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5952 #endif 5953 break; 5954 case MAT_STRUCTURALLY_SYMMETRIC: 5955 mat->structurally_symmetric = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5956 break; 5957 case MAT_SYMMETRY_ETERNAL: 5958 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"); 5959 mat->symmetry_eternal = flg; 5960 if (flg) mat->structural_symmetry_eternal = PETSC_TRUE; 5961 break; 5962 case MAT_STRUCTURAL_SYMMETRY_ETERNAL: 5963 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"); 5964 mat->structural_symmetry_eternal = flg; 5965 break; 5966 case MAT_SPD_ETERNAL: 5967 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"); 5968 mat->spd_eternal = flg; 5969 if (flg) { 5970 mat->structural_symmetry_eternal = PETSC_TRUE; 5971 mat->symmetry_eternal = PETSC_TRUE; 5972 } 5973 break; 5974 case MAT_STRUCTURE_ONLY: 5975 mat->structure_only = flg; 5976 break; 5977 case MAT_SORTED_FULL: 5978 mat->sortedfull = flg; 5979 break; 5980 default: 5981 break; 5982 } 5983 if (mat->ops->setoption) PetscCall((*mat->ops->setoption)(mat,op,flg)); 5984 PetscFunctionReturn(0); 5985 } 5986 5987 /*@ 5988 MatGetOption - Gets a parameter option that has been set for a matrix. 5989 5990 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5991 5992 Input Parameters: 5993 + mat - the matrix 5994 - option - the option, this only responds to certain options, check the code for which ones 5995 5996 Output Parameter: 5997 . flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5998 5999 Notes: 6000 Can only be called after MatSetSizes() and MatSetType() have been set. 6001 6002 Certain option values may be unknown, for those use the routines `MatIsSymmetric()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, or 6003 `MatIsSymmetricKnown()`, `MatIsHermitianKnown()`, `MatIsStructurallySymmetricKnown()` 6004 6005 Level: intermediate 6006 6007 .seealso: `MatOption`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, 6008 `MatIsSymmetricKnown()`, `MatIsHermitianKnown()`, `MatIsStructurallySymmetricKnown()` 6009 6010 @*/ 6011 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg) 6012 { 6013 PetscFunctionBegin; 6014 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6015 PetscValidType(mat,1); 6016 6017 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); 6018 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()"); 6019 6020 switch (op) { 6021 case MAT_NO_OFF_PROC_ENTRIES: 6022 *flg = mat->nooffprocentries; 6023 break; 6024 case MAT_NO_OFF_PROC_ZERO_ROWS: 6025 *flg = mat->nooffproczerorows; 6026 break; 6027 case MAT_SYMMETRIC: 6028 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Use MatIsSymmetric() or MatIsSymmetricKnown()"); 6029 break; 6030 case MAT_HERMITIAN: 6031 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Use MatIsHermitian() or MatIsHermitianKnown()"); 6032 break; 6033 case MAT_STRUCTURALLY_SYMMETRIC: 6034 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Use MatIsStructurallySymmetric() or MatIsStructurallySymmetricKnown()"); 6035 break; 6036 case MAT_SPD: 6037 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Use MatIsSPDKnown()"); 6038 break; 6039 case MAT_SYMMETRY_ETERNAL: 6040 *flg = mat->symmetry_eternal; 6041 break; 6042 case MAT_STRUCTURAL_SYMMETRY_ETERNAL: 6043 *flg = mat->symmetry_eternal; 6044 break; 6045 default: 6046 break; 6047 } 6048 PetscFunctionReturn(0); 6049 } 6050 6051 /*@ 6052 MatZeroEntries - Zeros all entries of a matrix. For sparse matrices 6053 this routine retains the old nonzero structure. 6054 6055 Logically Collective on Mat 6056 6057 Input Parameters: 6058 . mat - the matrix 6059 6060 Level: intermediate 6061 6062 Notes: 6063 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. 6064 See the Performance chapter of the users manual for information on preallocating matrices. 6065 6066 .seealso: `MatZeroRows()` 6067 @*/ 6068 PetscErrorCode MatZeroEntries(Mat mat) 6069 { 6070 PetscFunctionBegin; 6071 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6072 PetscValidType(mat,1); 6073 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6074 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"); 6075 PetscCheck(mat->ops->zeroentries,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6076 MatCheckPreallocated(mat,1); 6077 6078 PetscCall(PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0)); 6079 PetscCall((*mat->ops->zeroentries)(mat)); 6080 PetscCall(PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0)); 6081 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6082 PetscFunctionReturn(0); 6083 } 6084 6085 /*@ 6086 MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal) 6087 of a set of rows and columns of a matrix. 6088 6089 Collective on Mat 6090 6091 Input Parameters: 6092 + mat - the matrix 6093 . numRows - the number of rows to remove 6094 . rows - the global row indices 6095 . diag - value put in the diagonal of the eliminated rows 6096 . x - optional vector of solutions for zeroed rows (other entries in vector are not used), these must be set before this call 6097 - b - optional vector of right hand side, that will be adjusted by provided solution 6098 6099 Notes: 6100 This routine, along with `MatZeroRows()`, is typically used to eliminate known Dirichlet boundary conditions from a linear system. 6101 6102 For each zeroed row, the value of the corresponding b is set to diag times the value of the corresponding x. 6103 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 6104 6105 If the resulting linear system is to be solved with KSP then one can (but does not have to) call `KSPSetInitialGuessNonzero()` to allow the 6106 Krylov method to take advantage of the known solution on the zeroed rows. 6107 6108 For the parallel case, all processes that share the matrix (i.e., 6109 those in the communicator used for matrix creation) MUST call this 6110 routine, regardless of whether any rows being zeroed are owned by 6111 them. 6112 6113 Unlike `MatZeroRows()` this does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 6114 6115 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6116 list only rows local to itself). 6117 6118 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 6119 6120 Level: intermediate 6121 6122 .seealso: `MatZeroRowsIS()`, `MatZeroRows()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6123 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6124 @*/ 6125 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6126 { 6127 PetscFunctionBegin; 6128 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6129 PetscValidType(mat,1); 6130 if (numRows) PetscValidIntPointer(rows,3); 6131 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6132 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6133 PetscCheck(mat->ops->zerorowscolumns,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6134 MatCheckPreallocated(mat,1); 6135 6136 PetscCall((*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b)); 6137 PetscCall(MatViewFromOptions(mat,NULL,"-mat_view")); 6138 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6139 PetscFunctionReturn(0); 6140 } 6141 6142 /*@ 6143 MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal) 6144 of a set of rows and columns of a matrix. 6145 6146 Collective on Mat 6147 6148 Input Parameters: 6149 + mat - the matrix 6150 . is - the rows to zero 6151 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6152 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6153 - b - optional vector of right hand side, that will be adjusted by provided solution 6154 6155 Note: 6156 See `MatZeroRowsColumns()` for details on how this routine operates. 6157 6158 Level: intermediate 6159 6160 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6161 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRows()`, `MatZeroRowsColumnsStencil()` 6162 @*/ 6163 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6164 { 6165 PetscInt numRows; 6166 const PetscInt *rows; 6167 6168 PetscFunctionBegin; 6169 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6170 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6171 PetscValidType(mat,1); 6172 PetscValidType(is,2); 6173 PetscCall(ISGetLocalSize(is,&numRows)); 6174 PetscCall(ISGetIndices(is,&rows)); 6175 PetscCall(MatZeroRowsColumns(mat,numRows,rows,diag,x,b)); 6176 PetscCall(ISRestoreIndices(is,&rows)); 6177 PetscFunctionReturn(0); 6178 } 6179 6180 /*@ 6181 MatZeroRows - Zeros all entries (except possibly the main diagonal) 6182 of a set of rows of a matrix. 6183 6184 Collective on Mat 6185 6186 Input Parameters: 6187 + mat - the matrix 6188 . numRows - the number of rows to remove 6189 . rows - the global row indices 6190 . diag - value put in the diagonal of the eliminated rows 6191 . x - optional vector of solutions for zeroed rows (other entries in vector are not used), these must be set before this call 6192 - b - optional vector of right hand side, that will be adjusted by provided solution 6193 6194 Notes: 6195 This routine, along with `MatZeroRowsColumns()`, is typically used to eliminate known Dirichlet boundary conditions from a linear system. 6196 6197 For each zeroed row, the value of the corresponding b is set to diag times the value of the corresponding x. 6198 6199 If the resulting linear system is to be solved with KSP then one can (but does not have to) call `KSPSetInitialGuessNonzero()` to allow the 6200 Krylov method to take advantage of the known solution on the zeroed rows. 6201 6202 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) 6203 from the matrix. 6204 6205 Unlike `MatZeroRowsColumns()` for the AIJ and BAIJ matrix formats this removes the old nonzero structure, from the eliminated rows of the matrix 6206 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 6207 formats this does not alter the nonzero structure. 6208 6209 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6210 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6211 merely zeroed. 6212 6213 The user can set a value in the diagonal entry (or for the AIJ and 6214 row formats can optionally remove the main diagonal entry from the 6215 nonzero structure as well, by passing 0.0 as the final argument). 6216 6217 For the parallel case, all processes that share the matrix (i.e., 6218 those in the communicator used for matrix creation) MUST call this 6219 routine, regardless of whether any rows being zeroed are owned by 6220 them. 6221 6222 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6223 list only rows local to itself). 6224 6225 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6226 owns that are to be zeroed. This saves a global synchronization in the implementation. 6227 6228 Level: intermediate 6229 6230 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6231 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()`, `PCREDISTRIBUTE` 6232 @*/ 6233 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6234 { 6235 PetscFunctionBegin; 6236 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6237 PetscValidType(mat,1); 6238 if (numRows) PetscValidIntPointer(rows,3); 6239 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6240 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6241 PetscCheck(mat->ops->zerorows,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6242 MatCheckPreallocated(mat,1); 6243 6244 PetscCall((*mat->ops->zerorows)(mat,numRows,rows,diag,x,b)); 6245 PetscCall(MatViewFromOptions(mat,NULL,"-mat_view")); 6246 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6247 PetscFunctionReturn(0); 6248 } 6249 6250 /*@ 6251 MatZeroRowsIS - Zeros all entries (except possibly the main diagonal) 6252 of a set of rows of a matrix. 6253 6254 Collective on Mat 6255 6256 Input Parameters: 6257 + mat - the matrix 6258 . is - index set of rows to remove (if NULL then no row is removed) 6259 . diag - value put in all diagonals of eliminated rows 6260 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6261 - b - optional vector of right hand side, that will be adjusted by provided solution 6262 6263 Note: 6264 See `MatZeroRows()` for details on how this routine operates. 6265 6266 Level: intermediate 6267 6268 .seealso: `MatZeroRows()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6269 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6270 @*/ 6271 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6272 { 6273 PetscInt numRows = 0; 6274 const PetscInt *rows = NULL; 6275 6276 PetscFunctionBegin; 6277 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6278 PetscValidType(mat,1); 6279 if (is) { 6280 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6281 PetscCall(ISGetLocalSize(is,&numRows)); 6282 PetscCall(ISGetIndices(is,&rows)); 6283 } 6284 PetscCall(MatZeroRows(mat,numRows,rows,diag,x,b)); 6285 if (is) { 6286 PetscCall(ISRestoreIndices(is,&rows)); 6287 } 6288 PetscFunctionReturn(0); 6289 } 6290 6291 /*@ 6292 MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal) 6293 of a set of rows of a matrix. These rows must be local to the process. 6294 6295 Collective on Mat 6296 6297 Input Parameters: 6298 + mat - the matrix 6299 . numRows - the number of rows to remove 6300 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 6301 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6302 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6303 - b - optional vector of right hand side, that will be adjusted by provided solution 6304 6305 Notes: 6306 See `MatZeroRows()` for details on how this routine operates. 6307 6308 The grid coordinates are across the entire grid, not just the local portion 6309 6310 In Fortran idxm and idxn should be declared as 6311 $ MatStencil idxm(4,m) 6312 and the values inserted using 6313 $ idxm(MatStencil_i,1) = i 6314 $ idxm(MatStencil_j,1) = j 6315 $ idxm(MatStencil_k,1) = k 6316 $ idxm(MatStencil_c,1) = c 6317 etc 6318 6319 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6320 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6321 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6322 DM_BOUNDARY_PERIODIC boundary type. 6323 6324 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 6325 a single value per point) you can skip filling those indices. 6326 6327 Level: intermediate 6328 6329 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsl()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6330 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6331 @*/ 6332 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 6333 { 6334 PetscInt dim = mat->stencil.dim; 6335 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 6336 PetscInt *dims = mat->stencil.dims+1; 6337 PetscInt *starts = mat->stencil.starts; 6338 PetscInt *dxm = (PetscInt*) rows; 6339 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6340 6341 PetscFunctionBegin; 6342 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6343 PetscValidType(mat,1); 6344 if (numRows) PetscValidPointer(rows,3); 6345 6346 PetscCall(PetscMalloc1(numRows, &jdxm)); 6347 for (i = 0; i < numRows; ++i) { 6348 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6349 for (j = 0; j < 3-sdim; ++j) dxm++; 6350 /* Local index in X dir */ 6351 tmp = *dxm++ - starts[0]; 6352 /* Loop over remaining dimensions */ 6353 for (j = 0; j < dim-1; ++j) { 6354 /* If nonlocal, set index to be negative */ 6355 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6356 /* Update local index */ 6357 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6358 } 6359 /* Skip component slot if necessary */ 6360 if (mat->stencil.noc) dxm++; 6361 /* Local row number */ 6362 if (tmp >= 0) { 6363 jdxm[numNewRows++] = tmp; 6364 } 6365 } 6366 PetscCall(MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b)); 6367 PetscCall(PetscFree(jdxm)); 6368 PetscFunctionReturn(0); 6369 } 6370 6371 /*@ 6372 MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal) 6373 of a set of rows and columns of a matrix. 6374 6375 Collective on Mat 6376 6377 Input Parameters: 6378 + mat - the matrix 6379 . numRows - the number of rows/columns to remove 6380 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 6381 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6382 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6383 - b - optional vector of right hand side, that will be adjusted by provided solution 6384 6385 Notes: 6386 See `MatZeroRowsColumns()` for details on how this routine operates. 6387 6388 The grid coordinates are across the entire grid, not just the local portion 6389 6390 In Fortran idxm and idxn should be declared as 6391 $ MatStencil idxm(4,m) 6392 and the values inserted using 6393 $ idxm(MatStencil_i,1) = i 6394 $ idxm(MatStencil_j,1) = j 6395 $ idxm(MatStencil_k,1) = k 6396 $ idxm(MatStencil_c,1) = c 6397 etc 6398 6399 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6400 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6401 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6402 DM_BOUNDARY_PERIODIC boundary type. 6403 6404 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 6405 a single value per point) you can skip filling those indices. 6406 6407 Level: intermediate 6408 6409 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6410 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRows()` 6411 @*/ 6412 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 6413 { 6414 PetscInt dim = mat->stencil.dim; 6415 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 6416 PetscInt *dims = mat->stencil.dims+1; 6417 PetscInt *starts = mat->stencil.starts; 6418 PetscInt *dxm = (PetscInt*) rows; 6419 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6420 6421 PetscFunctionBegin; 6422 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6423 PetscValidType(mat,1); 6424 if (numRows) PetscValidPointer(rows,3); 6425 6426 PetscCall(PetscMalloc1(numRows, &jdxm)); 6427 for (i = 0; i < numRows; ++i) { 6428 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6429 for (j = 0; j < 3-sdim; ++j) dxm++; 6430 /* Local index in X dir */ 6431 tmp = *dxm++ - starts[0]; 6432 /* Loop over remaining dimensions */ 6433 for (j = 0; j < dim-1; ++j) { 6434 /* If nonlocal, set index to be negative */ 6435 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6436 /* Update local index */ 6437 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6438 } 6439 /* Skip component slot if necessary */ 6440 if (mat->stencil.noc) dxm++; 6441 /* Local row number */ 6442 if (tmp >= 0) { 6443 jdxm[numNewRows++] = tmp; 6444 } 6445 } 6446 PetscCall(MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b)); 6447 PetscCall(PetscFree(jdxm)); 6448 PetscFunctionReturn(0); 6449 } 6450 6451 /*@C 6452 MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal) 6453 of a set of rows of a matrix; using local numbering of rows. 6454 6455 Collective on Mat 6456 6457 Input Parameters: 6458 + mat - the matrix 6459 . numRows - the number of rows to remove 6460 . rows - the local row indices 6461 . diag - value put in all diagonals of eliminated rows 6462 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6463 - b - optional vector of right hand side, that will be adjusted by provided solution 6464 6465 Notes: 6466 Before calling `MatZeroRowsLocal()`, the user must first set the 6467 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6468 6469 See `MatZeroRows()` for details on how this routine operates. 6470 6471 Level: intermediate 6472 6473 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRows()`, `MatSetOption()`, 6474 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6475 @*/ 6476 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6477 { 6478 PetscFunctionBegin; 6479 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6480 PetscValidType(mat,1); 6481 if (numRows) PetscValidIntPointer(rows,3); 6482 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6483 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6484 MatCheckPreallocated(mat,1); 6485 6486 if (mat->ops->zerorowslocal) { 6487 PetscCall((*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b)); 6488 } else { 6489 IS is, newis; 6490 const PetscInt *newRows; 6491 6492 PetscCheck(mat->rmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6493 PetscCall(ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is)); 6494 PetscCall(ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis)); 6495 PetscCall(ISGetIndices(newis,&newRows)); 6496 PetscCall((*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b)); 6497 PetscCall(ISRestoreIndices(newis,&newRows)); 6498 PetscCall(ISDestroy(&newis)); 6499 PetscCall(ISDestroy(&is)); 6500 } 6501 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6502 PetscFunctionReturn(0); 6503 } 6504 6505 /*@ 6506 MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal) 6507 of a set of rows of a matrix; using local numbering of rows. 6508 6509 Collective on Mat 6510 6511 Input Parameters: 6512 + mat - the matrix 6513 . is - index set of rows to remove 6514 . diag - value put in all diagonals of eliminated rows 6515 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6516 - b - optional vector of right hand side, that will be adjusted by provided solution 6517 6518 Notes: 6519 Before calling `MatZeroRowsLocalIS()`, the user must first set the 6520 local-to-global mapping by calling `MatSetLocalToGlobalMapping()`. 6521 6522 See `MatZeroRows()` for details on how this routine operates. 6523 6524 Level: intermediate 6525 6526 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRows()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6527 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6528 @*/ 6529 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6530 { 6531 PetscInt numRows; 6532 const PetscInt *rows; 6533 6534 PetscFunctionBegin; 6535 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6536 PetscValidType(mat,1); 6537 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6538 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6539 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6540 MatCheckPreallocated(mat,1); 6541 6542 PetscCall(ISGetLocalSize(is,&numRows)); 6543 PetscCall(ISGetIndices(is,&rows)); 6544 PetscCall(MatZeroRowsLocal(mat,numRows,rows,diag,x,b)); 6545 PetscCall(ISRestoreIndices(is,&rows)); 6546 PetscFunctionReturn(0); 6547 } 6548 6549 /*@ 6550 MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal) 6551 of a set of rows and columns of a matrix; using local numbering of rows. 6552 6553 Collective on Mat 6554 6555 Input Parameters: 6556 + mat - the matrix 6557 . numRows - the number of rows to remove 6558 . rows - the global row indices 6559 . diag - value put in all diagonals of eliminated rows 6560 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6561 - b - optional vector of right hand side, that will be adjusted by provided solution 6562 6563 Notes: 6564 Before calling MatZeroRowsColumnsLocal(), the user must first set the 6565 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6566 6567 See `MatZeroRowsColumns()` for details on how this routine operates. 6568 6569 Level: intermediate 6570 6571 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6572 `MatZeroRows()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6573 @*/ 6574 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6575 { 6576 IS is, newis; 6577 const PetscInt *newRows; 6578 6579 PetscFunctionBegin; 6580 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6581 PetscValidType(mat,1); 6582 if (numRows) PetscValidIntPointer(rows,3); 6583 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6584 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6585 MatCheckPreallocated(mat,1); 6586 6587 PetscCheck(mat->cmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6588 PetscCall(ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is)); 6589 PetscCall(ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis)); 6590 PetscCall(ISGetIndices(newis,&newRows)); 6591 PetscCall((*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b)); 6592 PetscCall(ISRestoreIndices(newis,&newRows)); 6593 PetscCall(ISDestroy(&newis)); 6594 PetscCall(ISDestroy(&is)); 6595 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6596 PetscFunctionReturn(0); 6597 } 6598 6599 /*@ 6600 MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal) 6601 of a set of rows and columns of a matrix; using local numbering of rows. 6602 6603 Collective on Mat 6604 6605 Input Parameters: 6606 + mat - the matrix 6607 . is - index set of rows to remove 6608 . diag - value put in all diagonals of eliminated rows 6609 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6610 - b - optional vector of right hand side, that will be adjusted by provided solution 6611 6612 Notes: 6613 Before calling `MatZeroRowsColumnsLocalIS()`, the user must first set the 6614 local-to-global mapping by calling `MatSetLocalToGlobalMapping()`. 6615 6616 See `MatZeroRowsColumns()` for details on how this routine operates. 6617 6618 Level: intermediate 6619 6620 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6621 `MatZeroRowsColumnsLocal()`, `MatZeroRows()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6622 @*/ 6623 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6624 { 6625 PetscInt numRows; 6626 const PetscInt *rows; 6627 6628 PetscFunctionBegin; 6629 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6630 PetscValidType(mat,1); 6631 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6632 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6633 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6634 MatCheckPreallocated(mat,1); 6635 6636 PetscCall(ISGetLocalSize(is,&numRows)); 6637 PetscCall(ISGetIndices(is,&rows)); 6638 PetscCall(MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b)); 6639 PetscCall(ISRestoreIndices(is,&rows)); 6640 PetscFunctionReturn(0); 6641 } 6642 6643 /*@C 6644 MatGetSize - Returns the numbers of rows and columns in a matrix. 6645 6646 Not Collective 6647 6648 Input Parameter: 6649 . mat - the matrix 6650 6651 Output Parameters: 6652 + m - the number of global rows 6653 - n - the number of global columns 6654 6655 Note: both output parameters can be NULL on input. 6656 6657 Level: beginner 6658 6659 .seealso: `MatGetLocalSize()` 6660 @*/ 6661 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n) 6662 { 6663 PetscFunctionBegin; 6664 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6665 if (m) *m = mat->rmap->N; 6666 if (n) *n = mat->cmap->N; 6667 PetscFunctionReturn(0); 6668 } 6669 6670 /*@C 6671 MatGetLocalSize - For most matrix formats, excluding `MATELEMENTAL` and `MATSCALAPACK`, Returns the number of local rows and local columns 6672 of a matrix. For all matrices this is the local size of the left and right vectors as returned by MatCreateVecs(). 6673 6674 Not Collective 6675 6676 Input Parameter: 6677 . mat - the matrix 6678 6679 Output Parameters: 6680 + m - the number of local rows, use `NULL` to not obtain this value 6681 - n - the number of local columns, use `NULL` to not obtain this value 6682 6683 Level: beginner 6684 6685 .seealso: `MatGetSize()` 6686 @*/ 6687 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n) 6688 { 6689 PetscFunctionBegin; 6690 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6691 if (m) PetscValidIntPointer(m,2); 6692 if (n) PetscValidIntPointer(n,3); 6693 if (m) *m = mat->rmap->n; 6694 if (n) *n = mat->cmap->n; 6695 PetscFunctionReturn(0); 6696 } 6697 6698 /*@C 6699 MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies this matrix by that are owned by 6700 this processor. (The columns of the "diagonal block" for most sparse matrix formats). See :any:`<sec_matlayout>` for details on matrix layouts. 6701 6702 Not Collective, unless matrix has not been allocated, then collective on Mat 6703 6704 Input Parameter: 6705 . mat - the matrix 6706 6707 Output Parameters: 6708 + m - the global index of the first local column, use `NULL` to not obtain this value 6709 - n - one more than the global index of the last local column, use `NULL` to not obtain this value 6710 6711 Level: developer 6712 6713 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRanges()`, `MatGetOwnershipRangesColumn()`, `PetscLayout` 6714 6715 @*/ 6716 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n) 6717 { 6718 PetscFunctionBegin; 6719 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6720 PetscValidType(mat,1); 6721 if (m) PetscValidIntPointer(m,2); 6722 if (n) PetscValidIntPointer(n,3); 6723 MatCheckPreallocated(mat,1); 6724 if (m) *m = mat->cmap->rstart; 6725 if (n) *n = mat->cmap->rend; 6726 PetscFunctionReturn(0); 6727 } 6728 6729 /*@C 6730 MatGetOwnershipRange - For matrices that own values by row, excludes `MATELEMENTAL` and `MATSCALAPACK`, returns the range of matrix rows owned by 6731 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 6732 vector product with this matrix. See :any:`<sec_matlayout>` for details on matrix layouts 6733 6734 Not Collective 6735 6736 Input Parameter: 6737 . mat - the matrix 6738 6739 Output Parameters: 6740 + m - the global index of the first local row, use `NULL` to not obtain this value 6741 - n - one more than the global index of the last local row, use `NULL` to not obtain this value 6742 6743 Note: 6744 This function requires that the matrix be preallocated. If you have not preallocated, consider using 6745 `PetscSplitOwnership`(`MPI_Comm` comm, `PetscInt` *n, `PetscInt` *N) 6746 and then `MPI_Scan()` to calculate prefix sums of the local sizes. 6747 6748 Level: beginner 6749 6750 .seealso: `MatGetOwnershipRanges()`, `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRangesColumn()`, `PetscSplitOwnership()`, `PetscSplitOwnershipBlock()`, 6751 `PetscLayout` 6752 6753 @*/ 6754 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n) 6755 { 6756 PetscFunctionBegin; 6757 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6758 PetscValidType(mat,1); 6759 if (m) PetscValidIntPointer(m,2); 6760 if (n) PetscValidIntPointer(n,3); 6761 MatCheckPreallocated(mat,1); 6762 if (m) *m = mat->rmap->rstart; 6763 if (n) *n = mat->rmap->rend; 6764 PetscFunctionReturn(0); 6765 } 6766 6767 /*@C 6768 MatGetOwnershipRanges - For matrices that own values by row, excludes `MATELEMENTAL` and `MATSCALAPACK`, returns the range of matrix rows owned by 6769 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 6770 vector product with this matrix. See :any:`<sec_matlayout>` for details on matrix layouts 6771 6772 Not Collective, unless matrix has not been allocated, then collective on Mat 6773 6774 Input Parameters: 6775 . mat - the matrix 6776 6777 Output Parameters: 6778 . ranges - start of each processors portion plus one more than the total length at the end 6779 6780 Level: beginner 6781 6782 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRangesColumn()`, `PetscLayout` 6783 6784 @*/ 6785 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges) 6786 { 6787 PetscFunctionBegin; 6788 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6789 PetscValidType(mat,1); 6790 MatCheckPreallocated(mat,1); 6791 PetscCall(PetscLayoutGetRanges(mat->rmap,ranges)); 6792 PetscFunctionReturn(0); 6793 } 6794 6795 /*@C 6796 MatGetOwnershipRangesColumn - Returns the ranges of matrix columns associated with rows of a vector one multiplies this vector by that are owned by 6797 each processor. (The columns of the "diagonal blocks", for most sparse matrix formats). See :any:`<sec_matlayout>` for details on matrix layouts. 6798 6799 Not Collective, unless matrix has not been allocated, then collective on Mat 6800 6801 Input Parameters: 6802 . mat - the matrix 6803 6804 Output Parameters: 6805 . ranges - start of each processors portion plus one more then the total length at the end 6806 6807 Level: beginner 6808 6809 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRanges()` 6810 6811 @*/ 6812 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges) 6813 { 6814 PetscFunctionBegin; 6815 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6816 PetscValidType(mat,1); 6817 MatCheckPreallocated(mat,1); 6818 PetscCall(PetscLayoutGetRanges(mat->cmap,ranges)); 6819 PetscFunctionReturn(0); 6820 } 6821 6822 /*@C 6823 MatGetOwnershipIS - Get row and column ownership of a matrices' values as index sets. For most matrices, excluding `MATELEMENTAL` and `MATSCALAPACK`, this 6824 corresponds to values returned by `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`. For `MATELEMENTAL` and `MATSCALAPACK` the ownership 6825 is more complicated. See :any:`<sec_matlayout>` for details on matrix layouts. 6826 6827 Not Collective 6828 6829 Input Parameter: 6830 . A - matrix 6831 6832 Output Parameters: 6833 + rows - rows in which this process owns elements, , use `NULL` to not obtain this value 6834 - cols - columns in which this process owns elements, use `NULL` to not obtain this value 6835 6836 Level: intermediate 6837 6838 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`, `MatSetValues()`, ``MATELEMENTAL``, ``MATSCALAPACK`` 6839 @*/ 6840 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols) 6841 { 6842 PetscErrorCode (*f)(Mat,IS*,IS*); 6843 6844 PetscFunctionBegin; 6845 MatCheckPreallocated(A,1); 6846 PetscCall(PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f)); 6847 if (f) { 6848 PetscCall((*f)(A,rows,cols)); 6849 } else { /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */ 6850 if (rows) PetscCall(ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows)); 6851 if (cols) PetscCall(ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols)); 6852 } 6853 PetscFunctionReturn(0); 6854 } 6855 6856 /*@C 6857 MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix. 6858 Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric() 6859 to complete the factorization. 6860 6861 Collective on Mat 6862 6863 Input Parameters: 6864 + mat - the matrix 6865 . row - row permutation 6866 . column - column permutation 6867 - info - structure containing 6868 $ levels - number of levels of fill. 6869 $ expected fill - as ratio of original fill. 6870 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 6871 missing diagonal entries) 6872 6873 Output Parameters: 6874 . fact - new matrix that has been symbolically factored 6875 6876 Notes: 6877 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 6878 6879 Most users should employ the simplified KSP interface for linear solvers 6880 instead of working directly with matrix algebra routines such as this. 6881 See, e.g., KSPCreate(). 6882 6883 Level: developer 6884 6885 .seealso: `MatLUFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()` 6886 `MatGetOrdering()`, `MatFactorInfo` 6887 6888 Note: this uses the definition of level of fill as in Y. Saad, 2003 6889 6890 Developer Note: fortran interface is not autogenerated as the f90 6891 interface definition cannot be generated correctly [due to MatFactorInfo] 6892 6893 References: 6894 . * - Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6895 @*/ 6896 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 6897 { 6898 PetscFunctionBegin; 6899 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 6900 PetscValidType(mat,2); 6901 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,3); 6902 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,4); 6903 PetscValidPointer(info,5); 6904 PetscValidPointer(fact,1); 6905 PetscCheck(info->levels >= 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %" PetscInt_FMT,(PetscInt)info->levels); 6906 PetscCheck(info->fill >= 1.0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6907 if (!fact->ops->ilufactorsymbolic) { 6908 MatSolverType stype; 6909 PetscCall(MatFactorGetSolverType(fact,&stype)); 6910 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver type %s",((PetscObject)mat)->type_name,stype); 6911 } 6912 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6913 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6914 MatCheckPreallocated(mat,2); 6915 6916 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0)); 6917 PetscCall((fact->ops->ilufactorsymbolic)(fact,mat,row,col,info)); 6918 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0)); 6919 PetscFunctionReturn(0); 6920 } 6921 6922 /*@C 6923 MatICCFactorSymbolic - Performs symbolic incomplete 6924 Cholesky factorization for a symmetric matrix. Use 6925 MatCholeskyFactorNumeric() to complete the factorization. 6926 6927 Collective on Mat 6928 6929 Input Parameters: 6930 + mat - the matrix 6931 . perm - row and column permutation 6932 - info - structure containing 6933 $ levels - number of levels of fill. 6934 $ expected fill - as ratio of original fill. 6935 6936 Output Parameter: 6937 . fact - the factored matrix 6938 6939 Notes: 6940 Most users should employ the KSP interface for linear solvers 6941 instead of working directly with matrix algebra routines such as this. 6942 See, e.g., KSPCreate(). 6943 6944 Level: developer 6945 6946 .seealso: `MatCholeskyFactorNumeric()`, `MatCholeskyFactor()`, `MatFactorInfo` 6947 6948 Note: this uses the definition of level of fill as in Y. Saad, 2003 6949 6950 Developer Note: fortran interface is not autogenerated as the f90 6951 interface definition cannot be generated correctly [due to MatFactorInfo] 6952 6953 References: 6954 . * - Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6955 @*/ 6956 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 6957 { 6958 PetscFunctionBegin; 6959 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 6960 PetscValidType(mat,2); 6961 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,3); 6962 PetscValidPointer(info,4); 6963 PetscValidPointer(fact,1); 6964 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6965 PetscCheck(info->levels >= 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %" PetscInt_FMT,(PetscInt) info->levels); 6966 PetscCheck(info->fill >= 1.0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6967 if (!(fact)->ops->iccfactorsymbolic) { 6968 MatSolverType stype; 6969 PetscCall(MatFactorGetSolverType(fact,&stype)); 6970 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver type %s",((PetscObject)mat)->type_name,stype); 6971 } 6972 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6973 MatCheckPreallocated(mat,2); 6974 6975 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0)); 6976 PetscCall((fact->ops->iccfactorsymbolic)(fact,mat,perm,info)); 6977 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0)); 6978 PetscFunctionReturn(0); 6979 } 6980 6981 /*@C 6982 MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat 6983 points to an array of valid matrices, they may be reused to store the new 6984 submatrices. 6985 6986 Collective on Mat 6987 6988 Input Parameters: 6989 + mat - the matrix 6990 . n - the number of submatrixes to be extracted (on this processor, may be zero) 6991 . irow, icol - index sets of rows and columns to extract 6992 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6993 6994 Output Parameter: 6995 . submat - the array of submatrices 6996 6997 Notes: 6998 MatCreateSubMatrices() can extract ONLY sequential submatrices 6999 (from both sequential and parallel matrices). Use MatCreateSubMatrix() 7000 to extract a parallel submatrix. 7001 7002 Some matrix types place restrictions on the row and column 7003 indices, such as that they be sorted or that they be equal to each other. 7004 7005 The index sets may not have duplicate entries. 7006 7007 When extracting submatrices from a parallel matrix, each processor can 7008 form a different submatrix by setting the rows and columns of its 7009 individual index sets according to the local submatrix desired. 7010 7011 When finished using the submatrices, the user should destroy 7012 them with MatDestroySubMatrices(). 7013 7014 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 7015 original matrix has not changed from that last call to MatCreateSubMatrices(). 7016 7017 This routine creates the matrices in submat; you should NOT create them before 7018 calling it. It also allocates the array of matrix pointers submat. 7019 7020 For BAIJ matrices the index sets must respect the block structure, that is if they 7021 request one row/column in a block, they must request all rows/columns that are in 7022 that block. For example, if the block size is 2 you cannot request just row 0 and 7023 column 0. 7024 7025 Fortran Note: 7026 The Fortran interface is slightly different from that given below; it 7027 requires one to pass in as submat a Mat (integer) array of size at least n+1. 7028 7029 Level: advanced 7030 7031 .seealso: `MatDestroySubMatrices()`, `MatCreateSubMatrix()`, `MatGetRow()`, `MatGetDiagonal()`, `MatReuse` 7032 @*/ 7033 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 7034 { 7035 PetscInt i; 7036 PetscBool eq; 7037 7038 PetscFunctionBegin; 7039 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7040 PetscValidType(mat,1); 7041 if (n) { 7042 PetscValidPointer(irow,3); 7043 for (i=0; i<n; i++) PetscValidHeaderSpecific(irow[i],IS_CLASSID,3); 7044 PetscValidPointer(icol,4); 7045 for (i=0; i<n; i++) PetscValidHeaderSpecific(icol[i],IS_CLASSID,4); 7046 } 7047 PetscValidPointer(submat,6); 7048 if (n && scall == MAT_REUSE_MATRIX) { 7049 PetscValidPointer(*submat,6); 7050 for (i=0; i<n; i++) PetscValidHeaderSpecific((*submat)[i],MAT_CLASSID,6); 7051 } 7052 PetscCheck(mat->ops->createsubmatrices,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7053 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7054 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7055 MatCheckPreallocated(mat,1); 7056 PetscCall(PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0)); 7057 PetscCall((*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat)); 7058 PetscCall(PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0)); 7059 for (i=0; i<n; i++) { 7060 (*submat)[i]->factortype = MAT_FACTOR_NONE; /* in case in place factorization was previously done on submatrix */ 7061 PetscCall(ISEqualUnsorted(irow[i],icol[i],&eq)); 7062 if (eq) { 7063 PetscCall(MatPropagateSymmetryOptions(mat,(*submat)[i])); 7064 } 7065 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 7066 if (mat->boundtocpu && mat->bindingpropagates) { 7067 PetscCall(MatBindToCPU((*submat)[i],PETSC_TRUE)); 7068 PetscCall(MatSetBindingPropagates((*submat)[i],PETSC_TRUE)); 7069 } 7070 #endif 7071 } 7072 PetscFunctionReturn(0); 7073 } 7074 7075 /*@C 7076 MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms). 7077 7078 Collective on Mat 7079 7080 Input Parameters: 7081 + mat - the matrix 7082 . n - the number of submatrixes to be extracted 7083 . irow, icol - index sets of rows and columns to extract 7084 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 7085 7086 Output Parameter: 7087 . submat - the array of submatrices 7088 7089 Level: advanced 7090 7091 .seealso: `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRow()`, `MatGetDiagonal()`, `MatReuse` 7092 @*/ 7093 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 7094 { 7095 PetscInt i; 7096 PetscBool eq; 7097 7098 PetscFunctionBegin; 7099 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7100 PetscValidType(mat,1); 7101 if (n) { 7102 PetscValidPointer(irow,3); 7103 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 7104 PetscValidPointer(icol,4); 7105 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 7106 } 7107 PetscValidPointer(submat,6); 7108 if (n && scall == MAT_REUSE_MATRIX) { 7109 PetscValidPointer(*submat,6); 7110 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 7111 } 7112 PetscCheck(mat->ops->createsubmatricesmpi,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7113 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7114 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7115 MatCheckPreallocated(mat,1); 7116 7117 PetscCall(PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0)); 7118 PetscCall((*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat)); 7119 PetscCall(PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0)); 7120 for (i=0; i<n; i++) { 7121 PetscCall(ISEqualUnsorted(irow[i],icol[i],&eq)); 7122 if (eq) { 7123 PetscCall(MatPropagateSymmetryOptions(mat,(*submat)[i])); 7124 } 7125 } 7126 PetscFunctionReturn(0); 7127 } 7128 7129 /*@C 7130 MatDestroyMatrices - Destroys an array of matrices. 7131 7132 Collective on Mat 7133 7134 Input Parameters: 7135 + n - the number of local matrices 7136 - mat - the matrices (note that this is a pointer to the array of matrices) 7137 7138 Level: advanced 7139 7140 Notes: 7141 Frees not only the matrices, but also the array that contains the matrices 7142 In Fortran will not free the array. 7143 7144 .seealso: `MatCreateSubMatrices()` `MatDestroySubMatrices()` 7145 @*/ 7146 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[]) 7147 { 7148 PetscInt i; 7149 7150 PetscFunctionBegin; 7151 if (!*mat) PetscFunctionReturn(0); 7152 PetscCheck(n >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %" PetscInt_FMT,n); 7153 PetscValidPointer(mat,2); 7154 7155 for (i=0; i<n; i++) { 7156 PetscCall(MatDestroy(&(*mat)[i])); 7157 } 7158 7159 /* memory is allocated even if n = 0 */ 7160 PetscCall(PetscFree(*mat)); 7161 PetscFunctionReturn(0); 7162 } 7163 7164 /*@C 7165 MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices(). 7166 7167 Collective on Mat 7168 7169 Input Parameters: 7170 + n - the number of local matrices 7171 - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling 7172 sequence of MatCreateSubMatrices()) 7173 7174 Level: advanced 7175 7176 Notes: 7177 Frees not only the matrices, but also the array that contains the matrices 7178 In Fortran will not free the array. 7179 7180 .seealso: `MatCreateSubMatrices()` 7181 @*/ 7182 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[]) 7183 { 7184 Mat mat0; 7185 7186 PetscFunctionBegin; 7187 if (!*mat) PetscFunctionReturn(0); 7188 /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */ 7189 PetscCheck(n >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %" PetscInt_FMT,n); 7190 PetscValidPointer(mat,2); 7191 7192 mat0 = (*mat)[0]; 7193 if (mat0 && mat0->ops->destroysubmatrices) { 7194 PetscCall((mat0->ops->destroysubmatrices)(n,mat)); 7195 } else { 7196 PetscCall(MatDestroyMatrices(n,mat)); 7197 } 7198 PetscFunctionReturn(0); 7199 } 7200 7201 /*@C 7202 MatGetSeqNonzeroStructure - Extracts the nonzero structure from a matrix and stores it, in its entirety, on each process 7203 7204 Collective on Mat 7205 7206 Input Parameters: 7207 . mat - the matrix 7208 7209 Output Parameter: 7210 . matstruct - the sequential matrix with the nonzero structure of mat 7211 7212 Level: intermediate 7213 7214 .seealso: `MatDestroySeqNonzeroStructure()`, `MatCreateSubMatrices()`, `MatDestroyMatrices()` 7215 @*/ 7216 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct) 7217 { 7218 PetscFunctionBegin; 7219 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7220 PetscValidPointer(matstruct,2); 7221 7222 PetscValidType(mat,1); 7223 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7224 MatCheckPreallocated(mat,1); 7225 7226 PetscCheck(mat->ops->getseqnonzerostructure,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s",((PetscObject)mat)->type_name); 7227 PetscCall(PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0)); 7228 PetscCall((*mat->ops->getseqnonzerostructure)(mat,matstruct)); 7229 PetscCall(PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0)); 7230 PetscFunctionReturn(0); 7231 } 7232 7233 /*@C 7234 MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure(). 7235 7236 Collective on Mat 7237 7238 Input Parameters: 7239 . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling 7240 sequence of MatGetSequentialNonzeroStructure()) 7241 7242 Level: advanced 7243 7244 Notes: 7245 Frees not only the matrices, but also the array that contains the matrices 7246 7247 .seealso: `MatGetSeqNonzeroStructure()` 7248 @*/ 7249 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat) 7250 { 7251 PetscFunctionBegin; 7252 PetscValidPointer(mat,1); 7253 PetscCall(MatDestroy(mat)); 7254 PetscFunctionReturn(0); 7255 } 7256 7257 /*@ 7258 MatIncreaseOverlap - Given a set of submatrices indicated by index sets, 7259 replaces the index sets by larger ones that represent submatrices with 7260 additional overlap. 7261 7262 Collective on Mat 7263 7264 Input Parameters: 7265 + mat - the matrix 7266 . n - the number of index sets 7267 . is - the array of index sets (these index sets will changed during the call) 7268 - ov - the additional overlap requested 7269 7270 Options Database: 7271 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7272 7273 Level: developer 7274 7275 Developer Note: 7276 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. 7277 7278 .seealso: `MatCreateSubMatrices()` 7279 @*/ 7280 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov) 7281 { 7282 PetscInt i,bs,cbs; 7283 7284 PetscFunctionBegin; 7285 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7286 PetscValidType(mat,1); 7287 PetscValidLogicalCollectiveInt(mat,n,2); 7288 PetscCheck(n >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %" PetscInt_FMT,n); 7289 if (n) { 7290 PetscValidPointer(is,3); 7291 for (i = 0; i < n; i++) PetscValidHeaderSpecific(is[i],IS_CLASSID,3); 7292 } 7293 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7294 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7295 MatCheckPreallocated(mat,1); 7296 7297 if (!ov || !n) PetscFunctionReturn(0); 7298 PetscCheck(mat->ops->increaseoverlap,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7299 PetscCall(PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0)); 7300 PetscCall((*mat->ops->increaseoverlap)(mat,n,is,ov)); 7301 PetscCall(PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0)); 7302 PetscCall(MatGetBlockSizes(mat,&bs,&cbs)); 7303 if (bs == cbs) { 7304 for (i=0; i<n; i++) { 7305 PetscCall(ISSetBlockSize(is[i],bs)); 7306 } 7307 } 7308 PetscFunctionReturn(0); 7309 } 7310 7311 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt); 7312 7313 /*@ 7314 MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across 7315 a sub communicator, replaces the index sets by larger ones that represent submatrices with 7316 additional overlap. 7317 7318 Collective on Mat 7319 7320 Input Parameters: 7321 + mat - the matrix 7322 . n - the number of index sets 7323 . is - the array of index sets (these index sets will changed during the call) 7324 - ov - the additional overlap requested 7325 7326 Options Database: 7327 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7328 7329 Level: developer 7330 7331 .seealso: `MatCreateSubMatrices()` 7332 @*/ 7333 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov) 7334 { 7335 PetscInt i; 7336 7337 PetscFunctionBegin; 7338 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7339 PetscValidType(mat,1); 7340 PetscCheck(n >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %" PetscInt_FMT,n); 7341 if (n) { 7342 PetscValidPointer(is,3); 7343 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 7344 } 7345 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7346 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7347 MatCheckPreallocated(mat,1); 7348 if (!ov) PetscFunctionReturn(0); 7349 PetscCall(PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0)); 7350 for (i=0; i<n; i++) { 7351 PetscCall(MatIncreaseOverlapSplit_Single(mat,&is[i],ov)); 7352 } 7353 PetscCall(PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0)); 7354 PetscFunctionReturn(0); 7355 } 7356 7357 /*@ 7358 MatGetBlockSize - Returns the matrix block size. 7359 7360 Not Collective 7361 7362 Input Parameter: 7363 . mat - the matrix 7364 7365 Output Parameter: 7366 . bs - block size 7367 7368 Notes: 7369 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7370 7371 If the block size has not been set yet this routine returns 1. 7372 7373 Level: intermediate 7374 7375 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSizes()` 7376 @*/ 7377 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs) 7378 { 7379 PetscFunctionBegin; 7380 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7381 PetscValidIntPointer(bs,2); 7382 *bs = PetscAbs(mat->rmap->bs); 7383 PetscFunctionReturn(0); 7384 } 7385 7386 /*@ 7387 MatGetBlockSizes - Returns the matrix block row and column sizes. 7388 7389 Not Collective 7390 7391 Input Parameter: 7392 . mat - the matrix 7393 7394 Output Parameters: 7395 + rbs - row block size 7396 - cbs - column block size 7397 7398 Notes: 7399 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7400 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7401 7402 If a block size has not been set yet this routine returns 1. 7403 7404 Level: intermediate 7405 7406 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSize()`, `MatSetBlockSizes()` 7407 @*/ 7408 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs) 7409 { 7410 PetscFunctionBegin; 7411 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7412 if (rbs) PetscValidIntPointer(rbs,2); 7413 if (cbs) PetscValidIntPointer(cbs,3); 7414 if (rbs) *rbs = PetscAbs(mat->rmap->bs); 7415 if (cbs) *cbs = PetscAbs(mat->cmap->bs); 7416 PetscFunctionReturn(0); 7417 } 7418 7419 /*@ 7420 MatSetBlockSize - Sets the matrix block size. 7421 7422 Logically Collective on Mat 7423 7424 Input Parameters: 7425 + mat - the matrix 7426 - bs - block size 7427 7428 Notes: 7429 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7430 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7431 7432 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size 7433 is compatible with the matrix local sizes. 7434 7435 Level: intermediate 7436 7437 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`, `MatGetBlockSizes()` 7438 @*/ 7439 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs) 7440 { 7441 PetscFunctionBegin; 7442 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7443 PetscValidLogicalCollectiveInt(mat,bs,2); 7444 PetscCall(MatSetBlockSizes(mat,bs,bs)); 7445 PetscFunctionReturn(0); 7446 } 7447 7448 typedef struct { 7449 PetscInt n; 7450 IS *is; 7451 Mat *mat; 7452 PetscObjectState nonzerostate; 7453 Mat C; 7454 } EnvelopeData; 7455 7456 static PetscErrorCode EnvelopeDataDestroy(EnvelopeData *edata) 7457 { 7458 for (PetscInt i=0; i<edata->n; i++) { 7459 PetscCall(ISDestroy(&edata->is[i])); 7460 } 7461 PetscCall(PetscFree(edata->is)); 7462 PetscCall(PetscFree(edata)); 7463 return 0; 7464 } 7465 7466 /* 7467 MatComputeVariableBlockEnvelope - Given a matrix whose nonzeros are in blocks along the diagonal this computes and stores 7468 the sizes of these blocks in the matrix. An individual block may lie over several processes. 7469 7470 Collective on mat 7471 7472 Input Parameter: 7473 . mat - the matrix 7474 7475 Notes: 7476 There can be zeros within the blocks 7477 7478 The blocks can overlap between processes, including laying on more than two processes 7479 7480 */ 7481 static PetscErrorCode MatComputeVariableBlockEnvelope(Mat mat) 7482 { 7483 PetscInt n,*sizes,*starts,i = 0,env = 0, tbs = 0, lblocks = 0,rstart,II,ln = 0,cnt = 0,cstart,cend; 7484 PetscInt *diag,*odiag,sc; 7485 VecScatter scatter; 7486 PetscScalar *seqv; 7487 const PetscScalar *parv; 7488 const PetscInt *ia,*ja; 7489 PetscBool set,flag,done; 7490 Mat AA = mat,A; 7491 MPI_Comm comm; 7492 PetscMPIInt rank,size,tag; 7493 MPI_Status status; 7494 PetscContainer container; 7495 EnvelopeData *edata; 7496 Vec seq,par; 7497 IS isglobal; 7498 7499 PetscFunctionBegin; 7500 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7501 PetscCall(MatIsSymmetricKnown(mat,&set,&flag)); 7502 if (!set || !flag) { 7503 /* TOO: only needs nonzero structure of transpose */ 7504 PetscCall(MatTranspose(mat,MAT_INITIAL_MATRIX,&AA)); 7505 PetscCall(MatAXPY(AA,1.0,mat,DIFFERENT_NONZERO_PATTERN)); 7506 } 7507 PetscCall(MatAIJGetLocalMat(AA,&A)); 7508 PetscCall(MatGetRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ia,&ja,&done)); 7509 PetscCheck(done,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Unable to get IJ structure from matrix"); 7510 7511 PetscCall(MatGetLocalSize(mat,&n,NULL)); 7512 PetscCall(PetscObjectGetNewTag((PetscObject)mat,&tag)); 7513 PetscCall(PetscObjectGetComm((PetscObject)mat,&comm)); 7514 PetscCallMPI(MPI_Comm_size(comm,&size)); 7515 PetscCallMPI(MPI_Comm_rank(comm,&rank)); 7516 7517 PetscCall(PetscMalloc2(n,&sizes,n,&starts)); 7518 7519 if (rank > 0) { 7520 PetscCallMPI(MPI_Recv(&env,1,MPIU_INT,rank-1,tag,comm,&status)); 7521 PetscCallMPI(MPI_Recv(&tbs,1,MPIU_INT,rank-1,tag,comm,&status)); 7522 } 7523 PetscCall(MatGetOwnershipRange(mat,&rstart,NULL)); 7524 for (i=0; i<n; i++) { 7525 env = PetscMax(env,ja[ia[i+1]-1]); 7526 II = rstart + i; 7527 if (env == II) { 7528 starts[lblocks] = tbs; 7529 sizes[lblocks++] = 1 + II - tbs; 7530 tbs = 1 + II; 7531 } 7532 } 7533 if (rank < size-1) { 7534 PetscCallMPI(MPI_Send(&env,1,MPIU_INT,rank+1,tag,comm)); 7535 PetscCallMPI(MPI_Send(&tbs,1,MPIU_INT,rank+1,tag,comm)); 7536 } 7537 7538 PetscCall(MatRestoreRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ia,&ja,&done)); 7539 if (!set || !flag) { 7540 PetscCall(MatDestroy(&AA)); 7541 } 7542 PetscCall(MatDestroy(&A)); 7543 7544 PetscCall(PetscNew(&edata)); 7545 PetscCall(MatGetNonzeroState(mat,&edata->nonzerostate)); 7546 edata->n = lblocks; 7547 /* create IS needed for extracting blocks from the original matrix */ 7548 PetscCall(PetscMalloc1(lblocks,&edata->is)); 7549 for (PetscInt i=0; i<lblocks; i++) { 7550 PetscCall(ISCreateStride(PETSC_COMM_SELF,sizes[i],starts[i],1,&edata->is[i])); 7551 } 7552 7553 /* Create the resulting inverse matrix structure with preallocation information */ 7554 PetscCall(MatCreate(PetscObjectComm((PetscObject)mat),&edata->C)); 7555 PetscCall(MatSetSizes(edata->C,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N)); 7556 PetscCall(MatSetBlockSizesFromMats(edata->C,mat,mat)); 7557 PetscCall(MatSetType(edata->C,MATAIJ)); 7558 7559 /* Communicate the start and end of each row, from each block to the correct rank */ 7560 /* TODO: Use PetscSF instead of VecScatter */ 7561 for (PetscInt i=0; i<lblocks; i++) ln += sizes[i]; 7562 PetscCall(VecCreateSeq(PETSC_COMM_SELF,2*ln,&seq)); 7563 PetscCall(VecGetArrayWrite(seq,&seqv)); 7564 for (PetscInt i=0; i<lblocks; i++) { 7565 for (PetscInt j=0; j<sizes[i]; j++) { 7566 seqv[cnt] = starts[i]; 7567 seqv[cnt+1] = starts[i] + sizes[i]; 7568 cnt += 2; 7569 } 7570 } 7571 PetscCall(VecRestoreArrayWrite(seq,&seqv)); 7572 PetscCallMPI(MPI_Scan(&cnt,&sc,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat))); 7573 sc -= cnt; 7574 PetscCall(VecCreateMPI(PetscObjectComm((PetscObject)mat),2*mat->rmap->n,2*mat->rmap->N,&par)); 7575 PetscCall(ISCreateStride(PETSC_COMM_SELF,cnt,sc,1,&isglobal)); 7576 PetscCall(VecScatterCreate(seq, NULL ,par, isglobal,&scatter)); 7577 PetscCall(ISDestroy(&isglobal)); 7578 PetscCall(VecScatterBegin(scatter,seq,par,INSERT_VALUES,SCATTER_FORWARD)); 7579 PetscCall(VecScatterEnd(scatter,seq,par,INSERT_VALUES,SCATTER_FORWARD)); 7580 PetscCall(VecScatterDestroy(&scatter)); 7581 PetscCall(VecDestroy(&seq)); 7582 PetscCall(MatGetOwnershipRangeColumn(mat,&cstart,&cend)); 7583 PetscCall(PetscMalloc2(mat->rmap->n,&diag,mat->rmap->n,&odiag)); 7584 PetscCall(VecGetArrayRead(par,&parv)); 7585 cnt = 0; 7586 PetscCall(MatGetSize(mat,NULL,&n)); 7587 for (PetscInt i=0; i<mat->rmap->n; i++) { 7588 PetscInt start,end,d = 0,od = 0; 7589 7590 start = (PetscInt)PetscRealPart(parv[cnt]); 7591 end = (PetscInt)PetscRealPart(parv[cnt+1]); 7592 cnt += 2; 7593 7594 if (start < cstart) {od += cstart - start + n - cend; d += cend - cstart;} 7595 else if (start < cend) {od += n - cend; d += cend - start;} 7596 else od += n - start; 7597 if (end <= cstart) {od -= cstart - end + n - cend; d -= cend - cstart;} 7598 else if (end < cend) {od -= n - cend; d -= cend - end;} 7599 else od -= n - end; 7600 7601 odiag[i] = od; 7602 diag[i] = d; 7603 } 7604 PetscCall(VecRestoreArrayRead(par,&parv)); 7605 PetscCall(VecDestroy(&par)); 7606 PetscCall(MatXAIJSetPreallocation(edata->C,mat->rmap->bs,diag,odiag,NULL,NULL)); 7607 PetscCall(PetscFree2(diag,odiag)); 7608 PetscCall(PetscFree2(sizes,starts)); 7609 7610 PetscCall(PetscContainerCreate(PETSC_COMM_SELF,&container)); 7611 PetscCall(PetscContainerSetPointer(container,edata)); 7612 PetscCall(PetscContainerSetUserDestroy(container,(PetscErrorCode (*)(void*))EnvelopeDataDestroy)); 7613 PetscCall(PetscObjectCompose((PetscObject)mat,"EnvelopeData",(PetscObject)container)); 7614 PetscCall(PetscObjectDereference((PetscObject)container)); 7615 PetscFunctionReturn(0); 7616 } 7617 7618 /*@ 7619 MatInvertVariableBlockEnvelope - set matrix C to be the inverted block diagonal of matrix A 7620 7621 Collective on Mat 7622 7623 Input Parameters: 7624 . A - the matrix 7625 7626 Output Parameters: 7627 . C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set. 7628 7629 Notes: 7630 For efficiency the matrix A should have all the nonzero entries clustered in smallish blocks along the diagonal. 7631 7632 Level: advanced 7633 7634 .seealso: MatInvertBlockDiagonal(), MatComputeBlockDiagonal() 7635 @*/ 7636 PetscErrorCode MatInvertVariableBlockEnvelope(Mat A,MatReuse reuse, Mat *C) 7637 { 7638 PetscContainer container; 7639 EnvelopeData *edata; 7640 PetscObjectState nonzerostate; 7641 7642 PetscFunctionBegin; 7643 PetscCall(PetscObjectQuery((PetscObject)A,"EnvelopeData",(PetscObject*)&container)); 7644 if (!container) { 7645 PetscCall(MatComputeVariableBlockEnvelope(A)); 7646 PetscCall(PetscObjectQuery((PetscObject)A,"EnvelopeData",(PetscObject*)&container)); 7647 } 7648 PetscCall(PetscContainerGetPointer(container,(void**)&edata)); 7649 PetscCall(MatGetNonzeroState(A,&nonzerostate)); 7650 PetscCheck(nonzerostate <= edata->nonzerostate,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Cannot handle changes to matrix nonzero structure"); 7651 PetscCheck(reuse != MAT_REUSE_MATRIX || *C == edata->C,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C matrix must be the same as previously output"); 7652 7653 PetscCall(MatCreateSubMatrices(A,edata->n,edata->is,edata->is,MAT_INITIAL_MATRIX,&edata->mat)); 7654 *C = edata->C; 7655 7656 for (PetscInt i=0; i<edata->n; i++) { 7657 Mat D; 7658 PetscScalar *dvalues; 7659 7660 PetscCall(MatConvert(edata->mat[i], MATSEQDENSE,MAT_INITIAL_MATRIX,&D)); 7661 PetscCall(MatSetOption(*C,MAT_ROW_ORIENTED,PETSC_FALSE)); 7662 PetscCall(MatSeqDenseInvert(D)); 7663 PetscCall(MatDenseGetArray(D,&dvalues)); 7664 PetscCall(MatSetValuesIS(*C,edata->is[i],edata->is[i],dvalues,INSERT_VALUES)); 7665 PetscCall(MatDestroy(&D)); 7666 } 7667 PetscCall(MatDestroySubMatrices(edata->n,&edata->mat)); 7668 PetscCall(MatAssemblyBegin(*C,MAT_FINAL_ASSEMBLY)); 7669 PetscCall(MatAssemblyEnd(*C,MAT_FINAL_ASSEMBLY)); 7670 PetscFunctionReturn(0); 7671 } 7672 7673 /*@ 7674 MatSetVariableBlockSizes - Sets diagonal point-blocks of the matrix that need not be of the same size 7675 7676 Logically Collective on Mat 7677 7678 Input Parameters: 7679 + mat - the matrix 7680 . nblocks - the number of blocks on this process, each block can only exist on a single process 7681 - bsizes - the block sizes 7682 7683 Notes: 7684 Currently used by PCVPBJACOBI for AIJ matrices 7685 7686 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. 7687 7688 Level: intermediate 7689 7690 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`, `MatGetBlockSizes()`, `MatGetVariableBlockSizes()`, `MatComputeVariableBlockEnvelope()`, `PCVPBJACOBI` 7691 @*/ 7692 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes) 7693 { 7694 PetscInt i,ncnt = 0, nlocal; 7695 7696 PetscFunctionBegin; 7697 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7698 PetscCheck(nblocks >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero"); 7699 PetscCall(MatGetLocalSize(mat,&nlocal,NULL)); 7700 for (i=0; i<nblocks; i++) ncnt += bsizes[i]; 7701 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); 7702 PetscCall(PetscFree(mat->bsizes)); 7703 mat->nblocks = nblocks; 7704 PetscCall(PetscMalloc1(nblocks,&mat->bsizes)); 7705 PetscCall(PetscArraycpy(mat->bsizes,bsizes,nblocks)); 7706 PetscFunctionReturn(0); 7707 } 7708 7709 /*@C 7710 MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size 7711 7712 Logically Collective on Mat 7713 7714 Input Parameter: 7715 . mat - the matrix 7716 7717 Output Parameters: 7718 + nblocks - the number of blocks on this process 7719 - bsizes - the block sizes 7720 7721 Notes: Currently not supported from Fortran 7722 7723 Level: intermediate 7724 7725 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`, `MatGetBlockSizes()`, `MatSetVariableBlockSizes()`, `MatComputeVariableBlockEnvelope()` 7726 @*/ 7727 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes) 7728 { 7729 PetscFunctionBegin; 7730 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7731 *nblocks = mat->nblocks; 7732 *bsizes = mat->bsizes; 7733 PetscFunctionReturn(0); 7734 } 7735 7736 /*@ 7737 MatSetBlockSizes - Sets the matrix block row and column sizes. 7738 7739 Logically Collective on Mat 7740 7741 Input Parameters: 7742 + mat - the matrix 7743 . rbs - row block size 7744 - cbs - column block size 7745 7746 Notes: 7747 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7748 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7749 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7750 7751 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes 7752 are compatible with the matrix local sizes. 7753 7754 The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs(). 7755 7756 Level: intermediate 7757 7758 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSize()`, `MatGetBlockSizes()` 7759 @*/ 7760 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs) 7761 { 7762 PetscFunctionBegin; 7763 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7764 PetscValidLogicalCollectiveInt(mat,rbs,2); 7765 PetscValidLogicalCollectiveInt(mat,cbs,3); 7766 if (mat->ops->setblocksizes) PetscCall((*mat->ops->setblocksizes)(mat,rbs,cbs)); 7767 if (mat->rmap->refcnt) { 7768 ISLocalToGlobalMapping l2g = NULL; 7769 PetscLayout nmap = NULL; 7770 7771 PetscCall(PetscLayoutDuplicate(mat->rmap,&nmap)); 7772 if (mat->rmap->mapping) { 7773 PetscCall(ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g)); 7774 } 7775 PetscCall(PetscLayoutDestroy(&mat->rmap)); 7776 mat->rmap = nmap; 7777 mat->rmap->mapping = l2g; 7778 } 7779 if (mat->cmap->refcnt) { 7780 ISLocalToGlobalMapping l2g = NULL; 7781 PetscLayout nmap = NULL; 7782 7783 PetscCall(PetscLayoutDuplicate(mat->cmap,&nmap)); 7784 if (mat->cmap->mapping) { 7785 PetscCall(ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g)); 7786 } 7787 PetscCall(PetscLayoutDestroy(&mat->cmap)); 7788 mat->cmap = nmap; 7789 mat->cmap->mapping = l2g; 7790 } 7791 PetscCall(PetscLayoutSetBlockSize(mat->rmap,rbs)); 7792 PetscCall(PetscLayoutSetBlockSize(mat->cmap,cbs)); 7793 PetscFunctionReturn(0); 7794 } 7795 7796 /*@ 7797 MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices 7798 7799 Logically Collective on Mat 7800 7801 Input Parameters: 7802 + mat - the matrix 7803 . fromRow - matrix from which to copy row block size 7804 - fromCol - matrix from which to copy column block size (can be same as fromRow) 7805 7806 Level: developer 7807 7808 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()` 7809 @*/ 7810 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol) 7811 { 7812 PetscFunctionBegin; 7813 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7814 PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2); 7815 PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3); 7816 if (fromRow->rmap->bs > 0) PetscCall(PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs)); 7817 if (fromCol->cmap->bs > 0) PetscCall(PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs)); 7818 PetscFunctionReturn(0); 7819 } 7820 7821 /*@ 7822 MatResidual - Default routine to calculate the residual. 7823 7824 Collective on Mat 7825 7826 Input Parameters: 7827 + mat - the matrix 7828 . b - the right-hand-side 7829 - x - the approximate solution 7830 7831 Output Parameter: 7832 . r - location to store the residual 7833 7834 Level: developer 7835 7836 .seealso: `PCMGSetResidual()` 7837 @*/ 7838 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r) 7839 { 7840 PetscFunctionBegin; 7841 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7842 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 7843 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 7844 PetscValidHeaderSpecific(r,VEC_CLASSID,4); 7845 PetscValidType(mat,1); 7846 MatCheckPreallocated(mat,1); 7847 PetscCall(PetscLogEventBegin(MAT_Residual,mat,0,0,0)); 7848 if (!mat->ops->residual) { 7849 PetscCall(MatMult(mat,x,r)); 7850 PetscCall(VecAYPX(r,-1.0,b)); 7851 } else { 7852 PetscCall((*mat->ops->residual)(mat,b,x,r)); 7853 } 7854 PetscCall(PetscLogEventEnd(MAT_Residual,mat,0,0,0)); 7855 PetscFunctionReturn(0); 7856 } 7857 7858 /*@C 7859 MatGetRowIJ - Returns the compressed row storage i and j indices for the local rows of a sparse matrix 7860 7861 Collective on Mat 7862 7863 Input Parameters: 7864 + mat - the matrix 7865 . shift - 0 or 1 indicating we want the indices starting at 0 or 1 7866 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized 7867 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7868 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7869 always used. 7870 7871 Output Parameters: 7872 + n - number of local rows in the (possibly compressed) matrix 7873 . ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix 7874 . ja - the column indices 7875 - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers 7876 are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set 7877 7878 Level: developer 7879 7880 Notes: 7881 You CANNOT change any of the ia[] or ja[] values. 7882 7883 Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values. 7884 7885 Fortran Notes: 7886 In Fortran use 7887 $ 7888 $ PetscInt ia(1), ja(1) 7889 $ PetscOffset iia, jja 7890 $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr) 7891 $ ! Access the ith and jth entries via ia(iia + i) and ja(jja + j) 7892 7893 or 7894 $ 7895 $ PetscInt, pointer :: ia(:),ja(:) 7896 $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr) 7897 $ ! Access the ith and jth entries via ia(i) and ja(j) 7898 7899 .seealso: `MatGetColumnIJ()`, `MatRestoreRowIJ()`, `MatSeqAIJGetArray()` 7900 @*/ 7901 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7902 { 7903 PetscFunctionBegin; 7904 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7905 PetscValidType(mat,1); 7906 if (n) PetscValidIntPointer(n,5); 7907 if (ia) PetscValidPointer(ia,6); 7908 if (ja) PetscValidPointer(ja,7); 7909 if (done) PetscValidBoolPointer(done,8); 7910 MatCheckPreallocated(mat,1); 7911 if (!mat->ops->getrowij && done) *done = PETSC_FALSE; 7912 else { 7913 if (done) *done = PETSC_TRUE; 7914 PetscCall(PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0)); 7915 PetscCall((*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done)); 7916 PetscCall(PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0)); 7917 } 7918 PetscFunctionReturn(0); 7919 } 7920 7921 /*@C 7922 MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices. 7923 7924 Collective on Mat 7925 7926 Input Parameters: 7927 + mat - the matrix 7928 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7929 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7930 symmetrized 7931 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7932 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7933 always used. 7934 . n - number of columns in the (possibly compressed) matrix 7935 . ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix 7936 - ja - the row indices 7937 7938 Output Parameters: 7939 . done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned 7940 7941 Level: developer 7942 7943 .seealso: `MatGetRowIJ()`, `MatRestoreColumnIJ()` 7944 @*/ 7945 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7946 { 7947 PetscFunctionBegin; 7948 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7949 PetscValidType(mat,1); 7950 PetscValidIntPointer(n,5); 7951 if (ia) PetscValidPointer(ia,6); 7952 if (ja) PetscValidPointer(ja,7); 7953 PetscValidBoolPointer(done,8); 7954 MatCheckPreallocated(mat,1); 7955 if (!mat->ops->getcolumnij) *done = PETSC_FALSE; 7956 else { 7957 *done = PETSC_TRUE; 7958 PetscCall((*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done)); 7959 } 7960 PetscFunctionReturn(0); 7961 } 7962 7963 /*@C 7964 MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with 7965 MatGetRowIJ(). 7966 7967 Collective on Mat 7968 7969 Input Parameters: 7970 + mat - the matrix 7971 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7972 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7973 symmetrized 7974 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7975 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7976 always used. 7977 . n - size of (possibly compressed) matrix 7978 . ia - the row pointers 7979 - ja - the column indices 7980 7981 Output Parameters: 7982 . done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7983 7984 Note: 7985 This routine zeros out n, ia, and ja. This is to prevent accidental 7986 us of the array after it has been restored. If you pass NULL, it will 7987 not zero the pointers. Use of ia or ja after MatRestoreRowIJ() is invalid. 7988 7989 Level: developer 7990 7991 .seealso: `MatGetRowIJ()`, `MatRestoreColumnIJ()` 7992 @*/ 7993 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7994 { 7995 PetscFunctionBegin; 7996 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7997 PetscValidType(mat,1); 7998 if (ia) PetscValidPointer(ia,6); 7999 if (ja) PetscValidPointer(ja,7); 8000 if (done) PetscValidBoolPointer(done,8); 8001 MatCheckPreallocated(mat,1); 8002 8003 if (!mat->ops->restorerowij && done) *done = PETSC_FALSE; 8004 else { 8005 if (done) *done = PETSC_TRUE; 8006 PetscCall((*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done)); 8007 if (n) *n = 0; 8008 if (ia) *ia = NULL; 8009 if (ja) *ja = NULL; 8010 } 8011 PetscFunctionReturn(0); 8012 } 8013 8014 /*@C 8015 MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with 8016 MatGetColumnIJ(). 8017 8018 Collective on Mat 8019 8020 Input Parameters: 8021 + mat - the matrix 8022 . shift - 1 or zero indicating we want the indices starting at 0 or 1 8023 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 8024 symmetrized 8025 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 8026 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 8027 always used. 8028 8029 Output Parameters: 8030 + n - size of (possibly compressed) matrix 8031 . ia - the column pointers 8032 . ja - the row indices 8033 - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 8034 8035 Level: developer 8036 8037 .seealso: `MatGetColumnIJ()`, `MatRestoreRowIJ()` 8038 @*/ 8039 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 8040 { 8041 PetscFunctionBegin; 8042 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8043 PetscValidType(mat,1); 8044 if (ia) PetscValidPointer(ia,6); 8045 if (ja) PetscValidPointer(ja,7); 8046 PetscValidBoolPointer(done,8); 8047 MatCheckPreallocated(mat,1); 8048 8049 if (!mat->ops->restorecolumnij) *done = PETSC_FALSE; 8050 else { 8051 *done = PETSC_TRUE; 8052 PetscCall((*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done)); 8053 if (n) *n = 0; 8054 if (ia) *ia = NULL; 8055 if (ja) *ja = NULL; 8056 } 8057 PetscFunctionReturn(0); 8058 } 8059 8060 /*@C 8061 MatColoringPatch -Used inside matrix coloring routines that 8062 use MatGetRowIJ() and/or MatGetColumnIJ(). 8063 8064 Collective on Mat 8065 8066 Input Parameters: 8067 + mat - the matrix 8068 . ncolors - max color value 8069 . n - number of entries in colorarray 8070 - colorarray - array indicating color for each column 8071 8072 Output Parameters: 8073 . iscoloring - coloring generated using colorarray information 8074 8075 Level: developer 8076 8077 .seealso: `MatGetRowIJ()`, `MatGetColumnIJ()` 8078 8079 @*/ 8080 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring) 8081 { 8082 PetscFunctionBegin; 8083 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8084 PetscValidType(mat,1); 8085 PetscValidIntPointer(colorarray,4); 8086 PetscValidPointer(iscoloring,5); 8087 MatCheckPreallocated(mat,1); 8088 8089 if (!mat->ops->coloringpatch) { 8090 PetscCall(ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring)); 8091 } else { 8092 PetscCall((*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring)); 8093 } 8094 PetscFunctionReturn(0); 8095 } 8096 8097 /*@ 8098 MatSetUnfactored - Resets a factored matrix to be treated as unfactored. 8099 8100 Logically Collective on Mat 8101 8102 Input Parameter: 8103 . mat - the factored matrix to be reset 8104 8105 Notes: 8106 This routine should be used only with factored matrices formed by in-place 8107 factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE 8108 format). This option can save memory, for example, when solving nonlinear 8109 systems with a matrix-free Newton-Krylov method and a matrix-based, in-place 8110 ILU(0) preconditioner. 8111 8112 Note that one can specify in-place ILU(0) factorization by calling 8113 .vb 8114 PCType(pc,PCILU); 8115 PCFactorSeUseInPlace(pc); 8116 .ve 8117 or by using the options -pc_type ilu -pc_factor_in_place 8118 8119 In-place factorization ILU(0) can also be used as a local 8120 solver for the blocks within the block Jacobi or additive Schwarz 8121 methods (runtime option: -sub_pc_factor_in_place). See Users-Manual: ch_pc 8122 for details on setting local solver options. 8123 8124 Most users should employ the simplified KSP interface for linear solvers 8125 instead of working directly with matrix algebra routines such as this. 8126 See, e.g., KSPCreate(). 8127 8128 Level: developer 8129 8130 .seealso: `PCFactorSetUseInPlace()`, `PCFactorGetUseInPlace()` 8131 8132 @*/ 8133 PetscErrorCode MatSetUnfactored(Mat mat) 8134 { 8135 PetscFunctionBegin; 8136 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8137 PetscValidType(mat,1); 8138 MatCheckPreallocated(mat,1); 8139 mat->factortype = MAT_FACTOR_NONE; 8140 if (!mat->ops->setunfactored) PetscFunctionReturn(0); 8141 PetscCall((*mat->ops->setunfactored)(mat)); 8142 PetscFunctionReturn(0); 8143 } 8144 8145 /*MC 8146 MatDenseGetArrayF90 - Accesses a matrix array from Fortran90. 8147 8148 Synopsis: 8149 MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 8150 8151 Not collective 8152 8153 Input Parameter: 8154 . x - matrix 8155 8156 Output Parameters: 8157 + xx_v - the Fortran90 pointer to the array 8158 - ierr - error code 8159 8160 Example of Usage: 8161 .vb 8162 PetscScalar, pointer xx_v(:,:) 8163 .... 8164 call MatDenseGetArrayF90(x,xx_v,ierr) 8165 a = xx_v(3) 8166 call MatDenseRestoreArrayF90(x,xx_v,ierr) 8167 .ve 8168 8169 Level: advanced 8170 8171 .seealso: `MatDenseRestoreArrayF90()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatSeqAIJGetArrayF90()` 8172 8173 M*/ 8174 8175 /*MC 8176 MatDenseRestoreArrayF90 - Restores a matrix array that has been 8177 accessed with MatDenseGetArrayF90(). 8178 8179 Synopsis: 8180 MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 8181 8182 Not collective 8183 8184 Input Parameters: 8185 + x - matrix 8186 - xx_v - the Fortran90 pointer to the array 8187 8188 Output Parameter: 8189 . ierr - error code 8190 8191 Example of Usage: 8192 .vb 8193 PetscScalar, pointer xx_v(:,:) 8194 .... 8195 call MatDenseGetArrayF90(x,xx_v,ierr) 8196 a = xx_v(3) 8197 call MatDenseRestoreArrayF90(x,xx_v,ierr) 8198 .ve 8199 8200 Level: advanced 8201 8202 .seealso: `MatDenseGetArrayF90()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatSeqAIJRestoreArrayF90()` 8203 8204 M*/ 8205 8206 /*MC 8207 MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90. 8208 8209 Synopsis: 8210 MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 8211 8212 Not collective 8213 8214 Input Parameter: 8215 . x - matrix 8216 8217 Output Parameters: 8218 + xx_v - the Fortran90 pointer to the array 8219 - ierr - error code 8220 8221 Example of Usage: 8222 .vb 8223 PetscScalar, pointer xx_v(:) 8224 .... 8225 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 8226 a = xx_v(3) 8227 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 8228 .ve 8229 8230 Level: advanced 8231 8232 .seealso: `MatSeqAIJRestoreArrayF90()`, `MatSeqAIJGetArray()`, `MatSeqAIJRestoreArray()`, `MatDenseGetArrayF90()` 8233 8234 M*/ 8235 8236 /*MC 8237 MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been 8238 accessed with MatSeqAIJGetArrayF90(). 8239 8240 Synopsis: 8241 MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 8242 8243 Not collective 8244 8245 Input Parameters: 8246 + x - matrix 8247 - xx_v - the Fortran90 pointer to the array 8248 8249 Output Parameter: 8250 . ierr - error code 8251 8252 Example of Usage: 8253 .vb 8254 PetscScalar, pointer xx_v(:) 8255 .... 8256 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 8257 a = xx_v(3) 8258 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 8259 .ve 8260 8261 Level: advanced 8262 8263 .seealso: `MatSeqAIJGetArrayF90()`, `MatSeqAIJGetArray()`, `MatSeqAIJRestoreArray()`, `MatDenseRestoreArrayF90()` 8264 8265 M*/ 8266 8267 /*@ 8268 MatCreateSubMatrix - Gets a single submatrix on the same number of processors 8269 as the original matrix. 8270 8271 Collective on Mat 8272 8273 Input Parameters: 8274 + mat - the original matrix 8275 . isrow - parallel IS containing the rows this processor should obtain 8276 . 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. 8277 - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 8278 8279 Output Parameter: 8280 . newmat - the new submatrix, of the same type as the old 8281 8282 Level: advanced 8283 8284 Notes: 8285 The submatrix will be able to be multiplied with vectors using the same layout as iscol. 8286 8287 Some matrix types place restrictions on the row and column indices, such 8288 as that they be sorted or that they be equal to each other. 8289 8290 The index sets may not have duplicate entries. 8291 8292 The first time this is called you should use a cll of MAT_INITIAL_MATRIX, 8293 the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls 8294 to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX 8295 will reuse the matrix generated the first time. You should call MatDestroy() on newmat when 8296 you are finished using it. 8297 8298 The communicator of the newly obtained matrix is ALWAYS the same as the communicator of 8299 the input matrix. 8300 8301 If iscol is NULL then all columns are obtained (not supported in Fortran). 8302 8303 Example usage: 8304 Consider the following 8x8 matrix with 34 non-zero values, that is 8305 assembled across 3 processors. Let's assume that proc0 owns 3 rows, 8306 proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown 8307 as follows: 8308 8309 .vb 8310 1 2 0 | 0 3 0 | 0 4 8311 Proc0 0 5 6 | 7 0 0 | 8 0 8312 9 0 10 | 11 0 0 | 12 0 8313 ------------------------------------- 8314 13 0 14 | 15 16 17 | 0 0 8315 Proc1 0 18 0 | 19 20 21 | 0 0 8316 0 0 0 | 22 23 0 | 24 0 8317 ------------------------------------- 8318 Proc2 25 26 27 | 0 0 28 | 29 0 8319 30 0 0 | 31 32 33 | 0 34 8320 .ve 8321 8322 Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is 8323 8324 .vb 8325 2 0 | 0 3 0 | 0 8326 Proc0 5 6 | 7 0 0 | 8 8327 ------------------------------- 8328 Proc1 18 0 | 19 20 21 | 0 8329 ------------------------------- 8330 Proc2 26 27 | 0 0 28 | 29 8331 0 0 | 31 32 33 | 0 8332 .ve 8333 8334 .seealso: `MatCreateSubMatrices()`, `MatCreateSubMatricesMPI()`, `MatCreateSubMatrixVirtual()`, `MatSubMatrixVirtualUpdate()` 8335 @*/ 8336 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat) 8337 { 8338 PetscMPIInt size; 8339 Mat *local; 8340 IS iscoltmp; 8341 PetscBool flg; 8342 8343 PetscFunctionBegin; 8344 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8345 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 8346 if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 8347 PetscValidPointer(newmat,5); 8348 if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5); 8349 PetscValidType(mat,1); 8350 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8351 PetscCheck(cll != MAT_IGNORE_MATRIX,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX"); 8352 8353 MatCheckPreallocated(mat,1); 8354 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 8355 8356 if (!iscol || isrow == iscol) { 8357 PetscBool stride; 8358 PetscMPIInt grabentirematrix = 0,grab; 8359 PetscCall(PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride)); 8360 if (stride) { 8361 PetscInt first,step,n,rstart,rend; 8362 PetscCall(ISStrideGetInfo(isrow,&first,&step)); 8363 if (step == 1) { 8364 PetscCall(MatGetOwnershipRange(mat,&rstart,&rend)); 8365 if (rstart == first) { 8366 PetscCall(ISGetLocalSize(isrow,&n)); 8367 if (n == rend-rstart) { 8368 grabentirematrix = 1; 8369 } 8370 } 8371 } 8372 } 8373 PetscCall(MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat))); 8374 if (grab) { 8375 PetscCall(PetscInfo(mat,"Getting entire matrix as submatrix\n")); 8376 if (cll == MAT_INITIAL_MATRIX) { 8377 *newmat = mat; 8378 PetscCall(PetscObjectReference((PetscObject)mat)); 8379 } 8380 PetscFunctionReturn(0); 8381 } 8382 } 8383 8384 if (!iscol) { 8385 PetscCall(ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp)); 8386 } else { 8387 iscoltmp = iscol; 8388 } 8389 8390 /* if original matrix is on just one processor then use submatrix generated */ 8391 if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) { 8392 PetscCall(MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat)); 8393 goto setproperties; 8394 } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) { 8395 PetscCall(MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local)); 8396 *newmat = *local; 8397 PetscCall(PetscFree(local)); 8398 goto setproperties; 8399 } else if (!mat->ops->createsubmatrix) { 8400 /* Create a new matrix type that implements the operation using the full matrix */ 8401 PetscCall(PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0)); 8402 switch (cll) { 8403 case MAT_INITIAL_MATRIX: 8404 PetscCall(MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat)); 8405 break; 8406 case MAT_REUSE_MATRIX: 8407 PetscCall(MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp)); 8408 break; 8409 default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX"); 8410 } 8411 PetscCall(PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0)); 8412 goto setproperties; 8413 } 8414 8415 PetscCheck(mat->ops->createsubmatrix,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8416 PetscCall(PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0)); 8417 PetscCall((*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat)); 8418 PetscCall(PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0)); 8419 8420 setproperties: 8421 PetscCall(ISEqualUnsorted(isrow,iscoltmp,&flg)); 8422 if (flg) PetscCall(MatPropagateSymmetryOptions(mat,*newmat)); 8423 if (!iscol) PetscCall(ISDestroy(&iscoltmp)); 8424 if (*newmat && cll == MAT_INITIAL_MATRIX) PetscCall(PetscObjectStateIncrease((PetscObject)*newmat)); 8425 PetscFunctionReturn(0); 8426 } 8427 8428 /*@ 8429 MatPropagateSymmetryOptions - Propagates symmetry options set on a matrix to another matrix 8430 8431 Not Collective 8432 8433 Input Parameters: 8434 + A - the matrix we wish to propagate options from 8435 - B - the matrix we wish to propagate options to 8436 8437 Level: beginner 8438 8439 Notes: 8440 Propagates the options associated to `MAT_SYMMETRY_ETERNAL`, `MAT_STRUCTURALLY_SYMMETRIC`, `MAT_HERMITIAN`, `MAT_SPD`, `MAT_SYMMETRIC`, and `MAT_STRUCTURAL_SYMMETRY_ETERNAL` 8441 8442 .seealso: `MatSetOption()`, `MatIsSymmetricKnown()`, `MatIsSPDKnown()`, `MatIsHermitianKnown()`, MatIsStructurallySymmetricKnown()` 8443 @*/ 8444 PetscErrorCode MatPropagateSymmetryOptions(Mat A, Mat B) 8445 { 8446 PetscFunctionBegin; 8447 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8448 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 8449 B->symmetry_eternal = A->symmetry_eternal; 8450 B->structural_symmetry_eternal = A->structural_symmetry_eternal; 8451 B->symmetric = A->symmetric; 8452 B->structurally_symmetric = A->structurally_symmetric; 8453 B->spd = A->spd; 8454 B->hermitian = A->hermitian; 8455 PetscFunctionReturn(0); 8456 } 8457 8458 /*@ 8459 MatStashSetInitialSize - sets the sizes of the matrix stash, that is 8460 used during the assembly process to store values that belong to 8461 other processors. 8462 8463 Not Collective 8464 8465 Input Parameters: 8466 + mat - the matrix 8467 . size - the initial size of the stash. 8468 - bsize - the initial size of the block-stash(if used). 8469 8470 Options Database Keys: 8471 + -matstash_initial_size <size> or <size0,size1,...sizep-1> 8472 - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1> 8473 8474 Level: intermediate 8475 8476 Notes: 8477 The block-stash is used for values set with MatSetValuesBlocked() while 8478 the stash is used for values set with MatSetValues() 8479 8480 Run with the option -info and look for output of the form 8481 MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs. 8482 to determine the appropriate value, MM, to use for size and 8483 MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs. 8484 to determine the value, BMM to use for bsize 8485 8486 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `Mat`, `MatStashGetInfo()` 8487 8488 @*/ 8489 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize) 8490 { 8491 PetscFunctionBegin; 8492 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8493 PetscValidType(mat,1); 8494 PetscCall(MatStashSetInitialSize_Private(&mat->stash,size)); 8495 PetscCall(MatStashSetInitialSize_Private(&mat->bstash,bsize)); 8496 PetscFunctionReturn(0); 8497 } 8498 8499 /*@ 8500 MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 8501 the matrix 8502 8503 Neighbor-wise Collective on Mat 8504 8505 Input Parameters: 8506 + mat - the matrix 8507 . x,y - the vectors 8508 - w - where the result is stored 8509 8510 Level: intermediate 8511 8512 Notes: 8513 w may be the same vector as y. 8514 8515 This allows one to use either the restriction or interpolation (its transpose) 8516 matrix to do the interpolation 8517 8518 .seealso: `MatMultAdd()`, `MatMultTransposeAdd()`, `MatRestrict()` 8519 8520 @*/ 8521 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w) 8522 { 8523 PetscInt M,N,Ny; 8524 8525 PetscFunctionBegin; 8526 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8527 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8528 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8529 PetscValidHeaderSpecific(w,VEC_CLASSID,4); 8530 PetscCall(MatGetSize(A,&M,&N)); 8531 PetscCall(VecGetSize(y,&Ny)); 8532 if (M == Ny) { 8533 PetscCall(MatMultAdd(A,x,y,w)); 8534 } else { 8535 PetscCall(MatMultTransposeAdd(A,x,y,w)); 8536 } 8537 PetscFunctionReturn(0); 8538 } 8539 8540 /*@ 8541 MatInterpolate - y = A*x or A'*x depending on the shape of 8542 the matrix 8543 8544 Neighbor-wise Collective on Mat 8545 8546 Input Parameters: 8547 + mat - the matrix 8548 - x,y - the vectors 8549 8550 Level: intermediate 8551 8552 Notes: 8553 This allows one to use either the restriction or interpolation (its transpose) 8554 matrix to do the interpolation 8555 8556 .seealso: `MatMultAdd()`, `MatMultTransposeAdd()`, `MatRestrict()` 8557 8558 @*/ 8559 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y) 8560 { 8561 PetscInt M,N,Ny; 8562 8563 PetscFunctionBegin; 8564 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8565 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8566 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8567 PetscCall(MatGetSize(A,&M,&N)); 8568 PetscCall(VecGetSize(y,&Ny)); 8569 if (M == Ny) { 8570 PetscCall(MatMult(A,x,y)); 8571 } else { 8572 PetscCall(MatMultTranspose(A,x,y)); 8573 } 8574 PetscFunctionReturn(0); 8575 } 8576 8577 /*@ 8578 MatRestrict - y = A*x or A'*x 8579 8580 Neighbor-wise Collective on Mat 8581 8582 Input Parameters: 8583 + mat - the matrix 8584 - x,y - the vectors 8585 8586 Level: intermediate 8587 8588 Notes: 8589 This allows one to use either the restriction or interpolation (its transpose) 8590 matrix to do the restriction 8591 8592 .seealso: `MatMultAdd()`, `MatMultTransposeAdd()`, `MatInterpolate()` 8593 8594 @*/ 8595 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y) 8596 { 8597 PetscInt M,N,Ny; 8598 8599 PetscFunctionBegin; 8600 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8601 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8602 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8603 PetscCall(MatGetSize(A,&M,&N)); 8604 PetscCall(VecGetSize(y,&Ny)); 8605 if (M == Ny) { 8606 PetscCall(MatMult(A,x,y)); 8607 } else { 8608 PetscCall(MatMultTranspose(A,x,y)); 8609 } 8610 PetscFunctionReturn(0); 8611 } 8612 8613 /*@ 8614 MatMatInterpolateAdd - Y = W + A*X or W + A'*X 8615 8616 Neighbor-wise Collective on Mat 8617 8618 Input Parameters: 8619 + mat - the matrix 8620 - w, x - the input dense matrices 8621 8622 Output Parameters: 8623 . y - the output dense matrix 8624 8625 Level: intermediate 8626 8627 Notes: 8628 This allows one to use either the restriction or interpolation (its transpose) 8629 matrix to do the interpolation. y matrix can be reused if already created with the proper sizes, 8630 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8631 8632 .seealso: `MatInterpolateAdd()`, `MatMatInterpolate()`, `MatMatRestrict()` 8633 8634 @*/ 8635 PetscErrorCode MatMatInterpolateAdd(Mat A,Mat x,Mat w,Mat *y) 8636 { 8637 PetscInt M,N,Mx,Nx,Mo,My = 0,Ny = 0; 8638 PetscBool trans = PETSC_TRUE; 8639 MatReuse reuse = MAT_INITIAL_MATRIX; 8640 8641 PetscFunctionBegin; 8642 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8643 PetscValidHeaderSpecific(x,MAT_CLASSID,2); 8644 PetscValidType(x,2); 8645 if (w) PetscValidHeaderSpecific(w,MAT_CLASSID,3); 8646 if (*y) PetscValidHeaderSpecific(*y,MAT_CLASSID,4); 8647 PetscCall(MatGetSize(A,&M,&N)); 8648 PetscCall(MatGetSize(x,&Mx,&Nx)); 8649 if (N == Mx) trans = PETSC_FALSE; 8650 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); 8651 Mo = trans ? N : M; 8652 if (*y) { 8653 PetscCall(MatGetSize(*y,&My,&Ny)); 8654 if (Mo == My && Nx == Ny) { reuse = MAT_REUSE_MATRIX; } 8655 else { 8656 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); 8657 PetscCall(MatDestroy(y)); 8658 } 8659 } 8660 8661 if (w && *y == w) { /* this is to minimize changes in PCMG */ 8662 PetscBool flg; 8663 8664 PetscCall(PetscObjectQuery((PetscObject)*y,"__MatMatIntAdd_w",(PetscObject*)&w)); 8665 if (w) { 8666 PetscInt My,Ny,Mw,Nw; 8667 8668 PetscCall(PetscObjectTypeCompare((PetscObject)*y,((PetscObject)w)->type_name,&flg)); 8669 PetscCall(MatGetSize(*y,&My,&Ny)); 8670 PetscCall(MatGetSize(w,&Mw,&Nw)); 8671 if (!flg || My != Mw || Ny != Nw) w = NULL; 8672 } 8673 if (!w) { 8674 PetscCall(MatDuplicate(*y,MAT_COPY_VALUES,&w)); 8675 PetscCall(PetscObjectCompose((PetscObject)*y,"__MatMatIntAdd_w",(PetscObject)w)); 8676 PetscCall(PetscLogObjectParent((PetscObject)*y,(PetscObject)w)); 8677 PetscCall(PetscObjectDereference((PetscObject)w)); 8678 } else { 8679 PetscCall(MatCopy(*y,w,UNKNOWN_NONZERO_PATTERN)); 8680 } 8681 } 8682 if (!trans) { 8683 PetscCall(MatMatMult(A,x,reuse,PETSC_DEFAULT,y)); 8684 } else { 8685 PetscCall(MatTransposeMatMult(A,x,reuse,PETSC_DEFAULT,y)); 8686 } 8687 if (w) PetscCall(MatAXPY(*y,1.0,w,UNKNOWN_NONZERO_PATTERN)); 8688 PetscFunctionReturn(0); 8689 } 8690 8691 /*@ 8692 MatMatInterpolate - Y = A*X or A'*X 8693 8694 Neighbor-wise Collective on Mat 8695 8696 Input Parameters: 8697 + mat - the matrix 8698 - x - the input dense matrix 8699 8700 Output Parameters: 8701 . y - the output dense matrix 8702 8703 Level: intermediate 8704 8705 Notes: 8706 This allows one to use either the restriction or interpolation (its transpose) 8707 matrix to do the interpolation. y matrix can be reused if already created with the proper sizes, 8708 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8709 8710 .seealso: `MatInterpolate()`, `MatRestrict()`, `MatMatRestrict()` 8711 8712 @*/ 8713 PetscErrorCode MatMatInterpolate(Mat A,Mat x,Mat *y) 8714 { 8715 PetscFunctionBegin; 8716 PetscCall(MatMatInterpolateAdd(A,x,NULL,y)); 8717 PetscFunctionReturn(0); 8718 } 8719 8720 /*@ 8721 MatMatRestrict - Y = A*X or A'*X 8722 8723 Neighbor-wise Collective on Mat 8724 8725 Input Parameters: 8726 + mat - the matrix 8727 - x - the input dense matrix 8728 8729 Output Parameters: 8730 . y - the output dense matrix 8731 8732 Level: intermediate 8733 8734 Notes: 8735 This allows one to use either the restriction or interpolation (its transpose) 8736 matrix to do the restriction. y matrix can be reused if already created with the proper sizes, 8737 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8738 8739 .seealso: `MatRestrict()`, `MatInterpolate()`, `MatMatInterpolate()` 8740 @*/ 8741 PetscErrorCode MatMatRestrict(Mat A,Mat x,Mat *y) 8742 { 8743 PetscFunctionBegin; 8744 PetscCall(MatMatInterpolateAdd(A,x,NULL,y)); 8745 PetscFunctionReturn(0); 8746 } 8747 8748 /*@ 8749 MatGetNullSpace - retrieves the null space of a matrix. 8750 8751 Logically Collective on Mat 8752 8753 Input Parameters: 8754 + mat - the matrix 8755 - nullsp - the null space object 8756 8757 Level: developer 8758 8759 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatSetNullSpace()` 8760 @*/ 8761 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp) 8762 { 8763 PetscFunctionBegin; 8764 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8765 PetscValidPointer(nullsp,2); 8766 *nullsp = (mat->symmetric == PETSC_BOOL3_TRUE && !mat->nullsp) ? mat->transnullsp : mat->nullsp; 8767 PetscFunctionReturn(0); 8768 } 8769 8770 /*@ 8771 MatSetNullSpace - attaches a null space to a matrix. 8772 8773 Logically Collective on Mat 8774 8775 Input Parameters: 8776 + mat - the matrix 8777 - nullsp - the null space object 8778 8779 Level: advanced 8780 8781 Notes: 8782 This null space is used by the KSP linear solvers to solve singular systems. 8783 8784 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 8785 8786 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 8787 to zero but the linear system will still be solved in a least squares sense. 8788 8789 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8790 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). 8791 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 8792 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 8793 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). 8794 This \hat{b} can be obtained by calling MatNullSpaceRemove() with the null space of the transpose of the matrix. 8795 8796 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 8797 routine also automatically calls MatSetTransposeNullSpace(). 8798 8799 The user should call `MatNullSpaceDestroy()`. 8800 8801 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatGetNullSpace()`, `MatSetTransposeNullSpace()`, `MatGetTransposeNullSpace()`, `MatNullSpaceRemove()`, 8802 `KSPSetPCSide()` 8803 @*/ 8804 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp) 8805 { 8806 PetscFunctionBegin; 8807 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8808 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8809 if (nullsp) PetscCall(PetscObjectReference((PetscObject)nullsp)); 8810 PetscCall(MatNullSpaceDestroy(&mat->nullsp)); 8811 mat->nullsp = nullsp; 8812 if (mat->symmetric == PETSC_BOOL3_TRUE) { 8813 PetscCall(MatSetTransposeNullSpace(mat,nullsp)); 8814 } 8815 PetscFunctionReturn(0); 8816 } 8817 8818 /*@ 8819 MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix. 8820 8821 Logically Collective on Mat 8822 8823 Input Parameters: 8824 + mat - the matrix 8825 - nullsp - the null space object 8826 8827 Level: developer 8828 8829 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatSetTransposeNullSpace()`, `MatSetNullSpace()`, `MatGetNullSpace()` 8830 @*/ 8831 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp) 8832 { 8833 PetscFunctionBegin; 8834 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8835 PetscValidType(mat,1); 8836 PetscValidPointer(nullsp,2); 8837 *nullsp = (mat->symmetric == PETSC_BOOL3_TRUE && !mat->transnullsp) ? mat->nullsp : mat->transnullsp; 8838 PetscFunctionReturn(0); 8839 } 8840 8841 /*@ 8842 MatSetTransposeNullSpace - attaches the null space of a transpose of a matrix to the matrix 8843 8844 Logically Collective on Mat 8845 8846 Input Parameters: 8847 + mat - the matrix 8848 - nullsp - the null space object 8849 8850 Level: advanced 8851 8852 Notes: 8853 This allows solving singular linear systems defined by the transpose of the matrix using KSP solvers with left preconditioning. 8854 8855 See MatSetNullSpace() 8856 8857 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatGetNullSpace()`, `MatSetNullSpace()`, `MatGetTransposeNullSpace()`, `MatNullSpaceRemove()`, `KSPSetPCSide()` 8858 @*/ 8859 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp) 8860 { 8861 PetscFunctionBegin; 8862 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8863 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8864 if (nullsp) PetscCall(PetscObjectReference((PetscObject)nullsp)); 8865 PetscCall(MatNullSpaceDestroy(&mat->transnullsp)); 8866 mat->transnullsp = nullsp; 8867 PetscFunctionReturn(0); 8868 } 8869 8870 /*@ 8871 MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions 8872 This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix. 8873 8874 Logically Collective on Mat 8875 8876 Input Parameters: 8877 + mat - the matrix 8878 - nullsp - the null space object 8879 8880 Level: advanced 8881 8882 Notes: 8883 Overwrites any previous near null space that may have been attached 8884 8885 You can remove the null space by calling this routine with an nullsp of NULL 8886 8887 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNullSpace()`, `MatNullSpaceCreateRigidBody()`, `MatGetNearNullSpace()` 8888 @*/ 8889 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp) 8890 { 8891 PetscFunctionBegin; 8892 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8893 PetscValidType(mat,1); 8894 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8895 MatCheckPreallocated(mat,1); 8896 if (nullsp) PetscCall(PetscObjectReference((PetscObject)nullsp)); 8897 PetscCall(MatNullSpaceDestroy(&mat->nearnullsp)); 8898 mat->nearnullsp = nullsp; 8899 PetscFunctionReturn(0); 8900 } 8901 8902 /*@ 8903 MatGetNearNullSpace - Get null space attached with MatSetNearNullSpace() 8904 8905 Not Collective 8906 8907 Input Parameter: 8908 . mat - the matrix 8909 8910 Output Parameter: 8911 . nullsp - the null space object, NULL if not set 8912 8913 Level: developer 8914 8915 .seealso: `MatSetNearNullSpace()`, `MatGetNullSpace()`, `MatNullSpaceCreate()` 8916 @*/ 8917 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp) 8918 { 8919 PetscFunctionBegin; 8920 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8921 PetscValidType(mat,1); 8922 PetscValidPointer(nullsp,2); 8923 MatCheckPreallocated(mat,1); 8924 *nullsp = mat->nearnullsp; 8925 PetscFunctionReturn(0); 8926 } 8927 8928 /*@C 8929 MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix. 8930 8931 Collective on Mat 8932 8933 Input Parameters: 8934 + mat - the matrix 8935 . row - row/column permutation 8936 . fill - expected fill factor >= 1.0 8937 - level - level of fill, for ICC(k) 8938 8939 Notes: 8940 Probably really in-place only when level of fill is zero, otherwise allocates 8941 new space to store factored matrix and deletes previous memory. 8942 8943 Most users should employ the simplified KSP interface for linear solvers 8944 instead of working directly with matrix algebra routines such as this. 8945 See, e.g., KSPCreate(). 8946 8947 Level: developer 8948 8949 .seealso: `MatICCFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()` 8950 8951 Developer Note: fortran interface is not autogenerated as the f90 8952 interface definition cannot be generated correctly [due to MatFactorInfo] 8953 8954 @*/ 8955 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info) 8956 { 8957 PetscFunctionBegin; 8958 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8959 PetscValidType(mat,1); 8960 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 8961 PetscValidPointer(info,3); 8962 PetscCheck(mat->rmap->N == mat->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 8963 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8964 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8965 PetscCheck(mat->ops->iccfactor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8966 MatCheckPreallocated(mat,1); 8967 PetscCall((*mat->ops->iccfactor)(mat,row,info)); 8968 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 8969 PetscFunctionReturn(0); 8970 } 8971 8972 /*@ 8973 MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 8974 ghosted ones. 8975 8976 Not Collective 8977 8978 Input Parameters: 8979 + mat - the matrix 8980 - diag - the diagonal values, including ghost ones 8981 8982 Level: developer 8983 8984 Notes: 8985 Works only for MPIAIJ and MPIBAIJ matrices 8986 8987 .seealso: `MatDiagonalScale()` 8988 @*/ 8989 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag) 8990 { 8991 PetscMPIInt size; 8992 8993 PetscFunctionBegin; 8994 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8995 PetscValidHeaderSpecific(diag,VEC_CLASSID,2); 8996 PetscValidType(mat,1); 8997 8998 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled"); 8999 PetscCall(PetscLogEventBegin(MAT_Scale,mat,0,0,0)); 9000 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 9001 if (size == 1) { 9002 PetscInt n,m; 9003 PetscCall(VecGetSize(diag,&n)); 9004 PetscCall(MatGetSize(mat,NULL,&m)); 9005 if (m == n) { 9006 PetscCall(MatDiagonalScale(mat,NULL,diag)); 9007 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions"); 9008 } else { 9009 PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag)); 9010 } 9011 PetscCall(PetscLogEventEnd(MAT_Scale,mat,0,0,0)); 9012 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 9013 PetscFunctionReturn(0); 9014 } 9015 9016 /*@ 9017 MatGetInertia - Gets the inertia from a factored matrix 9018 9019 Collective on Mat 9020 9021 Input Parameter: 9022 . mat - the matrix 9023 9024 Output Parameters: 9025 + nneg - number of negative eigenvalues 9026 . nzero - number of zero eigenvalues 9027 - npos - number of positive eigenvalues 9028 9029 Level: advanced 9030 9031 Notes: 9032 Matrix must have been factored by MatCholeskyFactor() 9033 9034 @*/ 9035 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos) 9036 { 9037 PetscFunctionBegin; 9038 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9039 PetscValidType(mat,1); 9040 PetscCheck(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 9041 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled"); 9042 PetscCheck(mat->ops->getinertia,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 9043 PetscCall((*mat->ops->getinertia)(mat,nneg,nzero,npos)); 9044 PetscFunctionReturn(0); 9045 } 9046 9047 /* ----------------------------------------------------------------*/ 9048 /*@C 9049 MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors 9050 9051 Neighbor-wise Collective on Mats 9052 9053 Input Parameters: 9054 + mat - the factored matrix 9055 - b - the right-hand-side vectors 9056 9057 Output Parameter: 9058 . x - the result vectors 9059 9060 Notes: 9061 The vectors b and x cannot be the same. I.e., one cannot 9062 call MatSolves(A,x,x). 9063 9064 Notes: 9065 Most users should employ the simplified KSP interface for linear solvers 9066 instead of working directly with matrix algebra routines such as this. 9067 See, e.g., KSPCreate(). 9068 9069 Level: developer 9070 9071 .seealso: `MatSolveAdd()`, `MatSolveTranspose()`, `MatSolveTransposeAdd()`, `MatSolve()` 9072 @*/ 9073 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x) 9074 { 9075 PetscFunctionBegin; 9076 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9077 PetscValidType(mat,1); 9078 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 9079 PetscCheck(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 9080 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 9081 9082 PetscCheck(mat->ops->solves,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 9083 MatCheckPreallocated(mat,1); 9084 PetscCall(PetscLogEventBegin(MAT_Solves,mat,0,0,0)); 9085 PetscCall((*mat->ops->solves)(mat,b,x)); 9086 PetscCall(PetscLogEventEnd(MAT_Solves,mat,0,0,0)); 9087 PetscFunctionReturn(0); 9088 } 9089 9090 /*@ 9091 MatIsSymmetric - Test whether a matrix is symmetric 9092 9093 Collective on Mat 9094 9095 Input Parameters: 9096 + A - the matrix to test 9097 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose) 9098 9099 Output Parameters: 9100 . flg - the result 9101 9102 Notes: 9103 For real numbers MatIsSymmetric() and MatIsHermitian() return identical results 9104 9105 If the matrix does not yet know if it is symmetric or not this can be an expensive operation, also available `MatIsSymmetricKnown()` 9106 9107 Level: intermediate 9108 9109 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetricKnown()` 9110 @*/ 9111 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg) 9112 { 9113 PetscFunctionBegin; 9114 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9115 PetscValidBoolPointer(flg,3); 9116 9117 if (A->symmetric == PETSC_BOOL3_TRUE) *flg = PETSC_TRUE; 9118 else if (A->symmetric == PETSC_BOOL3_FALSE) *flg = PETSC_FALSE; 9119 else { 9120 if (!A->ops->issymmetric) { 9121 MatType mattype; 9122 PetscCall(MatGetType(A,&mattype)); 9123 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for symmetric",mattype); 9124 } 9125 PetscCall((*A->ops->issymmetric)(A,tol,flg)); 9126 if (!tol) PetscCall(MatSetOption(A,MAT_SYMMETRIC,*flg)); 9127 } 9128 PetscFunctionReturn(0); 9129 } 9130 9131 /*@ 9132 MatIsHermitian - Test whether a matrix is Hermitian 9133 9134 Collective on Mat 9135 9136 Input Parameters: 9137 + A - the matrix to test 9138 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian) 9139 9140 Output Parameters: 9141 . flg - the result 9142 9143 Level: intermediate 9144 9145 Notes: 9146 For real numbers MatIsSymmetric() and MatIsHermitian() return identical results 9147 9148 If the matrix does not yet know if it is hermitian or not this can be an expensive operation, also available `MatIsHermitianKnown()` 9149 9150 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitianKnown()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, 9151 `MatIsSymmetricKnown()`, `MatIsSymmetric()` 9152 @*/ 9153 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg) 9154 { 9155 PetscFunctionBegin; 9156 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9157 PetscValidBoolPointer(flg,3); 9158 9159 if (A->hermitian == PETSC_BOOL3_TRUE) *flg = PETSC_TRUE; 9160 else if (A->hermitian == PETSC_BOOL3_FALSE) *flg = PETSC_FALSE; 9161 else { 9162 if (!A->ops->ishermitian) { 9163 MatType mattype; 9164 PetscCall(MatGetType(A,&mattype)); 9165 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for hermitian",mattype); 9166 } 9167 PetscCall((*A->ops->ishermitian)(A,tol,flg)); 9168 if (!tol) PetscCall(MatSetOption(A,MAT_HERMITIAN,*flg)); 9169 } 9170 PetscFunctionReturn(0); 9171 } 9172 9173 /*@ 9174 MatIsSymmetricKnown - Checks if a matrix knows if it is symmetric or not and its symmetric state 9175 9176 Not Collective 9177 9178 Input Parameter: 9179 . A - the matrix to check 9180 9181 Output Parameters: 9182 + set - PETSC_TRUE if the matrix knows its symmetry state (this tells you if the next flag is valid) 9183 - flg - the result (only valid if set is PETSC_TRUE) 9184 9185 Level: advanced 9186 9187 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric() 9188 if you want it explicitly checked 9189 9190 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitianKnown()` 9191 @*/ 9192 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg) 9193 { 9194 PetscFunctionBegin; 9195 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9196 PetscValidBoolPointer(set,2); 9197 PetscValidBoolPointer(flg,3); 9198 if (A->symmetric != PETSC_BOOL3_UNKNOWN) { 9199 *set = PETSC_TRUE; 9200 *flg = PetscBool3ToBool(A->symmetric); 9201 } else { 9202 *set = PETSC_FALSE; 9203 } 9204 PetscFunctionReturn(0); 9205 } 9206 9207 /*@ 9208 MatIsSPDKnown - Checks if a matrix knows if it is symmetric positive definite or not and its symmetric positive definite state 9209 9210 Not Collective 9211 9212 Input Parameter: 9213 . A - the matrix to check 9214 9215 Output Parameters: 9216 + set - PETSC_TRUE if the matrix knows its symmetric positive definite state (this tells you if the next flag is valid) 9217 - flg - the result (only valid if set is PETSC_TRUE) 9218 9219 Level: advanced 9220 9221 Note: 9222 Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). 9223 9224 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitianKnown()` 9225 @*/ 9226 PetscErrorCode MatIsSPDKnown(Mat A,PetscBool *set,PetscBool *flg) 9227 { 9228 PetscFunctionBegin; 9229 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9230 PetscValidBoolPointer(set,2); 9231 PetscValidBoolPointer(flg,3); 9232 if (A->spd != PETSC_BOOL3_UNKNOWN) { 9233 *set = PETSC_TRUE; 9234 *flg = PetscBool3ToBool(A->spd); 9235 } else { 9236 *set = PETSC_FALSE; 9237 } 9238 PetscFunctionReturn(0); 9239 } 9240 9241 /*@ 9242 MatIsHermitianKnown - Checks if a matrix knows if it is Hermitian or not and its Hermitian state 9243 9244 Not Collective 9245 9246 Input Parameter: 9247 . A - the matrix to check 9248 9249 Output Parameters: 9250 + set - PETSC_TRUE if the matrix knows its Hermitian state (this tells you if the next flag is valid) 9251 - flg - the result (only valid if set is PETSC_TRUE) 9252 9253 Level: advanced 9254 9255 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian() 9256 if you want it explicitly checked 9257 9258 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()` 9259 @*/ 9260 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg) 9261 { 9262 PetscFunctionBegin; 9263 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9264 PetscValidBoolPointer(set,2); 9265 PetscValidBoolPointer(flg,3); 9266 if (A->hermitian != PETSC_BOOL3_UNKNOWN) { 9267 *set = PETSC_TRUE; 9268 *flg = PetscBool3ToBool(A->hermitian); 9269 } else { 9270 *set = PETSC_FALSE; 9271 } 9272 PetscFunctionReturn(0); 9273 } 9274 9275 /*@ 9276 MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric 9277 9278 Collective on Mat 9279 9280 Input Parameter: 9281 . A - the matrix to test 9282 9283 Output Parameters: 9284 . flg - the result 9285 9286 Notes: 9287 If the matrix does yet know it is structurally symmetric this can be an expensive operation, also available `MatIsStructurallySymmetricKnown()` 9288 9289 Level: intermediate 9290 9291 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsSymmetric()`, `MatSetOption()`, `MatIsStructurallySymmetricKnown()` 9292 @*/ 9293 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg) 9294 { 9295 PetscFunctionBegin; 9296 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9297 PetscValidBoolPointer(flg,2); 9298 if (A->structurally_symmetric != PETSC_BOOL3_UNKNOWN) { 9299 *flg = PetscBool3ToBool(A->structurally_symmetric); 9300 } else { 9301 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); 9302 PetscCall((*A->ops->isstructurallysymmetric)(A,flg)); 9303 PetscCall(MatSetOption(A,MAT_STRUCTURALLY_SYMMETRIC,*flg)); 9304 } 9305 PetscFunctionReturn(0); 9306 } 9307 9308 /*@ 9309 MatIsStructurallySymmetricKnown - Checks if a matrix knows if it is structurally symmetric or not and its structurally symmetric state 9310 9311 Not Collective 9312 9313 Input Parameter: 9314 . A - the matrix to check 9315 9316 Output Parameters: 9317 + set - PETSC_TRUE if the matrix knows its structurally symmetric state (this tells you if the next flag is valid) 9318 - flg - the result (only valid if set is PETSC_TRUE) 9319 9320 Level: advanced 9321 9322 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitianKnown()` 9323 @*/ 9324 PetscErrorCode MatIsStructurallySymmetricKnown(Mat A,PetscBool *set,PetscBool *flg) 9325 { 9326 PetscFunctionBegin; 9327 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9328 PetscValidBoolPointer(set,2); 9329 PetscValidBoolPointer(flg,3); 9330 if (A->structurally_symmetric != PETSC_BOOL3_UNKNOWN) { 9331 *set = PETSC_TRUE; 9332 *flg = PetscBool3ToBool(A->structurally_symmetric); 9333 } else { 9334 *set = PETSC_FALSE; 9335 } 9336 PetscFunctionReturn(0); 9337 } 9338 9339 /*@ 9340 MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need 9341 to be communicated to other processors during the MatAssemblyBegin/End() process 9342 9343 Not collective 9344 9345 Input Parameter: 9346 . vec - the vector 9347 9348 Output Parameters: 9349 + nstash - the size of the stash 9350 . reallocs - the number of additional mallocs incurred. 9351 . bnstash - the size of the block stash 9352 - breallocs - the number of additional mallocs incurred.in the block stash 9353 9354 Level: advanced 9355 9356 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `Mat`, `MatStashSetInitialSize()` 9357 9358 @*/ 9359 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs) 9360 { 9361 PetscFunctionBegin; 9362 PetscCall(MatStashGetInfo_Private(&mat->stash,nstash,reallocs)); 9363 PetscCall(MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs)); 9364 PetscFunctionReturn(0); 9365 } 9366 9367 /*@C 9368 MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same 9369 parallel layout 9370 9371 Collective on Mat 9372 9373 Input Parameter: 9374 . mat - the matrix 9375 9376 Output Parameters: 9377 + right - (optional) vector that the matrix can be multiplied against 9378 - left - (optional) vector that the matrix vector product can be stored in 9379 9380 Notes: 9381 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(). 9382 9383 Notes: 9384 These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed 9385 9386 Level: advanced 9387 9388 .seealso: `MatCreate()`, `VecDestroy()` 9389 @*/ 9390 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left) 9391 { 9392 PetscFunctionBegin; 9393 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9394 PetscValidType(mat,1); 9395 if (mat->ops->getvecs) { 9396 PetscCall((*mat->ops->getvecs)(mat,right,left)); 9397 } else { 9398 PetscInt rbs,cbs; 9399 PetscCall(MatGetBlockSizes(mat,&rbs,&cbs)); 9400 if (right) { 9401 PetscCheck(mat->cmap->n >= 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup"); 9402 PetscCall(VecCreate(PetscObjectComm((PetscObject)mat),right)); 9403 PetscCall(VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE)); 9404 PetscCall(VecSetBlockSize(*right,cbs)); 9405 PetscCall(VecSetType(*right,mat->defaultvectype)); 9406 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 9407 if (mat->boundtocpu && mat->bindingpropagates) { 9408 PetscCall(VecSetBindingPropagates(*right,PETSC_TRUE)); 9409 PetscCall(VecBindToCPU(*right,PETSC_TRUE)); 9410 } 9411 #endif 9412 PetscCall(PetscLayoutReference(mat->cmap,&(*right)->map)); 9413 } 9414 if (left) { 9415 PetscCheck(mat->rmap->n >= 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup"); 9416 PetscCall(VecCreate(PetscObjectComm((PetscObject)mat),left)); 9417 PetscCall(VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE)); 9418 PetscCall(VecSetBlockSize(*left,rbs)); 9419 PetscCall(VecSetType(*left,mat->defaultvectype)); 9420 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 9421 if (mat->boundtocpu && mat->bindingpropagates) { 9422 PetscCall(VecSetBindingPropagates(*left,PETSC_TRUE)); 9423 PetscCall(VecBindToCPU(*left,PETSC_TRUE)); 9424 } 9425 #endif 9426 PetscCall(PetscLayoutReference(mat->rmap,&(*left)->map)); 9427 } 9428 } 9429 PetscFunctionReturn(0); 9430 } 9431 9432 /*@C 9433 MatFactorInfoInitialize - Initializes a MatFactorInfo data structure 9434 with default values. 9435 9436 Not Collective 9437 9438 Input Parameters: 9439 . info - the MatFactorInfo data structure 9440 9441 Notes: 9442 The solvers are generally used through the KSP and PC objects, for example 9443 PCLU, PCILU, PCCHOLESKY, PCICC 9444 9445 Level: developer 9446 9447 .seealso: `MatFactorInfo` 9448 9449 Developer Note: fortran interface is not autogenerated as the f90 9450 interface definition cannot be generated correctly [due to MatFactorInfo] 9451 9452 @*/ 9453 9454 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info) 9455 { 9456 PetscFunctionBegin; 9457 PetscCall(PetscMemzero(info,sizeof(MatFactorInfo))); 9458 PetscFunctionReturn(0); 9459 } 9460 9461 /*@ 9462 MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed 9463 9464 Collective on Mat 9465 9466 Input Parameters: 9467 + mat - the factored matrix 9468 - is - the index set defining the Schur indices (0-based) 9469 9470 Notes: 9471 Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system. 9472 9473 You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call. 9474 9475 Level: developer 9476 9477 .seealso: `MatGetFactor()`, `MatFactorGetSchurComplement()`, `MatFactorRestoreSchurComplement()`, `MatFactorCreateSchurComplement()`, `MatFactorSolveSchurComplement()`, 9478 `MatFactorSolveSchurComplementTranspose()`, `MatFactorSolveSchurComplement()` 9479 9480 @*/ 9481 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is) 9482 { 9483 PetscErrorCode (*f)(Mat,IS); 9484 9485 PetscFunctionBegin; 9486 PetscValidType(mat,1); 9487 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9488 PetscValidType(is,2); 9489 PetscValidHeaderSpecific(is,IS_CLASSID,2); 9490 PetscCheckSameComm(mat,1,is,2); 9491 PetscCheck(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 9492 PetscCall(PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f)); 9493 PetscCheck(f,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"The selected MatSolverType does not support Schur complement computation. You should use MATSOLVERMUMPS or MATSOLVERMKL_PARDISO"); 9494 PetscCall(MatDestroy(&mat->schur)); 9495 PetscCall((*f)(mat,is)); 9496 PetscCheck(mat->schur,PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created"); 9497 PetscFunctionReturn(0); 9498 } 9499 9500 /*@ 9501 MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step 9502 9503 Logically Collective on Mat 9504 9505 Input Parameters: 9506 + F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface 9507 . S - location where to return the Schur complement, can be NULL 9508 - status - the status of the Schur complement matrix, can be NULL 9509 9510 Notes: 9511 You must call MatFactorSetSchurIS() before calling this routine. 9512 9513 The routine provides a copy of the Schur matrix stored within the solver data structures. 9514 The caller must destroy the object when it is no longer needed. 9515 If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse. 9516 9517 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) 9518 9519 Developer Notes: 9520 The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc 9521 matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix. 9522 9523 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 9524 9525 Level: advanced 9526 9527 References: 9528 9529 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorGetSchurComplement()`, `MatFactorSchurStatus` 9530 @*/ 9531 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 9532 { 9533 PetscFunctionBegin; 9534 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9535 if (S) PetscValidPointer(S,2); 9536 if (status) PetscValidPointer(status,3); 9537 if (S) { 9538 PetscErrorCode (*f)(Mat,Mat*); 9539 9540 PetscCall(PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f)); 9541 if (f) { 9542 PetscCall((*f)(F,S)); 9543 } else { 9544 PetscCall(MatDuplicate(F->schur,MAT_COPY_VALUES,S)); 9545 } 9546 } 9547 if (status) *status = F->schur_status; 9548 PetscFunctionReturn(0); 9549 } 9550 9551 /*@ 9552 MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix 9553 9554 Logically Collective on Mat 9555 9556 Input Parameters: 9557 + F - the factored matrix obtained by calling MatGetFactor() 9558 . *S - location where to return the Schur complement, can be NULL 9559 - status - the status of the Schur complement matrix, can be NULL 9560 9561 Notes: 9562 You must call MatFactorSetSchurIS() before calling this routine. 9563 9564 Schur complement mode is currently implemented for sequential matrices. 9565 The routine returns a the Schur Complement stored within the data strutures of the solver. 9566 If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement. 9567 The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed. 9568 9569 Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix 9570 9571 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 9572 9573 Level: advanced 9574 9575 References: 9576 9577 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorRestoreSchurComplement()`, `MatFactorCreateSchurComplement()`, `MatFactorSchurStatus` 9578 @*/ 9579 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 9580 { 9581 PetscFunctionBegin; 9582 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9583 if (S) PetscValidPointer(S,2); 9584 if (status) PetscValidPointer(status,3); 9585 if (S) *S = F->schur; 9586 if (status) *status = F->schur_status; 9587 PetscFunctionReturn(0); 9588 } 9589 9590 /*@ 9591 MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement 9592 9593 Logically Collective on Mat 9594 9595 Input Parameters: 9596 + F - the factored matrix obtained by calling MatGetFactor() 9597 . *S - location where the Schur complement is stored 9598 - status - the status of the Schur complement matrix (see MatFactorSchurStatus) 9599 9600 Notes: 9601 9602 Level: advanced 9603 9604 References: 9605 9606 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorRestoreSchurComplement()`, `MatFactorCreateSchurComplement()`, `MatFactorSchurStatus` 9607 @*/ 9608 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status) 9609 { 9610 PetscFunctionBegin; 9611 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9612 if (S) { 9613 PetscValidHeaderSpecific(*S,MAT_CLASSID,2); 9614 *S = NULL; 9615 } 9616 F->schur_status = status; 9617 PetscCall(MatFactorUpdateSchurStatus_Private(F)); 9618 PetscFunctionReturn(0); 9619 } 9620 9621 /*@ 9622 MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step 9623 9624 Logically Collective on Mat 9625 9626 Input Parameters: 9627 + F - the factored matrix obtained by calling MatGetFactor() 9628 . rhs - location where the right hand side of the Schur complement system is stored 9629 - sol - location where the solution of the Schur complement system has to be returned 9630 9631 Notes: 9632 The sizes of the vectors should match the size of the Schur complement 9633 9634 Must be called after MatFactorSetSchurIS() 9635 9636 Level: advanced 9637 9638 References: 9639 9640 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorSolveSchurComplement()` 9641 @*/ 9642 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol) 9643 { 9644 PetscFunctionBegin; 9645 PetscValidType(F,1); 9646 PetscValidType(rhs,2); 9647 PetscValidType(sol,3); 9648 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9649 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9650 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9651 PetscCheckSameComm(F,1,rhs,2); 9652 PetscCheckSameComm(F,1,sol,3); 9653 PetscCall(MatFactorFactorizeSchurComplement(F)); 9654 switch (F->schur_status) { 9655 case MAT_FACTOR_SCHUR_FACTORED: 9656 PetscCall(MatSolveTranspose(F->schur,rhs,sol)); 9657 break; 9658 case MAT_FACTOR_SCHUR_INVERTED: 9659 PetscCall(MatMultTranspose(F->schur,rhs,sol)); 9660 break; 9661 default: 9662 SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %d",F->schur_status); 9663 } 9664 PetscFunctionReturn(0); 9665 } 9666 9667 /*@ 9668 MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step 9669 9670 Logically Collective on Mat 9671 9672 Input Parameters: 9673 + F - the factored matrix obtained by calling MatGetFactor() 9674 . rhs - location where the right hand side of the Schur complement system is stored 9675 - sol - location where the solution of the Schur complement system has to be returned 9676 9677 Notes: 9678 The sizes of the vectors should match the size of the Schur complement 9679 9680 Must be called after MatFactorSetSchurIS() 9681 9682 Level: advanced 9683 9684 References: 9685 9686 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorSolveSchurComplementTranspose()` 9687 @*/ 9688 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol) 9689 { 9690 PetscFunctionBegin; 9691 PetscValidType(F,1); 9692 PetscValidType(rhs,2); 9693 PetscValidType(sol,3); 9694 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9695 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9696 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9697 PetscCheckSameComm(F,1,rhs,2); 9698 PetscCheckSameComm(F,1,sol,3); 9699 PetscCall(MatFactorFactorizeSchurComplement(F)); 9700 switch (F->schur_status) { 9701 case MAT_FACTOR_SCHUR_FACTORED: 9702 PetscCall(MatSolve(F->schur,rhs,sol)); 9703 break; 9704 case MAT_FACTOR_SCHUR_INVERTED: 9705 PetscCall(MatMult(F->schur,rhs,sol)); 9706 break; 9707 default: 9708 SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %d",F->schur_status); 9709 } 9710 PetscFunctionReturn(0); 9711 } 9712 9713 /*@ 9714 MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step 9715 9716 Logically Collective on Mat 9717 9718 Input Parameters: 9719 . F - the factored matrix obtained by calling MatGetFactor() 9720 9721 Notes: 9722 Must be called after MatFactorSetSchurIS(). 9723 9724 Call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it. 9725 9726 Level: advanced 9727 9728 References: 9729 9730 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorGetSchurComplement()`, `MatFactorCreateSchurComplement()` 9731 @*/ 9732 PetscErrorCode MatFactorInvertSchurComplement(Mat F) 9733 { 9734 PetscFunctionBegin; 9735 PetscValidType(F,1); 9736 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9737 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0); 9738 PetscCall(MatFactorFactorizeSchurComplement(F)); 9739 PetscCall(MatFactorInvertSchurComplement_Private(F)); 9740 F->schur_status = MAT_FACTOR_SCHUR_INVERTED; 9741 PetscFunctionReturn(0); 9742 } 9743 9744 /*@ 9745 MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step 9746 9747 Logically Collective on Mat 9748 9749 Input Parameters: 9750 . F - the factored matrix obtained by calling MatGetFactor() 9751 9752 Notes: 9753 Must be called after MatFactorSetSchurIS(). 9754 9755 Level: advanced 9756 9757 References: 9758 9759 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorInvertSchurComplement()` 9760 @*/ 9761 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F) 9762 { 9763 PetscFunctionBegin; 9764 PetscValidType(F,1); 9765 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9766 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0); 9767 PetscCall(MatFactorFactorizeSchurComplement_Private(F)); 9768 F->schur_status = MAT_FACTOR_SCHUR_FACTORED; 9769 PetscFunctionReturn(0); 9770 } 9771 9772 /*@ 9773 MatPtAP - Creates the matrix product C = P^T * A * P 9774 9775 Neighbor-wise Collective on Mat 9776 9777 Input Parameters: 9778 + A - the matrix 9779 . P - the projection matrix 9780 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9781 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate 9782 if the result is a dense matrix this is irrelevant 9783 9784 Output Parameters: 9785 . C - the product matrix 9786 9787 Notes: 9788 C will be created and must be destroyed by the user with MatDestroy(). 9789 9790 For matrix types without special implementation the function fallbacks to MatMatMult() followed by MatTransposeMatMult(). 9791 9792 Level: intermediate 9793 9794 .seealso: `MatMatMult()`, `MatRARt()` 9795 @*/ 9796 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 9797 { 9798 PetscFunctionBegin; 9799 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*C,5); 9800 PetscCheck(scall != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9801 9802 if (scall == MAT_INITIAL_MATRIX) { 9803 PetscCall(MatProductCreate(A,P,NULL,C)); 9804 PetscCall(MatProductSetType(*C,MATPRODUCT_PtAP)); 9805 PetscCall(MatProductSetAlgorithm(*C,"default")); 9806 PetscCall(MatProductSetFill(*C,fill)); 9807 9808 (*C)->product->api_user = PETSC_TRUE; 9809 PetscCall(MatProductSetFromOptions(*C)); 9810 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); 9811 PetscCall(MatProductSymbolic(*C)); 9812 } else { /* scall == MAT_REUSE_MATRIX */ 9813 PetscCall(MatProductReplaceMats(A,P,NULL,*C)); 9814 } 9815 9816 PetscCall(MatProductNumeric(*C)); 9817 (*C)->symmetric = A->symmetric; 9818 (*C)->spd = A->spd; 9819 PetscFunctionReturn(0); 9820 } 9821 9822 /*@ 9823 MatRARt - Creates the matrix product C = R * A * R^T 9824 9825 Neighbor-wise Collective on Mat 9826 9827 Input Parameters: 9828 + A - the matrix 9829 . R - the projection matrix 9830 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9831 - fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate 9832 if the result is a dense matrix this is irrelevant 9833 9834 Output Parameters: 9835 . C - the product matrix 9836 9837 Notes: 9838 C will be created and must be destroyed by the user with MatDestroy(). 9839 9840 This routine is currently only implemented for pairs of AIJ matrices and classes 9841 which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes, 9842 parallel MatRARt is implemented via explicit transpose of R, which could be very expensive. 9843 We recommend using MatPtAP(). 9844 9845 Level: intermediate 9846 9847 .seealso: `MatMatMult()`, `MatPtAP()` 9848 @*/ 9849 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C) 9850 { 9851 PetscFunctionBegin; 9852 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*C,5); 9853 PetscCheck(scall != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9854 9855 if (scall == MAT_INITIAL_MATRIX) { 9856 PetscCall(MatProductCreate(A,R,NULL,C)); 9857 PetscCall(MatProductSetType(*C,MATPRODUCT_RARt)); 9858 PetscCall(MatProductSetAlgorithm(*C,"default")); 9859 PetscCall(MatProductSetFill(*C,fill)); 9860 9861 (*C)->product->api_user = PETSC_TRUE; 9862 PetscCall(MatProductSetFromOptions(*C)); 9863 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); 9864 PetscCall(MatProductSymbolic(*C)); 9865 } else { /* scall == MAT_REUSE_MATRIX */ 9866 PetscCall(MatProductReplaceMats(A,R,NULL,*C)); 9867 } 9868 9869 PetscCall(MatProductNumeric(*C)); 9870 if (A->symmetric == PETSC_BOOL3_TRUE) { 9871 PetscCall(MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE)); 9872 } 9873 PetscFunctionReturn(0); 9874 } 9875 9876 static PetscErrorCode MatProduct_Private(Mat A,Mat B,MatReuse scall,PetscReal fill,MatProductType ptype, Mat *C) 9877 { 9878 PetscFunctionBegin; 9879 PetscCheck(scall != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9880 9881 if (scall == MAT_INITIAL_MATRIX) { 9882 PetscCall(PetscInfo(A,"Calling MatProduct API with MAT_INITIAL_MATRIX and product type %s\n",MatProductTypes[ptype])); 9883 PetscCall(MatProductCreate(A,B,NULL,C)); 9884 PetscCall(MatProductSetType(*C,ptype)); 9885 PetscCall(MatProductSetAlgorithm(*C,MATPRODUCTALGORITHMDEFAULT)); 9886 PetscCall(MatProductSetFill(*C,fill)); 9887 9888 (*C)->product->api_user = PETSC_TRUE; 9889 PetscCall(MatProductSetFromOptions(*C)); 9890 PetscCall(MatProductSymbolic(*C)); 9891 } else { /* scall == MAT_REUSE_MATRIX */ 9892 Mat_Product *product = (*C)->product; 9893 PetscBool isdense; 9894 9895 PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)(*C),&isdense,MATSEQDENSE,MATMPIDENSE,"")); 9896 if (isdense && product && product->type != ptype) { 9897 PetscCall(MatProductClear(*C)); 9898 product = NULL; 9899 } 9900 PetscCall(PetscInfo(A,"Calling MatProduct API with MAT_REUSE_MATRIX %s product present and product type %s\n",product ? "with" : "without",MatProductTypes[ptype])); 9901 if (!product) { /* user provide the dense matrix *C without calling MatProductCreate() or reusing it from previous calls */ 9902 if (isdense) { 9903 PetscCall(MatProductCreate_Private(A,B,NULL,*C)); 9904 product = (*C)->product; 9905 product->fill = fill; 9906 product->api_user = PETSC_TRUE; 9907 product->clear = PETSC_TRUE; 9908 9909 PetscCall(MatProductSetType(*C,ptype)); 9910 PetscCall(MatProductSetFromOptions(*C)); 9911 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); 9912 PetscCall(MatProductSymbolic(*C)); 9913 } else SETERRQ(PetscObjectComm((PetscObject)(*C)),PETSC_ERR_SUP,"Call MatProductCreate() first"); 9914 } else { /* user may change input matrices A or B when REUSE */ 9915 PetscCall(MatProductReplaceMats(A,B,NULL,*C)); 9916 } 9917 } 9918 PetscCall(MatProductNumeric(*C)); 9919 PetscFunctionReturn(0); 9920 } 9921 9922 /*@ 9923 MatMatMult - Performs Matrix-Matrix Multiplication C=A*B. 9924 9925 Neighbor-wise Collective on Mat 9926 9927 Input Parameters: 9928 + A - the left matrix 9929 . B - the right matrix 9930 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9931 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate 9932 if the result is a dense matrix this is irrelevant 9933 9934 Output Parameters: 9935 . C - the product matrix 9936 9937 Notes: 9938 Unless scall is MAT_REUSE_MATRIX C will be created. 9939 9940 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 9941 call to this function with MAT_INITIAL_MATRIX. 9942 9943 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value actually needed. 9944 9945 If you have many matrices with the same non-zero structure to multiply, you should use MatProductCreate()/MatProductSymbolic()/MatProductReplaceMats(), and call MatProductNumeric() repeatedly. 9946 9947 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. 9948 9949 Example of Usage: 9950 .vb 9951 MatProductCreate(A,B,NULL,&C); 9952 MatProductSetType(C,MATPRODUCT_AB); 9953 MatProductSymbolic(C); 9954 MatProductNumeric(C); // compute C=A * B 9955 MatProductReplaceMats(A1,B1,NULL,C); // compute C=A1 * B1 9956 MatProductNumeric(C); 9957 MatProductReplaceMats(A2,NULL,NULL,C); // compute C=A2 * B1 9958 MatProductNumeric(C); 9959 .ve 9960 9961 Level: intermediate 9962 9963 .seealso: `MatTransposeMatMult()`, `MatMatTransposeMult()`, `MatPtAP()`, `MatProductCreate()`, `MatProductSymbolic()`, `MatProductReplaceMats()`, `MatProductNumeric()` 9964 @*/ 9965 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9966 { 9967 PetscFunctionBegin; 9968 PetscCall(MatProduct_Private(A,B,scall,fill,MATPRODUCT_AB,C)); 9969 PetscFunctionReturn(0); 9970 } 9971 9972 /*@ 9973 MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T. 9974 9975 Neighbor-wise Collective on Mat 9976 9977 Input Parameters: 9978 + A - the left matrix 9979 . B - the right matrix 9980 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9981 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9982 9983 Output Parameters: 9984 . C - the product matrix 9985 9986 Notes: 9987 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9988 9989 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9990 9991 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9992 actually needed. 9993 9994 This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class, 9995 and for pairs of MPIDense matrices. 9996 9997 Options Database Keys: 9998 . -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorithms for MPIDense matrices: the 9999 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity; 10000 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity. 10001 10002 Level: intermediate 10003 10004 .seealso: `MatMatMult()`, `MatTransposeMatMult()` `MatPtAP()` 10005 @*/ 10006 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 10007 { 10008 PetscFunctionBegin; 10009 PetscCall(MatProduct_Private(A,B,scall,fill,MATPRODUCT_ABt,C)); 10010 if (A == B) { 10011 PetscCall(MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE)); 10012 } 10013 PetscFunctionReturn(0); 10014 } 10015 10016 /*@ 10017 MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B. 10018 10019 Neighbor-wise Collective on Mat 10020 10021 Input Parameters: 10022 + A - the left matrix 10023 . B - the right matrix 10024 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10025 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 10026 10027 Output Parameters: 10028 . C - the product matrix 10029 10030 Notes: 10031 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 10032 10033 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call. 10034 10035 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 10036 actually needed. 10037 10038 This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes 10039 which inherit from SeqAIJ. C will be of the same type as the input matrices. 10040 10041 Level: intermediate 10042 10043 .seealso: `MatMatMult()`, `MatMatTransposeMult()`, `MatPtAP()` 10044 @*/ 10045 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 10046 { 10047 PetscFunctionBegin; 10048 PetscCall(MatProduct_Private(A,B,scall,fill,MATPRODUCT_AtB,C)); 10049 PetscFunctionReturn(0); 10050 } 10051 10052 /*@ 10053 MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C. 10054 10055 Neighbor-wise Collective on Mat 10056 10057 Input Parameters: 10058 + A - the left matrix 10059 . B - the middle matrix 10060 . C - the right matrix 10061 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10062 - 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 10063 if the result is a dense matrix this is irrelevant 10064 10065 Output Parameters: 10066 . D - the product matrix 10067 10068 Notes: 10069 Unless scall is MAT_REUSE_MATRIX D will be created. 10070 10071 MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call 10072 10073 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 10074 actually needed. 10075 10076 If you have many matrices with the same non-zero structure to multiply, you 10077 should use MAT_REUSE_MATRIX in all calls but the first 10078 10079 Level: intermediate 10080 10081 .seealso: `MatMatMult`, `MatPtAP()`, `MatMatTransposeMult()`, `MatTransposeMatMult()` 10082 @*/ 10083 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D) 10084 { 10085 PetscFunctionBegin; 10086 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*D,6); 10087 PetscCheck(scall != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 10088 10089 if (scall == MAT_INITIAL_MATRIX) { 10090 PetscCall(MatProductCreate(A,B,C,D)); 10091 PetscCall(MatProductSetType(*D,MATPRODUCT_ABC)); 10092 PetscCall(MatProductSetAlgorithm(*D,"default")); 10093 PetscCall(MatProductSetFill(*D,fill)); 10094 10095 (*D)->product->api_user = PETSC_TRUE; 10096 PetscCall(MatProductSetFromOptions(*D)); 10097 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); 10098 PetscCall(MatProductSymbolic(*D)); 10099 } else { /* user may change input matrices when REUSE */ 10100 PetscCall(MatProductReplaceMats(A,B,C,*D)); 10101 } 10102 PetscCall(MatProductNumeric(*D)); 10103 PetscFunctionReturn(0); 10104 } 10105 10106 /*@ 10107 MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators. 10108 10109 Collective on Mat 10110 10111 Input Parameters: 10112 + mat - the matrix 10113 . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices) 10114 . subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used) 10115 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10116 10117 Output Parameter: 10118 . matredundant - redundant matrix 10119 10120 Notes: 10121 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 10122 original matrix has not changed from that last call to MatCreateRedundantMatrix(). 10123 10124 This routine creates the duplicated matrices in the subcommunicators; you should NOT create them before 10125 calling it. 10126 10127 Level: advanced 10128 10129 .seealso: `MatDestroy()` 10130 @*/ 10131 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant) 10132 { 10133 MPI_Comm comm; 10134 PetscMPIInt size; 10135 PetscInt mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs; 10136 Mat_Redundant *redund=NULL; 10137 PetscSubcomm psubcomm=NULL; 10138 MPI_Comm subcomm_in=subcomm; 10139 Mat *matseq; 10140 IS isrow,iscol; 10141 PetscBool newsubcomm=PETSC_FALSE; 10142 10143 PetscFunctionBegin; 10144 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10145 if (nsubcomm && reuse == MAT_REUSE_MATRIX) { 10146 PetscValidPointer(*matredundant,5); 10147 PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5); 10148 } 10149 10150 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 10151 if (size == 1 || nsubcomm == 1) { 10152 if (reuse == MAT_INITIAL_MATRIX) { 10153 PetscCall(MatDuplicate(mat,MAT_COPY_VALUES,matredundant)); 10154 } else { 10155 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"); 10156 PetscCall(MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN)); 10157 } 10158 PetscFunctionReturn(0); 10159 } 10160 10161 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10162 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10163 MatCheckPreallocated(mat,1); 10164 10165 PetscCall(PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0)); 10166 if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */ 10167 /* create psubcomm, then get subcomm */ 10168 PetscCall(PetscObjectGetComm((PetscObject)mat,&comm)); 10169 PetscCallMPI(MPI_Comm_size(comm,&size)); 10170 PetscCheck(nsubcomm >= 1 && nsubcomm <= size,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %d",size); 10171 10172 PetscCall(PetscSubcommCreate(comm,&psubcomm)); 10173 PetscCall(PetscSubcommSetNumber(psubcomm,nsubcomm)); 10174 PetscCall(PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS)); 10175 PetscCall(PetscSubcommSetFromOptions(psubcomm)); 10176 PetscCall(PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL)); 10177 newsubcomm = PETSC_TRUE; 10178 PetscCall(PetscSubcommDestroy(&psubcomm)); 10179 } 10180 10181 /* get isrow, iscol and a local sequential matrix matseq[0] */ 10182 if (reuse == MAT_INITIAL_MATRIX) { 10183 mloc_sub = PETSC_DECIDE; 10184 nloc_sub = PETSC_DECIDE; 10185 if (bs < 1) { 10186 PetscCall(PetscSplitOwnership(subcomm,&mloc_sub,&M)); 10187 PetscCall(PetscSplitOwnership(subcomm,&nloc_sub,&N)); 10188 } else { 10189 PetscCall(PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M)); 10190 PetscCall(PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N)); 10191 } 10192 PetscCallMPI(MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm)); 10193 rstart = rend - mloc_sub; 10194 PetscCall(ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow)); 10195 PetscCall(ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol)); 10196 } else { /* reuse == MAT_REUSE_MATRIX */ 10197 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"); 10198 /* retrieve subcomm */ 10199 PetscCall(PetscObjectGetComm((PetscObject)(*matredundant),&subcomm)); 10200 redund = (*matredundant)->redundant; 10201 isrow = redund->isrow; 10202 iscol = redund->iscol; 10203 matseq = redund->matseq; 10204 } 10205 PetscCall(MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq)); 10206 10207 /* get matredundant over subcomm */ 10208 if (reuse == MAT_INITIAL_MATRIX) { 10209 PetscCall(MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant)); 10210 10211 /* create a supporting struct and attach it to C for reuse */ 10212 PetscCall(PetscNewLog(*matredundant,&redund)); 10213 (*matredundant)->redundant = redund; 10214 redund->isrow = isrow; 10215 redund->iscol = iscol; 10216 redund->matseq = matseq; 10217 if (newsubcomm) { 10218 redund->subcomm = subcomm; 10219 } else { 10220 redund->subcomm = MPI_COMM_NULL; 10221 } 10222 } else { 10223 PetscCall(MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant)); 10224 } 10225 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 10226 if (matseq[0]->boundtocpu && matseq[0]->bindingpropagates) { 10227 PetscCall(MatBindToCPU(*matredundant,PETSC_TRUE)); 10228 PetscCall(MatSetBindingPropagates(*matredundant,PETSC_TRUE)); 10229 } 10230 #endif 10231 PetscCall(PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0)); 10232 PetscFunctionReturn(0); 10233 } 10234 10235 /*@C 10236 MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from 10237 a given 'mat' object. Each submatrix can span multiple procs. 10238 10239 Collective on Mat 10240 10241 Input Parameters: 10242 + mat - the matrix 10243 . subcomm - the subcommunicator obtained by com_split(comm) 10244 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10245 10246 Output Parameter: 10247 . subMat - 'parallel submatrices each spans a given subcomm 10248 10249 Notes: 10250 The submatrix partition across processors is dictated by 'subComm' a 10251 communicator obtained by MPI_comm_split(). The subComm 10252 is not restriced to be grouped with consecutive original ranks. 10253 10254 Due the MPI_Comm_split() usage, the parallel layout of the submatrices 10255 map directly to the layout of the original matrix [wrt the local 10256 row,col partitioning]. So the original 'DiagonalMat' naturally maps 10257 into the 'DiagonalMat' of the subMat, hence it is used directly from 10258 the subMat. However the offDiagMat looses some columns - and this is 10259 reconstructed with MatSetValues() 10260 10261 Level: advanced 10262 10263 .seealso: `MatCreateSubMatrices()` 10264 @*/ 10265 PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat) 10266 { 10267 PetscMPIInt commsize,subCommSize; 10268 10269 PetscFunctionBegin; 10270 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize)); 10271 PetscCallMPI(MPI_Comm_size(subComm,&subCommSize)); 10272 PetscCheck(subCommSize <= commsize,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %d < SubCommZize %d",commsize,subCommSize); 10273 10274 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"); 10275 PetscCall(PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0)); 10276 PetscCall((*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat)); 10277 PetscCall(PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0)); 10278 PetscFunctionReturn(0); 10279 } 10280 10281 /*@ 10282 MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering 10283 10284 Not Collective 10285 10286 Input Parameters: 10287 + mat - matrix to extract local submatrix from 10288 . isrow - local row indices for submatrix 10289 - iscol - local column indices for submatrix 10290 10291 Output Parameter: 10292 . submat - the submatrix 10293 10294 Level: intermediate 10295 10296 Notes: 10297 The submat should be returned with MatRestoreLocalSubMatrix(). 10298 10299 Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be 10300 the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's. 10301 10302 The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then 10303 MatSetValuesBlockedLocal() will also be implemented. 10304 10305 The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that 10306 matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided. 10307 10308 .seealso: `MatRestoreLocalSubMatrix()`, `MatCreateLocalRef()`, `MatSetLocalToGlobalMapping()` 10309 @*/ 10310 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10311 { 10312 PetscFunctionBegin; 10313 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10314 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10315 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10316 PetscCheckSameComm(isrow,2,iscol,3); 10317 PetscValidPointer(submat,4); 10318 PetscCheck(mat->rmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call"); 10319 10320 if (mat->ops->getlocalsubmatrix) { 10321 PetscCall((*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat)); 10322 } else { 10323 PetscCall(MatCreateLocalRef(mat,isrow,iscol,submat)); 10324 } 10325 PetscFunctionReturn(0); 10326 } 10327 10328 /*@ 10329 MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering 10330 10331 Not Collective 10332 10333 Input Parameters: 10334 + mat - matrix to extract local submatrix from 10335 . isrow - local row indices for submatrix 10336 . iscol - local column indices for submatrix 10337 - submat - the submatrix 10338 10339 Level: intermediate 10340 10341 .seealso: `MatGetLocalSubMatrix()` 10342 @*/ 10343 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10344 { 10345 PetscFunctionBegin; 10346 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10347 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10348 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10349 PetscCheckSameComm(isrow,2,iscol,3); 10350 PetscValidPointer(submat,4); 10351 if (*submat) { 10352 PetscValidHeaderSpecific(*submat,MAT_CLASSID,4); 10353 } 10354 10355 if (mat->ops->restorelocalsubmatrix) { 10356 PetscCall((*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat)); 10357 } else { 10358 PetscCall(MatDestroy(submat)); 10359 } 10360 *submat = NULL; 10361 PetscFunctionReturn(0); 10362 } 10363 10364 /* --------------------------------------------------------*/ 10365 /*@ 10366 MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix 10367 10368 Collective on Mat 10369 10370 Input Parameter: 10371 . mat - the matrix 10372 10373 Output Parameter: 10374 . is - if any rows have zero diagonals this contains the list of them 10375 10376 Level: developer 10377 10378 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 10379 @*/ 10380 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is) 10381 { 10382 PetscFunctionBegin; 10383 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10384 PetscValidType(mat,1); 10385 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10386 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10387 10388 if (!mat->ops->findzerodiagonals) { 10389 Vec diag; 10390 const PetscScalar *a; 10391 PetscInt *rows; 10392 PetscInt rStart, rEnd, r, nrow = 0; 10393 10394 PetscCall(MatCreateVecs(mat, &diag, NULL)); 10395 PetscCall(MatGetDiagonal(mat, diag)); 10396 PetscCall(MatGetOwnershipRange(mat, &rStart, &rEnd)); 10397 PetscCall(VecGetArrayRead(diag, &a)); 10398 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow; 10399 PetscCall(PetscMalloc1(nrow, &rows)); 10400 nrow = 0; 10401 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart; 10402 PetscCall(VecRestoreArrayRead(diag, &a)); 10403 PetscCall(VecDestroy(&diag)); 10404 PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is)); 10405 } else { 10406 PetscCall((*mat->ops->findzerodiagonals)(mat, is)); 10407 } 10408 PetscFunctionReturn(0); 10409 } 10410 10411 /*@ 10412 MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size) 10413 10414 Collective on Mat 10415 10416 Input Parameter: 10417 . mat - the matrix 10418 10419 Output Parameter: 10420 . is - contains the list of rows with off block diagonal entries 10421 10422 Level: developer 10423 10424 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 10425 @*/ 10426 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is) 10427 { 10428 PetscFunctionBegin; 10429 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10430 PetscValidType(mat,1); 10431 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10432 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10433 10434 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); 10435 PetscCall((*mat->ops->findoffblockdiagonalentries)(mat,is)); 10436 PetscFunctionReturn(0); 10437 } 10438 10439 /*@C 10440 MatInvertBlockDiagonal - Inverts the block diagonal entries. 10441 10442 Collective on Mat 10443 10444 Input Parameters: 10445 . mat - the matrix 10446 10447 Output Parameters: 10448 . values - the block inverses in column major order (FORTRAN-like) 10449 10450 Note: 10451 The size of the blocks is determined by the block size of the matrix. 10452 10453 Fortran Note: 10454 This routine is not available from Fortran. 10455 10456 Level: advanced 10457 10458 .seealso: `MatInvertVariableBlockEnvelope()`, `MatInvertBlockDiagonalMat()` 10459 @*/ 10460 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values) 10461 { 10462 PetscFunctionBegin; 10463 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10464 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10465 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10466 PetscCheck(mat->ops->invertblockdiagonal,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for type %s",((PetscObject)mat)->type_name); 10467 PetscCall((*mat->ops->invertblockdiagonal)(mat,values)); 10468 PetscFunctionReturn(0); 10469 } 10470 10471 /*@C 10472 MatInvertVariableBlockDiagonal - Inverts the point block diagonal entries. 10473 10474 Collective on Mat 10475 10476 Input Parameters: 10477 + mat - the matrix 10478 . nblocks - the number of blocks on the process, set with MatSetVariableBlockSizes() 10479 - bsizes - the size of each block on the process, set with MatSetVariableBlockSizes() 10480 10481 Output Parameters: 10482 . values - the block inverses in column major order (FORTRAN-like) 10483 10484 Note: 10485 This routine is not available from Fortran. 10486 10487 Level: advanced 10488 10489 .seealso: `MatInvertBlockDiagonal()`, `MatSetVariableBlockSizes()`, `MatInvertVariableBlockEnvelope()` 10490 @*/ 10491 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values) 10492 { 10493 PetscFunctionBegin; 10494 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10495 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10496 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10497 PetscCheck(mat->ops->invertvariableblockdiagonal,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for type %s",((PetscObject)mat)->type_name); 10498 PetscCall((*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values)); 10499 PetscFunctionReturn(0); 10500 } 10501 10502 /*@ 10503 MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A 10504 10505 Collective on Mat 10506 10507 Input Parameters: 10508 . A - the matrix 10509 10510 Output Parameters: 10511 . C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set. 10512 10513 Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C 10514 10515 Level: advanced 10516 10517 .seealso: `MatInvertBlockDiagonal()` 10518 @*/ 10519 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C) 10520 { 10521 const PetscScalar *vals; 10522 PetscInt *dnnz; 10523 PetscInt m,rstart,rend,bs,i,j; 10524 10525 PetscFunctionBegin; 10526 PetscCall(MatInvertBlockDiagonal(A,&vals)); 10527 PetscCall(MatGetBlockSize(A,&bs)); 10528 PetscCall(MatGetLocalSize(A,&m,NULL)); 10529 PetscCall(MatSetLayouts(C,A->rmap,A->cmap)); 10530 PetscCall(PetscMalloc1(m/bs,&dnnz)); 10531 for (j = 0; j < m/bs; j++) dnnz[j] = 1; 10532 PetscCall(MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL)); 10533 PetscCall(PetscFree(dnnz)); 10534 PetscCall(MatGetOwnershipRange(C,&rstart,&rend)); 10535 PetscCall(MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE)); 10536 for (i = rstart/bs; i < rend/bs; i++) { 10537 PetscCall(MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES)); 10538 } 10539 PetscCall(MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY)); 10540 PetscCall(MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY)); 10541 PetscCall(MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE)); 10542 PetscFunctionReturn(0); 10543 } 10544 10545 /*@C 10546 MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created 10547 via MatTransposeColoringCreate(). 10548 10549 Collective on MatTransposeColoring 10550 10551 Input Parameter: 10552 . c - coloring context 10553 10554 Level: intermediate 10555 10556 .seealso: `MatTransposeColoringCreate()` 10557 @*/ 10558 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c) 10559 { 10560 MatTransposeColoring matcolor=*c; 10561 10562 PetscFunctionBegin; 10563 if (!matcolor) PetscFunctionReturn(0); 10564 if (--((PetscObject)matcolor)->refct > 0) {matcolor = NULL; PetscFunctionReturn(0);} 10565 10566 PetscCall(PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow)); 10567 PetscCall(PetscFree(matcolor->rows)); 10568 PetscCall(PetscFree(matcolor->den2sp)); 10569 PetscCall(PetscFree(matcolor->colorforcol)); 10570 PetscCall(PetscFree(matcolor->columns)); 10571 if (matcolor->brows>0) PetscCall(PetscFree(matcolor->lstart)); 10572 PetscCall(PetscHeaderDestroy(c)); 10573 PetscFunctionReturn(0); 10574 } 10575 10576 /*@C 10577 MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which 10578 a MatTransposeColoring context has been created, computes a dense B^T by Apply 10579 MatTransposeColoring to sparse B. 10580 10581 Collective on MatTransposeColoring 10582 10583 Input Parameters: 10584 + B - sparse matrix B 10585 . Btdense - symbolic dense matrix B^T 10586 - coloring - coloring context created with MatTransposeColoringCreate() 10587 10588 Output Parameter: 10589 . Btdense - dense matrix B^T 10590 10591 Level: advanced 10592 10593 Notes: 10594 These are used internally for some implementations of MatRARt() 10595 10596 .seealso: `MatTransposeColoringCreate()`, `MatTransposeColoringDestroy()`, `MatTransColoringApplyDenToSp()` 10597 10598 @*/ 10599 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense) 10600 { 10601 PetscFunctionBegin; 10602 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 10603 PetscValidHeaderSpecific(Btdense,MAT_CLASSID,3); 10604 PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,1); 10605 10606 PetscCheck(B->ops->transcoloringapplysptoden,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name); 10607 PetscCall((B->ops->transcoloringapplysptoden)(coloring,B,Btdense)); 10608 PetscFunctionReturn(0); 10609 } 10610 10611 /*@C 10612 MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which 10613 a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense 10614 in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix 10615 Csp from Cden. 10616 10617 Collective on MatTransposeColoring 10618 10619 Input Parameters: 10620 + coloring - coloring context created with MatTransposeColoringCreate() 10621 - Cden - matrix product of a sparse matrix and a dense matrix Btdense 10622 10623 Output Parameter: 10624 . Csp - sparse matrix 10625 10626 Level: advanced 10627 10628 Notes: 10629 These are used internally for some implementations of MatRARt() 10630 10631 .seealso: `MatTransposeColoringCreate()`, `MatTransposeColoringDestroy()`, `MatTransColoringApplySpToDen()` 10632 10633 @*/ 10634 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp) 10635 { 10636 PetscFunctionBegin; 10637 PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1); 10638 PetscValidHeaderSpecific(Cden,MAT_CLASSID,2); 10639 PetscValidHeaderSpecific(Csp,MAT_CLASSID,3); 10640 10641 PetscCheck(Csp->ops->transcoloringapplydentosp,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name); 10642 PetscCall((Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp)); 10643 PetscCall(MatAssemblyBegin(Csp,MAT_FINAL_ASSEMBLY)); 10644 PetscCall(MatAssemblyEnd(Csp,MAT_FINAL_ASSEMBLY)); 10645 PetscFunctionReturn(0); 10646 } 10647 10648 /*@C 10649 MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T. 10650 10651 Collective on Mat 10652 10653 Input Parameters: 10654 + mat - the matrix product C 10655 - iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring() 10656 10657 Output Parameter: 10658 . color - the new coloring context 10659 10660 Level: intermediate 10661 10662 .seealso: `MatTransposeColoringDestroy()`, `MatTransColoringApplySpToDen()`, 10663 `MatTransColoringApplyDenToSp()` 10664 @*/ 10665 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color) 10666 { 10667 MatTransposeColoring c; 10668 MPI_Comm comm; 10669 10670 PetscFunctionBegin; 10671 PetscCall(PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0)); 10672 PetscCall(PetscObjectGetComm((PetscObject)mat,&comm)); 10673 PetscCall(PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL)); 10674 10675 c->ctype = iscoloring->ctype; 10676 if (mat->ops->transposecoloringcreate) { 10677 PetscCall((*mat->ops->transposecoloringcreate)(mat,iscoloring,c)); 10678 } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for matrix type %s",((PetscObject)mat)->type_name); 10679 10680 *color = c; 10681 PetscCall(PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0)); 10682 PetscFunctionReturn(0); 10683 } 10684 10685 /*@ 10686 MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the 10687 matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the 10688 same, otherwise it will be larger 10689 10690 Not Collective 10691 10692 Input Parameter: 10693 . A - the matrix 10694 10695 Output Parameter: 10696 . state - the current state 10697 10698 Notes: 10699 You can only compare states from two different calls to the SAME matrix, you cannot compare calls between 10700 different matrices 10701 10702 Level: intermediate 10703 10704 .seealso: `PetscObjectStateGet()` 10705 @*/ 10706 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state) 10707 { 10708 PetscFunctionBegin; 10709 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10710 *state = mat->nonzerostate; 10711 PetscFunctionReturn(0); 10712 } 10713 10714 /*@ 10715 MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential 10716 matrices from each processor 10717 10718 Collective 10719 10720 Input Parameters: 10721 + comm - the communicators the parallel matrix will live on 10722 . seqmat - the input sequential matrices 10723 . n - number of local columns (or PETSC_DECIDE) 10724 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10725 10726 Output Parameter: 10727 . mpimat - the parallel matrix generated 10728 10729 Level: advanced 10730 10731 Notes: 10732 The number of columns of the matrix in EACH processor MUST be the same. 10733 10734 @*/ 10735 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat) 10736 { 10737 PetscMPIInt size; 10738 10739 PetscFunctionBegin; 10740 PetscCallMPI(MPI_Comm_size(comm,&size)); 10741 if (size == 1) { 10742 if (reuse == MAT_INITIAL_MATRIX) { 10743 PetscCall(MatDuplicate(seqmat,MAT_COPY_VALUES,mpimat)); 10744 } else { 10745 PetscCall(MatCopy(seqmat,*mpimat,SAME_NONZERO_PATTERN)); 10746 } 10747 PetscFunctionReturn(0); 10748 } 10749 10750 PetscCheck(seqmat->ops->creatempimatconcatenateseqmat,PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name); 10751 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"); 10752 10753 PetscCall(PetscLogEventBegin(MAT_Merge,seqmat,0,0,0)); 10754 PetscCall((*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat)); 10755 PetscCall(PetscLogEventEnd(MAT_Merge,seqmat,0,0,0)); 10756 PetscFunctionReturn(0); 10757 } 10758 10759 /*@ 10760 MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent 10761 ranks' ownership ranges. 10762 10763 Collective on A 10764 10765 Input Parameters: 10766 + A - the matrix to create subdomains from 10767 - N - requested number of subdomains 10768 10769 Output Parameters: 10770 + n - number of subdomains resulting on this rank 10771 - iss - IS list with indices of subdomains on this rank 10772 10773 Level: advanced 10774 10775 Notes: 10776 number of subdomains must be smaller than the communicator size 10777 @*/ 10778 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[]) 10779 { 10780 MPI_Comm comm,subcomm; 10781 PetscMPIInt size,rank,color; 10782 PetscInt rstart,rend,k; 10783 10784 PetscFunctionBegin; 10785 PetscCall(PetscObjectGetComm((PetscObject)A,&comm)); 10786 PetscCallMPI(MPI_Comm_size(comm,&size)); 10787 PetscCallMPI(MPI_Comm_rank(comm,&rank)); 10788 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); 10789 *n = 1; 10790 k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */ 10791 color = rank/k; 10792 PetscCallMPI(MPI_Comm_split(comm,color,rank,&subcomm)); 10793 PetscCall(PetscMalloc1(1,iss)); 10794 PetscCall(MatGetOwnershipRange(A,&rstart,&rend)); 10795 PetscCall(ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0])); 10796 PetscCallMPI(MPI_Comm_free(&subcomm)); 10797 PetscFunctionReturn(0); 10798 } 10799 10800 /*@ 10801 MatGalerkin - Constructs the coarse grid problem via Galerkin projection. 10802 10803 If the interpolation and restriction operators are the same, uses MatPtAP. 10804 If they are not the same, use MatMatMatMult. 10805 10806 Once the coarse grid problem is constructed, correct for interpolation operators 10807 that are not of full rank, which can legitimately happen in the case of non-nested 10808 geometric multigrid. 10809 10810 Input Parameters: 10811 + restrct - restriction operator 10812 . dA - fine grid matrix 10813 . interpolate - interpolation operator 10814 . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10815 - fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate 10816 10817 Output Parameters: 10818 . A - the Galerkin coarse matrix 10819 10820 Options Database Key: 10821 . -pc_mg_galerkin <both,pmat,mat,none> - for what matrices the Galerkin process should be used 10822 10823 Level: developer 10824 10825 .seealso: `MatPtAP()`, `MatMatMatMult()` 10826 @*/ 10827 PetscErrorCode MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A) 10828 { 10829 IS zerorows; 10830 Vec diag; 10831 10832 PetscFunctionBegin; 10833 PetscCheck(reuse != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 10834 /* Construct the coarse grid matrix */ 10835 if (interpolate == restrct) { 10836 PetscCall(MatPtAP(dA,interpolate,reuse,fill,A)); 10837 } else { 10838 PetscCall(MatMatMatMult(restrct,dA,interpolate,reuse,fill,A)); 10839 } 10840 10841 /* If the interpolation matrix is not of full rank, A will have zero rows. 10842 This can legitimately happen in the case of non-nested geometric multigrid. 10843 In that event, we set the rows of the matrix to the rows of the identity, 10844 ignoring the equations (as the RHS will also be zero). */ 10845 10846 PetscCall(MatFindZeroRows(*A, &zerorows)); 10847 10848 if (zerorows != NULL) { /* if there are any zero rows */ 10849 PetscCall(MatCreateVecs(*A, &diag, NULL)); 10850 PetscCall(MatGetDiagonal(*A, diag)); 10851 PetscCall(VecISSet(diag, zerorows, 1.0)); 10852 PetscCall(MatDiagonalSet(*A, diag, INSERT_VALUES)); 10853 PetscCall(VecDestroy(&diag)); 10854 PetscCall(ISDestroy(&zerorows)); 10855 } 10856 PetscFunctionReturn(0); 10857 } 10858 10859 /*@C 10860 MatSetOperation - Allows user to set a matrix operation for any matrix type 10861 10862 Logically Collective on Mat 10863 10864 Input Parameters: 10865 + mat - the matrix 10866 . op - the name of the operation 10867 - f - the function that provides the operation 10868 10869 Level: developer 10870 10871 Usage: 10872 $ extern PetscErrorCode usermult(Mat,Vec,Vec); 10873 $ PetscCall(MatCreateXXX(comm,...&A); 10874 $ PetscCall(MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult); 10875 10876 Notes: 10877 See the file include/petscmat.h for a complete list of matrix 10878 operations, which all have the form MATOP_<OPERATION>, where 10879 <OPERATION> is the name (in all capital letters) of the 10880 user interface routine (e.g., MatMult() -> MATOP_MULT). 10881 10882 All user-provided functions (except for MATOP_DESTROY) should have the same calling 10883 sequence as the usual matrix interface routines, since they 10884 are intended to be accessed via the usual matrix interface 10885 routines, e.g., 10886 $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 10887 10888 In particular each function MUST return an error code of 0 on success and 10889 nonzero on failure. 10890 10891 This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type. 10892 10893 .seealso: `MatGetOperation()`, `MatCreateShell()`, `MatShellSetContext()`, `MatShellSetOperation()` 10894 @*/ 10895 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void)) 10896 { 10897 PetscFunctionBegin; 10898 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10899 if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) { 10900 mat->ops->viewnative = mat->ops->view; 10901 } 10902 (((void(**)(void))mat->ops)[op]) = f; 10903 PetscFunctionReturn(0); 10904 } 10905 10906 /*@C 10907 MatGetOperation - Gets a matrix operation for any matrix type. 10908 10909 Not Collective 10910 10911 Input Parameters: 10912 + mat - the matrix 10913 - op - the name of the operation 10914 10915 Output Parameter: 10916 . f - the function that provides the operation 10917 10918 Level: developer 10919 10920 Usage: 10921 $ PetscErrorCode (*usermult)(Mat,Vec,Vec); 10922 $ MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult); 10923 10924 Notes: 10925 See the file include/petscmat.h for a complete list of matrix 10926 operations, which all have the form MATOP_<OPERATION>, where 10927 <OPERATION> is the name (in all capital letters) of the 10928 user interface routine (e.g., MatMult() -> MATOP_MULT). 10929 10930 This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type. 10931 10932 .seealso: `MatSetOperation()`, `MatCreateShell()`, `MatShellGetContext()`, `MatShellGetOperation()` 10933 @*/ 10934 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void)) 10935 { 10936 PetscFunctionBegin; 10937 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10938 *f = (((void (**)(void))mat->ops)[op]); 10939 PetscFunctionReturn(0); 10940 } 10941 10942 /*@ 10943 MatHasOperation - Determines whether the given matrix supports the particular 10944 operation. 10945 10946 Not Collective 10947 10948 Input Parameters: 10949 + mat - the matrix 10950 - op - the operation, for example, MATOP_GET_DIAGONAL 10951 10952 Output Parameter: 10953 . has - either PETSC_TRUE or PETSC_FALSE 10954 10955 Level: advanced 10956 10957 Notes: 10958 See the file include/petscmat.h for a complete list of matrix 10959 operations, which all have the form MATOP_<OPERATION>, where 10960 <OPERATION> is the name (in all capital letters) of the 10961 user-level routine. E.g., MatNorm() -> MATOP_NORM. 10962 10963 .seealso: `MatCreateShell()` 10964 @*/ 10965 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has) 10966 { 10967 PetscFunctionBegin; 10968 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10969 PetscValidBoolPointer(has,3); 10970 if (mat->ops->hasoperation) { 10971 PetscCall((*mat->ops->hasoperation)(mat,op,has)); 10972 } else { 10973 if (((void**)mat->ops)[op]) *has = PETSC_TRUE; 10974 else { 10975 *has = PETSC_FALSE; 10976 if (op == MATOP_CREATE_SUBMATRIX) { 10977 PetscMPIInt size; 10978 10979 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 10980 if (size == 1) { 10981 PetscCall(MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has)); 10982 } 10983 } 10984 } 10985 } 10986 PetscFunctionReturn(0); 10987 } 10988 10989 /*@ 10990 MatHasCongruentLayouts - Determines whether the rows and columns layouts 10991 of the matrix are congruent 10992 10993 Collective on mat 10994 10995 Input Parameters: 10996 . mat - the matrix 10997 10998 Output Parameter: 10999 . cong - either PETSC_TRUE or PETSC_FALSE 11000 11001 Level: beginner 11002 11003 Notes: 11004 11005 .seealso: `MatCreate()`, `MatSetSizes()` 11006 @*/ 11007 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong) 11008 { 11009 PetscFunctionBegin; 11010 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 11011 PetscValidType(mat,1); 11012 PetscValidBoolPointer(cong,2); 11013 if (!mat->rmap || !mat->cmap) { 11014 *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE; 11015 PetscFunctionReturn(0); 11016 } 11017 if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */ 11018 PetscCall(PetscLayoutSetUp(mat->rmap)); 11019 PetscCall(PetscLayoutSetUp(mat->cmap)); 11020 PetscCall(PetscLayoutCompare(mat->rmap,mat->cmap,cong)); 11021 if (*cong) mat->congruentlayouts = 1; 11022 else mat->congruentlayouts = 0; 11023 } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE; 11024 PetscFunctionReturn(0); 11025 } 11026 11027 PetscErrorCode MatSetInf(Mat A) 11028 { 11029 PetscFunctionBegin; 11030 PetscCheck(A->ops->setinf,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"No support for this operation for this matrix type"); 11031 PetscCall((*A->ops->setinf)(A)); 11032 PetscFunctionReturn(0); 11033 } 11034 11035 /*C 11036 MatCreateGraph - create a scalar matrix, for use in graph algorithms 11037 11038 Collective on mat 11039 11040 Input Parameters: 11041 + A - the matrix 11042 - sym - PETSC_TRUE indicates that the graph will be symmetrized 11043 . scale - PETSC_TRUE indicates that the graph will be scaled with the diagonal 11044 11045 Output Parameter: 11046 . graph - the resulting graph 11047 11048 Level: advanced 11049 11050 Notes: 11051 11052 .seealso: `MatCreate()`, `MatFilter()` 11053 */ 11054 PETSC_EXTERN PetscErrorCode MatCreateGraph(Mat A, PetscBool sym, PetscBool scale, Mat *graph) 11055 { 11056 PetscFunctionBegin; 11057 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 11058 PetscValidType(A,1); 11059 PetscValidPointer(graph,3); 11060 PetscCheck(A->ops->creategraph,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"No support for this operation for this matrix type"); 11061 PetscCall((*A->ops->creategraph)(A,sym,scale,graph)); 11062 PetscFunctionReturn(0); 11063 } 11064 11065 /*C 11066 MatFilter - filters a Mat values with an absolut value equal to or below a give threshold 11067 11068 Collective on mat 11069 11070 Input Parameter: 11071 . value - filter value - < 0: does nothing; == 0: removes only 0.0 entries; otherwise: removes entries <= value 11072 11073 Input/Output Parameter: 11074 . A - the Mat to filter in place 11075 11076 Level: advanced 11077 11078 Notes: 11079 11080 .seealso: `MatCreate()`, `MatCreateGraph()` 11081 */ 11082 PETSC_EXTERN PetscErrorCode MatFilter(Mat G,PetscReal value,Mat *F) 11083 { 11084 PetscFunctionBegin; 11085 PetscValidHeaderSpecific(G,MAT_CLASSID,1); 11086 PetscValidType(G,1); 11087 PetscValidPointer(F,3); 11088 if (value >= 0.0) { 11089 PetscCheck(G->ops->filter,PetscObjectComm((PetscObject)G),PETSC_ERR_SUP,"No support for this operation for this matrix type"); 11090 PetscCall((G->ops->filter)(G,value,F)); 11091 } 11092 PetscFunctionReturn(0); 11093 } 11094