1 /* 2 This is where the abstract matrix operations are defined 3 */ 4 5 #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/ 6 #include <petsc/private/isimpl.h> 7 #include <petsc/private/vecimpl.h> 8 9 /* Logging support */ 10 PetscClassId MAT_CLASSID; 11 PetscClassId MAT_COLORING_CLASSID; 12 PetscClassId MAT_FDCOLORING_CLASSID; 13 PetscClassId MAT_TRANSPOSECOLORING_CLASSID; 14 15 PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultAdd, MAT_MultTranspose; 16 PetscLogEvent MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve,MAT_MatTrSolve; 17 PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic; 18 PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor; 19 PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin; 20 PetscLogEvent MAT_QRFactorNumeric, MAT_QRFactorSymbolic, MAT_QRFactor; 21 PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_CreateSubMats, MAT_GetOrdering, MAT_RedundantMat, MAT_GetSeqNonzeroStructure; 22 PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_PartitioningND, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate; 23 PetscLogEvent MAT_FDColoringSetUp, MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction, MAT_CreateSubMat; 24 PetscLogEvent MAT_TransposeColoringCreate; 25 PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric; 26 PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric; 27 PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric; 28 PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric; 29 PetscLogEvent MAT_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric; 30 PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd; 31 PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_GetBrowsOfAcols; 32 PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym; 33 PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure; 34 PetscLogEvent MAT_GetMultiProcBlock; 35 PetscLogEvent MAT_CUSPARSECopyToGPU, MAT_CUSPARSECopyFromGPU, MAT_CUSPARSEGenerateTranspose, MAT_CUSPARSESolveAnalysis; 36 PetscLogEvent MAT_PreallCOO, MAT_SetVCOO; 37 PetscLogEvent MAT_SetValuesBatch; 38 PetscLogEvent MAT_ViennaCLCopyToGPU; 39 PetscLogEvent MAT_DenseCopyToGPU, MAT_DenseCopyFromGPU; 40 PetscLogEvent MAT_Merge,MAT_Residual,MAT_SetRandom; 41 PetscLogEvent MAT_FactorFactS,MAT_FactorInvS; 42 PetscLogEvent MATCOLORING_Apply,MATCOLORING_Comm,MATCOLORING_Local,MATCOLORING_ISCreate,MATCOLORING_SetUp,MATCOLORING_Weights; 43 PetscLogEvent MAT_H2Opus_Build,MAT_H2Opus_Compress,MAT_H2Opus_Orthog,MAT_H2Opus_LR; 44 45 const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","QR","MatFactorType","MAT_FACTOR_",NULL}; 46 47 /*@ 48 MatSetRandom - Sets all components of a matrix to random numbers. For sparse matrices that have been preallocated but not been assembled it randomly selects appropriate locations, 49 for sparse matrices that already have locations it fills the locations with random numbers 50 51 Logically Collective on Mat 52 53 Input Parameters: 54 + x - the matrix 55 - rctx - the random number context, formed by `PetscRandomCreate()`, or NULL and 56 it will create one internally. 57 58 Output Parameter: 59 . x - the matrix 60 61 Example of Usage: 62 .vb 63 PetscRandomCreate(PETSC_COMM_WORLD,&rctx); 64 MatSetRandom(x,rctx); 65 PetscRandomDestroy(rctx); 66 .ve 67 68 Level: intermediate 69 70 .seealso: `MatZeroEntries()`, `MatSetValues()`, `PetscRandomCreate()`, `PetscRandomDestroy()` 71 @*/ 72 PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx) 73 { 74 PetscRandom randObj = NULL; 75 76 PetscFunctionBegin; 77 PetscValidHeaderSpecific(x,MAT_CLASSID,1); 78 if (rctx) PetscValidHeaderSpecific(rctx,PETSC_RANDOM_CLASSID,2); 79 PetscValidType(x,1); 80 MatCheckPreallocated(x,1); 81 82 PetscCheck(x->ops->setrandom,PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Mat type %s",((PetscObject)x)->type_name); 83 84 if (!rctx) { 85 MPI_Comm comm; 86 PetscCall(PetscObjectGetComm((PetscObject)x,&comm)); 87 PetscCall(PetscRandomCreate(comm,&randObj)); 88 PetscCall(PetscRandomSetFromOptions(randObj)); 89 rctx = randObj; 90 } 91 PetscCall(PetscLogEventBegin(MAT_SetRandom,x,rctx,0,0)); 92 PetscCall((*x->ops->setrandom)(x,rctx)); 93 PetscCall(PetscLogEventEnd(MAT_SetRandom,x,rctx,0,0)); 94 95 PetscCall(MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY)); 96 PetscCall(MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY)); 97 PetscCall(PetscRandomDestroy(&randObj)); 98 PetscFunctionReturn(0); 99 } 100 101 /*@ 102 MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in 103 104 Logically Collective on Mat 105 106 Input Parameter: 107 . mat - the factored matrix 108 109 Output Parameters: 110 + pivot - the pivot value computed 111 - row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes 112 the share the matrix 113 114 Level: advanced 115 116 Notes: 117 This routine does not work for factorizations done with external packages. 118 119 This routine should only be called if `MatGetFactorError()` returns a value of `MAT_FACTOR_NUMERIC_ZEROPIVOT` 120 121 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 122 123 .seealso: `MatZeroEntries()`, `MatFactor()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()`, `MatFactorClearError()`, `MatFactorGetErrorZeroPivot()` 124 @*/ 125 PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row) 126 { 127 PetscFunctionBegin; 128 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 129 PetscValidRealPointer(pivot,2); 130 PetscValidIntPointer(row,3); 131 *pivot = mat->factorerror_zeropivot_value; 132 *row = mat->factorerror_zeropivot_row; 133 PetscFunctionReturn(0); 134 } 135 136 /*@ 137 MatFactorGetError - gets the error code from a factorization 138 139 Logically Collective on Mat 140 141 Input Parameters: 142 . mat - the factored matrix 143 144 Output Parameter: 145 . err - the error code 146 147 Level: advanced 148 149 Notes: 150 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 151 152 .seealso: `MatZeroEntries()`, `MatFactor()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()`, `MatFactorClearError()`, `MatFactorGetErrorZeroPivot()`, 153 `MatErrorCode` 154 @*/ 155 PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err) 156 { 157 PetscFunctionBegin; 158 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 159 PetscValidPointer(err,2); 160 *err = mat->factorerrortype; 161 PetscFunctionReturn(0); 162 } 163 164 /*@ 165 MatFactorClearError - clears the error code in a factorization 166 167 Logically Collective on Mat 168 169 Input Parameter: 170 . mat - the factored matrix 171 172 Level: developer 173 174 Notes: 175 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 176 177 .seealso: `MatZeroEntries()`, `MatFactor()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()`, `MatFactorGetError()`, `MatFactorGetErrorZeroPivot()`, 178 `MatGetErrorCode()`, `MatErrorCode` 179 @*/ 180 PetscErrorCode MatFactorClearError(Mat mat) 181 { 182 PetscFunctionBegin; 183 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 184 mat->factorerrortype = MAT_FACTOR_NOERROR; 185 mat->factorerror_zeropivot_value = 0.0; 186 mat->factorerror_zeropivot_row = 0; 187 PetscFunctionReturn(0); 188 } 189 190 PETSC_INTERN PetscErrorCode MatFindNonzeroRowsOrCols_Basic(Mat mat,PetscBool cols,PetscReal tol,IS *nonzero) 191 { 192 Vec r,l; 193 const PetscScalar *al; 194 PetscInt i,nz,gnz,N,n; 195 196 PetscFunctionBegin; 197 PetscCall(MatCreateVecs(mat,&r,&l)); 198 if (!cols) { /* nonzero rows */ 199 PetscCall(MatGetSize(mat,&N,NULL)); 200 PetscCall(MatGetLocalSize(mat,&n,NULL)); 201 PetscCall(VecSet(l,0.0)); 202 PetscCall(VecSetRandom(r,NULL)); 203 PetscCall(MatMult(mat,r,l)); 204 PetscCall(VecGetArrayRead(l,&al)); 205 } else { /* nonzero columns */ 206 PetscCall(MatGetSize(mat,NULL,&N)); 207 PetscCall(MatGetLocalSize(mat,NULL,&n)); 208 PetscCall(VecSet(r,0.0)); 209 PetscCall(VecSetRandom(l,NULL)); 210 PetscCall(MatMultTranspose(mat,l,r)); 211 PetscCall(VecGetArrayRead(r,&al)); 212 } 213 if (tol <= 0.0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++; } 214 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nz++; } 215 PetscCall(MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat))); 216 if (gnz != N) { 217 PetscInt *nzr; 218 PetscCall(PetscMalloc1(nz,&nzr)); 219 if (nz) { 220 if (tol < 0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; } 221 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nzr[nz++] = i; } 222 } 223 PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,nonzero)); 224 } else *nonzero = NULL; 225 if (!cols) { /* nonzero rows */ 226 PetscCall(VecRestoreArrayRead(l,&al)); 227 } else { 228 PetscCall(VecRestoreArrayRead(r,&al)); 229 } 230 PetscCall(VecDestroy(&l)); 231 PetscCall(VecDestroy(&r)); 232 PetscFunctionReturn(0); 233 } 234 235 /*@ 236 MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix 237 238 Input Parameter: 239 . A - the matrix 240 241 Output Parameter: 242 . keptrows - the rows that are not completely zero 243 244 Notes: 245 keptrows is set to NULL if all rows are nonzero. 246 247 Level: intermediate 248 249 @*/ 250 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows) 251 { 252 PetscFunctionBegin; 253 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 254 PetscValidType(mat,1); 255 PetscValidPointer(keptrows,2); 256 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 257 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 258 if (mat->ops->findnonzerorows) { 259 PetscCall((*mat->ops->findnonzerorows)(mat,keptrows)); 260 } else { 261 PetscCall(MatFindNonzeroRowsOrCols_Basic(mat,PETSC_FALSE,0.0,keptrows)); 262 } 263 PetscFunctionReturn(0); 264 } 265 266 /*@ 267 MatFindZeroRows - Locate all rows that are completely zero in the matrix 268 269 Input Parameter: 270 . A - the matrix 271 272 Output Parameter: 273 . zerorows - the rows that are completely zero 274 275 Notes: 276 zerorows is set to NULL if no rows are zero. 277 278 Level: intermediate 279 280 @*/ 281 PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows) 282 { 283 IS keptrows; 284 PetscInt m, n; 285 286 PetscFunctionBegin; 287 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 288 PetscValidType(mat,1); 289 PetscValidPointer(zerorows,2); 290 PetscCall(MatFindNonzeroRows(mat, &keptrows)); 291 /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows. 292 In keeping with this convention, we set zerorows to NULL if there are no zero 293 rows. */ 294 if (keptrows == NULL) { 295 *zerorows = NULL; 296 } else { 297 PetscCall(MatGetOwnershipRange(mat,&m,&n)); 298 PetscCall(ISComplement(keptrows,m,n,zerorows)); 299 PetscCall(ISDestroy(&keptrows)); 300 } 301 PetscFunctionReturn(0); 302 } 303 304 /*@ 305 MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling 306 307 Not Collective 308 309 Input Parameters: 310 . A - the matrix 311 312 Output Parameters: 313 . a - the diagonal part (which is a SEQUENTIAL matrix) 314 315 Notes: 316 See the manual page for `MatCreateAIJ()` for more information on the "diagonal part" of the matrix. 317 318 Use caution, as the reference count on the returned matrix is not incremented and it is used as part of the containing MPI Mat's normal operation. 319 320 Level: advanced 321 322 .seelaso: `MatCreateAIJ()` 323 @*/ 324 PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a) 325 { 326 PetscFunctionBegin; 327 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 328 PetscValidType(A,1); 329 PetscValidPointer(a,2); 330 PetscCheck(!A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 331 if (A->ops->getdiagonalblock) { 332 PetscCall((*A->ops->getdiagonalblock)(A,a)); 333 } else { 334 PetscMPIInt size; 335 336 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)A),&size)); 337 PetscCheck(size == 1,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not for parallel matrix type %s",((PetscObject)A)->type_name); 338 *a = A; 339 } 340 PetscFunctionReturn(0); 341 } 342 343 /*@ 344 MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries. 345 346 Collective on Mat 347 348 Input Parameters: 349 . mat - the matrix 350 351 Output Parameter: 352 . trace - the sum of the diagonal entries 353 354 Level: advanced 355 356 @*/ 357 PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace) 358 { 359 Vec diag; 360 361 PetscFunctionBegin; 362 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 363 PetscValidScalarPointer(trace,2); 364 PetscCall(MatCreateVecs(mat,&diag,NULL)); 365 PetscCall(MatGetDiagonal(mat,diag)); 366 PetscCall(VecSum(diag,trace)); 367 PetscCall(VecDestroy(&diag)); 368 PetscFunctionReturn(0); 369 } 370 371 /*@ 372 MatRealPart - Zeros out the imaginary part of the matrix 373 374 Logically Collective on Mat 375 376 Input Parameters: 377 . mat - the matrix 378 379 Level: advanced 380 381 .seealso: `MatImaginaryPart()` 382 @*/ 383 PetscErrorCode MatRealPart(Mat mat) 384 { 385 PetscFunctionBegin; 386 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 387 PetscValidType(mat,1); 388 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 389 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 390 PetscCheck(mat->ops->realpart,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 391 MatCheckPreallocated(mat,1); 392 PetscCall((*mat->ops->realpart)(mat)); 393 PetscFunctionReturn(0); 394 } 395 396 /*@C 397 MatGetGhosts - Get the global indices of all ghost nodes defined by the sparse matrix 398 399 Collective on Mat 400 401 Input Parameter: 402 . mat - the matrix 403 404 Output Parameters: 405 + nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block) 406 - ghosts - the global indices of the ghost points 407 408 Notes: 409 the nghosts and ghosts are suitable to pass into `VecCreateGhost()` 410 411 Level: advanced 412 413 @*/ 414 PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[]) 415 { 416 PetscFunctionBegin; 417 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 418 PetscValidType(mat,1); 419 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 420 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 421 if (mat->ops->getghosts) { 422 PetscCall((*mat->ops->getghosts)(mat,nghosts,ghosts)); 423 } else { 424 if (nghosts) *nghosts = 0; 425 if (ghosts) *ghosts = NULL; 426 } 427 PetscFunctionReturn(0); 428 } 429 430 /*@ 431 MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part 432 433 Logically Collective on Mat 434 435 Input Parameters: 436 . mat - the matrix 437 438 Level: advanced 439 440 .seealso: `MatRealPart()` 441 @*/ 442 PetscErrorCode MatImaginaryPart(Mat mat) 443 { 444 PetscFunctionBegin; 445 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 446 PetscValidType(mat,1); 447 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 448 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 449 PetscCheck(mat->ops->imaginarypart,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 450 MatCheckPreallocated(mat,1); 451 PetscCall((*mat->ops->imaginarypart)(mat)); 452 PetscFunctionReturn(0); 453 } 454 455 /*@ 456 MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices) 457 458 Not Collective 459 460 Input Parameter: 461 . mat - the matrix 462 463 Output Parameters: 464 + missing - is any diagonal missing 465 - dd - first diagonal entry that is missing (optional) on this process 466 467 Level: advanced 468 469 .seealso: `MatRealPart()` 470 @*/ 471 PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd) 472 { 473 PetscFunctionBegin; 474 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 475 PetscValidType(mat,1); 476 PetscValidBoolPointer(missing,2); 477 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix %s",((PetscObject)mat)->type_name); 478 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 479 PetscCheck(mat->ops->missingdiagonal,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 480 PetscCall((*mat->ops->missingdiagonal)(mat,missing,dd)); 481 PetscFunctionReturn(0); 482 } 483 484 /*@C 485 MatGetRow - Gets a row of a matrix. You MUST call `MatRestoreRow()` 486 for each row that you get to ensure that your application does 487 not bleed memory. 488 489 Not Collective 490 491 Input Parameters: 492 + mat - the matrix 493 - row - the row to get 494 495 Output Parameters: 496 + ncols - if not NULL, the number of nonzeros in the row 497 . cols - if not NULL, the column numbers 498 - vals - if not NULL, the values 499 500 Notes: 501 This routine is provided for people who need to have direct access 502 to the structure of a matrix. We hope that we provide enough 503 high-level matrix routines that few users will need it. 504 505 `MatGetRow()` always returns 0-based column indices, regardless of 506 whether the internal representation is 0-based (default) or 1-based. 507 508 For better efficiency, set cols and/or vals to NULL if you do 509 not wish to extract these quantities. 510 511 The user can only examine the values extracted with `MatGetRow()`; 512 the values cannot be altered. To change the matrix entries, one 513 must use `MatSetValues()`. 514 515 You can only have one call to `MatGetRow()` outstanding for a particular 516 matrix at a time, per processor. `MatGetRow()` can only obtain rows 517 associated with the given processor, it cannot get rows from the 518 other processors; for that we suggest using `MatCreateSubMatrices()`, then 519 MatGetRow() on the submatrix. The row index passed to `MatGetRow()` 520 is in the global number of rows. 521 522 Use `MatGetRowIJ()` and `MatRestoreRowIJ()` to access all the local indices of the sparse matrix. 523 524 Use `MatSeqAIJGetArray()` and similar functions to access the numerical values for certain matrix types directly. 525 526 Fortran Notes: 527 The calling sequence from Fortran is 528 .vb 529 MatGetRow(matrix,row,ncols,cols,values,ierr) 530 Mat matrix (input) 531 integer row (input) 532 integer ncols (output) 533 integer cols(maxcols) (output) 534 double precision (or double complex) values(maxcols) output 535 .ve 536 where maxcols >= maximum nonzeros in any row of the matrix. 537 538 Caution: 539 Do not try to change the contents of the output arrays (cols and vals). 540 In some cases, this may corrupt the matrix. 541 542 Level: advanced 543 544 .seealso: `MatRestoreRow()`, `MatSetValues()`, `MatGetValues()`, `MatCreateSubMatrices()`, `MatGetDiagonal()`, `MatGetRowIJ()`, `MatRestoreRowIJ()` 545 @*/ 546 PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 547 { 548 PetscInt incols; 549 550 PetscFunctionBegin; 551 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 552 PetscValidType(mat,1); 553 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 554 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 555 PetscCheck(mat->ops->getrow,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 556 MatCheckPreallocated(mat,1); 557 PetscCheck(row >= mat->rmap->rstart && row < mat->rmap->rend,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Only for local rows, %" PetscInt_FMT " not in [%" PetscInt_FMT ",%" PetscInt_FMT ")",row,mat->rmap->rstart,mat->rmap->rend); 558 PetscCall(PetscLogEventBegin(MAT_GetRow,mat,0,0,0)); 559 PetscCall((*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals)); 560 if (ncols) *ncols = incols; 561 PetscCall(PetscLogEventEnd(MAT_GetRow,mat,0,0,0)); 562 PetscFunctionReturn(0); 563 } 564 565 /*@ 566 MatConjugate - replaces the matrix values with their complex conjugates 567 568 Logically Collective on Mat 569 570 Input Parameters: 571 . mat - the matrix 572 573 Level: advanced 574 575 .seealso: `VecConjugate()`, `MatTranspose()` 576 @*/ 577 PetscErrorCode MatConjugate(Mat mat) 578 { 579 PetscFunctionBegin; 580 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 581 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 582 if (PetscDefined(USE_COMPLEX)) { 583 PetscCheck(mat->ops->conjugate,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not provided for matrix type %s, send email to petsc-maint@mcs.anl.gov",((PetscObject)mat)->type_name); 584 PetscCall((*mat->ops->conjugate)(mat)); 585 } 586 PetscFunctionReturn(0); 587 } 588 589 /*@C 590 MatRestoreRow - Frees any temporary space allocated by `MatGetRow()`. 591 592 Not Collective 593 594 Input Parameters: 595 + mat - the matrix 596 . row - the row to get 597 . ncols, cols - the number of nonzeros and their columns 598 - vals - if nonzero the column values 599 600 Notes: 601 This routine should be called after you have finished examining the entries. 602 603 This routine zeros out ncols, cols, and vals. This is to prevent accidental 604 us of the array after it has been restored. If you pass NULL, it will 605 not zero the pointers. Use of cols or vals after `MatRestoreRow()` is invalid. 606 607 Fortran Notes: 608 The calling sequence from Fortran is 609 .vb 610 MatRestoreRow(matrix,row,ncols,cols,values,ierr) 611 Mat matrix (input) 612 integer row (input) 613 integer ncols (output) 614 integer cols(maxcols) (output) 615 double precision (or double complex) values(maxcols) output 616 .ve 617 Where maxcols >= maximum nonzeros in any row of the matrix. 618 619 In Fortran `MatRestoreRow()` MUST be called after `MatGetRow()` 620 before another call to `MatGetRow()` can be made. 621 622 Level: advanced 623 624 .seealso: `MatGetRow()` 625 @*/ 626 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 627 { 628 PetscFunctionBegin; 629 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 630 if (ncols) PetscValidIntPointer(ncols,3); 631 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 632 if (!mat->ops->restorerow) PetscFunctionReturn(0); 633 PetscCall((*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals)); 634 if (ncols) *ncols = 0; 635 if (cols) *cols = NULL; 636 if (vals) *vals = NULL; 637 PetscFunctionReturn(0); 638 } 639 640 /*@ 641 MatGetRowUpperTriangular - Sets a flag to enable calls to `MatGetRow()` for matrix in `MATSBAIJ` format. 642 You should call `MatRestoreRowUpperTriangular()` after calling` MatGetRow()` and `MatRestoreRow()` to disable the flag. 643 644 Not Collective 645 646 Input Parameters: 647 . mat - the matrix 648 649 Notes: 650 The flag is to ensure that users are aware of `MatGetRow()` only provides the upper triangular part of the row for the matrices in `MATSBAIJ` format. 651 652 Level: advanced 653 654 .seealso: `MatRestoreRowUpperTriangular()` 655 @*/ 656 PetscErrorCode MatGetRowUpperTriangular(Mat mat) 657 { 658 PetscFunctionBegin; 659 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 660 PetscValidType(mat,1); 661 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 662 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 663 MatCheckPreallocated(mat,1); 664 if (!mat->ops->getrowuppertriangular) PetscFunctionReturn(0); 665 PetscCall((*mat->ops->getrowuppertriangular)(mat)); 666 PetscFunctionReturn(0); 667 } 668 669 /*@ 670 MatRestoreRowUpperTriangular - Disable calls to `MatGetRow()` for matrix in `MATSBAIJ` format. 671 672 Not Collective 673 674 Input Parameters: 675 . mat - the matrix 676 677 Notes: 678 This routine should be called after you have finished calls to `MatGetRow()` and `MatRestoreRow()`. 679 680 Level: advanced 681 682 .seealso: `MatGetRowUpperTriangular()` 683 @*/ 684 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat) 685 { 686 PetscFunctionBegin; 687 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 688 PetscValidType(mat,1); 689 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 690 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 691 MatCheckPreallocated(mat,1); 692 if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0); 693 PetscCall((*mat->ops->restorerowuppertriangular)(mat)); 694 PetscFunctionReturn(0); 695 } 696 697 /*@C 698 MatSetOptionsPrefix - Sets the prefix used for searching for all 699 Mat options in the database. 700 701 Logically Collective on Mat 702 703 Input Parameters: 704 + A - the Mat context 705 - prefix - the prefix to prepend to all option names 706 707 Notes: 708 A hyphen (-) must NOT be given at the beginning of the prefix name. 709 The first character of all runtime options is AUTOMATICALLY the hyphen. 710 711 This is NOT used for options for the factorization of the matrix. Normally the 712 prefix is automatically passed in from the PC calling the factorization. To set 713 it directly use `MatSetOptionsPrefixFactor()` 714 715 Level: advanced 716 717 .seealso: `MatSetFromOptions()`, `MatSetOptionsPrefixFactor()` 718 @*/ 719 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[]) 720 { 721 PetscFunctionBegin; 722 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 723 PetscCall(PetscObjectSetOptionsPrefix((PetscObject)A,prefix)); 724 PetscFunctionReturn(0); 725 } 726 727 /*@C 728 MatSetOptionsPrefixFactor - Sets the prefix used for searching for all Mat factor options in the database for 729 for matrices created with `MatGetFactor()` 730 731 Logically Collective on Mat 732 733 Input Parameters: 734 + A - the Mat context 735 - prefix - the prefix to prepend to all option names for the factored matrix 736 737 Notes: 738 A hyphen (-) must NOT be given at the beginning of the prefix name. 739 The first character of all runtime options is AUTOMATICALLY the hyphen. 740 741 Normally the prefix is automatically passed in from the PC calling the factorization. To set 742 it directly when not using `KSP`/`PC` use `MatSetOptionsPrefixFactor()` 743 744 Level: developer 745 746 .seealso: `MatSetFromOptions()`, `MatSetOptionsPrefix()`, `MatAppendOptionsPrefixFactor()` 747 @*/ 748 PetscErrorCode MatSetOptionsPrefixFactor(Mat A,const char prefix[]) 749 { 750 PetscFunctionBegin; 751 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 752 if (prefix) { 753 PetscValidCharPointer(prefix,2); 754 PetscCheck(prefix[0] != '-',PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Options prefix should not begin with a hyphen"); 755 if (prefix != A->factorprefix) { 756 PetscCall(PetscFree(A->factorprefix)); 757 PetscCall(PetscStrallocpy(prefix,&A->factorprefix)); 758 } 759 } else PetscCall(PetscFree(A->factorprefix)); 760 PetscFunctionReturn(0); 761 } 762 763 /*@C 764 MatAppendOptionsPrefixFactor - Appends to the prefix used for searching for all Mat factor options in the database for 765 for matrices created with `MatGetFactor()` 766 767 Logically Collective on Mat 768 769 Input Parameters: 770 + A - the Mat context 771 - prefix - the prefix to prepend to all option names for the factored matrix 772 773 Notes: 774 A hyphen (-) must NOT be given at the beginning of the prefix name. 775 The first character of all runtime options is AUTOMATICALLY the hyphen. 776 777 Normally the prefix is automatically passed in from the PC calling the factorization. To set 778 it directly when not using `KSP`/`PC` use `MatAppendOptionsPrefixFactor()` 779 780 Level: developer 781 .seealso: `PetscOptionsCreate()`, `PetscOptionsDestroy()`, `PetscObjectSetOptionsPrefix()`, `PetscObjectPrependOptionsPrefix()`, 782 `PetscObjectGetOptionsPrefix()`, `TSAppendOptionsPrefix()`, `SNESAppendOptionsPrefix()`, `KSPAppendOptionsPrefix()`, `MatSetOptionsPrefixFactor()`, 783 `MatSetOptionsPrefix()` 784 @*/ 785 PetscErrorCode MatAppendOptionsPrefixFactor(Mat A,const char prefix[]) 786 { 787 char *buf = A->factorprefix; 788 size_t len1,len2; 789 790 PetscFunctionBegin; 791 PetscValidHeader(A,1); 792 if (!prefix) PetscFunctionReturn(0); 793 if (!buf) { 794 PetscCall(MatSetOptionsPrefixFactor(A,prefix)); 795 PetscFunctionReturn(0); 796 } 797 PetscCheck(prefix[0] != '-',PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Options prefix should not begin with a hyphen"); 798 799 PetscCall(PetscStrlen(prefix,&len1)); 800 PetscCall(PetscStrlen(buf,&len2)); 801 PetscCall(PetscMalloc1(1+len1+len2,&A->factorprefix)); 802 PetscCall(PetscStrcpy(A->factorprefix,buf)); 803 PetscCall(PetscStrcat(A->factorprefix,prefix)); 804 PetscCall(PetscFree(buf)); 805 PetscFunctionReturn(0); 806 } 807 808 /*@C 809 MatAppendOptionsPrefix - Appends to the prefix used for searching for all 810 Mat options in the database. 811 812 Logically Collective on Mat 813 814 Input Parameters: 815 + A - the Mat context 816 - prefix - the prefix to prepend to all option names 817 818 Notes: 819 A hyphen (-) must NOT be given at the beginning of the prefix name. 820 The first character of all runtime options is AUTOMATICALLY the hyphen. 821 822 Level: advanced 823 824 .seealso: `MatGetOptionsPrefix()` 825 @*/ 826 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[]) 827 { 828 PetscFunctionBegin; 829 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 830 PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)A,prefix)); 831 PetscFunctionReturn(0); 832 } 833 834 /*@C 835 MatGetOptionsPrefix - Gets the prefix used for searching for all 836 Mat options in the database. 837 838 Not Collective 839 840 Input Parameter: 841 . A - the Mat context 842 843 Output Parameter: 844 . prefix - pointer to the prefix string used 845 846 Notes: 847 On the fortran side, the user should pass in a string 'prefix' of 848 sufficient length to hold the prefix. 849 850 Level: advanced 851 852 .seealso: `MatAppendOptionsPrefix()` 853 @*/ 854 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[]) 855 { 856 PetscFunctionBegin; 857 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 858 PetscValidPointer(prefix,2); 859 PetscCall(PetscObjectGetOptionsPrefix((PetscObject)A,prefix)); 860 PetscFunctionReturn(0); 861 } 862 863 /*@ 864 MatResetPreallocation - Reset mat to use the original nonzero pattern provided by users. 865 866 Collective on Mat 867 868 Input Parameters: 869 . A - the Mat context 870 871 Notes: 872 The allocated memory will be shrunk after calling `MatAssemblyBegin()` and `MatAssemblyEnd()` with `MAT_FINAL_ASSEMBLY`. 873 874 Users can reset the preallocation to access the original memory. 875 876 Currently only supported for `MATMPIAIJ` and `MATSEQAIJ` matrices. 877 878 Level: beginner 879 880 .seealso: `MatSeqAIJSetPreallocation()`, `MatMPIAIJSetPreallocation()`, `MatXAIJSetPreallocation()` 881 @*/ 882 PetscErrorCode MatResetPreallocation(Mat A) 883 { 884 PetscFunctionBegin; 885 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 886 PetscValidType(A,1); 887 PetscUseMethod(A,"MatResetPreallocation_C",(Mat),(A)); 888 PetscFunctionReturn(0); 889 } 890 891 /*@ 892 MatSetUp - Sets up the internal matrix data structures for later use. 893 894 Collective on Mat 895 896 Input Parameters: 897 . A - the Mat context 898 899 Notes: 900 If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used. 901 902 If a suitable preallocation routine is used, this function does not need to be called. 903 904 See the Performance chapter of the PETSc users manual for how to preallocate matrices 905 906 Level: beginner 907 908 .seealso: `MatCreate()`, `MatDestroy()` 909 @*/ 910 PetscErrorCode MatSetUp(Mat A) 911 { 912 PetscFunctionBegin; 913 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 914 if (!((PetscObject)A)->type_name) { 915 PetscMPIInt size; 916 917 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)A), &size)); 918 PetscCall(MatSetType(A, size == 1 ? MATSEQAIJ : MATMPIAIJ)); 919 } 920 if (!A->preallocated && A->ops->setup) { 921 PetscCall(PetscInfo(A,"Warning not preallocating matrix storage\n")); 922 PetscCall((*A->ops->setup)(A)); 923 } 924 PetscCall(PetscLayoutSetUp(A->rmap)); 925 PetscCall(PetscLayoutSetUp(A->cmap)); 926 A->preallocated = PETSC_TRUE; 927 PetscFunctionReturn(0); 928 } 929 930 #if defined(PETSC_HAVE_SAWS) 931 #include <petscviewersaws.h> 932 #endif 933 934 /*@C 935 MatViewFromOptions - View from Options 936 937 Collective on Mat 938 939 Input Parameters: 940 + A - the Mat context 941 . obj - Optional object 942 - name - command line option 943 944 Level: intermediate 945 .seealso: `Mat`, `MatView`, `PetscObjectViewFromOptions()`, `MatCreate()` 946 @*/ 947 PetscErrorCode MatViewFromOptions(Mat A,PetscObject obj,const char name[]) 948 { 949 PetscFunctionBegin; 950 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 951 PetscCall(PetscObjectViewFromOptions((PetscObject)A,obj,name)); 952 PetscFunctionReturn(0); 953 } 954 955 /*@C 956 MatView - Visualizes a matrix object. 957 958 Collective on Mat 959 960 Input Parameters: 961 + mat - the matrix 962 - viewer - visualization context 963 964 Notes: 965 The available visualization contexts include 966 + `PETSC_VIEWER_STDOUT_SELF` - for sequential matrices 967 . `PETSC_VIEWER_STDOUT_WORLD` - for parallel matrices created on `PETSC_COMM_WORLD` 968 . `PETSC_VIEWER_STDOUT_`(comm) - for matrices created on MPI communicator comm 969 - `PETSC_VIEWER_DRAW_WORLD` - graphical display of nonzero structure 970 971 The user can open alternative visualization contexts with 972 + `PetscViewerASCIIOpen()` - Outputs matrix to a specified file 973 . `PetscViewerBinaryOpen()` - Outputs matrix in binary to a 974 specified file; corresponding input uses MatLoad() 975 . `PetscViewerDrawOpen()` - Outputs nonzero matrix structure to 976 an X window display 977 - `PetscViewerSocketOpen()` - Outputs matrix to Socket viewer. 978 Currently only the sequential dense and AIJ 979 matrix types support the Socket viewer. 980 981 The user can call `PetscViewerPushFormat()` to specify the output 982 format of ASCII printed objects (when using `PETSC_VIEWER_STDOUT_SELF`, 983 `PETSC_VIEWER_STDOUT_WORLD` and `PetscViewerASCIIOpen()`). Available formats include 984 + `PETSC_VIEWER_DEFAULT` - default, prints matrix contents 985 . `PETSC_VIEWER_ASCII_MATLAB` - prints matrix contents in Matlab format 986 . `PETSC_VIEWER_ASCII_DENSE` - prints entire matrix including zeros 987 . `PETSC_VIEWER_ASCII_COMMON` - prints matrix contents, using a sparse 988 format common among all matrix types 989 . `PETSC_VIEWER_ASCII_IMPL` - prints matrix contents, using an implementation-specific 990 format (which is in many cases the same as the default) 991 . `PETSC_VIEWER_ASCII_INFO` - prints basic information about the matrix 992 size and structure (not the matrix entries) 993 - `PETSC_VIEWER_ASCII_INFO_DETAIL` - prints more detailed information about 994 the matrix structure 995 996 Options Database Keys: 997 + -mat_view ::ascii_info - Prints info on matrix at conclusion of `MatAssemblyEnd()` 998 . -mat_view ::ascii_info_detail - Prints more detailed info 999 . -mat_view - Prints matrix in ASCII format 1000 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 1001 . -mat_view draw - PetscDraws nonzero structure of matrix, using `MatView()` and `PetscDrawOpenX()`. 1002 . -display <name> - Sets display name (default is host) 1003 . -draw_pause <sec> - Sets number of seconds to pause after display 1004 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details) 1005 . -viewer_socket_machine <machine> - 1006 . -viewer_socket_port <port> - 1007 . -mat_view binary - save matrix to file in binary format 1008 - -viewer_binary_filename <name> - 1009 1010 Level: beginner 1011 1012 Notes: 1013 The ASCII viewers are only recommended for small matrices on at most a moderate number of processes, 1014 the program will seemingly hang and take hours for larger matrices, for larger matrices one should use the binary format. 1015 1016 In the debugger you can do "call MatView(mat,0)" to display the matrix. (The same holds for any PETSc object viewer). 1017 1018 See the manual page for `MatLoad()` for the exact format of the binary file when the binary 1019 viewer is used. 1020 1021 See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary 1022 viewer is used and lib/petsc/bin/PetscBinaryIO.py for loading them into Python. 1023 1024 One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure, 1025 and then use the following mouse functions. 1026 .vb 1027 left mouse: zoom in 1028 middle mouse: zoom out 1029 right mouse: continue with the simulation 1030 .ve 1031 1032 .seealso: `PetscViewerPushFormat()`, `PetscViewerASCIIOpen()`, `PetscViewerDrawOpen()`, 1033 `PetscViewerSocketOpen()`, `PetscViewerBinaryOpen()`, `MatLoad()` 1034 @*/ 1035 PetscErrorCode MatView(Mat mat,PetscViewer viewer) 1036 { 1037 PetscInt rows,cols,rbs,cbs; 1038 PetscBool isascii,isstring,issaws; 1039 PetscViewerFormat format; 1040 PetscMPIInt size; 1041 1042 PetscFunctionBegin; 1043 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1044 PetscValidType(mat,1); 1045 if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer)); 1046 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1047 PetscCheckSameComm(mat,1,viewer,2); 1048 MatCheckPreallocated(mat,1); 1049 1050 PetscCall(PetscViewerGetFormat(viewer,&format)); 1051 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 1052 if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0); 1053 1054 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring)); 1055 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii)); 1056 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws)); 1057 if ((!isascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) { 1058 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detail"); 1059 } 1060 1061 PetscCall(PetscLogEventBegin(MAT_View,mat,viewer,0,0)); 1062 if (isascii) { 1063 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix"); 1064 PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer)); 1065 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1066 MatNullSpace nullsp,transnullsp; 1067 1068 PetscCall(PetscViewerASCIIPushTab(viewer)); 1069 PetscCall(MatGetSize(mat,&rows,&cols)); 1070 PetscCall(MatGetBlockSizes(mat,&rbs,&cbs)); 1071 if (rbs != 1 || cbs != 1) { 1072 if (rbs != cbs) PetscCall(PetscViewerASCIIPrintf(viewer,"rows=%" PetscInt_FMT ", cols=%" PetscInt_FMT ", rbs=%" PetscInt_FMT ", cbs=%" PetscInt_FMT "\n",rows,cols,rbs,cbs)); 1073 else PetscCall(PetscViewerASCIIPrintf(viewer,"rows=%" PetscInt_FMT ", cols=%" PetscInt_FMT ", bs=%" PetscInt_FMT "\n",rows,cols,rbs)); 1074 } else PetscCall(PetscViewerASCIIPrintf(viewer,"rows=%" PetscInt_FMT ", cols=%" PetscInt_FMT "\n",rows,cols)); 1075 if (mat->factortype) { 1076 MatSolverType solver; 1077 PetscCall(MatFactorGetSolverType(mat,&solver)); 1078 PetscCall(PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver)); 1079 } 1080 if (mat->ops->getinfo) { 1081 MatInfo info; 1082 PetscCall(MatGetInfo(mat,MAT_GLOBAL_SUM,&info)); 1083 PetscCall(PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated)); 1084 if (!mat->factortype) PetscCall(PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls=%" PetscInt_FMT "\n",(PetscInt)info.mallocs)); 1085 } 1086 PetscCall(MatGetNullSpace(mat,&nullsp)); 1087 PetscCall(MatGetTransposeNullSpace(mat,&transnullsp)); 1088 if (nullsp) PetscCall(PetscViewerASCIIPrintf(viewer," has attached null space\n")); 1089 if (transnullsp && transnullsp != nullsp) PetscCall(PetscViewerASCIIPrintf(viewer," has attached transposed null space\n")); 1090 PetscCall(MatGetNearNullSpace(mat,&nullsp)); 1091 if (nullsp) PetscCall(PetscViewerASCIIPrintf(viewer," has attached near null space\n")); 1092 PetscCall(PetscViewerASCIIPushTab(viewer)); 1093 PetscCall(MatProductView(mat,viewer)); 1094 PetscCall(PetscViewerASCIIPopTab(viewer)); 1095 } 1096 } else if (issaws) { 1097 #if defined(PETSC_HAVE_SAWS) 1098 PetscMPIInt rank; 1099 1100 PetscCall(PetscObjectName((PetscObject)mat)); 1101 PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD,&rank)); 1102 if (!((PetscObject)mat)->amsmem && rank == 0) { 1103 PetscCall(PetscObjectViewSAWs((PetscObject)mat,viewer)); 1104 } 1105 #endif 1106 } else if (isstring) { 1107 const char *type; 1108 PetscCall(MatGetType(mat,&type)); 1109 PetscCall(PetscViewerStringSPrintf(viewer," MatType: %-7.7s",type)); 1110 if (mat->ops->view) PetscCall((*mat->ops->view)(mat,viewer)); 1111 } 1112 if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) { 1113 PetscCall(PetscViewerASCIIPushTab(viewer)); 1114 PetscCall((*mat->ops->viewnative)(mat,viewer)); 1115 PetscCall(PetscViewerASCIIPopTab(viewer)); 1116 } else if (mat->ops->view) { 1117 PetscCall(PetscViewerASCIIPushTab(viewer)); 1118 PetscCall((*mat->ops->view)(mat,viewer)); 1119 PetscCall(PetscViewerASCIIPopTab(viewer)); 1120 } 1121 if (isascii) { 1122 PetscCall(PetscViewerGetFormat(viewer,&format)); 1123 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1124 PetscCall(PetscViewerASCIIPopTab(viewer)); 1125 } 1126 } 1127 PetscCall(PetscLogEventEnd(MAT_View,mat,viewer,0,0)); 1128 PetscFunctionReturn(0); 1129 } 1130 1131 #if defined(PETSC_USE_DEBUG) 1132 #include <../src/sys/totalview/tv_data_display.h> 1133 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat) 1134 { 1135 TV_add_row("Local rows", "int", &mat->rmap->n); 1136 TV_add_row("Local columns", "int", &mat->cmap->n); 1137 TV_add_row("Global rows", "int", &mat->rmap->N); 1138 TV_add_row("Global columns", "int", &mat->cmap->N); 1139 TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name); 1140 return TV_format_OK; 1141 } 1142 #endif 1143 1144 /*@C 1145 MatLoad - Loads a matrix that has been stored in binary/HDF5 format 1146 with `MatView()`. The matrix format is determined from the options database. 1147 Generates a parallel MPI matrix if the communicator has more than one 1148 processor. The default matrix type is AIJ. 1149 1150 Collective on PetscViewer 1151 1152 Input Parameters: 1153 + mat - the newly loaded matrix, this needs to have been created with `MatCreate()` 1154 or some related function before a call to `MatLoad()` 1155 - viewer - binary/HDF5 file viewer 1156 1157 Options Database Keys: 1158 Used with block matrix formats (`MATSEQBAIJ`, ...) to specify 1159 block size 1160 . -matload_block_size <bs> - set block size 1161 1162 Level: beginner 1163 1164 Notes: 1165 If the Mat type has not yet been given then `MATAIJ` is used, call `MatSetFromOptions()` on the 1166 Mat before calling this routine if you wish to set it from the options database. 1167 1168 `MatLoad()` automatically loads into the options database any options 1169 given in the file filename.info where filename is the name of the file 1170 that was passed to the `PetscViewerBinaryOpen()`. The options in the info 1171 file will be ignored if you use the -viewer_binary_skip_info option. 1172 1173 If the type or size of mat is not set before a call to `MatLoad()`, PETSc 1174 sets the default matrix type AIJ and sets the local and global sizes. 1175 If type and/or size is already set, then the same are used. 1176 1177 In parallel, each processor can load a subset of rows (or the 1178 entire matrix). This routine is especially useful when a large 1179 matrix is stored on disk and only part of it is desired on each 1180 processor. For example, a parallel solver may access only some of 1181 the rows from each processor. The algorithm used here reads 1182 relatively small blocks of data rather than reading the entire 1183 matrix and then subsetting it. 1184 1185 Viewer's `PetscViewerType` must be either `PETSCVIEWERBINARY` or `PETSCVIEWERHDF5`. 1186 Such viewer can be created using `PetscViewerBinaryOpen()` or `PetscViewerHDF5Open()`, 1187 or the sequence like 1188 .vb 1189 `PetscViewer` v; 1190 `PetscViewerCreate`(`PETSC_COMM_WORLD`,&v); 1191 `PetscViewerSetType`(v,`PETSCVIEWERBINARY`); 1192 `PetscViewerSetFromOptions`(v); 1193 `PetscViewerFileSetMode`(v,`FILE_MODE_READ`); 1194 `PetscViewerFileSetName`(v,"datafile"); 1195 .ve 1196 The optional `PetscViewerSetFromOptions()` call allows overriding `PetscViewerSetType()` using the option 1197 $ -viewer_type {binary,hdf5} 1198 1199 See the example src/ksp/ksp/tutorials/ex27.c with the first approach, 1200 and src/mat/tutorials/ex10.c with the second approach. 1201 1202 Notes about the PETSc binary format: 1203 In case of `PETSCVIEWERBINARY`, a native PETSc binary format is used. Each of the blocks 1204 is read onto rank 0 and then shipped to its destination rank, one after another. 1205 Multiple objects, both matrices and vectors, can be stored within the same file. 1206 Their PetscObject name is ignored; they are loaded in the order of their storage. 1207 1208 Most users should not need to know the details of the binary storage 1209 format, since `MatLoad()` and `MatView()` completely hide these details. 1210 But for anyone who's interested, the standard binary matrix storage 1211 format is 1212 1213 $ PetscInt MAT_FILE_CLASSID 1214 $ PetscInt number of rows 1215 $ PetscInt number of columns 1216 $ PetscInt total number of nonzeros 1217 $ PetscInt *number nonzeros in each row 1218 $ PetscInt *column indices of all nonzeros (starting index is zero) 1219 $ PetscScalar *values of all nonzeros 1220 1221 PETSc automatically does the byte swapping for 1222 machines that store the bytes reversed, e.g. DEC alpha, freebsd, 1223 Linux, Microsoft Windows and the Intel Paragon; thus if you write your own binary 1224 read/write routines you have to swap the bytes; see `PetscBinaryRead()` 1225 and `PetscBinaryWrite()` to see how this may be done. 1226 1227 Notes about the HDF5 (MATLAB MAT-File Version 7.3) format: 1228 In case of `PETSCVIEWERHDF5`, a parallel HDF5 reader is used. 1229 Each processor's chunk is loaded independently by its owning rank. 1230 Multiple objects, both matrices and vectors, can be stored within the same file. 1231 They are looked up by their PetscObject name. 1232 1233 As the MATLAB MAT-File Version 7.3 format is also a HDF5 flavor, we decided to use 1234 by default the same structure and naming of the AIJ arrays and column count 1235 within the HDF5 file. This means that a MAT file saved with -v7.3 flag, e.g. 1236 $ save example.mat A b -v7.3 1237 can be directly read by this routine (see Reference 1 for details). 1238 Note that depending on your MATLAB version, this format might be a default, 1239 otherwise you can set it as default in Preferences. 1240 1241 Unless -nocompression flag is used to save the file in MATLAB, 1242 PETSc must be configured with ZLIB package. 1243 1244 See also examples src/mat/tutorials/ex10.c and src/ksp/ksp/tutorials/ex27.c 1245 1246 Current HDF5 (MAT-File) limitations: 1247 This reader currently supports only real `MATSEQAIJ`, `MATMPIAIJ`, `MATSEQDENSE` and `MATMPIDENSE` matrices. 1248 1249 Corresponding `MatView()` is not yet implemented. 1250 1251 The loaded matrix is actually a transpose of the original one in MATLAB, 1252 unless you push `PETSC_VIEWER_HDF5_MAT` format (see examples above). 1253 With this format, matrix is automatically transposed by PETSc, 1254 unless the matrix is marked as SPD or symmetric 1255 (see `MatSetOption()`, `MAT_SPD`, `MAT_SYMMETRIC`). 1256 1257 References: 1258 . * - MATLAB(R) Documentation, manual page of save(), https://www.mathworks.com/help/matlab/ref/save.html#btox10b-1-version 1259 1260 .seealso: `PetscViewerBinaryOpen()`, `PetscViewerSetType()`, `MatView()`, `VecLoad()` 1261 1262 @*/ 1263 PetscErrorCode MatLoad(Mat mat,PetscViewer viewer) 1264 { 1265 PetscBool flg; 1266 1267 PetscFunctionBegin; 1268 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1269 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1270 1271 if (!((PetscObject)mat)->type_name) PetscCall(MatSetType(mat,MATAIJ)); 1272 1273 flg = PETSC_FALSE; 1274 PetscCall(PetscOptionsGetBool(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matload_symmetric",&flg,NULL)); 1275 if (flg) { 1276 PetscCall(MatSetOption(mat,MAT_SYMMETRIC,PETSC_TRUE)); 1277 PetscCall(MatSetOption(mat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE)); 1278 } 1279 flg = PETSC_FALSE; 1280 PetscCall(PetscOptionsGetBool(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matload_spd",&flg,NULL)); 1281 if (flg) PetscCall(MatSetOption(mat,MAT_SPD,PETSC_TRUE)); 1282 1283 PetscCheck(mat->ops->load,PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type %s",((PetscObject)mat)->type_name); 1284 PetscCall(PetscLogEventBegin(MAT_Load,mat,viewer,0,0)); 1285 PetscCall((*mat->ops->load)(mat,viewer)); 1286 PetscCall(PetscLogEventEnd(MAT_Load,mat,viewer,0,0)); 1287 PetscFunctionReturn(0); 1288 } 1289 1290 static PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant) 1291 { 1292 Mat_Redundant *redund = *redundant; 1293 1294 PetscFunctionBegin; 1295 if (redund) { 1296 if (redund->matseq) { /* via MatCreateSubMatrices() */ 1297 PetscCall(ISDestroy(&redund->isrow)); 1298 PetscCall(ISDestroy(&redund->iscol)); 1299 PetscCall(MatDestroySubMatrices(1,&redund->matseq)); 1300 } else { 1301 PetscCall(PetscFree2(redund->send_rank,redund->recv_rank)); 1302 PetscCall(PetscFree(redund->sbuf_j)); 1303 PetscCall(PetscFree(redund->sbuf_a)); 1304 for (PetscInt i=0; i<redund->nrecvs; i++) { 1305 PetscCall(PetscFree(redund->rbuf_j[i])); 1306 PetscCall(PetscFree(redund->rbuf_a[i])); 1307 } 1308 PetscCall(PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a)); 1309 } 1310 1311 if (redund->subcomm) PetscCall(PetscCommDestroy(&redund->subcomm)); 1312 PetscCall(PetscFree(redund)); 1313 } 1314 PetscFunctionReturn(0); 1315 } 1316 1317 /*@C 1318 MatDestroy - Frees space taken by a matrix. 1319 1320 Collective on Mat 1321 1322 Input Parameter: 1323 . A - the matrix 1324 1325 Level: beginner 1326 1327 Developer Notes: 1328 Some special arrays of matrices are not destroyed in this routine but instead by the routines called by 1329 `MatDestroySubMatrices()`. Thus one must be sure that any changes here must also be made in those routines. 1330 MatHeaderMerge() and MatHeaderReplace() also manipulate the data in the `Mat` object and likely need changes 1331 if changes are needed here. 1332 @*/ 1333 PetscErrorCode MatDestroy(Mat *A) 1334 { 1335 PetscFunctionBegin; 1336 if (!*A) PetscFunctionReturn(0); 1337 PetscValidHeaderSpecific(*A,MAT_CLASSID,1); 1338 if (--((PetscObject)(*A))->refct > 0) {*A = NULL; PetscFunctionReturn(0);} 1339 1340 /* if memory was published with SAWs then destroy it */ 1341 PetscCall(PetscObjectSAWsViewOff((PetscObject)*A)); 1342 if ((*A)->ops->destroy) PetscCall((*(*A)->ops->destroy)(*A)); 1343 1344 PetscCall(PetscFree((*A)->factorprefix)); 1345 PetscCall(PetscFree((*A)->defaultvectype)); 1346 PetscCall(PetscFree((*A)->bsizes)); 1347 PetscCall(PetscFree((*A)->solvertype)); 1348 for (PetscInt i=0; i<MAT_FACTOR_NUM_TYPES; i++) PetscCall(PetscFree((*A)->preferredordering[i])); 1349 if ((*A)->redundant && (*A)->redundant->matseq[0] == *A) (*A)->redundant->matseq[0] = NULL; 1350 PetscCall(MatDestroy_Redundant(&(*A)->redundant)); 1351 PetscCall(MatProductClear(*A)); 1352 PetscCall(MatNullSpaceDestroy(&(*A)->nullsp)); 1353 PetscCall(MatNullSpaceDestroy(&(*A)->transnullsp)); 1354 PetscCall(MatNullSpaceDestroy(&(*A)->nearnullsp)); 1355 PetscCall(MatDestroy(&(*A)->schur)); 1356 PetscCall(PetscLayoutDestroy(&(*A)->rmap)); 1357 PetscCall(PetscLayoutDestroy(&(*A)->cmap)); 1358 PetscCall(PetscHeaderDestroy(A)); 1359 PetscFunctionReturn(0); 1360 } 1361 1362 /*@C 1363 MatSetValues - Inserts or adds a block of values into a matrix. 1364 These values may be cached, so `MatAssemblyBegin()` and `MatAssemblyEnd()` 1365 MUST be called after all calls to `MatSetValues()` have been completed. 1366 1367 Not Collective 1368 1369 Input Parameters: 1370 + mat - the matrix 1371 . v - a logically two-dimensional array of values 1372 . m, idxm - the number of rows and their global indices 1373 . n, idxn - the number of columns and their global indices 1374 - addv - either `ADD_VALUES` or `INSERT_VALUES`, where 1375 `ADD_VALUES` adds values to any existing entries, and 1376 `INSERT_VALUES` replaces existing entries with new values 1377 1378 Notes: 1379 If you create the matrix yourself (that is not with a call to `DMCreateMatrix()`) then you MUST call MatXXXXSetPreallocation() or 1380 `MatSetUp()` before using this routine 1381 1382 By default the values, v, are row-oriented. See `MatSetOption()` for other options. 1383 1384 Calls to `MatSetValues()` with the `INSERT_VALUES` and `ADD_VALUES` 1385 options cannot be mixed without intervening calls to the assembly 1386 routines. 1387 1388 `MatSetValues()` uses 0-based row and column numbers in Fortran 1389 as well as in C. 1390 1391 Negative indices may be passed in idxm and idxn, these rows and columns are 1392 simply ignored. This allows easily inserting element stiffness matrices 1393 with homogeneous Dirchlet boundary conditions that you don't want represented 1394 in the matrix. 1395 1396 Efficiency Alert: 1397 The routine `MatSetValuesBlocked()` may offer much better efficiency 1398 for users of block sparse formats (`MATSEQBAIJ` and `MATMPIBAIJ`). 1399 1400 Level: beginner 1401 1402 Developer Notes: 1403 This is labeled with C so does not automatically generate Fortran stubs and interfaces 1404 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 1405 1406 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 1407 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES` 1408 @*/ 1409 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1410 { 1411 PetscFunctionBeginHot; 1412 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1413 PetscValidType(mat,1); 1414 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1415 PetscValidIntPointer(idxm,3); 1416 PetscValidIntPointer(idxn,5); 1417 MatCheckPreallocated(mat,1); 1418 1419 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 1420 else PetscCheck(mat->insertmode == addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1421 1422 if (PetscDefined(USE_DEBUG)) { 1423 PetscInt i,j; 1424 1425 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1426 PetscCheck(mat->ops->setvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1427 1428 for (i=0; i<m; i++) { 1429 for (j=0; j<n; j++) { 1430 if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j])) 1431 #if defined(PETSC_USE_COMPLEX) 1432 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g+i%g at matrix entry (%" PetscInt_FMT ",%" PetscInt_FMT ")",(double)PetscRealPart(v[i*n+j]),(double)PetscImaginaryPart(v[i*n+j]),idxm[i],idxn[j]); 1433 #else 1434 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%" PetscInt_FMT ",%" PetscInt_FMT ")",(double)v[i*n+j],idxm[i],idxn[j]); 1435 #endif 1436 } 1437 } 1438 for (i=0; i<m; i++) PetscCheck(idxm[i] < mat->rmap->N,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Cannot insert in row %" PetscInt_FMT ", maximum is %" PetscInt_FMT,idxm[i],mat->rmap->N-1); 1439 for (i=0; i<n; i++) PetscCheck(idxn[i] < mat->cmap->N,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Cannot insert in column %" PetscInt_FMT ", maximum is %" PetscInt_FMT,idxn[i],mat->cmap->N-1); 1440 } 1441 1442 if (mat->assembled) { 1443 mat->was_assembled = PETSC_TRUE; 1444 mat->assembled = PETSC_FALSE; 1445 } 1446 PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 1447 PetscCall((*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv)); 1448 PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 1449 PetscFunctionReturn(0); 1450 } 1451 1452 /*@C 1453 MatSetValuesIS - Inserts or adds a block of values into a matrix using IS to indicate the rows and columns 1454 These values may be cached, so `MatAssemblyBegin()` and `MatAssemblyEnd()` 1455 MUST be called after all calls to `MatSetValues()` have been completed. 1456 1457 Not Collective 1458 1459 Input Parameters: 1460 + mat - the matrix 1461 . v - a logically two-dimensional array of values 1462 . ism - the rows to provide 1463 . isn - the columns to provide 1464 - addv - either `ADD_VALUES` or `INSERT_VALUES`, where 1465 `ADD_VALUES` adds values to any existing entries, and 1466 `INSERT_VALUES` replaces existing entries with new values 1467 1468 Notes: 1469 If you create the matrix yourself (that is not with a call to `DMCreateMatrix()`) then you MUST call MatXXXXSetPreallocation() or 1470 `MatSetUp()` before using this routine 1471 1472 By default the values, v, are row-oriented. See `MatSetOption()` for other options. 1473 1474 Calls to `MatSetValues()` with the `INSERT_VALUES` and `ADD_VALUES` 1475 options cannot be mixed without intervening calls to the assembly 1476 routines. 1477 1478 MatSetValues() uses 0-based row and column numbers in Fortran 1479 as well as in C. 1480 1481 Negative indices may be passed in ism and isn, these rows and columns are 1482 simply ignored. This allows easily inserting element stiffness matrices 1483 with homogeneous Dirchlet boundary conditions that you don't want represented 1484 in the matrix. 1485 1486 Efficiency Alert: 1487 The routine `MatSetValuesBlocked()` may offer much better efficiency 1488 for users of block sparse formats (`MATSEQBAIJ` and `MATMPIBAIJ`). 1489 1490 Level: beginner 1491 1492 Developer Notes: 1493 This is labeled with C so does not automatically generate Fortran stubs and interfaces 1494 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 1495 1496 This is currently not optimized for any particular IS type 1497 1498 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 1499 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()` 1500 @*/ 1501 PetscErrorCode MatSetValuesIS(Mat mat,IS ism,IS isn,const PetscScalar v[],InsertMode addv) 1502 { 1503 PetscInt m,n; 1504 const PetscInt *rows,*cols; 1505 1506 PetscFunctionBeginHot; 1507 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1508 PetscCall(ISGetIndices(ism,&rows)); 1509 PetscCall(ISGetIndices(isn,&cols)); 1510 PetscCall(ISGetLocalSize(ism,&m)); 1511 PetscCall(ISGetLocalSize(isn,&n)); 1512 PetscCall(MatSetValues(mat,m,rows,n,cols,v,addv)); 1513 PetscCall(ISRestoreIndices(ism,&rows)); 1514 PetscCall(ISRestoreIndices(isn,&cols)); 1515 PetscFunctionReturn(0); 1516 } 1517 1518 /*@ 1519 MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero 1520 values into a matrix 1521 1522 Not Collective 1523 1524 Input Parameters: 1525 + mat - the matrix 1526 . row - the (block) row to set 1527 - v - a logically two-dimensional array of values 1528 1529 Notes: 1530 By the values, v, are column-oriented (for the block version) and sorted 1531 1532 All the nonzeros in the row must be provided 1533 1534 The matrix must have previously had its column indices set 1535 1536 The row must belong to this process 1537 1538 Level: intermediate 1539 1540 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 1541 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()`, `MatSetValuesRow()`, `MatSetLocalToGlobalMapping()` 1542 @*/ 1543 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[]) 1544 { 1545 PetscInt globalrow; 1546 1547 PetscFunctionBegin; 1548 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1549 PetscValidType(mat,1); 1550 PetscValidScalarPointer(v,3); 1551 PetscCall(ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow)); 1552 PetscCall(MatSetValuesRow(mat,globalrow,v)); 1553 PetscFunctionReturn(0); 1554 } 1555 1556 /*@ 1557 MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero 1558 values into a matrix 1559 1560 Not Collective 1561 1562 Input Parameters: 1563 + mat - the matrix 1564 . row - the (block) row to set 1565 - v - a logically two-dimensional (column major) array of values for block matrices with blocksize larger than one, otherwise a one dimensional array of values 1566 1567 Notes: 1568 The values, v, are column-oriented for the block version. 1569 1570 All the nonzeros in the row must be provided 1571 1572 THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually `MatSetValues()` is used. 1573 1574 The row must belong to this process 1575 1576 Level: advanced 1577 1578 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 1579 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()` 1580 @*/ 1581 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[]) 1582 { 1583 PetscFunctionBeginHot; 1584 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1585 PetscValidType(mat,1); 1586 MatCheckPreallocated(mat,1); 1587 PetscValidScalarPointer(v,3); 1588 PetscCheck(mat->insertmode != ADD_VALUES,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values"); 1589 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1590 mat->insertmode = INSERT_VALUES; 1591 1592 if (mat->assembled) { 1593 mat->was_assembled = PETSC_TRUE; 1594 mat->assembled = PETSC_FALSE; 1595 } 1596 PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 1597 PetscCheck(mat->ops->setvaluesrow,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1598 PetscCall((*mat->ops->setvaluesrow)(mat,row,v)); 1599 PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 1600 PetscFunctionReturn(0); 1601 } 1602 1603 /*@ 1604 MatSetValuesStencil - Inserts or adds a block of values into a matrix. 1605 Using structured grid indexing 1606 1607 Not Collective 1608 1609 Input Parameters: 1610 + mat - the matrix 1611 . m - number of rows being entered 1612 . idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered 1613 . n - number of columns being entered 1614 . idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered 1615 . v - a logically two-dimensional array of values 1616 - addv - either ADD_VALUES or INSERT_VALUES, where 1617 ADD_VALUES adds values to any existing entries, and 1618 INSERT_VALUES replaces existing entries with new values 1619 1620 Notes: 1621 By default the values, v, are row-oriented. See `MatSetOption()` for other options. 1622 1623 Calls to `MatSetValuesStencil()` with the `INSERT_VALUES` and `ADD_VALUES` 1624 options cannot be mixed without intervening calls to the assembly 1625 routines. 1626 1627 The grid coordinates are across the entire grid, not just the local portion 1628 1629 `MatSetValuesStencil()` uses 0-based row and column numbers in Fortran 1630 as well as in C. 1631 1632 For setting/accessing vector values via array coordinates you can use the `DMDAVecGetArray()` routine 1633 1634 In order to use this routine you must either obtain the matrix with `DMCreateMatrix()` 1635 or call `MatSetLocalToGlobalMapping()` and `MatSetStencil()` first. 1636 1637 The columns and rows in the stencil passed in MUST be contained within the 1638 ghost region of the given process as set with DMDACreateXXX() or `MatSetStencil()`. For example, 1639 if you create a `DMDA` with an overlap of one grid level and on a particular process its first 1640 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1641 first i index you can use in your column and row indices in `MatSetStencil()` is 5. 1642 1643 In Fortran idxm and idxn should be declared as 1644 $ MatStencil idxm(4,m),idxn(4,n) 1645 and the values inserted using 1646 $ idxm(MatStencil_i,1) = i 1647 $ idxm(MatStencil_j,1) = j 1648 $ idxm(MatStencil_k,1) = k 1649 $ idxm(MatStencil_c,1) = c 1650 etc 1651 1652 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 1653 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 1654 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 1655 `DM_BOUNDARY_PERIODIC` boundary type. 1656 1657 For indices that don't mean anything for your case (like the k index when working in 2d) or the c index when you have 1658 a single value per point) you can skip filling those indices. 1659 1660 Inspired by the structured grid interface to the HYPRE package 1661 (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods) 1662 1663 Efficiency Alert: 1664 The routine `MatSetValuesBlockedStencil()` may offer much better efficiency 1665 for users of block sparse formats (`MATSEQBAIJ` and `MATMPIBAIJ`). 1666 1667 Level: beginner 1668 1669 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()` 1670 `MatSetValues()`, `MatSetValuesBlockedStencil()`, `MatSetStencil()`, `DMCreateMatrix()`, `DMDAVecGetArray()`, `MatStencil` 1671 @*/ 1672 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1673 { 1674 PetscInt buf[8192],*bufm=NULL,*bufn=NULL,*jdxm,*jdxn; 1675 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1676 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1677 1678 PetscFunctionBegin; 1679 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1680 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1681 PetscValidType(mat,1); 1682 PetscValidPointer(idxm,3); 1683 PetscValidPointer(idxn,5); 1684 1685 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1686 jdxm = buf; jdxn = buf+m; 1687 } else { 1688 PetscCall(PetscMalloc2(m,&bufm,n,&bufn)); 1689 jdxm = bufm; jdxn = bufn; 1690 } 1691 for (i=0; i<m; i++) { 1692 for (j=0; j<3-sdim; j++) dxm++; 1693 tmp = *dxm++ - starts[0]; 1694 for (j=0; j<dim-1; j++) { 1695 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1696 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1697 } 1698 if (mat->stencil.noc) dxm++; 1699 jdxm[i] = tmp; 1700 } 1701 for (i=0; i<n; i++) { 1702 for (j=0; j<3-sdim; j++) dxn++; 1703 tmp = *dxn++ - starts[0]; 1704 for (j=0; j<dim-1; j++) { 1705 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1706 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1707 } 1708 if (mat->stencil.noc) dxn++; 1709 jdxn[i] = tmp; 1710 } 1711 PetscCall(MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv)); 1712 PetscCall(PetscFree2(bufm,bufn)); 1713 PetscFunctionReturn(0); 1714 } 1715 1716 /*@ 1717 MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix. 1718 Using structured grid indexing 1719 1720 Not Collective 1721 1722 Input Parameters: 1723 + mat - the matrix 1724 . m - number of rows being entered 1725 . idxm - grid coordinates for matrix rows being entered 1726 . n - number of columns being entered 1727 . idxn - grid coordinates for matrix columns being entered 1728 . v - a logically two-dimensional array of values 1729 - addv - either ADD_VALUES or INSERT_VALUES, where 1730 ADD_VALUES adds values to any existing entries, and 1731 INSERT_VALUES replaces existing entries with new values 1732 1733 Notes: 1734 By default the values, v, are row-oriented and unsorted. 1735 See MatSetOption() for other options. 1736 1737 Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES 1738 options cannot be mixed without intervening calls to the assembly 1739 routines. 1740 1741 The grid coordinates are across the entire grid, not just the local portion 1742 1743 MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran 1744 as well as in C. 1745 1746 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine 1747 1748 In order to use this routine you must either obtain the matrix with DMCreateMatrix() 1749 or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first. 1750 1751 The columns and rows in the stencil passed in MUST be contained within the 1752 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example, 1753 if you create a DMDA with an overlap of one grid level and on a particular process its first 1754 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1755 first i index you can use in your column and row indices in MatSetStencil() is 5. 1756 1757 In Fortran idxm and idxn should be declared as 1758 $ MatStencil idxm(4,m),idxn(4,n) 1759 and the values inserted using 1760 $ idxm(MatStencil_i,1) = i 1761 $ idxm(MatStencil_j,1) = j 1762 $ idxm(MatStencil_k,1) = k 1763 etc 1764 1765 Negative indices may be passed in idxm and idxn, these rows and columns are 1766 simply ignored. This allows easily inserting element stiffness matrices 1767 with homogeneous Dirchlet boundary conditions that you don't want represented 1768 in the matrix. 1769 1770 Inspired by the structured grid interface to the HYPRE package 1771 (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods) 1772 1773 Level: beginner 1774 1775 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()` 1776 `MatSetValues()`, `MatSetValuesStencil()`, `MatSetStencil()`, `DMCreateMatrix()`, `DMDAVecGetArray()`, `MatStencil`, 1777 `MatSetBlockSize()`, `MatSetLocalToGlobalMapping()` 1778 @*/ 1779 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1780 { 1781 PetscInt buf[8192],*bufm=NULL,*bufn=NULL,*jdxm,*jdxn; 1782 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1783 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1784 1785 PetscFunctionBegin; 1786 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1787 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1788 PetscValidType(mat,1); 1789 PetscValidPointer(idxm,3); 1790 PetscValidPointer(idxn,5); 1791 PetscValidScalarPointer(v,6); 1792 1793 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1794 jdxm = buf; jdxn = buf+m; 1795 } else { 1796 PetscCall(PetscMalloc2(m,&bufm,n,&bufn)); 1797 jdxm = bufm; jdxn = bufn; 1798 } 1799 for (i=0; i<m; i++) { 1800 for (j=0; j<3-sdim; j++) dxm++; 1801 tmp = *dxm++ - starts[0]; 1802 for (j=0; j<sdim-1; j++) { 1803 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1804 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1805 } 1806 dxm++; 1807 jdxm[i] = tmp; 1808 } 1809 for (i=0; i<n; i++) { 1810 for (j=0; j<3-sdim; j++) dxn++; 1811 tmp = *dxn++ - starts[0]; 1812 for (j=0; j<sdim-1; j++) { 1813 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1814 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1815 } 1816 dxn++; 1817 jdxn[i] = tmp; 1818 } 1819 PetscCall(MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv)); 1820 PetscCall(PetscFree2(bufm,bufn)); 1821 PetscFunctionReturn(0); 1822 } 1823 1824 /*@ 1825 MatSetStencil - Sets the grid information for setting values into a matrix via 1826 MatSetValuesStencil() 1827 1828 Not Collective 1829 1830 Input Parameters: 1831 + mat - the matrix 1832 . dim - dimension of the grid 1, 2, or 3 1833 . dims - number of grid points in x, y, and z direction, including ghost points on your processor 1834 . starts - starting point of ghost nodes on your processor in x, y, and z direction 1835 - dof - number of degrees of freedom per node 1836 1837 Inspired by the structured grid interface to the HYPRE package 1838 (www.llnl.gov/CASC/hyper) 1839 1840 For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the 1841 user. 1842 1843 Level: beginner 1844 1845 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()` 1846 `MatSetValues()`, `MatSetValuesBlockedStencil()`, `MatSetValuesStencil()` 1847 @*/ 1848 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof) 1849 { 1850 PetscFunctionBegin; 1851 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1852 PetscValidIntPointer(dims,3); 1853 PetscValidIntPointer(starts,4); 1854 1855 mat->stencil.dim = dim + (dof > 1); 1856 for (PetscInt i=0; i<dim; i++) { 1857 mat->stencil.dims[i] = dims[dim-i-1]; /* copy the values in backwards */ 1858 mat->stencil.starts[i] = starts[dim-i-1]; 1859 } 1860 mat->stencil.dims[dim] = dof; 1861 mat->stencil.starts[dim] = 0; 1862 mat->stencil.noc = (PetscBool)(dof == 1); 1863 PetscFunctionReturn(0); 1864 } 1865 1866 /*@C 1867 MatSetValuesBlocked - Inserts or adds a block of values into a matrix. 1868 1869 Not Collective 1870 1871 Input Parameters: 1872 + mat - the matrix 1873 . v - a logically two-dimensional array of values 1874 . m, idxm - the number of block rows and their global block indices 1875 . n, idxn - the number of block columns and their global block indices 1876 - addv - either ADD_VALUES or INSERT_VALUES, where 1877 ADD_VALUES adds values to any existing entries, and 1878 INSERT_VALUES replaces existing entries with new values 1879 1880 Notes: 1881 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call 1882 MatXXXXSetPreallocation() or MatSetUp() before using this routine. 1883 1884 The m and n count the NUMBER of blocks in the row direction and column direction, 1885 NOT the total number of rows/columns; for example, if the block size is 2 and 1886 you are passing in values for rows 2,3,4,5 then m would be 2 (not 4). 1887 The values in idxm would be 1 2; that is the first index for each block divided by 1888 the block size. 1889 1890 Note that you must call MatSetBlockSize() when constructing this matrix (before 1891 preallocating it). 1892 1893 By default the values, v, are row-oriented, so the layout of 1894 v is the same as for MatSetValues(). See MatSetOption() for other options. 1895 1896 Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES 1897 options cannot be mixed without intervening calls to the assembly 1898 routines. 1899 1900 MatSetValuesBlocked() uses 0-based row and column numbers in Fortran 1901 as well as in C. 1902 1903 Negative indices may be passed in idxm and idxn, these rows and columns are 1904 simply ignored. This allows easily inserting element stiffness matrices 1905 with homogeneous Dirchlet boundary conditions that you don't want represented 1906 in the matrix. 1907 1908 Each time an entry is set within a sparse matrix via MatSetValues(), 1909 internal searching must be done to determine where to place the 1910 data in the matrix storage space. By instead inserting blocks of 1911 entries via MatSetValuesBlocked(), the overhead of matrix assembly is 1912 reduced. 1913 1914 Example: 1915 $ Suppose m=n=2 and block size(bs) = 2 The array is 1916 $ 1917 $ 1 2 | 3 4 1918 $ 5 6 | 7 8 1919 $ - - - | - - - 1920 $ 9 10 | 11 12 1921 $ 13 14 | 15 16 1922 $ 1923 $ v[] should be passed in like 1924 $ v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] 1925 $ 1926 $ If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then 1927 $ v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16] 1928 1929 Level: intermediate 1930 1931 .seealso: `MatSetBlockSize()`, `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetValuesBlockedLocal()` 1932 @*/ 1933 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1934 { 1935 PetscFunctionBeginHot; 1936 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1937 PetscValidType(mat,1); 1938 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1939 PetscValidIntPointer(idxm,3); 1940 PetscValidIntPointer(idxn,5); 1941 MatCheckPreallocated(mat,1); 1942 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 1943 else PetscCheck(mat->insertmode == addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1944 if (PetscDefined(USE_DEBUG)) { 1945 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1946 PetscCheck(mat->ops->setvaluesblocked || mat->ops->setvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1947 } 1948 if (PetscDefined(USE_DEBUG)) { 1949 PetscInt rbs,cbs,M,N,i; 1950 PetscCall(MatGetBlockSizes(mat,&rbs,&cbs)); 1951 PetscCall(MatGetSize(mat,&M,&N)); 1952 for (i=0; i<m; i++) PetscCheck(idxm[i]*rbs < M,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row block index %" PetscInt_FMT " (index %" PetscInt_FMT ") greater than row length %" PetscInt_FMT,i,idxm[i],M); 1953 for (i=0; i<n; i++) PetscCheck(idxn[i]*cbs < N,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column block index %" PetscInt_FMT " (index %" PetscInt_FMT ") great than column length %" PetscInt_FMT,i,idxn[i],N); 1954 } 1955 if (mat->assembled) { 1956 mat->was_assembled = PETSC_TRUE; 1957 mat->assembled = PETSC_FALSE; 1958 } 1959 PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 1960 if (mat->ops->setvaluesblocked) { 1961 PetscCall((*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv)); 1962 } else { 1963 PetscInt buf[8192],*bufr=NULL,*bufc=NULL,*iidxm,*iidxn; 1964 PetscInt i,j,bs,cbs; 1965 1966 PetscCall(MatGetBlockSizes(mat,&bs,&cbs)); 1967 if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1968 iidxm = buf; 1969 iidxn = buf + m*bs; 1970 } else { 1971 PetscCall(PetscMalloc2(m*bs,&bufr,n*cbs,&bufc)); 1972 iidxm = bufr; 1973 iidxn = bufc; 1974 } 1975 for (i=0; i<m; i++) { 1976 for (j=0; j<bs; j++) { 1977 iidxm[i*bs+j] = bs*idxm[i] + j; 1978 } 1979 } 1980 if (m != n || bs != cbs || idxm != idxn) { 1981 for (i=0; i<n; i++) { 1982 for (j=0; j<cbs; j++) { 1983 iidxn[i*cbs+j] = cbs*idxn[i] + j; 1984 } 1985 } 1986 } else iidxn = iidxm; 1987 PetscCall(MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv)); 1988 PetscCall(PetscFree2(bufr,bufc)); 1989 } 1990 PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 1991 PetscFunctionReturn(0); 1992 } 1993 1994 /*@C 1995 MatGetValues - Gets a block of values from a matrix. 1996 1997 Not Collective; can only return values that are owned by the give process 1998 1999 Input Parameters: 2000 + mat - the matrix 2001 . v - a logically two-dimensional array for storing the values 2002 . m, idxm - the number of rows and their global indices 2003 - n, idxn - the number of columns and their global indices 2004 2005 Notes: 2006 The user must allocate space (m*n PetscScalars) for the values, v. 2007 The values, v, are then returned in a row-oriented format, 2008 analogous to that used by default in MatSetValues(). 2009 2010 MatGetValues() uses 0-based row and column numbers in 2011 Fortran as well as in C. 2012 2013 MatGetValues() requires that the matrix has been assembled 2014 with MatAssemblyBegin()/MatAssemblyEnd(). Thus, calls to 2015 MatSetValues() and MatGetValues() CANNOT be made in succession 2016 without intermediate matrix assembly. 2017 2018 Negative row or column indices will be ignored and those locations in v[] will be 2019 left unchanged. 2020 2021 For the standard row-based matrix formats, idxm[] can only contain rows owned by the requesting MPI rank. 2022 That is, rows with global index greater than or equal to rstart and less than rend where rstart and rend are obtainable 2023 from MatGetOwnershipRange(mat,&rstart,&rend). 2024 2025 Level: advanced 2026 2027 .seealso: `MatGetRow()`, `MatCreateSubMatrices()`, `MatSetValues()`, `MatGetOwnershipRange()`, `MatGetValuesLocal()`, `MatGetValue()` 2028 @*/ 2029 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[]) 2030 { 2031 PetscFunctionBegin; 2032 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2033 PetscValidType(mat,1); 2034 if (!m || !n) PetscFunctionReturn(0); 2035 PetscValidIntPointer(idxm,3); 2036 PetscValidIntPointer(idxn,5); 2037 PetscValidScalarPointer(v,6); 2038 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2039 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2040 PetscCheck(mat->ops->getvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2041 MatCheckPreallocated(mat,1); 2042 2043 PetscCall(PetscLogEventBegin(MAT_GetValues,mat,0,0,0)); 2044 PetscCall((*mat->ops->getvalues)(mat,m,idxm,n,idxn,v)); 2045 PetscCall(PetscLogEventEnd(MAT_GetValues,mat,0,0,0)); 2046 PetscFunctionReturn(0); 2047 } 2048 2049 /*@C 2050 MatGetValuesLocal - retrieves values from certain locations in a matrix using the local numbering of the indices 2051 defined previously by MatSetLocalToGlobalMapping() 2052 2053 Not Collective 2054 2055 Input Parameters: 2056 + mat - the matrix 2057 . nrow, irow - number of rows and their local indices 2058 - ncol, icol - number of columns and their local indices 2059 2060 Output Parameter: 2061 . y - a logically two-dimensional array of values 2062 2063 Notes: 2064 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine. 2065 2066 This routine can only return values that are owned by the requesting MPI rank. That is, for standard matrix formats, rows that, in the global numbering, 2067 are greater than or equal to rstart and less than rend where rstart and rend are obtainable from MatGetOwnershipRange(mat,&rstart,&rend). One can 2068 determine if the resulting global row associated with the local row r is owned by the requesting MPI rank by applying the ISLocalToGlobalMapping set 2069 with MatSetLocalToGlobalMapping(). 2070 2071 Developer Notes: 2072 This is labelled with C so does not automatically generate Fortran stubs and interfaces 2073 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2074 2075 Level: advanced 2076 2077 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetLocalToGlobalMapping()`, 2078 `MatSetValuesLocal()`, `MatGetValues()` 2079 @*/ 2080 PetscErrorCode MatGetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],PetscScalar y[]) 2081 { 2082 PetscFunctionBeginHot; 2083 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2084 PetscValidType(mat,1); 2085 MatCheckPreallocated(mat,1); 2086 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to retrieve */ 2087 PetscValidIntPointer(irow,3); 2088 PetscValidIntPointer(icol,5); 2089 if (PetscDefined(USE_DEBUG)) { 2090 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2091 PetscCheck(mat->ops->getvalueslocal || mat->ops->getvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2092 } 2093 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2094 PetscCall(PetscLogEventBegin(MAT_GetValues,mat,0,0,0)); 2095 if (mat->ops->getvalueslocal) { 2096 PetscCall((*mat->ops->getvalueslocal)(mat,nrow,irow,ncol,icol,y)); 2097 } else { 2098 PetscInt buf[8192],*bufr=NULL,*bufc=NULL,*irowm,*icolm; 2099 if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2100 irowm = buf; icolm = buf+nrow; 2101 } else { 2102 PetscCall(PetscMalloc2(nrow,&bufr,ncol,&bufc)); 2103 irowm = bufr; icolm = bufc; 2104 } 2105 PetscCheck(mat->rmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MatGetValuesLocal() cannot proceed without local-to-global row mapping (See MatSetLocalToGlobalMapping())."); 2106 PetscCheck(mat->cmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MatGetValuesLocal() cannot proceed without local-to-global column mapping (See MatSetLocalToGlobalMapping())."); 2107 PetscCall(ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm)); 2108 PetscCall(ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm)); 2109 PetscCall(MatGetValues(mat,nrow,irowm,ncol,icolm,y)); 2110 PetscCall(PetscFree2(bufr,bufc)); 2111 } 2112 PetscCall(PetscLogEventEnd(MAT_GetValues,mat,0,0,0)); 2113 PetscFunctionReturn(0); 2114 } 2115 2116 /*@ 2117 MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and 2118 the same size. Currently, this can only be called once and creates the given matrix. 2119 2120 Not Collective 2121 2122 Input Parameters: 2123 + mat - the matrix 2124 . nb - the number of blocks 2125 . bs - the number of rows (and columns) in each block 2126 . rows - a concatenation of the rows for each block 2127 - v - a concatenation of logically two-dimensional arrays of values 2128 2129 Notes: 2130 In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix. 2131 2132 Level: advanced 2133 2134 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 2135 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()` 2136 @*/ 2137 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[]) 2138 { 2139 PetscFunctionBegin; 2140 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2141 PetscValidType(mat,1); 2142 PetscValidIntPointer(rows,4); 2143 PetscValidScalarPointer(v,5); 2144 PetscAssert(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2145 2146 PetscCall(PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0)); 2147 if (mat->ops->setvaluesbatch) { 2148 PetscCall((*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v)); 2149 } else { 2150 for (PetscInt b = 0; b < nb; ++b) PetscCall(MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES)); 2151 } 2152 PetscCall(PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0)); 2153 PetscFunctionReturn(0); 2154 } 2155 2156 /*@ 2157 MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by 2158 the routine MatSetValuesLocal() to allow users to insert matrix entries 2159 using a local (per-processor) numbering. 2160 2161 Not Collective 2162 2163 Input Parameters: 2164 + x - the matrix 2165 . rmapping - row mapping created with ISLocalToGlobalMappingCreate() or ISLocalToGlobalMappingCreateIS() 2166 - cmapping - column mapping 2167 2168 Level: intermediate 2169 2170 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetValuesLocal()`, `MatGetValuesLocal()` 2171 @*/ 2172 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 2173 { 2174 PetscFunctionBegin; 2175 PetscValidHeaderSpecific(x,MAT_CLASSID,1); 2176 PetscValidType(x,1); 2177 if (rmapping) PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2); 2178 if (cmapping) PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3); 2179 if (x->ops->setlocaltoglobalmapping) { 2180 PetscCall((*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping)); 2181 } else { 2182 PetscCall(PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping)); 2183 PetscCall(PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping)); 2184 } 2185 PetscFunctionReturn(0); 2186 } 2187 2188 /*@ 2189 MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping() 2190 2191 Not Collective 2192 2193 Input Parameter: 2194 . A - the matrix 2195 2196 Output Parameters: 2197 + rmapping - row mapping 2198 - cmapping - column mapping 2199 2200 Level: advanced 2201 2202 .seealso: `MatSetValuesLocal()` 2203 @*/ 2204 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping) 2205 { 2206 PetscFunctionBegin; 2207 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2208 PetscValidType(A,1); 2209 if (rmapping) { 2210 PetscValidPointer(rmapping,2); 2211 *rmapping = A->rmap->mapping; 2212 } 2213 if (cmapping) { 2214 PetscValidPointer(cmapping,3); 2215 *cmapping = A->cmap->mapping; 2216 } 2217 PetscFunctionReturn(0); 2218 } 2219 2220 /*@ 2221 MatSetLayouts - Sets the PetscLayout objects for rows and columns of a matrix 2222 2223 Logically Collective on A 2224 2225 Input Parameters: 2226 + A - the matrix 2227 . rmap - row layout 2228 - cmap - column layout 2229 2230 Level: advanced 2231 2232 .seealso: `MatCreateVecs()`, `MatGetLocalToGlobalMapping()`, `MatGetLayouts()` 2233 @*/ 2234 PetscErrorCode MatSetLayouts(Mat A,PetscLayout rmap,PetscLayout cmap) 2235 { 2236 PetscFunctionBegin; 2237 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2238 PetscCall(PetscLayoutReference(rmap,&A->rmap)); 2239 PetscCall(PetscLayoutReference(cmap,&A->cmap)); 2240 PetscFunctionReturn(0); 2241 } 2242 2243 /*@ 2244 MatGetLayouts - Gets the PetscLayout objects for rows and columns 2245 2246 Not Collective 2247 2248 Input Parameter: 2249 . A - the matrix 2250 2251 Output Parameters: 2252 + rmap - row layout 2253 - cmap - column layout 2254 2255 Level: advanced 2256 2257 .seealso: `MatCreateVecs()`, `MatGetLocalToGlobalMapping()`, `MatSetLayouts()` 2258 @*/ 2259 PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap) 2260 { 2261 PetscFunctionBegin; 2262 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2263 PetscValidType(A,1); 2264 if (rmap) { 2265 PetscValidPointer(rmap,2); 2266 *rmap = A->rmap; 2267 } 2268 if (cmap) { 2269 PetscValidPointer(cmap,3); 2270 *cmap = A->cmap; 2271 } 2272 PetscFunctionReturn(0); 2273 } 2274 2275 /*@C 2276 MatSetValuesLocal - Inserts or adds values into certain locations of a matrix, 2277 using a local numbering of the nodes. 2278 2279 Not Collective 2280 2281 Input Parameters: 2282 + mat - the matrix 2283 . nrow, irow - number of rows and their local indices 2284 . ncol, icol - number of columns and their local indices 2285 . y - a logically two-dimensional array of values 2286 - addv - either INSERT_VALUES or ADD_VALUES, where 2287 ADD_VALUES adds values to any existing entries, and 2288 INSERT_VALUES replaces existing entries with new values 2289 2290 Notes: 2291 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2292 MatSetUp() before using this routine 2293 2294 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine 2295 2296 Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES 2297 options cannot be mixed without intervening calls to the assembly 2298 routines. 2299 2300 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2301 MUST be called after all calls to MatSetValuesLocal() have been completed. 2302 2303 Level: intermediate 2304 2305 Developer Notes: 2306 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2307 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2308 2309 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetLocalToGlobalMapping()`, 2310 `MatSetValueLocal()`, `MatGetValuesLocal()` 2311 @*/ 2312 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2313 { 2314 PetscFunctionBeginHot; 2315 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2316 PetscValidType(mat,1); 2317 MatCheckPreallocated(mat,1); 2318 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2319 PetscValidIntPointer(irow,3); 2320 PetscValidIntPointer(icol,5); 2321 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 2322 else PetscCheck(mat->insertmode == addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2323 if (PetscDefined(USE_DEBUG)) { 2324 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2325 PetscCheck(mat->ops->setvalueslocal || mat->ops->setvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2326 } 2327 2328 if (mat->assembled) { 2329 mat->was_assembled = PETSC_TRUE; 2330 mat->assembled = PETSC_FALSE; 2331 } 2332 PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 2333 if (mat->ops->setvalueslocal) { 2334 PetscCall((*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv)); 2335 } else { 2336 PetscInt buf[8192],*bufr=NULL,*bufc=NULL; 2337 const PetscInt *irowm,*icolm; 2338 2339 if ((!mat->rmap->mapping && !mat->cmap->mapping) || (nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2340 bufr = buf; 2341 bufc = buf + nrow; 2342 irowm = bufr; 2343 icolm = bufc; 2344 } else { 2345 PetscCall(PetscMalloc2(nrow,&bufr,ncol,&bufc)); 2346 irowm = bufr; 2347 icolm = bufc; 2348 } 2349 if (mat->rmap->mapping) PetscCall(ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,bufr)); 2350 else irowm = irow; 2351 if (mat->cmap->mapping) { 2352 if (mat->cmap->mapping != mat->rmap->mapping || ncol != nrow || icol != irow) { 2353 PetscCall(ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,bufc)); 2354 } else icolm = irowm; 2355 } else icolm = icol; 2356 PetscCall(MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv)); 2357 if (bufr != buf) PetscCall(PetscFree2(bufr,bufc)); 2358 } 2359 PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 2360 PetscFunctionReturn(0); 2361 } 2362 2363 /*@C 2364 MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix, 2365 using a local ordering of the nodes a block at a time. 2366 2367 Not Collective 2368 2369 Input Parameters: 2370 + x - the matrix 2371 . nrow, irow - number of rows and their local indices 2372 . ncol, icol - number of columns and their local indices 2373 . y - a logically two-dimensional array of values 2374 - addv - either INSERT_VALUES or ADD_VALUES, where 2375 ADD_VALUES adds values to any existing entries, and 2376 INSERT_VALUES replaces existing entries with new values 2377 2378 Notes: 2379 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2380 MatSetUp() before using this routine 2381 2382 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping() 2383 before using this routineBefore calling MatSetValuesLocal(), the user must first set the 2384 2385 Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES 2386 options cannot be mixed without intervening calls to the assembly 2387 routines. 2388 2389 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2390 MUST be called after all calls to MatSetValuesBlockedLocal() have been completed. 2391 2392 Level: intermediate 2393 2394 Developer Notes: 2395 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2396 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2397 2398 .seealso: `MatSetBlockSize()`, `MatSetLocalToGlobalMapping()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, 2399 `MatSetValuesLocal()`, `MatSetValuesBlocked()` 2400 @*/ 2401 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2402 { 2403 PetscFunctionBeginHot; 2404 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2405 PetscValidType(mat,1); 2406 MatCheckPreallocated(mat,1); 2407 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2408 PetscValidIntPointer(irow,3); 2409 PetscValidIntPointer(icol,5); 2410 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 2411 else PetscCheck(mat->insertmode == addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2412 if (PetscDefined(USE_DEBUG)) { 2413 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2414 PetscCheck(mat->ops->setvaluesblockedlocal || mat->ops->setvaluesblocked || mat->ops->setvalueslocal || mat->ops->setvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2415 } 2416 2417 if (mat->assembled) { 2418 mat->was_assembled = PETSC_TRUE; 2419 mat->assembled = PETSC_FALSE; 2420 } 2421 if (PetscUnlikelyDebug(mat->rmap->mapping)) { /* Condition on the mapping existing, because MatSetValuesBlockedLocal_IS does not require it to be set. */ 2422 PetscInt irbs, rbs; 2423 PetscCall(MatGetBlockSizes(mat, &rbs, NULL)); 2424 PetscCall(ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&irbs)); 2425 PetscCheck(rbs == irbs,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different row block sizes! mat %" PetscInt_FMT ", row l2g map %" PetscInt_FMT,rbs,irbs); 2426 } 2427 if (PetscUnlikelyDebug(mat->cmap->mapping)) { 2428 PetscInt icbs, cbs; 2429 PetscCall(MatGetBlockSizes(mat,NULL,&cbs)); 2430 PetscCall(ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&icbs)); 2431 PetscCheck(cbs == icbs,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different col block sizes! mat %" PetscInt_FMT ", col l2g map %" PetscInt_FMT,cbs,icbs); 2432 } 2433 PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 2434 if (mat->ops->setvaluesblockedlocal) { 2435 PetscCall((*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv)); 2436 } else { 2437 PetscInt buf[8192],*bufr=NULL,*bufc=NULL; 2438 const PetscInt *irowm,*icolm; 2439 2440 if ((!mat->rmap->mapping && !mat->cmap->mapping) || (nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2441 bufr = buf; 2442 bufc = buf + nrow; 2443 irowm = bufr; 2444 icolm = bufc; 2445 } else { 2446 PetscCall(PetscMalloc2(nrow,&bufr,ncol,&bufc)); 2447 irowm = bufr; 2448 icolm = bufc; 2449 } 2450 if (mat->rmap->mapping) PetscCall(ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,bufr)); 2451 else irowm = irow; 2452 if (mat->cmap->mapping) { 2453 if (mat->cmap->mapping != mat->rmap->mapping || ncol != nrow || icol != irow) { 2454 PetscCall(ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,bufc)); 2455 } else icolm = irowm; 2456 } else icolm = icol; 2457 PetscCall(MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv)); 2458 if (bufr != buf) PetscCall(PetscFree2(bufr,bufc)); 2459 } 2460 PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 2461 PetscFunctionReturn(0); 2462 } 2463 2464 /*@ 2465 MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal 2466 2467 Collective on Mat 2468 2469 Input Parameters: 2470 + mat - the matrix 2471 - x - the vector to be multiplied 2472 2473 Output Parameters: 2474 . y - the result 2475 2476 Notes: 2477 The vectors x and y cannot be the same. I.e., one cannot 2478 call MatMult(A,y,y). 2479 2480 Level: developer 2481 2482 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 2483 @*/ 2484 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y) 2485 { 2486 PetscFunctionBegin; 2487 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2488 PetscValidType(mat,1); 2489 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2490 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2491 2492 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2493 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2494 PetscCheck(x != y,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2495 MatCheckPreallocated(mat,1); 2496 2497 PetscCheck(mat->ops->multdiagonalblock,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a multiply defined",((PetscObject)mat)->type_name); 2498 PetscCall((*mat->ops->multdiagonalblock)(mat,x,y)); 2499 PetscCall(PetscObjectStateIncrease((PetscObject)y)); 2500 PetscFunctionReturn(0); 2501 } 2502 2503 /* --------------------------------------------------------*/ 2504 /*@ 2505 MatMult - Computes the matrix-vector product, y = Ax. 2506 2507 Neighbor-wise Collective on Mat 2508 2509 Input Parameters: 2510 + mat - the matrix 2511 - x - the vector to be multiplied 2512 2513 Output Parameters: 2514 . y - the result 2515 2516 Notes: 2517 The vectors x and y cannot be the same. I.e., one cannot 2518 call MatMult(A,y,y). 2519 2520 Level: beginner 2521 2522 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 2523 @*/ 2524 PetscErrorCode MatMult(Mat mat,Vec x,Vec y) 2525 { 2526 PetscFunctionBegin; 2527 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2528 PetscValidType(mat,1); 2529 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2530 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2531 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2532 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2533 PetscCheck(x != y,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2534 PetscCheck(mat->cmap->N == x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,x->map->N); 2535 PetscCheck(mat->rmap->N == y->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,y->map->N); 2536 PetscCheck(mat->cmap->n == x->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->n,x->map->n); 2537 PetscCheck(mat->rmap->n == y->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,y->map->n); 2538 PetscCall(VecSetErrorIfLocked(y,3)); 2539 if (mat->erroriffailure) PetscCall(VecValidValues(x,2,PETSC_TRUE)); 2540 MatCheckPreallocated(mat,1); 2541 2542 PetscCall(VecLockReadPush(x)); 2543 PetscCheck(mat->ops->mult,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a multiply defined",((PetscObject)mat)->type_name); 2544 PetscCall(PetscLogEventBegin(MAT_Mult,mat,x,y,0)); 2545 PetscCall((*mat->ops->mult)(mat,x,y)); 2546 PetscCall(PetscLogEventEnd(MAT_Mult,mat,x,y,0)); 2547 if (mat->erroriffailure) PetscCall(VecValidValues(y,3,PETSC_FALSE)); 2548 PetscCall(VecLockReadPop(x)); 2549 PetscFunctionReturn(0); 2550 } 2551 2552 /*@ 2553 MatMultTranspose - Computes matrix transpose times a vector y = A^T * x. 2554 2555 Neighbor-wise Collective on Mat 2556 2557 Input Parameters: 2558 + mat - the matrix 2559 - x - the vector to be multiplied 2560 2561 Output Parameters: 2562 . y - the result 2563 2564 Notes: 2565 The vectors x and y cannot be the same. I.e., one cannot 2566 call MatMultTranspose(A,y,y). 2567 2568 For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple, 2569 use MatMultHermitianTranspose() 2570 2571 Level: beginner 2572 2573 .seealso: `MatMult()`, `MatMultAdd()`, `MatMultTransposeAdd()`, `MatMultHermitianTranspose()`, `MatTranspose()` 2574 @*/ 2575 PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y) 2576 { 2577 PetscErrorCode (*op)(Mat,Vec,Vec) = NULL; 2578 2579 PetscFunctionBegin; 2580 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2581 PetscValidType(mat,1); 2582 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2583 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2584 2585 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2586 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2587 PetscCheck(x != y,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2588 PetscCheck(mat->cmap->N == y->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,y->map->N); 2589 PetscCheck(mat->rmap->N == x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,x->map->N); 2590 PetscCheck(mat->cmap->n == y->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->n,y->map->n); 2591 PetscCheck(mat->rmap->n == x->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,x->map->n); 2592 if (mat->erroriffailure) PetscCall(VecValidValues(x,2,PETSC_TRUE)); 2593 MatCheckPreallocated(mat,1); 2594 2595 if (!mat->ops->multtranspose) { 2596 if (mat->symmetric == PETSC_BOOL3_TRUE && mat->ops->mult) op = mat->ops->mult; 2597 PetscCheck(op,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a multiply transpose defined or is symmetric and does not have a multiply defined",((PetscObject)mat)->type_name); 2598 } else op = mat->ops->multtranspose; 2599 PetscCall(PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0)); 2600 PetscCall(VecLockReadPush(x)); 2601 PetscCall((*op)(mat,x,y)); 2602 PetscCall(VecLockReadPop(x)); 2603 PetscCall(PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0)); 2604 PetscCall(PetscObjectStateIncrease((PetscObject)y)); 2605 if (mat->erroriffailure) PetscCall(VecValidValues(y,3,PETSC_FALSE)); 2606 PetscFunctionReturn(0); 2607 } 2608 2609 /*@ 2610 MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector. 2611 2612 Neighbor-wise Collective on Mat 2613 2614 Input Parameters: 2615 + mat - the matrix 2616 - x - the vector to be multilplied 2617 2618 Output Parameters: 2619 . y - the result 2620 2621 Notes: 2622 The vectors x and y cannot be the same. I.e., one cannot 2623 call MatMultHermitianTranspose(A,y,y). 2624 2625 Also called the conjugate transpose, complex conjugate transpose, or adjoint. 2626 2627 For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical. 2628 2629 Level: beginner 2630 2631 .seealso: `MatMult()`, `MatMultAdd()`, `MatMultHermitianTransposeAdd()`, `MatMultTranspose()` 2632 @*/ 2633 PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y) 2634 { 2635 PetscFunctionBegin; 2636 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2637 PetscValidType(mat,1); 2638 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2639 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2640 2641 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2642 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2643 PetscCheck(x != y,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2644 PetscCheck(mat->cmap->N == y->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,y->map->N); 2645 PetscCheck(mat->rmap->N == x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,x->map->N); 2646 PetscCheck(mat->cmap->n == y->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->n,y->map->n); 2647 PetscCheck(mat->rmap->n == x->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,x->map->n); 2648 MatCheckPreallocated(mat,1); 2649 2650 PetscCall(PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0)); 2651 #if defined(PETSC_USE_COMPLEX) 2652 if (mat->ops->multhermitiantranspose || (mat->hermitian == PETSC_BOOL3_TRUE && mat->ops->mult)) { 2653 PetscCall(VecLockReadPush(x)); 2654 if (mat->ops->multhermitiantranspose) { 2655 PetscCall((*mat->ops->multhermitiantranspose)(mat,x,y)); 2656 } else { 2657 PetscCall((*mat->ops->mult)(mat,x,y)); 2658 } 2659 PetscCall(VecLockReadPop(x)); 2660 } else { 2661 Vec w; 2662 PetscCall(VecDuplicate(x,&w)); 2663 PetscCall(VecCopy(x,w)); 2664 PetscCall(VecConjugate(w)); 2665 PetscCall(MatMultTranspose(mat,w,y)); 2666 PetscCall(VecDestroy(&w)); 2667 PetscCall(VecConjugate(y)); 2668 } 2669 PetscCall(PetscObjectStateIncrease((PetscObject)y)); 2670 #else 2671 PetscCall(MatMultTranspose(mat,x,y)); 2672 #endif 2673 PetscCall(PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0)); 2674 PetscFunctionReturn(0); 2675 } 2676 2677 /*@ 2678 MatMultAdd - Computes v3 = v2 + A * v1. 2679 2680 Neighbor-wise Collective on Mat 2681 2682 Input Parameters: 2683 + mat - the matrix 2684 - v1, v2 - the vectors 2685 2686 Output Parameters: 2687 . v3 - the result 2688 2689 Notes: 2690 The vectors v1 and v3 cannot be the same. I.e., one cannot 2691 call MatMultAdd(A,v1,v2,v1). 2692 2693 Level: beginner 2694 2695 .seealso: `MatMultTranspose()`, `MatMult()`, `MatMultTransposeAdd()` 2696 @*/ 2697 PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2698 { 2699 PetscFunctionBegin; 2700 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2701 PetscValidType(mat,1); 2702 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2703 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2704 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2705 2706 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2707 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2708 PetscCheck(mat->cmap->N == v1->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,v1->map->N); 2709 /* PetscCheck(mat->rmap->N == v2->map->N,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,v2->map->N); 2710 PetscCheck(mat->rmap->N == v3->map->N,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,v3->map->N); */ 2711 PetscCheck(mat->rmap->n == v3->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,v3->map->n); 2712 PetscCheck(mat->rmap->n == v2->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,v2->map->n); 2713 PetscCheck(v1 != v3,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2714 MatCheckPreallocated(mat,1); 2715 2716 PetscCheck(mat->ops->multadd,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type %s",((PetscObject)mat)->type_name); 2717 PetscCall(PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3)); 2718 PetscCall(VecLockReadPush(v1)); 2719 PetscCall((*mat->ops->multadd)(mat,v1,v2,v3)); 2720 PetscCall(VecLockReadPop(v1)); 2721 PetscCall(PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3)); 2722 PetscCall(PetscObjectStateIncrease((PetscObject)v3)); 2723 PetscFunctionReturn(0); 2724 } 2725 2726 /*@ 2727 MatMultTransposeAdd - Computes v3 = v2 + A' * v1. 2728 2729 Neighbor-wise Collective on Mat 2730 2731 Input Parameters: 2732 + mat - the matrix 2733 - v1, v2 - the vectors 2734 2735 Output Parameters: 2736 . v3 - the result 2737 2738 Notes: 2739 The vectors v1 and v3 cannot be the same. I.e., one cannot 2740 call MatMultTransposeAdd(A,v1,v2,v1). 2741 2742 Level: beginner 2743 2744 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMult()` 2745 @*/ 2746 PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2747 { 2748 PetscErrorCode (*op)(Mat,Vec,Vec,Vec) = (!mat->ops->multtransposeadd && mat->symmetric) ? mat->ops->multadd : mat->ops->multtransposeadd; 2749 2750 PetscFunctionBegin; 2751 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2752 PetscValidType(mat,1); 2753 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2754 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2755 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2756 2757 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2758 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2759 PetscCheck(mat->rmap->N == v1->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,v1->map->N); 2760 PetscCheck(mat->cmap->N == v2->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,v2->map->N); 2761 PetscCheck(mat->cmap->N == v3->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,v3->map->N); 2762 PetscCheck(v1 != v3,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2763 PetscCheck(op,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2764 MatCheckPreallocated(mat,1); 2765 2766 PetscCall(PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3)); 2767 PetscCall(VecLockReadPush(v1)); 2768 PetscCall((*op)(mat,v1,v2,v3)); 2769 PetscCall(VecLockReadPop(v1)); 2770 PetscCall(PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3)); 2771 PetscCall(PetscObjectStateIncrease((PetscObject)v3)); 2772 PetscFunctionReturn(0); 2773 } 2774 2775 /*@ 2776 MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1. 2777 2778 Neighbor-wise Collective on Mat 2779 2780 Input Parameters: 2781 + mat - the matrix 2782 - v1, v2 - the vectors 2783 2784 Output Parameters: 2785 . v3 - the result 2786 2787 Notes: 2788 The vectors v1 and v3 cannot be the same. I.e., one cannot 2789 call MatMultHermitianTransposeAdd(A,v1,v2,v1). 2790 2791 Level: beginner 2792 2793 .seealso: `MatMultHermitianTranspose()`, `MatMultTranspose()`, `MatMultAdd()`, `MatMult()` 2794 @*/ 2795 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2796 { 2797 PetscFunctionBegin; 2798 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2799 PetscValidType(mat,1); 2800 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2801 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2802 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2803 2804 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2805 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2806 PetscCheck(v1 != v3,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2807 PetscCheck(mat->rmap->N == v1->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,v1->map->N); 2808 PetscCheck(mat->cmap->N == v2->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,v2->map->N); 2809 PetscCheck(mat->cmap->N == v3->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,v3->map->N); 2810 MatCheckPreallocated(mat,1); 2811 2812 PetscCall(PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3)); 2813 PetscCall(VecLockReadPush(v1)); 2814 if (mat->ops->multhermitiantransposeadd) { 2815 PetscCall((*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3)); 2816 } else { 2817 Vec w,z; 2818 PetscCall(VecDuplicate(v1,&w)); 2819 PetscCall(VecCopy(v1,w)); 2820 PetscCall(VecConjugate(w)); 2821 PetscCall(VecDuplicate(v3,&z)); 2822 PetscCall(MatMultTranspose(mat,w,z)); 2823 PetscCall(VecDestroy(&w)); 2824 PetscCall(VecConjugate(z)); 2825 if (v2 != v3) { 2826 PetscCall(VecWAXPY(v3,1.0,v2,z)); 2827 } else { 2828 PetscCall(VecAXPY(v3,1.0,z)); 2829 } 2830 PetscCall(VecDestroy(&z)); 2831 } 2832 PetscCall(VecLockReadPop(v1)); 2833 PetscCall(PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3)); 2834 PetscCall(PetscObjectStateIncrease((PetscObject)v3)); 2835 PetscFunctionReturn(0); 2836 } 2837 2838 /*@C 2839 MatGetFactorType - gets the type of factorization it is 2840 2841 Not Collective 2842 2843 Input Parameters: 2844 . mat - the matrix 2845 2846 Output Parameters: 2847 . t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT 2848 2849 Level: intermediate 2850 2851 .seealso: `MatFactorType`, `MatGetFactor()`, `MatSetFactorType()` 2852 @*/ 2853 PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t) 2854 { 2855 PetscFunctionBegin; 2856 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2857 PetscValidType(mat,1); 2858 PetscValidPointer(t,2); 2859 *t = mat->factortype; 2860 PetscFunctionReturn(0); 2861 } 2862 2863 /*@C 2864 MatSetFactorType - sets the type of factorization it is 2865 2866 Logically Collective on Mat 2867 2868 Input Parameters: 2869 + mat - the matrix 2870 - t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT 2871 2872 Level: intermediate 2873 2874 .seealso: `MatFactorType`, `MatGetFactor()`, `MatGetFactorType()` 2875 @*/ 2876 PetscErrorCode MatSetFactorType(Mat mat, MatFactorType t) 2877 { 2878 PetscFunctionBegin; 2879 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2880 PetscValidType(mat,1); 2881 mat->factortype = t; 2882 PetscFunctionReturn(0); 2883 } 2884 2885 /* ------------------------------------------------------------*/ 2886 /*@C 2887 MatGetInfo - Returns information about matrix storage (number of 2888 nonzeros, memory, etc.). 2889 2890 Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag 2891 2892 Input Parameter: 2893 . mat - the matrix 2894 2895 Output Parameters: 2896 + flag - flag indicating the type of parameters to be returned 2897 (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors, 2898 MAT_GLOBAL_SUM - sum over all processors) 2899 - info - matrix information context 2900 2901 Notes: 2902 The MatInfo context contains a variety of matrix data, including 2903 number of nonzeros allocated and used, number of mallocs during 2904 matrix assembly, etc. Additional information for factored matrices 2905 is provided (such as the fill ratio, number of mallocs during 2906 factorization, etc.). Much of this info is printed to PETSC_STDOUT 2907 when using the runtime options 2908 $ -info -mat_view ::ascii_info 2909 2910 Example for C/C++ Users: 2911 See the file ${PETSC_DIR}/include/petscmat.h for a complete list of 2912 data within the MatInfo context. For example, 2913 .vb 2914 MatInfo info; 2915 Mat A; 2916 double mal, nz_a, nz_u; 2917 2918 MatGetInfo(A,MAT_LOCAL,&info); 2919 mal = info.mallocs; 2920 nz_a = info.nz_allocated; 2921 .ve 2922 2923 Example for Fortran Users: 2924 Fortran users should declare info as a double precision 2925 array of dimension MAT_INFO_SIZE, and then extract the parameters 2926 of interest. See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h 2927 a complete list of parameter names. 2928 .vb 2929 double precision info(MAT_INFO_SIZE) 2930 double precision mal, nz_a 2931 Mat A 2932 integer ierr 2933 2934 call MatGetInfo(A,MAT_LOCAL,info,ierr) 2935 mal = info(MAT_INFO_MALLOCS) 2936 nz_a = info(MAT_INFO_NZ_ALLOCATED) 2937 .ve 2938 2939 Level: intermediate 2940 2941 Developer Note: fortran interface is not autogenerated as the f90 2942 interface definition cannot be generated correctly [due to MatInfo] 2943 2944 .seealso: `MatStashGetInfo()` 2945 2946 @*/ 2947 PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info) 2948 { 2949 PetscFunctionBegin; 2950 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2951 PetscValidType(mat,1); 2952 PetscValidPointer(info,3); 2953 PetscCheck(mat->ops->getinfo,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2954 MatCheckPreallocated(mat,1); 2955 PetscCall((*mat->ops->getinfo)(mat,flag,info)); 2956 PetscFunctionReturn(0); 2957 } 2958 2959 /* 2960 This is used by external packages where it is not easy to get the info from the actual 2961 matrix factorization. 2962 */ 2963 PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info) 2964 { 2965 PetscFunctionBegin; 2966 PetscCall(PetscMemzero(info,sizeof(MatInfo))); 2967 PetscFunctionReturn(0); 2968 } 2969 2970 /* ----------------------------------------------------------*/ 2971 2972 /*@C 2973 MatLUFactor - Performs in-place LU factorization of matrix. 2974 2975 Collective on Mat 2976 2977 Input Parameters: 2978 + mat - the matrix 2979 . row - row permutation 2980 . col - column permutation 2981 - info - options for factorization, includes 2982 $ fill - expected fill as ratio of original fill. 2983 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 2984 $ Run with the option -info to determine an optimal value to use 2985 2986 Notes: 2987 Most users should employ the simplified KSP interface for linear solvers 2988 instead of working directly with matrix algebra routines such as this. 2989 See, e.g., KSPCreate(). 2990 2991 This changes the state of the matrix to a factored matrix; it cannot be used 2992 for example with MatSetValues() unless one first calls MatSetUnfactored(). 2993 2994 Level: developer 2995 2996 .seealso: `MatLUFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()`, 2997 `MatGetOrdering()`, `MatSetUnfactored()`, `MatFactorInfo`, `MatGetFactor()` 2998 2999 Developer Note: fortran interface is not autogenerated as the f90 3000 interface definition cannot be generated correctly [due to MatFactorInfo] 3001 3002 @*/ 3003 PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 3004 { 3005 MatFactorInfo tinfo; 3006 3007 PetscFunctionBegin; 3008 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3009 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 3010 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 3011 if (info) PetscValidPointer(info,4); 3012 PetscValidType(mat,1); 3013 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3014 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3015 PetscCheck(mat->ops->lufactor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3016 MatCheckPreallocated(mat,1); 3017 if (!info) { 3018 PetscCall(MatFactorInfoInitialize(&tinfo)); 3019 info = &tinfo; 3020 } 3021 3022 PetscCall(PetscLogEventBegin(MAT_LUFactor,mat,row,col,0)); 3023 PetscCall((*mat->ops->lufactor)(mat,row,col,info)); 3024 PetscCall(PetscLogEventEnd(MAT_LUFactor,mat,row,col,0)); 3025 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 3026 PetscFunctionReturn(0); 3027 } 3028 3029 /*@C 3030 MatILUFactor - Performs in-place ILU factorization of matrix. 3031 3032 Collective on Mat 3033 3034 Input Parameters: 3035 + mat - the matrix 3036 . row - row permutation 3037 . col - column permutation 3038 - info - structure containing 3039 $ levels - number of levels of fill. 3040 $ expected fill - as ratio of original fill. 3041 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 3042 missing diagonal entries) 3043 3044 Notes: 3045 Probably really in-place only when level of fill is zero, otherwise allocates 3046 new space to store factored matrix and deletes previous memory. 3047 3048 Most users should employ the simplified KSP interface for linear solvers 3049 instead of working directly with matrix algebra routines such as this. 3050 See, e.g., KSPCreate(). 3051 3052 Level: developer 3053 3054 .seealso: `MatILUFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()`, `MatFactorInfo` 3055 3056 Developer Note: fortran interface is not autogenerated as the f90 3057 interface definition cannot be generated correctly [due to MatFactorInfo] 3058 3059 @*/ 3060 PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 3061 { 3062 PetscFunctionBegin; 3063 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3064 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 3065 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 3066 PetscValidPointer(info,4); 3067 PetscValidType(mat,1); 3068 PetscCheck(mat->rmap->N == mat->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 3069 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3070 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3071 PetscCheck(mat->ops->ilufactor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3072 MatCheckPreallocated(mat,1); 3073 3074 PetscCall(PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0)); 3075 PetscCall((*mat->ops->ilufactor)(mat,row,col,info)); 3076 PetscCall(PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0)); 3077 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 3078 PetscFunctionReturn(0); 3079 } 3080 3081 /*@C 3082 MatLUFactorSymbolic - Performs symbolic LU factorization of matrix. 3083 Call this routine before calling MatLUFactorNumeric(). 3084 3085 Collective on Mat 3086 3087 Input Parameters: 3088 + fact - the factor matrix obtained with MatGetFactor() 3089 . mat - the matrix 3090 . row, col - row and column permutations 3091 - info - options for factorization, includes 3092 $ fill - expected fill as ratio of original fill. 3093 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3094 $ Run with the option -info to determine an optimal value to use 3095 3096 Notes: 3097 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 3098 3099 Most users should employ the simplified KSP interface for linear solvers 3100 instead of working directly with matrix algebra routines such as this. 3101 See, e.g., KSPCreate(). 3102 3103 Level: developer 3104 3105 .seealso: `MatLUFactor()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()`, `MatFactorInfo`, `MatFactorInfoInitialize()` 3106 3107 Developer Note: fortran interface is not autogenerated as the f90 3108 interface definition cannot be generated correctly [due to MatFactorInfo] 3109 3110 @*/ 3111 PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 3112 { 3113 MatFactorInfo tinfo; 3114 3115 PetscFunctionBegin; 3116 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3117 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,3); 3118 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,4); 3119 if (info) PetscValidPointer(info,5); 3120 PetscValidType(mat,2); 3121 PetscValidPointer(fact,1); 3122 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3123 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3124 if (!(fact)->ops->lufactorsymbolic) { 3125 MatSolverType stype; 3126 PetscCall(MatFactorGetSolverType(fact,&stype)); 3127 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,stype); 3128 } 3129 MatCheckPreallocated(mat,2); 3130 if (!info) { 3131 PetscCall(MatFactorInfoInitialize(&tinfo)); 3132 info = &tinfo; 3133 } 3134 3135 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0)); 3136 PetscCall((fact->ops->lufactorsymbolic)(fact,mat,row,col,info)); 3137 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0)); 3138 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3139 PetscFunctionReturn(0); 3140 } 3141 3142 /*@C 3143 MatLUFactorNumeric - Performs numeric LU factorization of a matrix. 3144 Call this routine after first calling MatLUFactorSymbolic(). 3145 3146 Collective on Mat 3147 3148 Input Parameters: 3149 + fact - the factor matrix obtained with MatGetFactor() 3150 . mat - the matrix 3151 - info - options for factorization 3152 3153 Notes: 3154 See MatLUFactor() for in-place factorization. See 3155 MatCholeskyFactorNumeric() for the symmetric, positive definite case. 3156 3157 Most users should employ the simplified KSP interface for linear solvers 3158 instead of working directly with matrix algebra routines such as this. 3159 See, e.g., KSPCreate(). 3160 3161 Level: developer 3162 3163 .seealso: `MatLUFactorSymbolic()`, `MatLUFactor()`, `MatCholeskyFactor()` 3164 3165 Developer Note: fortran interface is not autogenerated as the f90 3166 interface definition cannot be generated correctly [due to MatFactorInfo] 3167 3168 @*/ 3169 PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3170 { 3171 MatFactorInfo tinfo; 3172 3173 PetscFunctionBegin; 3174 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3175 PetscValidType(mat,2); 3176 PetscValidPointer(fact,1); 3177 PetscValidHeaderSpecific(fact,MAT_CLASSID,1); 3178 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3179 PetscCheck(mat->rmap->N == (fact)->rmap->N && mat->cmap->N == (fact)->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dimensions are different %" PetscInt_FMT " should = %" PetscInt_FMT " %" PetscInt_FMT " should = %" PetscInt_FMT,mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N); 3180 3181 PetscCheck((fact)->ops->lufactornumeric,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name); 3182 MatCheckPreallocated(mat,2); 3183 if (!info) { 3184 PetscCall(MatFactorInfoInitialize(&tinfo)); 3185 info = &tinfo; 3186 } 3187 3188 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0)); 3189 else PetscCall(PetscLogEventBegin(MAT_LUFactor,mat,fact,0,0)); 3190 PetscCall((fact->ops->lufactornumeric)(fact,mat,info)); 3191 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0)); 3192 else PetscCall(PetscLogEventEnd(MAT_LUFactor,mat,fact,0,0)); 3193 PetscCall(MatViewFromOptions(fact,NULL,"-mat_factor_view")); 3194 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3195 PetscFunctionReturn(0); 3196 } 3197 3198 /*@C 3199 MatCholeskyFactor - Performs in-place Cholesky factorization of a 3200 symmetric matrix. 3201 3202 Collective on Mat 3203 3204 Input Parameters: 3205 + mat - the matrix 3206 . perm - row and column permutations 3207 - f - expected fill as ratio of original fill 3208 3209 Notes: 3210 See MatLUFactor() for the nonsymmetric case. See also 3211 MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric(). 3212 3213 Most users should employ the simplified KSP interface for linear solvers 3214 instead of working directly with matrix algebra routines such as this. 3215 See, e.g., KSPCreate(). 3216 3217 Level: developer 3218 3219 .seealso: `MatLUFactor()`, `MatCholeskyFactorSymbolic()`, `MatCholeskyFactorNumeric()` 3220 `MatGetOrdering()` 3221 3222 Developer Note: fortran interface is not autogenerated as the f90 3223 interface definition cannot be generated correctly [due to MatFactorInfo] 3224 3225 @*/ 3226 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info) 3227 { 3228 MatFactorInfo tinfo; 3229 3230 PetscFunctionBegin; 3231 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3232 PetscValidType(mat,1); 3233 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2); 3234 if (info) PetscValidPointer(info,3); 3235 PetscCheck(mat->rmap->N == mat->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square"); 3236 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3237 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3238 PetscCheck(mat->ops->choleskyfactor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"In-place factorization for Mat type %s is not supported, try out-of-place factorization. See MatCholeskyFactorSymbolic/Numeric",((PetscObject)mat)->type_name); 3239 MatCheckPreallocated(mat,1); 3240 if (!info) { 3241 PetscCall(MatFactorInfoInitialize(&tinfo)); 3242 info = &tinfo; 3243 } 3244 3245 PetscCall(PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0)); 3246 PetscCall((*mat->ops->choleskyfactor)(mat,perm,info)); 3247 PetscCall(PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0)); 3248 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 3249 PetscFunctionReturn(0); 3250 } 3251 3252 /*@C 3253 MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization 3254 of a symmetric matrix. 3255 3256 Collective on Mat 3257 3258 Input Parameters: 3259 + fact - the factor matrix obtained with MatGetFactor() 3260 . mat - the matrix 3261 . perm - row and column permutations 3262 - info - options for factorization, includes 3263 $ fill - expected fill as ratio of original fill. 3264 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3265 $ Run with the option -info to determine an optimal value to use 3266 3267 Notes: 3268 See MatLUFactorSymbolic() for the nonsymmetric case. See also 3269 MatCholeskyFactor() and MatCholeskyFactorNumeric(). 3270 3271 Most users should employ the simplified KSP interface for linear solvers 3272 instead of working directly with matrix algebra routines such as this. 3273 See, e.g., KSPCreate(). 3274 3275 Level: developer 3276 3277 .seealso: `MatLUFactorSymbolic()`, `MatCholeskyFactor()`, `MatCholeskyFactorNumeric()` 3278 `MatGetOrdering()` 3279 3280 Developer Note: fortran interface is not autogenerated as the f90 3281 interface definition cannot be generated correctly [due to MatFactorInfo] 3282 3283 @*/ 3284 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 3285 { 3286 MatFactorInfo tinfo; 3287 3288 PetscFunctionBegin; 3289 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3290 PetscValidType(mat,2); 3291 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,3); 3292 if (info) PetscValidPointer(info,4); 3293 PetscValidPointer(fact,1); 3294 PetscCheck(mat->rmap->N == mat->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square"); 3295 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3296 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3297 if (!(fact)->ops->choleskyfactorsymbolic) { 3298 MatSolverType stype; 3299 PetscCall(MatFactorGetSolverType(fact,&stype)); 3300 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,stype); 3301 } 3302 MatCheckPreallocated(mat,2); 3303 if (!info) { 3304 PetscCall(MatFactorInfoInitialize(&tinfo)); 3305 info = &tinfo; 3306 } 3307 3308 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0)); 3309 PetscCall((fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info)); 3310 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0)); 3311 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3312 PetscFunctionReturn(0); 3313 } 3314 3315 /*@C 3316 MatCholeskyFactorNumeric - Performs numeric Cholesky factorization 3317 of a symmetric matrix. Call this routine after first calling 3318 MatCholeskyFactorSymbolic(). 3319 3320 Collective on Mat 3321 3322 Input Parameters: 3323 + fact - the factor matrix obtained with MatGetFactor() 3324 . mat - the initial matrix 3325 . info - options for factorization 3326 - fact - the symbolic factor of mat 3327 3328 Notes: 3329 Most users should employ the simplified KSP interface for linear solvers 3330 instead of working directly with matrix algebra routines such as this. 3331 See, e.g., KSPCreate(). 3332 3333 Level: developer 3334 3335 .seealso: `MatCholeskyFactorSymbolic()`, `MatCholeskyFactor()`, `MatLUFactorNumeric()` 3336 3337 Developer Note: fortran interface is not autogenerated as the f90 3338 interface definition cannot be generated correctly [due to MatFactorInfo] 3339 3340 @*/ 3341 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3342 { 3343 MatFactorInfo tinfo; 3344 3345 PetscFunctionBegin; 3346 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3347 PetscValidType(mat,2); 3348 PetscValidPointer(fact,1); 3349 PetscValidHeaderSpecific(fact,MAT_CLASSID,1); 3350 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3351 PetscCheck((fact)->ops->choleskyfactornumeric,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name); 3352 PetscCheck(mat->rmap->N == (fact)->rmap->N && mat->cmap->N == (fact)->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dim %" PetscInt_FMT " should = %" PetscInt_FMT " %" PetscInt_FMT " should = %" PetscInt_FMT,mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N); 3353 MatCheckPreallocated(mat,2); 3354 if (!info) { 3355 PetscCall(MatFactorInfoInitialize(&tinfo)); 3356 info = &tinfo; 3357 } 3358 3359 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0)); 3360 else PetscCall(PetscLogEventBegin(MAT_CholeskyFactor,mat,fact,0,0)); 3361 PetscCall((fact->ops->choleskyfactornumeric)(fact,mat,info)); 3362 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0)); 3363 else PetscCall(PetscLogEventEnd(MAT_CholeskyFactor,mat,fact,0,0)); 3364 PetscCall(MatViewFromOptions(fact,NULL,"-mat_factor_view")); 3365 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3366 PetscFunctionReturn(0); 3367 } 3368 3369 /*@ 3370 MatQRFactor - Performs in-place QR factorization of matrix. 3371 3372 Collective on Mat 3373 3374 Input Parameters: 3375 + mat - the matrix 3376 . col - column permutation 3377 - info - options for factorization, includes 3378 $ fill - expected fill as ratio of original fill. 3379 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3380 $ Run with the option -info to determine an optimal value to use 3381 3382 Notes: 3383 Most users should employ the simplified KSP interface for linear solvers 3384 instead of working directly with matrix algebra routines such as this. 3385 See, e.g., KSPCreate(). 3386 3387 This changes the state of the matrix to a factored matrix; it cannot be used 3388 for example with MatSetValues() unless one first calls MatSetUnfactored(). 3389 3390 Level: developer 3391 3392 .seealso: `MatQRFactorSymbolic()`, `MatQRFactorNumeric()`, `MatLUFactor()`, 3393 `MatSetUnfactored()`, `MatFactorInfo`, `MatGetFactor()` 3394 3395 Developer Note: fortran interface is not autogenerated as the f90 3396 interface definition cannot be generated correctly [due to MatFactorInfo] 3397 3398 @*/ 3399 PetscErrorCode MatQRFactor(Mat mat, IS col, const MatFactorInfo *info) 3400 { 3401 PetscFunctionBegin; 3402 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3403 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,2); 3404 if (info) PetscValidPointer(info,3); 3405 PetscValidType(mat,1); 3406 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3407 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3408 MatCheckPreallocated(mat,1); 3409 PetscCall(PetscLogEventBegin(MAT_QRFactor,mat,col,0,0)); 3410 PetscUseMethod(mat,"MatQRFactor_C", (Mat,IS,const MatFactorInfo*), (mat, col, info)); 3411 PetscCall(PetscLogEventEnd(MAT_QRFactor,mat,col,0,0)); 3412 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 3413 PetscFunctionReturn(0); 3414 } 3415 3416 /*@ 3417 MatQRFactorSymbolic - Performs symbolic QR factorization of matrix. 3418 Call this routine before calling MatQRFactorNumeric(). 3419 3420 Collective on Mat 3421 3422 Input Parameters: 3423 + fact - the factor matrix obtained with MatGetFactor() 3424 . mat - the matrix 3425 . col - column permutation 3426 - info - options for factorization, includes 3427 $ fill - expected fill as ratio of original fill. 3428 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3429 $ Run with the option -info to determine an optimal value to use 3430 3431 Most users should employ the simplified KSP interface for linear solvers 3432 instead of working directly with matrix algebra routines such as this. 3433 See, e.g., KSPCreate(). 3434 3435 Level: developer 3436 3437 .seealso: `MatQRFactor()`, `MatQRFactorNumeric()`, `MatLUFactor()`, `MatFactorInfo`, `MatFactorInfoInitialize()` 3438 3439 Developer Note: fortran interface is not autogenerated as the f90 3440 interface definition cannot be generated correctly [due to MatFactorInfo] 3441 3442 @*/ 3443 PetscErrorCode MatQRFactorSymbolic(Mat fact,Mat mat,IS col,const MatFactorInfo *info) 3444 { 3445 MatFactorInfo tinfo; 3446 3447 PetscFunctionBegin; 3448 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3449 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 3450 if (info) PetscValidPointer(info,4); 3451 PetscValidType(mat,2); 3452 PetscValidPointer(fact,1); 3453 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3454 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3455 MatCheckPreallocated(mat,2); 3456 if (!info) { 3457 PetscCall(MatFactorInfoInitialize(&tinfo)); 3458 info = &tinfo; 3459 } 3460 3461 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_QRFactorSymbolic,fact,mat,col,0)); 3462 PetscUseMethod(fact,"MatQRFactorSymbolic_C", (Mat,Mat,IS,const MatFactorInfo*), (fact, mat, col, info)); 3463 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_QRFactorSymbolic,fact,mat,col,0)); 3464 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3465 PetscFunctionReturn(0); 3466 } 3467 3468 /*@ 3469 MatQRFactorNumeric - Performs numeric QR factorization of a matrix. 3470 Call this routine after first calling MatQRFactorSymbolic(). 3471 3472 Collective on Mat 3473 3474 Input Parameters: 3475 + fact - the factor matrix obtained with MatGetFactor() 3476 . mat - the matrix 3477 - info - options for factorization 3478 3479 Notes: 3480 See MatQRFactor() for in-place factorization. 3481 3482 Most users should employ the simplified KSP interface for linear solvers 3483 instead of working directly with matrix algebra routines such as this. 3484 See, e.g., KSPCreate(). 3485 3486 Level: developer 3487 3488 .seealso: `MatQRFactorSymbolic()`, `MatLUFactor()` 3489 3490 Developer Note: fortran interface is not autogenerated as the f90 3491 interface definition cannot be generated correctly [due to MatFactorInfo] 3492 3493 @*/ 3494 PetscErrorCode MatQRFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3495 { 3496 MatFactorInfo tinfo; 3497 3498 PetscFunctionBegin; 3499 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3500 PetscValidType(mat,2); 3501 PetscValidPointer(fact,1); 3502 PetscValidHeaderSpecific(fact,MAT_CLASSID,1); 3503 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3504 PetscCheck(mat->rmap->N == fact->rmap->N && mat->cmap->N == fact->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dimensions are different %" PetscInt_FMT " should = %" PetscInt_FMT " %" PetscInt_FMT " should = %" PetscInt_FMT,mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N); 3505 3506 MatCheckPreallocated(mat,2); 3507 if (!info) { 3508 PetscCall(MatFactorInfoInitialize(&tinfo)); 3509 info = &tinfo; 3510 } 3511 3512 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_QRFactorNumeric,mat,fact,0,0)); 3513 else PetscCall(PetscLogEventBegin(MAT_QRFactor,mat,fact,0,0)); 3514 PetscUseMethod(fact,"MatQRFactorNumeric_C", (Mat,Mat,const MatFactorInfo*), (fact, mat, info)); 3515 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_QRFactorNumeric,mat,fact,0,0)); 3516 else PetscCall(PetscLogEventEnd(MAT_QRFactor,mat,fact,0,0)); 3517 PetscCall(MatViewFromOptions(fact,NULL,"-mat_factor_view")); 3518 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3519 PetscFunctionReturn(0); 3520 } 3521 3522 /* ----------------------------------------------------------------*/ 3523 /*@ 3524 MatSolve - Solves A x = b, given a factored matrix. 3525 3526 Neighbor-wise Collective on Mat 3527 3528 Input Parameters: 3529 + mat - the factored matrix 3530 - b - the right-hand-side vector 3531 3532 Output Parameter: 3533 . x - the result vector 3534 3535 Notes: 3536 The vectors b and x cannot be the same. I.e., one cannot 3537 call MatSolve(A,x,x). 3538 3539 Notes: 3540 Most users should employ the simplified KSP interface for linear solvers 3541 instead of working directly with matrix algebra routines such as this. 3542 See, e.g., KSPCreate(). 3543 3544 Level: developer 3545 3546 .seealso: `MatSolveAdd()`, `MatSolveTranspose()`, `MatSolveTransposeAdd()` 3547 @*/ 3548 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x) 3549 { 3550 PetscFunctionBegin; 3551 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3552 PetscValidType(mat,1); 3553 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3554 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3555 PetscCheckSameComm(mat,1,b,2); 3556 PetscCheckSameComm(mat,1,x,3); 3557 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3558 PetscCheck(mat->cmap->N == x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,x->map->N); 3559 PetscCheck(mat->rmap->N == b->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,b->map->N); 3560 PetscCheck(mat->rmap->n == b->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,b->map->n); 3561 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3562 MatCheckPreallocated(mat,1); 3563 3564 PetscCall(PetscLogEventBegin(MAT_Solve,mat,b,x,0)); 3565 if (mat->factorerrortype) { 3566 PetscCall(PetscInfo(mat,"MatFactorError %d\n",mat->factorerrortype)); 3567 PetscCall(VecSetInf(x)); 3568 } else { 3569 PetscCheck(mat->ops->solve,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3570 PetscCall((*mat->ops->solve)(mat,b,x)); 3571 } 3572 PetscCall(PetscLogEventEnd(MAT_Solve,mat,b,x,0)); 3573 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3574 PetscFunctionReturn(0); 3575 } 3576 3577 static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X,PetscBool trans) 3578 { 3579 Vec b,x; 3580 PetscInt N,i; 3581 PetscErrorCode (*f)(Mat,Vec,Vec); 3582 PetscBool Abound,Bneedconv = PETSC_FALSE,Xneedconv = PETSC_FALSE; 3583 3584 PetscFunctionBegin; 3585 if (A->factorerrortype) { 3586 PetscCall(PetscInfo(A,"MatFactorError %d\n",A->factorerrortype)); 3587 PetscCall(MatSetInf(X)); 3588 PetscFunctionReturn(0); 3589 } 3590 f = (!trans || (!A->ops->solvetranspose && A->symmetric)) ? A->ops->solve : A->ops->solvetranspose; 3591 PetscCheck(f,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 3592 PetscCall(MatBoundToCPU(A,&Abound)); 3593 if (!Abound) { 3594 PetscCall(PetscObjectTypeCompareAny((PetscObject)B,&Bneedconv,MATSEQDENSE,MATMPIDENSE,"")); 3595 PetscCall(PetscObjectTypeCompareAny((PetscObject)X,&Xneedconv,MATSEQDENSE,MATMPIDENSE,"")); 3596 } 3597 if (Bneedconv) { 3598 PetscCall(MatConvert(B,MATDENSECUDA,MAT_INPLACE_MATRIX,&B)); 3599 } 3600 if (Xneedconv) { 3601 PetscCall(MatConvert(X,MATDENSECUDA,MAT_INPLACE_MATRIX,&X)); 3602 } 3603 PetscCall(MatGetSize(B,NULL,&N)); 3604 for (i=0; i<N; i++) { 3605 PetscCall(MatDenseGetColumnVecRead(B,i,&b)); 3606 PetscCall(MatDenseGetColumnVecWrite(X,i,&x)); 3607 PetscCall((*f)(A,b,x)); 3608 PetscCall(MatDenseRestoreColumnVecWrite(X,i,&x)); 3609 PetscCall(MatDenseRestoreColumnVecRead(B,i,&b)); 3610 } 3611 if (Bneedconv) { 3612 PetscCall(MatConvert(B,MATDENSE,MAT_INPLACE_MATRIX,&B)); 3613 } 3614 if (Xneedconv) { 3615 PetscCall(MatConvert(X,MATDENSE,MAT_INPLACE_MATRIX,&X)); 3616 } 3617 PetscFunctionReturn(0); 3618 } 3619 3620 /*@ 3621 MatMatSolve - Solves A X = B, given a factored matrix. 3622 3623 Neighbor-wise Collective on Mat 3624 3625 Input Parameters: 3626 + A - the factored matrix 3627 - B - the right-hand-side matrix MATDENSE (or sparse -- when using MUMPS) 3628 3629 Output Parameter: 3630 . X - the result matrix (dense matrix) 3631 3632 Notes: 3633 If B is a MATDENSE matrix then one can call MatMatSolve(A,B,B) except with MKL_CPARDISO; 3634 otherwise, B and X cannot be the same. 3635 3636 Notes: 3637 Most users should usually employ the simplified KSP interface for linear solvers 3638 instead of working directly with matrix algebra routines such as this. 3639 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3640 at a time. 3641 3642 Level: developer 3643 3644 .seealso: `MatMatSolveTranspose()`, `MatLUFactor()`, `MatCholeskyFactor()` 3645 @*/ 3646 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X) 3647 { 3648 PetscFunctionBegin; 3649 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3650 PetscValidType(A,1); 3651 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3652 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3653 PetscCheckSameComm(A,1,B,2); 3654 PetscCheckSameComm(A,1,X,3); 3655 PetscCheck(A->cmap->N == X->rmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %" PetscInt_FMT " %" PetscInt_FMT,A->cmap->N,X->rmap->N); 3656 PetscCheck(A->rmap->N == B->rmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %" PetscInt_FMT " %" PetscInt_FMT,A->rmap->N,B->rmap->N); 3657 PetscCheck(X->cmap->N == B->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix"); 3658 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3659 PetscCheck(A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3660 MatCheckPreallocated(A,1); 3661 3662 PetscCall(PetscLogEventBegin(MAT_MatSolve,A,B,X,0)); 3663 if (!A->ops->matsolve) { 3664 PetscCall(PetscInfo(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name)); 3665 PetscCall(MatMatSolve_Basic(A,B,X,PETSC_FALSE)); 3666 } else { 3667 PetscCall((*A->ops->matsolve)(A,B,X)); 3668 } 3669 PetscCall(PetscLogEventEnd(MAT_MatSolve,A,B,X,0)); 3670 PetscCall(PetscObjectStateIncrease((PetscObject)X)); 3671 PetscFunctionReturn(0); 3672 } 3673 3674 /*@ 3675 MatMatSolveTranspose - Solves A^T X = B, given a factored matrix. 3676 3677 Neighbor-wise Collective on Mat 3678 3679 Input Parameters: 3680 + A - the factored matrix 3681 - B - the right-hand-side matrix (dense matrix) 3682 3683 Output Parameter: 3684 . X - the result matrix (dense matrix) 3685 3686 Notes: 3687 The matrices B and X cannot be the same. I.e., one cannot 3688 call MatMatSolveTranspose(A,X,X). 3689 3690 Notes: 3691 Most users should usually employ the simplified KSP interface for linear solvers 3692 instead of working directly with matrix algebra routines such as this. 3693 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3694 at a time. 3695 3696 When using SuperLU_Dist or MUMPS as a parallel solver, PETSc will use their functionality to solve multiple right hand sides simultaneously. 3697 3698 Level: developer 3699 3700 .seealso: `MatMatSolve()`, `MatLUFactor()`, `MatCholeskyFactor()` 3701 @*/ 3702 PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X) 3703 { 3704 PetscFunctionBegin; 3705 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3706 PetscValidType(A,1); 3707 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3708 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3709 PetscCheckSameComm(A,1,B,2); 3710 PetscCheckSameComm(A,1,X,3); 3711 PetscCheck(X != B,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3712 PetscCheck(A->cmap->N == X->rmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %" PetscInt_FMT " %" PetscInt_FMT,A->cmap->N,X->rmap->N); 3713 PetscCheck(A->rmap->N == B->rmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %" PetscInt_FMT " %" PetscInt_FMT,A->rmap->N,B->rmap->N); 3714 PetscCheck(A->rmap->n == B->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat A,Mat B: local dim %" PetscInt_FMT " %" PetscInt_FMT,A->rmap->n,B->rmap->n); 3715 PetscCheck(X->cmap->N >= B->cmap->N,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix"); 3716 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3717 PetscCheck(A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3718 MatCheckPreallocated(A,1); 3719 3720 PetscCall(PetscLogEventBegin(MAT_MatSolve,A,B,X,0)); 3721 if (!A->ops->matsolvetranspose) { 3722 PetscCall(PetscInfo(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name)); 3723 PetscCall(MatMatSolve_Basic(A,B,X,PETSC_TRUE)); 3724 } else { 3725 PetscCall((*A->ops->matsolvetranspose)(A,B,X)); 3726 } 3727 PetscCall(PetscLogEventEnd(MAT_MatSolve,A,B,X,0)); 3728 PetscCall(PetscObjectStateIncrease((PetscObject)X)); 3729 PetscFunctionReturn(0); 3730 } 3731 3732 /*@ 3733 MatMatTransposeSolve - Solves A X = B^T, given a factored matrix. 3734 3735 Neighbor-wise Collective on Mat 3736 3737 Input Parameters: 3738 + A - the factored matrix 3739 - Bt - the transpose of right-hand-side matrix 3740 3741 Output Parameter: 3742 . X - the result matrix (dense matrix) 3743 3744 Notes: 3745 Most users should usually employ the simplified KSP interface for linear solvers 3746 instead of working directly with matrix algebra routines such as this. 3747 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3748 at a time. 3749 3750 For MUMPS, it only supports centralized sparse compressed column format on the host processor for right hand side matrix. User must create B^T in sparse compressed row format on the host processor and call MatMatTransposeSolve() to implement MUMPS' MatMatSolve(). 3751 3752 Level: developer 3753 3754 .seealso: `MatMatSolve()`, `MatMatSolveTranspose()`, `MatLUFactor()`, `MatCholeskyFactor()` 3755 @*/ 3756 PetscErrorCode MatMatTransposeSolve(Mat A,Mat Bt,Mat X) 3757 { 3758 PetscFunctionBegin; 3759 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3760 PetscValidType(A,1); 3761 PetscValidHeaderSpecific(Bt,MAT_CLASSID,2); 3762 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3763 PetscCheckSameComm(A,1,Bt,2); 3764 PetscCheckSameComm(A,1,X,3); 3765 3766 PetscCheck(X != Bt,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3767 PetscCheck(A->cmap->N == X->rmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %" PetscInt_FMT " %" PetscInt_FMT,A->cmap->N,X->rmap->N); 3768 PetscCheck(A->rmap->N == Bt->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat Bt: global dim %" PetscInt_FMT " %" PetscInt_FMT,A->rmap->N,Bt->cmap->N); 3769 PetscCheck(X->cmap->N >= Bt->rmap->N,PetscObjectComm((PetscObject)X),PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as row number of the rhs matrix"); 3770 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3771 PetscCheck(A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3772 MatCheckPreallocated(A,1); 3773 3774 PetscCheck(A->ops->mattransposesolve,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 3775 PetscCall(PetscLogEventBegin(MAT_MatTrSolve,A,Bt,X,0)); 3776 PetscCall((*A->ops->mattransposesolve)(A,Bt,X)); 3777 PetscCall(PetscLogEventEnd(MAT_MatTrSolve,A,Bt,X,0)); 3778 PetscCall(PetscObjectStateIncrease((PetscObject)X)); 3779 PetscFunctionReturn(0); 3780 } 3781 3782 /*@ 3783 MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or 3784 U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U, 3785 3786 Neighbor-wise Collective on Mat 3787 3788 Input Parameters: 3789 + mat - the factored matrix 3790 - b - the right-hand-side vector 3791 3792 Output Parameter: 3793 . x - the result vector 3794 3795 Notes: 3796 MatSolve() should be used for most applications, as it performs 3797 a forward solve followed by a backward solve. 3798 3799 The vectors b and x cannot be the same, i.e., one cannot 3800 call MatForwardSolve(A,x,x). 3801 3802 For matrix in seqsbaij format with block size larger than 1, 3803 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3804 MatForwardSolve() solves U^T*D y = b, and 3805 MatBackwardSolve() solves U x = y. 3806 Thus they do not provide a symmetric preconditioner. 3807 3808 Most users should employ the simplified KSP interface for linear solvers 3809 instead of working directly with matrix algebra routines such as this. 3810 See, e.g., KSPCreate(). 3811 3812 Level: developer 3813 3814 .seealso: `MatSolve()`, `MatBackwardSolve()` 3815 @*/ 3816 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x) 3817 { 3818 PetscFunctionBegin; 3819 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3820 PetscValidType(mat,1); 3821 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3822 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3823 PetscCheckSameComm(mat,1,b,2); 3824 PetscCheckSameComm(mat,1,x,3); 3825 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3826 PetscCheck(mat->cmap->N == x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,x->map->N); 3827 PetscCheck(mat->rmap->N == b->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,b->map->N); 3828 PetscCheck(mat->rmap->n == b->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,b->map->n); 3829 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3830 MatCheckPreallocated(mat,1); 3831 3832 PetscCheck(mat->ops->forwardsolve,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3833 PetscCall(PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0)); 3834 PetscCall((*mat->ops->forwardsolve)(mat,b,x)); 3835 PetscCall(PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0)); 3836 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3837 PetscFunctionReturn(0); 3838 } 3839 3840 /*@ 3841 MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU. 3842 D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U, 3843 3844 Neighbor-wise Collective on Mat 3845 3846 Input Parameters: 3847 + mat - the factored matrix 3848 - b - the right-hand-side vector 3849 3850 Output Parameter: 3851 . x - the result vector 3852 3853 Notes: 3854 MatSolve() should be used for most applications, as it performs 3855 a forward solve followed by a backward solve. 3856 3857 The vectors b and x cannot be the same. I.e., one cannot 3858 call MatBackwardSolve(A,x,x). 3859 3860 For matrix in seqsbaij format with block size larger than 1, 3861 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3862 MatForwardSolve() solves U^T*D y = b, and 3863 MatBackwardSolve() solves U x = y. 3864 Thus they do not provide a symmetric preconditioner. 3865 3866 Most users should employ the simplified KSP interface for linear solvers 3867 instead of working directly with matrix algebra routines such as this. 3868 See, e.g., KSPCreate(). 3869 3870 Level: developer 3871 3872 .seealso: `MatSolve()`, `MatForwardSolve()` 3873 @*/ 3874 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x) 3875 { 3876 PetscFunctionBegin; 3877 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3878 PetscValidType(mat,1); 3879 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3880 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3881 PetscCheckSameComm(mat,1,b,2); 3882 PetscCheckSameComm(mat,1,x,3); 3883 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3884 PetscCheck(mat->cmap->N == x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,x->map->N); 3885 PetscCheck(mat->rmap->N == b->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,b->map->N); 3886 PetscCheck(mat->rmap->n == b->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,b->map->n); 3887 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3888 MatCheckPreallocated(mat,1); 3889 3890 PetscCheck(mat->ops->backwardsolve,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3891 PetscCall(PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0)); 3892 PetscCall((*mat->ops->backwardsolve)(mat,b,x)); 3893 PetscCall(PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0)); 3894 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3895 PetscFunctionReturn(0); 3896 } 3897 3898 /*@ 3899 MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix. 3900 3901 Neighbor-wise Collective on Mat 3902 3903 Input Parameters: 3904 + mat - the factored matrix 3905 . b - the right-hand-side vector 3906 - y - the vector to be added to 3907 3908 Output Parameter: 3909 . x - the result vector 3910 3911 Notes: 3912 The vectors b and x cannot be the same. I.e., one cannot 3913 call MatSolveAdd(A,x,y,x). 3914 3915 Most users should employ the simplified KSP interface for linear solvers 3916 instead of working directly with matrix algebra routines such as this. 3917 See, e.g., KSPCreate(). 3918 3919 Level: developer 3920 3921 .seealso: `MatSolve()`, `MatSolveTranspose()`, `MatSolveTransposeAdd()` 3922 @*/ 3923 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x) 3924 { 3925 PetscScalar one = 1.0; 3926 Vec tmp; 3927 3928 PetscFunctionBegin; 3929 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3930 PetscValidType(mat,1); 3931 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 3932 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3933 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 3934 PetscCheckSameComm(mat,1,b,2); 3935 PetscCheckSameComm(mat,1,y,3); 3936 PetscCheckSameComm(mat,1,x,4); 3937 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3938 PetscCheck(mat->cmap->N == x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,x->map->N); 3939 PetscCheck(mat->rmap->N == b->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,b->map->N); 3940 PetscCheck(mat->rmap->N == y->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,y->map->N); 3941 PetscCheck(mat->rmap->n == b->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,b->map->n); 3942 PetscCheck(x->map->n == y->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %" PetscInt_FMT " %" PetscInt_FMT,x->map->n,y->map->n); 3943 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3944 MatCheckPreallocated(mat,1); 3945 3946 PetscCall(PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y)); 3947 if (mat->factorerrortype) { 3948 3949 PetscCall(PetscInfo(mat,"MatFactorError %d\n",mat->factorerrortype)); 3950 PetscCall(VecSetInf(x)); 3951 } else if (mat->ops->solveadd) { 3952 PetscCall((*mat->ops->solveadd)(mat,b,y,x)); 3953 } else { 3954 /* do the solve then the add manually */ 3955 if (x != y) { 3956 PetscCall(MatSolve(mat,b,x)); 3957 PetscCall(VecAXPY(x,one,y)); 3958 } else { 3959 PetscCall(VecDuplicate(x,&tmp)); 3960 PetscCall(PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp)); 3961 PetscCall(VecCopy(x,tmp)); 3962 PetscCall(MatSolve(mat,b,x)); 3963 PetscCall(VecAXPY(x,one,tmp)); 3964 PetscCall(VecDestroy(&tmp)); 3965 } 3966 } 3967 PetscCall(PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y)); 3968 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3969 PetscFunctionReturn(0); 3970 } 3971 3972 /*@ 3973 MatSolveTranspose - Solves A' x = b, given a factored matrix. 3974 3975 Neighbor-wise Collective on Mat 3976 3977 Input Parameters: 3978 + mat - the factored matrix 3979 - b - the right-hand-side vector 3980 3981 Output Parameter: 3982 . x - the result vector 3983 3984 Notes: 3985 The vectors b and x cannot be the same. I.e., one cannot 3986 call MatSolveTranspose(A,x,x). 3987 3988 Most users should employ the simplified KSP interface for linear solvers 3989 instead of working directly with matrix algebra routines such as this. 3990 See, e.g., KSPCreate(). 3991 3992 Level: developer 3993 3994 .seealso: `MatSolve()`, `MatSolveAdd()`, `MatSolveTransposeAdd()` 3995 @*/ 3996 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x) 3997 { 3998 PetscErrorCode (*f)(Mat,Vec,Vec) = (!mat->ops->solvetranspose && mat->symmetric) ? mat->ops->solve : mat->ops->solvetranspose; 3999 4000 PetscFunctionBegin; 4001 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4002 PetscValidType(mat,1); 4003 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 4004 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 4005 PetscCheckSameComm(mat,1,b,2); 4006 PetscCheckSameComm(mat,1,x,3); 4007 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 4008 PetscCheck(mat->rmap->N == x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,x->map->N); 4009 PetscCheck(mat->cmap->N == b->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,b->map->N); 4010 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 4011 MatCheckPreallocated(mat,1); 4012 PetscCall(PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0)); 4013 if (mat->factorerrortype) { 4014 PetscCall(PetscInfo(mat,"MatFactorError %d\n",mat->factorerrortype)); 4015 PetscCall(VecSetInf(x)); 4016 } else { 4017 PetscCheck(f,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name); 4018 PetscCall((*f)(mat,b,x)); 4019 } 4020 PetscCall(PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0)); 4021 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 4022 PetscFunctionReturn(0); 4023 } 4024 4025 /*@ 4026 MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a 4027 factored matrix. 4028 4029 Neighbor-wise Collective on Mat 4030 4031 Input Parameters: 4032 + mat - the factored matrix 4033 . b - the right-hand-side vector 4034 - y - the vector to be added to 4035 4036 Output Parameter: 4037 . x - the result vector 4038 4039 Notes: 4040 The vectors b and x cannot be the same. I.e., one cannot 4041 call MatSolveTransposeAdd(A,x,y,x). 4042 4043 Most users should employ the simplified KSP interface for linear solvers 4044 instead of working directly with matrix algebra routines such as this. 4045 See, e.g., KSPCreate(). 4046 4047 Level: developer 4048 4049 .seealso: `MatSolve()`, `MatSolveAdd()`, `MatSolveTranspose()` 4050 @*/ 4051 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x) 4052 { 4053 PetscScalar one = 1.0; 4054 Vec tmp; 4055 PetscErrorCode (*f)(Mat,Vec,Vec,Vec) = (!mat->ops->solvetransposeadd && mat->symmetric) ? mat->ops->solveadd : mat->ops->solvetransposeadd; 4056 4057 PetscFunctionBegin; 4058 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4059 PetscValidType(mat,1); 4060 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 4061 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 4062 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 4063 PetscCheckSameComm(mat,1,b,2); 4064 PetscCheckSameComm(mat,1,y,3); 4065 PetscCheckSameComm(mat,1,x,4); 4066 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 4067 PetscCheck(mat->rmap->N == x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,x->map->N); 4068 PetscCheck(mat->cmap->N == b->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,b->map->N); 4069 PetscCheck(mat->cmap->N == y->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,y->map->N); 4070 PetscCheck(x->map->n == y->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %" PetscInt_FMT " %" PetscInt_FMT,x->map->n,y->map->n); 4071 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 4072 MatCheckPreallocated(mat,1); 4073 4074 PetscCall(PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y)); 4075 if (mat->factorerrortype) { 4076 PetscCall(PetscInfo(mat,"MatFactorError %d\n",mat->factorerrortype)); 4077 PetscCall(VecSetInf(x)); 4078 } else if (f) { 4079 PetscCall((*f)(mat,b,y,x)); 4080 } else { 4081 /* do the solve then the add manually */ 4082 if (x != y) { 4083 PetscCall(MatSolveTranspose(mat,b,x)); 4084 PetscCall(VecAXPY(x,one,y)); 4085 } else { 4086 PetscCall(VecDuplicate(x,&tmp)); 4087 PetscCall(PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp)); 4088 PetscCall(VecCopy(x,tmp)); 4089 PetscCall(MatSolveTranspose(mat,b,x)); 4090 PetscCall(VecAXPY(x,one,tmp)); 4091 PetscCall(VecDestroy(&tmp)); 4092 } 4093 } 4094 PetscCall(PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y)); 4095 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 4096 PetscFunctionReturn(0); 4097 } 4098 /* ----------------------------------------------------------------*/ 4099 4100 /*@ 4101 MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps. 4102 4103 Neighbor-wise Collective on Mat 4104 4105 Input Parameters: 4106 + mat - the matrix 4107 . b - the right hand side 4108 . omega - the relaxation factor 4109 . flag - flag indicating the type of SOR (see below) 4110 . shift - diagonal shift 4111 . its - the number of iterations 4112 - lits - the number of local iterations 4113 4114 Output Parameter: 4115 . x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess) 4116 4117 SOR Flags: 4118 + SOR_FORWARD_SWEEP - forward SOR 4119 . SOR_BACKWARD_SWEEP - backward SOR 4120 . SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR) 4121 . SOR_LOCAL_FORWARD_SWEEP - local forward SOR 4122 . SOR_LOCAL_BACKWARD_SWEEP - local forward SOR 4123 . SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR 4124 . SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies 4125 upper/lower triangular part of matrix to 4126 vector (with omega) 4127 - SOR_ZERO_INITIAL_GUESS - zero initial guess 4128 4129 Notes: 4130 SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and 4131 SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings 4132 on each processor. 4133 4134 Application programmers will not generally use MatSOR() directly, 4135 but instead will employ the KSP/PC interface. 4136 4137 Notes: 4138 for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing 4139 4140 Notes for Advanced Users: 4141 The flags are implemented as bitwise inclusive or operations. 4142 For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP) 4143 to specify a zero initial guess for SSOR. 4144 4145 Most users should employ the simplified KSP interface for linear solvers 4146 instead of working directly with matrix algebra routines such as this. 4147 See, e.g., KSPCreate(). 4148 4149 Vectors x and b CANNOT be the same 4150 4151 Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes 4152 4153 Level: developer 4154 4155 @*/ 4156 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x) 4157 { 4158 PetscFunctionBegin; 4159 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4160 PetscValidType(mat,1); 4161 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 4162 PetscValidHeaderSpecific(x,VEC_CLASSID,8); 4163 PetscCheckSameComm(mat,1,b,2); 4164 PetscCheckSameComm(mat,1,x,8); 4165 PetscCheck(mat->ops->sor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4166 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4167 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4168 PetscCheck(mat->cmap->N == x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,x->map->N); 4169 PetscCheck(mat->rmap->N == b->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,b->map->N); 4170 PetscCheck(mat->rmap->n == b->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,b->map->n); 4171 PetscCheck(its > 0,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %" PetscInt_FMT " positive",its); 4172 PetscCheck(lits > 0,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %" PetscInt_FMT " positive",lits); 4173 PetscCheck(b != x,PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same"); 4174 4175 MatCheckPreallocated(mat,1); 4176 PetscCall(PetscLogEventBegin(MAT_SOR,mat,b,x,0)); 4177 PetscCall((*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x)); 4178 PetscCall(PetscLogEventEnd(MAT_SOR,mat,b,x,0)); 4179 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 4180 PetscFunctionReturn(0); 4181 } 4182 4183 /* 4184 Default matrix copy routine. 4185 */ 4186 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str) 4187 { 4188 PetscInt i,rstart = 0,rend = 0,nz; 4189 const PetscInt *cwork; 4190 const PetscScalar *vwork; 4191 4192 PetscFunctionBegin; 4193 if (B->assembled) PetscCall(MatZeroEntries(B)); 4194 if (str == SAME_NONZERO_PATTERN) { 4195 PetscCall(MatGetOwnershipRange(A,&rstart,&rend)); 4196 for (i=rstart; i<rend; i++) { 4197 PetscCall(MatGetRow(A,i,&nz,&cwork,&vwork)); 4198 PetscCall(MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES)); 4199 PetscCall(MatRestoreRow(A,i,&nz,&cwork,&vwork)); 4200 } 4201 } else { 4202 PetscCall(MatAYPX(B,0.0,A,str)); 4203 } 4204 PetscCall(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY)); 4205 PetscCall(MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY)); 4206 PetscFunctionReturn(0); 4207 } 4208 4209 /*@ 4210 MatCopy - Copies a matrix to another matrix. 4211 4212 Collective on Mat 4213 4214 Input Parameters: 4215 + A - the matrix 4216 - str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN 4217 4218 Output Parameter: 4219 . B - where the copy is put 4220 4221 Notes: 4222 If you use SAME_NONZERO_PATTERN then the two matrices must have the same nonzero pattern or the routine will crash. 4223 4224 MatCopy() copies the matrix entries of a matrix to another existing 4225 matrix (after first zeroing the second matrix). A related routine is 4226 MatConvert(), which first creates a new matrix and then copies the data. 4227 4228 Level: intermediate 4229 4230 .seealso: `MatConvert()`, `MatDuplicate()` 4231 @*/ 4232 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str) 4233 { 4234 PetscInt i; 4235 4236 PetscFunctionBegin; 4237 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4238 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4239 PetscValidType(A,1); 4240 PetscValidType(B,2); 4241 PetscCheckSameComm(A,1,B,2); 4242 MatCheckPreallocated(B,2); 4243 PetscCheck(A->assembled,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4244 PetscCheck(!A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4245 PetscCheck(A->rmap->N == B->rmap->N && A->cmap->N == B->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim (%" PetscInt_FMT ",%" PetscInt_FMT ") (%" PetscInt_FMT ",%" PetscInt_FMT ")",A->rmap->N,B->rmap->N,A->cmap->N,B->cmap->N); 4246 MatCheckPreallocated(A,1); 4247 if (A == B) PetscFunctionReturn(0); 4248 4249 PetscCall(PetscLogEventBegin(MAT_Copy,A,B,0,0)); 4250 if (A->ops->copy) { 4251 PetscCall((*A->ops->copy)(A,B,str)); 4252 } else { /* generic conversion */ 4253 PetscCall(MatCopy_Basic(A,B,str)); 4254 } 4255 4256 B->stencil.dim = A->stencil.dim; 4257 B->stencil.noc = A->stencil.noc; 4258 for (i=0; i<=A->stencil.dim; i++) { 4259 B->stencil.dims[i] = A->stencil.dims[i]; 4260 B->stencil.starts[i] = A->stencil.starts[i]; 4261 } 4262 4263 PetscCall(PetscLogEventEnd(MAT_Copy,A,B,0,0)); 4264 PetscCall(PetscObjectStateIncrease((PetscObject)B)); 4265 PetscFunctionReturn(0); 4266 } 4267 4268 /*@C 4269 MatConvert - Converts a matrix to another matrix, either of the same 4270 or different type. 4271 4272 Collective on Mat 4273 4274 Input Parameters: 4275 + mat - the matrix 4276 . newtype - new matrix type. Use MATSAME to create a new matrix of the 4277 same type as the original matrix. 4278 - reuse - denotes if the destination matrix is to be created or reused. 4279 Use MAT_INPLACE_MATRIX for inplace conversion (that is when you want the input mat to be changed to contain the matrix in the new format), otherwise use 4280 MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX (can only be used after the first call was made with MAT_INITIAL_MATRIX, causes the matrix space in M to be reused). 4281 4282 Output Parameter: 4283 . M - pointer to place new matrix 4284 4285 Notes: 4286 MatConvert() first creates a new matrix and then copies the data from 4287 the first matrix. A related routine is MatCopy(), which copies the matrix 4288 entries of one matrix to another already existing matrix context. 4289 4290 Cannot be used to convert a sequential matrix to parallel or parallel to sequential, 4291 the MPI communicator of the generated matrix is always the same as the communicator 4292 of the input matrix. 4293 4294 Level: intermediate 4295 4296 .seealso: `MatCopy()`, `MatDuplicate()` 4297 @*/ 4298 PetscErrorCode MatConvert(Mat mat,MatType newtype,MatReuse reuse,Mat *M) 4299 { 4300 PetscBool sametype,issame,flg; 4301 PetscBool3 issymmetric,ishermitian; 4302 char convname[256],mtype[256]; 4303 Mat B; 4304 4305 PetscFunctionBegin; 4306 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4307 PetscValidType(mat,1); 4308 PetscValidPointer(M,4); 4309 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4310 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4311 MatCheckPreallocated(mat,1); 4312 4313 PetscCall(PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,sizeof(mtype),&flg)); 4314 if (flg) newtype = mtype; 4315 4316 PetscCall(PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype)); 4317 PetscCall(PetscStrcmp(newtype,"same",&issame)); 4318 PetscCheck(!(reuse == MAT_INPLACE_MATRIX) || !(mat != *M),PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix"); 4319 PetscCheck(!(reuse == MAT_REUSE_MATRIX) || !(mat == *M),PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_REUSE_MATRIX means reuse matrix in final argument, perhaps you mean MAT_INPLACE_MATRIX"); 4320 4321 if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) { 4322 PetscCall(PetscInfo(mat,"Early return for inplace %s %d %d\n",((PetscObject)mat)->type_name,sametype,issame)); 4323 PetscFunctionReturn(0); 4324 } 4325 4326 /* Cache Mat options because some converters use MatHeaderReplace */ 4327 issymmetric = mat->symmetric; 4328 ishermitian = mat->hermitian; 4329 4330 if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) { 4331 PetscCall(PetscInfo(mat,"Calling duplicate for initial matrix %s %d %d\n",((PetscObject)mat)->type_name,sametype,issame)); 4332 PetscCall((*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M)); 4333 } else { 4334 PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL; 4335 const char *prefix[3] = {"seq","mpi",""}; 4336 PetscInt i; 4337 /* 4338 Order of precedence: 4339 0) See if newtype is a superclass of the current matrix. 4340 1) See if a specialized converter is known to the current matrix. 4341 2) See if a specialized converter is known to the desired matrix class. 4342 3) See if a good general converter is registered for the desired class 4343 (as of 6/27/03 only MATMPIADJ falls into this category). 4344 4) See if a good general converter is known for the current matrix. 4345 5) Use a really basic converter. 4346 */ 4347 4348 /* 0) See if newtype is a superclass of the current matrix. 4349 i.e mat is mpiaij and newtype is aij */ 4350 for (i=0; i<2; i++) { 4351 PetscCall(PetscStrncpy(convname,prefix[i],sizeof(convname))); 4352 PetscCall(PetscStrlcat(convname,newtype,sizeof(convname))); 4353 PetscCall(PetscStrcmp(convname,((PetscObject)mat)->type_name,&flg)); 4354 PetscCall(PetscInfo(mat,"Check superclass %s %s -> %d\n",convname,((PetscObject)mat)->type_name,flg)); 4355 if (flg) { 4356 if (reuse == MAT_INPLACE_MATRIX) { 4357 PetscCall(PetscInfo(mat,"Early return\n")); 4358 PetscFunctionReturn(0); 4359 } else if (reuse == MAT_INITIAL_MATRIX && mat->ops->duplicate) { 4360 PetscCall(PetscInfo(mat,"Calling MatDuplicate\n")); 4361 PetscCall((*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M)); 4362 PetscFunctionReturn(0); 4363 } else if (reuse == MAT_REUSE_MATRIX && mat->ops->copy) { 4364 PetscCall(PetscInfo(mat,"Calling MatCopy\n")); 4365 PetscCall(MatCopy(mat,*M,SAME_NONZERO_PATTERN)); 4366 PetscFunctionReturn(0); 4367 } 4368 } 4369 } 4370 /* 1) See if a specialized converter is known to the current matrix and the desired class */ 4371 for (i=0; i<3; i++) { 4372 PetscCall(PetscStrncpy(convname,"MatConvert_",sizeof(convname))); 4373 PetscCall(PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname))); 4374 PetscCall(PetscStrlcat(convname,"_",sizeof(convname))); 4375 PetscCall(PetscStrlcat(convname,prefix[i],sizeof(convname))); 4376 PetscCall(PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname))); 4377 PetscCall(PetscStrlcat(convname,"_C",sizeof(convname))); 4378 PetscCall(PetscObjectQueryFunction((PetscObject)mat,convname,&conv)); 4379 PetscCall(PetscInfo(mat,"Check specialized (1) %s (%s) -> %d\n",convname,((PetscObject)mat)->type_name,!!conv)); 4380 if (conv) goto foundconv; 4381 } 4382 4383 /* 2) See if a specialized converter is known to the desired matrix class. */ 4384 PetscCall(MatCreate(PetscObjectComm((PetscObject)mat),&B)); 4385 PetscCall(MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N)); 4386 PetscCall(MatSetType(B,newtype)); 4387 for (i=0; i<3; i++) { 4388 PetscCall(PetscStrncpy(convname,"MatConvert_",sizeof(convname))); 4389 PetscCall(PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname))); 4390 PetscCall(PetscStrlcat(convname,"_",sizeof(convname))); 4391 PetscCall(PetscStrlcat(convname,prefix[i],sizeof(convname))); 4392 PetscCall(PetscStrlcat(convname,newtype,sizeof(convname))); 4393 PetscCall(PetscStrlcat(convname,"_C",sizeof(convname))); 4394 PetscCall(PetscObjectQueryFunction((PetscObject)B,convname,&conv)); 4395 PetscCall(PetscInfo(mat,"Check specialized (2) %s (%s) -> %d\n",convname,((PetscObject)B)->type_name,!!conv)); 4396 if (conv) { 4397 PetscCall(MatDestroy(&B)); 4398 goto foundconv; 4399 } 4400 } 4401 4402 /* 3) See if a good general converter is registered for the desired class */ 4403 conv = B->ops->convertfrom; 4404 PetscCall(PetscInfo(mat,"Check convertfrom (%s) -> %d\n",((PetscObject)B)->type_name,!!conv)); 4405 PetscCall(MatDestroy(&B)); 4406 if (conv) goto foundconv; 4407 4408 /* 4) See if a good general converter is known for the current matrix */ 4409 if (mat->ops->convert) conv = mat->ops->convert; 4410 PetscCall(PetscInfo(mat,"Check general convert (%s) -> %d\n",((PetscObject)mat)->type_name,!!conv)); 4411 if (conv) goto foundconv; 4412 4413 /* 5) Use a really basic converter. */ 4414 PetscCall(PetscInfo(mat,"Using MatConvert_Basic\n")); 4415 conv = MatConvert_Basic; 4416 4417 foundconv: 4418 PetscCall(PetscLogEventBegin(MAT_Convert,mat,0,0,0)); 4419 PetscCall((*conv)(mat,newtype,reuse,M)); 4420 if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) { 4421 /* the block sizes must be same if the mappings are copied over */ 4422 (*M)->rmap->bs = mat->rmap->bs; 4423 (*M)->cmap->bs = mat->cmap->bs; 4424 PetscCall(PetscObjectReference((PetscObject)mat->rmap->mapping)); 4425 PetscCall(PetscObjectReference((PetscObject)mat->cmap->mapping)); 4426 (*M)->rmap->mapping = mat->rmap->mapping; 4427 (*M)->cmap->mapping = mat->cmap->mapping; 4428 } 4429 (*M)->stencil.dim = mat->stencil.dim; 4430 (*M)->stencil.noc = mat->stencil.noc; 4431 for (i=0; i<=mat->stencil.dim; i++) { 4432 (*M)->stencil.dims[i] = mat->stencil.dims[i]; 4433 (*M)->stencil.starts[i] = mat->stencil.starts[i]; 4434 } 4435 PetscCall(PetscLogEventEnd(MAT_Convert,mat,0,0,0)); 4436 } 4437 PetscCall(PetscObjectStateIncrease((PetscObject)*M)); 4438 4439 /* Copy Mat options */ 4440 if (issymmetric == PETSC_BOOL3_TRUE) PetscCall(MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE)); 4441 else if (issymmetric == PETSC_BOOL3_FALSE) PetscCall(MatSetOption(*M,MAT_SYMMETRIC,PETSC_FALSE)); 4442 if (ishermitian == PETSC_BOOL3_TRUE) PetscCall(MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE)); 4443 else if (ishermitian == PETSC_BOOL3_FALSE) PetscCall(MatSetOption(*M,MAT_HERMITIAN,PETSC_FALSE)); 4444 PetscFunctionReturn(0); 4445 } 4446 4447 /*@C 4448 MatFactorGetSolverType - Returns name of the package providing the factorization routines 4449 4450 Not Collective 4451 4452 Input Parameter: 4453 . mat - the matrix, must be a factored matrix 4454 4455 Output Parameter: 4456 . type - the string name of the package (do not free this string) 4457 4458 Notes: 4459 In Fortran you pass in a empty string and the package name will be copied into it. 4460 (Make sure the string is long enough) 4461 4462 Level: intermediate 4463 4464 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()` 4465 @*/ 4466 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type) 4467 { 4468 PetscErrorCode (*conv)(Mat,MatSolverType*); 4469 4470 PetscFunctionBegin; 4471 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4472 PetscValidType(mat,1); 4473 PetscValidPointer(type,2); 4474 PetscCheck(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 4475 PetscCall(PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv)); 4476 if (conv) PetscCall((*conv)(mat,type)); 4477 else *type = MATSOLVERPETSC; 4478 PetscFunctionReturn(0); 4479 } 4480 4481 typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType; 4482 struct _MatSolverTypeForSpecifcType { 4483 MatType mtype; 4484 /* no entry for MAT_FACTOR_NONE */ 4485 PetscErrorCode (*createfactor[MAT_FACTOR_NUM_TYPES-1])(Mat,MatFactorType,Mat*); 4486 MatSolverTypeForSpecifcType next; 4487 }; 4488 4489 typedef struct _MatSolverTypeHolder* MatSolverTypeHolder; 4490 struct _MatSolverTypeHolder { 4491 char *name; 4492 MatSolverTypeForSpecifcType handlers; 4493 MatSolverTypeHolder next; 4494 }; 4495 4496 static MatSolverTypeHolder MatSolverTypeHolders = NULL; 4497 4498 /*@C 4499 MatSolverTypeRegister - Registers a MatSolverType that works for a particular matrix type 4500 4501 Input Parameters: 4502 + package - name of the package, for example petsc or superlu 4503 . mtype - the matrix type that works with this package 4504 . ftype - the type of factorization supported by the package 4505 - createfactor - routine that will create the factored matrix ready to be used 4506 4507 Level: intermediate 4508 4509 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()` 4510 @*/ 4511 PetscErrorCode MatSolverTypeRegister(MatSolverType package,MatType mtype,MatFactorType ftype,PetscErrorCode (*createfactor)(Mat,MatFactorType,Mat*)) 4512 { 4513 MatSolverTypeHolder next = MatSolverTypeHolders,prev = NULL; 4514 PetscBool flg; 4515 MatSolverTypeForSpecifcType inext,iprev = NULL; 4516 4517 PetscFunctionBegin; 4518 PetscCall(MatInitializePackage()); 4519 if (!next) { 4520 PetscCall(PetscNew(&MatSolverTypeHolders)); 4521 PetscCall(PetscStrallocpy(package,&MatSolverTypeHolders->name)); 4522 PetscCall(PetscNew(&MatSolverTypeHolders->handlers)); 4523 PetscCall(PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype)); 4524 MatSolverTypeHolders->handlers->createfactor[(int)ftype-1] = createfactor; 4525 PetscFunctionReturn(0); 4526 } 4527 while (next) { 4528 PetscCall(PetscStrcasecmp(package,next->name,&flg)); 4529 if (flg) { 4530 PetscCheck(next->handlers,PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers"); 4531 inext = next->handlers; 4532 while (inext) { 4533 PetscCall(PetscStrcasecmp(mtype,inext->mtype,&flg)); 4534 if (flg) { 4535 inext->createfactor[(int)ftype-1] = createfactor; 4536 PetscFunctionReturn(0); 4537 } 4538 iprev = inext; 4539 inext = inext->next; 4540 } 4541 PetscCall(PetscNew(&iprev->next)); 4542 PetscCall(PetscStrallocpy(mtype,(char **)&iprev->next->mtype)); 4543 iprev->next->createfactor[(int)ftype-1] = createfactor; 4544 PetscFunctionReturn(0); 4545 } 4546 prev = next; 4547 next = next->next; 4548 } 4549 PetscCall(PetscNew(&prev->next)); 4550 PetscCall(PetscStrallocpy(package,&prev->next->name)); 4551 PetscCall(PetscNew(&prev->next->handlers)); 4552 PetscCall(PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype)); 4553 prev->next->handlers->createfactor[(int)ftype-1] = createfactor; 4554 PetscFunctionReturn(0); 4555 } 4556 4557 /*@C 4558 MatSolverTypeGet - Gets the function that creates the factor matrix if it exist 4559 4560 Input Parameters: 4561 + type - name of the package, for example petsc or superlu 4562 . ftype - the type of factorization supported by the type 4563 - mtype - the matrix type that works with this type 4564 4565 Output Parameters: 4566 + foundtype - PETSC_TRUE if the type was registered 4567 . foundmtype - PETSC_TRUE if the type supports the requested mtype 4568 - createfactor - routine that will create the factored matrix ready to be used or NULL if not found 4569 4570 Level: intermediate 4571 4572 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatSolverTypeRegister()`, `MatGetFactor()` 4573 @*/ 4574 PetscErrorCode MatSolverTypeGet(MatSolverType type,MatType mtype,MatFactorType ftype,PetscBool *foundtype,PetscBool *foundmtype,PetscErrorCode (**createfactor)(Mat,MatFactorType,Mat*)) 4575 { 4576 MatSolverTypeHolder next = MatSolverTypeHolders; 4577 PetscBool flg; 4578 MatSolverTypeForSpecifcType inext; 4579 4580 PetscFunctionBegin; 4581 if (foundtype) *foundtype = PETSC_FALSE; 4582 if (foundmtype) *foundmtype = PETSC_FALSE; 4583 if (createfactor) *createfactor = NULL; 4584 4585 if (type) { 4586 while (next) { 4587 PetscCall(PetscStrcasecmp(type,next->name,&flg)); 4588 if (flg) { 4589 if (foundtype) *foundtype = PETSC_TRUE; 4590 inext = next->handlers; 4591 while (inext) { 4592 PetscCall(PetscStrbeginswith(mtype,inext->mtype,&flg)); 4593 if (flg) { 4594 if (foundmtype) *foundmtype = PETSC_TRUE; 4595 if (createfactor) *createfactor = inext->createfactor[(int)ftype-1]; 4596 PetscFunctionReturn(0); 4597 } 4598 inext = inext->next; 4599 } 4600 } 4601 next = next->next; 4602 } 4603 } else { 4604 while (next) { 4605 inext = next->handlers; 4606 while (inext) { 4607 PetscCall(PetscStrcmp(mtype,inext->mtype,&flg)); 4608 if (flg && inext->createfactor[(int)ftype-1]) { 4609 if (foundtype) *foundtype = PETSC_TRUE; 4610 if (foundmtype) *foundmtype = PETSC_TRUE; 4611 if (createfactor) *createfactor = inext->createfactor[(int)ftype-1]; 4612 PetscFunctionReturn(0); 4613 } 4614 inext = inext->next; 4615 } 4616 next = next->next; 4617 } 4618 /* try with base classes inext->mtype */ 4619 next = MatSolverTypeHolders; 4620 while (next) { 4621 inext = next->handlers; 4622 while (inext) { 4623 PetscCall(PetscStrbeginswith(mtype,inext->mtype,&flg)); 4624 if (flg && inext->createfactor[(int)ftype-1]) { 4625 if (foundtype) *foundtype = PETSC_TRUE; 4626 if (foundmtype) *foundmtype = PETSC_TRUE; 4627 if (createfactor) *createfactor = inext->createfactor[(int)ftype-1]; 4628 PetscFunctionReturn(0); 4629 } 4630 inext = inext->next; 4631 } 4632 next = next->next; 4633 } 4634 } 4635 PetscFunctionReturn(0); 4636 } 4637 4638 PetscErrorCode MatSolverTypeDestroy(void) 4639 { 4640 MatSolverTypeHolder next = MatSolverTypeHolders,prev; 4641 MatSolverTypeForSpecifcType inext,iprev; 4642 4643 PetscFunctionBegin; 4644 while (next) { 4645 PetscCall(PetscFree(next->name)); 4646 inext = next->handlers; 4647 while (inext) { 4648 PetscCall(PetscFree(inext->mtype)); 4649 iprev = inext; 4650 inext = inext->next; 4651 PetscCall(PetscFree(iprev)); 4652 } 4653 prev = next; 4654 next = next->next; 4655 PetscCall(PetscFree(prev)); 4656 } 4657 MatSolverTypeHolders = NULL; 4658 PetscFunctionReturn(0); 4659 } 4660 4661 /*@C 4662 MatFactorGetCanUseOrdering - Indicates if the factorization can use the ordering provided in MatLUFactorSymbolic(), MatCholeskyFactorSymbolic() 4663 4664 Logically Collective on Mat 4665 4666 Input Parameters: 4667 . mat - the matrix 4668 4669 Output Parameters: 4670 . flg - PETSC_TRUE if uses the ordering 4671 4672 Notes: 4673 Most internal PETSc factorizations use the ordering passed to the factorization routine but external 4674 packages do not, thus we want to skip generating the ordering when it is not needed or used. 4675 4676 Level: developer 4677 4678 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()` 4679 @*/ 4680 PetscErrorCode MatFactorGetCanUseOrdering(Mat mat, PetscBool *flg) 4681 { 4682 PetscFunctionBegin; 4683 *flg = mat->canuseordering; 4684 PetscFunctionReturn(0); 4685 } 4686 4687 /*@C 4688 MatFactorGetPreferredOrdering - The preferred ordering for a particular matrix factor object 4689 4690 Logically Collective on Mat 4691 4692 Input Parameters: 4693 . mat - the matrix 4694 4695 Output Parameters: 4696 . otype - the preferred type 4697 4698 Level: developer 4699 4700 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()` 4701 @*/ 4702 PetscErrorCode MatFactorGetPreferredOrdering(Mat mat, MatFactorType ftype, MatOrderingType *otype) 4703 { 4704 PetscFunctionBegin; 4705 *otype = mat->preferredordering[ftype]; 4706 PetscCheck(*otype,PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatFactor did not have a preferred ordering"); 4707 PetscFunctionReturn(0); 4708 } 4709 4710 /*@C 4711 MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic() 4712 4713 Collective on Mat 4714 4715 Input Parameters: 4716 + mat - the matrix 4717 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4718 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4719 4720 Output Parameters: 4721 . f - the factor matrix used with MatXXFactorSymbolic() calls 4722 4723 Options Database Key: 4724 . -mat_factor_bind_factorization <host, device> - Where to do matrix factorization? Default is device (might consume more device memory. 4725 One can choose host to save device memory). Currently only supported with SEQAIJCUSPARSE matrices. 4726 4727 Notes: 4728 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4729 such as pastix, superlu, mumps etc. 4730 4731 PETSc must have been ./configure to use the external solver, using the option --download-package 4732 4733 Some of the packages have options for controlling the factorization, these are in the form -prefix_mat_packagename_packageoption 4734 where prefix is normally obtained from the calling `KSP`/`PC`. If `MatGetFactor()` is called directly one can set 4735 call `MatSetOptionsPrefixFactor()` on the originating matrix or `MatSetOptionsPrefix()` on the resulting factor matrix. 4736 4737 Developer Notes: 4738 This should actually be called MatCreateFactor() since it creates a new factor object 4739 4740 Level: intermediate 4741 4742 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatFactorGetCanUseOrdering()`, `MatSolverTypeRegister()` 4743 @*/ 4744 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f) 4745 { 4746 PetscBool foundtype,foundmtype; 4747 PetscErrorCode (*conv)(Mat,MatFactorType,Mat*); 4748 4749 PetscFunctionBegin; 4750 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4751 PetscValidType(mat,1); 4752 4753 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4754 MatCheckPreallocated(mat,1); 4755 4756 PetscCall(MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundtype,&foundmtype,&conv)); 4757 if (!foundtype) { 4758 if (type) { 4759 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver type %s for factorization type %s and matrix type %s. Perhaps you must ./configure with --download-%s",type,MatFactorTypes[ftype],((PetscObject)mat)->type_name,type); 4760 } else { 4761 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver type for factorization type %s and matrix type %s.",MatFactorTypes[ftype],((PetscObject)mat)->type_name); 4762 } 4763 } 4764 PetscCheck(foundmtype,PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name); 4765 PetscCheck(conv,PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support factorization type %s for matrix type %s",type,MatFactorTypes[ftype],((PetscObject)mat)->type_name); 4766 4767 PetscCall((*conv)(mat,ftype,f)); 4768 if (mat->factorprefix) PetscCall(MatSetOptionsPrefix(*f,mat->factorprefix)); 4769 PetscFunctionReturn(0); 4770 } 4771 4772 /*@C 4773 MatGetFactorAvailable - Returns a a flag if matrix supports particular type and factor type 4774 4775 Not Collective 4776 4777 Input Parameters: 4778 + mat - the matrix 4779 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4780 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4781 4782 Output Parameter: 4783 . flg - PETSC_TRUE if the factorization is available 4784 4785 Notes: 4786 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4787 such as pastix, superlu, mumps etc. 4788 4789 PETSc must have been ./configure to use the external solver, using the option --download-package 4790 4791 Developer Notes: 4792 This should actually be called MatCreateFactorAvailable() since MatGetFactor() creates a new factor object 4793 4794 Level: intermediate 4795 4796 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactor()`, `MatSolverTypeRegister()` 4797 @*/ 4798 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool *flg) 4799 { 4800 PetscErrorCode (*gconv)(Mat,MatFactorType,Mat*); 4801 4802 PetscFunctionBegin; 4803 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4804 PetscValidType(mat,1); 4805 PetscValidBoolPointer(flg,4); 4806 4807 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4808 MatCheckPreallocated(mat,1); 4809 4810 PetscCall(MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv)); 4811 *flg = gconv ? PETSC_TRUE : PETSC_FALSE; 4812 PetscFunctionReturn(0); 4813 } 4814 4815 /*@ 4816 MatDuplicate - Duplicates a matrix including the non-zero structure. 4817 4818 Collective on Mat 4819 4820 Input Parameters: 4821 + mat - the matrix 4822 - op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN. 4823 See the manual page for MatDuplicateOption for an explanation of these options. 4824 4825 Output Parameter: 4826 . M - pointer to place new matrix 4827 4828 Level: intermediate 4829 4830 Notes: 4831 You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN. 4832 May be called with an unassembled input Mat if MAT_DO_NOT_COPY_VALUES is used, in which case the output Mat is unassembled as well. 4833 When original mat is a product of matrix operation, e.g., an output of MatMatMult() or MatCreateSubMatrix(), only the simple matrix data structure of mat is duplicated and the internal data structures created for the reuse of previous matrix operations are not duplicated. User should not use MatDuplicate() to create new matrix M if M is intended to be reused as the product of matrix operation. 4834 4835 .seealso: `MatCopy()`, `MatConvert()`, `MatDuplicateOption` 4836 @*/ 4837 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M) 4838 { 4839 Mat B; 4840 VecType vtype; 4841 PetscInt i; 4842 PetscObject dm; 4843 void (*viewf)(void); 4844 4845 PetscFunctionBegin; 4846 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4847 PetscValidType(mat,1); 4848 PetscValidPointer(M,3); 4849 PetscCheck(op != MAT_COPY_VALUES || mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix"); 4850 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4851 MatCheckPreallocated(mat,1); 4852 4853 *M = NULL; 4854 PetscCheck(mat->ops->duplicate,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for matrix type %s",((PetscObject)mat)->type_name); 4855 PetscCall(PetscLogEventBegin(MAT_Convert,mat,0,0,0)); 4856 PetscCall((*mat->ops->duplicate)(mat,op,M)); 4857 PetscCall(PetscLogEventEnd(MAT_Convert,mat,0,0,0)); 4858 B = *M; 4859 4860 PetscCall(MatGetOperation(mat,MATOP_VIEW,&viewf)); 4861 if (viewf) PetscCall(MatSetOperation(B,MATOP_VIEW,viewf)); 4862 PetscCall(MatGetVecType(mat,&vtype)); 4863 PetscCall(MatSetVecType(B,vtype)); 4864 4865 B->stencil.dim = mat->stencil.dim; 4866 B->stencil.noc = mat->stencil.noc; 4867 for (i=0; i<=mat->stencil.dim; i++) { 4868 B->stencil.dims[i] = mat->stencil.dims[i]; 4869 B->stencil.starts[i] = mat->stencil.starts[i]; 4870 } 4871 4872 B->nooffproczerorows = mat->nooffproczerorows; 4873 B->nooffprocentries = mat->nooffprocentries; 4874 4875 PetscCall(PetscObjectQuery((PetscObject) mat, "__PETSc_dm", &dm)); 4876 if (dm) { 4877 PetscCall(PetscObjectCompose((PetscObject) B, "__PETSc_dm", dm)); 4878 } 4879 PetscCall(PetscObjectStateIncrease((PetscObject)B)); 4880 PetscFunctionReturn(0); 4881 } 4882 4883 /*@ 4884 MatGetDiagonal - Gets the diagonal of a matrix. 4885 4886 Logically Collective on Mat 4887 4888 Input Parameters: 4889 + mat - the matrix 4890 - v - the vector for storing the diagonal 4891 4892 Output Parameter: 4893 . v - the diagonal of the matrix 4894 4895 Level: intermediate 4896 4897 Note: 4898 Currently only correct in parallel for square matrices. 4899 4900 .seealso: `MatGetRow()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMaxAbs()` 4901 @*/ 4902 PetscErrorCode MatGetDiagonal(Mat mat,Vec v) 4903 { 4904 PetscFunctionBegin; 4905 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4906 PetscValidType(mat,1); 4907 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4908 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4909 PetscCheck(mat->ops->getdiagonal,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4910 MatCheckPreallocated(mat,1); 4911 4912 PetscCall((*mat->ops->getdiagonal)(mat,v)); 4913 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 4914 PetscFunctionReturn(0); 4915 } 4916 4917 /*@C 4918 MatGetRowMin - Gets the minimum value (of the real part) of each 4919 row of the matrix 4920 4921 Logically Collective on Mat 4922 4923 Input Parameter: 4924 . mat - the matrix 4925 4926 Output Parameters: 4927 + v - the vector for storing the maximums 4928 - idx - the indices of the column found for each row (optional) 4929 4930 Level: intermediate 4931 4932 Notes: 4933 The result of this call are the same as if one converted the matrix to dense format 4934 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4935 4936 This code is only implemented for a couple of matrix formats. 4937 4938 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMaxAbs()`, 4939 `MatGetRowMax()` 4940 @*/ 4941 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[]) 4942 { 4943 PetscFunctionBegin; 4944 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4945 PetscValidType(mat,1); 4946 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4947 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4948 4949 if (!mat->cmap->N) { 4950 PetscCall(VecSet(v,PETSC_MAX_REAL)); 4951 if (idx) { 4952 PetscInt i,m = mat->rmap->n; 4953 for (i=0; i<m; i++) idx[i] = -1; 4954 } 4955 } else { 4956 PetscCheck(mat->ops->getrowmin,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4957 MatCheckPreallocated(mat,1); 4958 } 4959 PetscCall((*mat->ops->getrowmin)(mat,v,idx)); 4960 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 4961 PetscFunctionReturn(0); 4962 } 4963 4964 /*@C 4965 MatGetRowMinAbs - Gets the minimum value (in absolute value) of each 4966 row of the matrix 4967 4968 Logically Collective on Mat 4969 4970 Input Parameter: 4971 . mat - the matrix 4972 4973 Output Parameters: 4974 + v - the vector for storing the minimums 4975 - idx - the indices of the column found for each row (or NULL if not needed) 4976 4977 Level: intermediate 4978 4979 Notes: 4980 if a row is completely empty or has only 0.0 values then the idx[] value for that 4981 row is 0 (the first column). 4982 4983 This code is only implemented for a couple of matrix formats. 4984 4985 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMax()`, `MatGetRowMaxAbs()`, `MatGetRowMin()` 4986 @*/ 4987 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[]) 4988 { 4989 PetscFunctionBegin; 4990 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4991 PetscValidType(mat,1); 4992 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4993 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4994 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4995 4996 if (!mat->cmap->N) { 4997 PetscCall(VecSet(v,0.0)); 4998 if (idx) { 4999 PetscInt i,m = mat->rmap->n; 5000 for (i=0; i<m; i++) idx[i] = -1; 5001 } 5002 } else { 5003 PetscCheck(mat->ops->getrowminabs,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5004 MatCheckPreallocated(mat,1); 5005 if (idx) PetscCall(PetscArrayzero(idx,mat->rmap->n)); 5006 PetscCall((*mat->ops->getrowminabs)(mat,v,idx)); 5007 } 5008 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 5009 PetscFunctionReturn(0); 5010 } 5011 5012 /*@C 5013 MatGetRowMax - Gets the maximum value (of the real part) of each 5014 row of the matrix 5015 5016 Logically Collective on Mat 5017 5018 Input Parameter: 5019 . mat - the matrix 5020 5021 Output Parameters: 5022 + v - the vector for storing the maximums 5023 - idx - the indices of the column found for each row (optional) 5024 5025 Level: intermediate 5026 5027 Notes: 5028 The result of this call are the same as if one converted the matrix to dense format 5029 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 5030 5031 This code is only implemented for a couple of matrix formats. 5032 5033 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMaxAbs()`, `MatGetRowMin()` 5034 @*/ 5035 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[]) 5036 { 5037 PetscFunctionBegin; 5038 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5039 PetscValidType(mat,1); 5040 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 5041 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5042 5043 if (!mat->cmap->N) { 5044 PetscCall(VecSet(v,PETSC_MIN_REAL)); 5045 if (idx) { 5046 PetscInt i,m = mat->rmap->n; 5047 for (i=0; i<m; i++) idx[i] = -1; 5048 } 5049 } else { 5050 PetscCheck(mat->ops->getrowmax,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5051 MatCheckPreallocated(mat,1); 5052 PetscCall((*mat->ops->getrowmax)(mat,v,idx)); 5053 } 5054 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 5055 PetscFunctionReturn(0); 5056 } 5057 5058 /*@C 5059 MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each 5060 row of the matrix 5061 5062 Logically Collective on Mat 5063 5064 Input Parameter: 5065 . mat - the matrix 5066 5067 Output Parameters: 5068 + v - the vector for storing the maximums 5069 - idx - the indices of the column found for each row (or NULL if not needed) 5070 5071 Level: intermediate 5072 5073 Notes: 5074 if a row is completely empty or has only 0.0 values then the idx[] value for that 5075 row is 0 (the first column). 5076 5077 This code is only implemented for a couple of matrix formats. 5078 5079 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMax()`, `MatGetRowMin()` 5080 @*/ 5081 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[]) 5082 { 5083 PetscFunctionBegin; 5084 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5085 PetscValidType(mat,1); 5086 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 5087 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5088 5089 if (!mat->cmap->N) { 5090 PetscCall(VecSet(v,0.0)); 5091 if (idx) { 5092 PetscInt i,m = mat->rmap->n; 5093 for (i=0; i<m; i++) idx[i] = -1; 5094 } 5095 } else { 5096 PetscCheck(mat->ops->getrowmaxabs,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5097 MatCheckPreallocated(mat,1); 5098 if (idx) PetscCall(PetscArrayzero(idx,mat->rmap->n)); 5099 PetscCall((*mat->ops->getrowmaxabs)(mat,v,idx)); 5100 } 5101 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 5102 PetscFunctionReturn(0); 5103 } 5104 5105 /*@ 5106 MatGetRowSum - Gets the sum of each row of the matrix 5107 5108 Logically or Neighborhood Collective on Mat 5109 5110 Input Parameters: 5111 . mat - the matrix 5112 5113 Output Parameter: 5114 . v - the vector for storing the sum of rows 5115 5116 Level: intermediate 5117 5118 Notes: 5119 This code is slow since it is not currently specialized for different formats 5120 5121 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMax()`, `MatGetRowMin()` 5122 @*/ 5123 PetscErrorCode MatGetRowSum(Mat mat, Vec v) 5124 { 5125 Vec ones; 5126 5127 PetscFunctionBegin; 5128 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5129 PetscValidType(mat,1); 5130 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 5131 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5132 MatCheckPreallocated(mat,1); 5133 PetscCall(MatCreateVecs(mat,&ones,NULL)); 5134 PetscCall(VecSet(ones,1.)); 5135 PetscCall(MatMult(mat,ones,v)); 5136 PetscCall(VecDestroy(&ones)); 5137 PetscFunctionReturn(0); 5138 } 5139 5140 /*@ 5141 MatTransposeSetPrecursor - Set the matrix from which the second matrix will receive numerical transpose data with a call to `MatTranspose`(A,`MAT_REUSE_MATRIX`,&B) 5142 when B was not obtained with `MatTranspose`(A,`MAT_INITIAL_MATRIX`,&B) 5143 5144 Collective on Mat 5145 5146 Input Parameter: 5147 . mat - the matrix to provide the transpose 5148 5149 Output Parameter: 5150 . mat - the matrix to contain the transpose; it MUST have the nonzero structure of the transpose of A or the code will crash or generate incorrect results 5151 5152 Level: advanced 5153 5154 Note: 5155 Normally he use of `MatTranspose`(A,`MAT_REUSE_MATRIX`,&B) requires that B was obtained with a call to `MatTranspose`(A,`MAT_INITIAL_MATRIX`,&B). This 5156 routine allows bypassing that call. 5157 5158 .seealso: `MatTransposeSymbolic()`, `MatTranspose()`, `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse`, `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, `MAT_INPLACE_MATRIX` 5159 @*/ 5160 PetscErrorCode MatTransposeSetPrecursor(Mat mat,Mat B) 5161 { 5162 PetscContainer rB = NULL; 5163 MatParentState *rb = NULL; 5164 5165 PetscFunctionBegin; 5166 PetscCall(PetscNew(&rb)); 5167 rb->id = ((PetscObject)mat)->id; 5168 rb->state = 0; 5169 PetscCall(MatGetNonzeroState(mat,&rb->nonzerostate)); 5170 PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)B),&rB)); 5171 PetscCall(PetscContainerSetPointer(rB,rb)); 5172 PetscCall(PetscContainerSetUserDestroy(rB,PetscContainerUserDestroyDefault)); 5173 PetscCall(PetscObjectCompose((PetscObject)B,"MatTransposeParent",(PetscObject)rB)); 5174 PetscCall(PetscObjectDereference((PetscObject)rB)); 5175 PetscFunctionReturn(0); 5176 } 5177 5178 /*@ 5179 MatTranspose - Computes an in-place or out-of-place transpose of a matrix. 5180 5181 Collective on Mat 5182 5183 Input Parameters: 5184 + mat - the matrix to transpose 5185 - reuse - either `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, or `MAT_INPLACE_MATRIX` 5186 5187 Output Parameter: 5188 . B - the transpose 5189 5190 Notes: 5191 If you use `MAT_INPLACE_MATRIX` then you must pass in &mat for B 5192 5193 `MAT_REUSE_MATRIX` uses the B matrix obtained from a previous call to this function with `MAT_INITIAL_MATRIX`. If you already have a matrix to contain the 5194 transpose, call `MatTransposeSetPrecursor`(mat,B) before calling this routine. 5195 5196 If the nonzero structure of mat changed from the previous call to this function with the same matrices an error will be generated for some matrix types. 5197 5198 Consider using `MatCreateTranspose()` instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed. 5199 5200 If mat is unchanged from the last call this function returns immediately without recomputing the result 5201 5202 If you only need the symbolic transpose, and not the numerical values, use `MatTransposeSymbolic()` 5203 5204 Level: intermediate 5205 5206 .seealso: `MatTransposeSetPrecursor()`, `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse`, `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, `MAT_INPLACE_MATRIX`, 5207 `MatTransposeSymbolic()` 5208 @*/ 5209 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B) 5210 { 5211 PetscContainer rB = NULL; 5212 MatParentState *rb = NULL; 5213 5214 PetscFunctionBegin; 5215 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5216 PetscValidType(mat,1); 5217 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5218 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5219 PetscCheck(mat->ops->transpose,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5220 PetscCheck(reuse != MAT_INPLACE_MATRIX || mat == *B,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first"); 5221 PetscCheck(reuse != MAT_REUSE_MATRIX || mat != *B,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX"); 5222 MatCheckPreallocated(mat,1); 5223 if (reuse == MAT_REUSE_MATRIX) { 5224 PetscCall(PetscObjectQuery((PetscObject)*B,"MatTransposeParent",(PetscObject*)&rB)); 5225 PetscCheck(rB,PetscObjectComm((PetscObject)*B),PETSC_ERR_ARG_WRONG,"Reuse matrix used was not generated from call to MatTranspose(). Suggest MatTransposeSetPrecursor()."); 5226 PetscCall(PetscContainerGetPointer(rB,(void**)&rb)); 5227 PetscCheck(rb->id == ((PetscObject)mat)->id,PetscObjectComm((PetscObject)*B),PETSC_ERR_ARG_WRONG,"Reuse matrix used was not generated from input matrix"); 5228 if (rb->state == ((PetscObject)mat)->state) PetscFunctionReturn(0); 5229 } 5230 5231 PetscCall(PetscLogEventBegin(MAT_Transpose,mat,0,0,0)); 5232 PetscCall((*mat->ops->transpose)(mat,reuse,B)); 5233 PetscCall(PetscLogEventEnd(MAT_Transpose,mat,0,0,0)); 5234 PetscCall(PetscObjectStateIncrease((PetscObject)*B)); 5235 5236 if (reuse == MAT_INITIAL_MATRIX) PetscCall(MatTransposeSetPrecursor(mat,*B)); 5237 if (reuse != MAT_INPLACE_MATRIX) { 5238 PetscCall(PetscObjectQuery((PetscObject)*B,"MatTransposeParent",(PetscObject*)&rB)); 5239 PetscCall(PetscContainerGetPointer(rB,(void**)&rb)); 5240 rb->state = ((PetscObject)mat)->state; 5241 rb->nonzerostate = mat->nonzerostate; 5242 } 5243 PetscFunctionReturn(0); 5244 } 5245 5246 /*@ 5247 MatTransposeSymbolic - Computes the symbolic part of the transpose of a matrix. 5248 5249 Collective on Mat 5250 5251 Input Parameters: 5252 . A - the matrix to transpose 5253 5254 Output Parameter: 5255 . B - the transpose. This is a complete matrix but the numerical portion is invalid. One can call `MatTranspose`(A,MAT_REUSE_MATRIX,&B) to compute the 5256 numerical portion. 5257 5258 Level: intermediate 5259 5260 Note: 5261 This is not supported for many matrix types, use `MatTranspose()` in those cases 5262 5263 .seealso: `MatTransposeSetPrecursor()`, `MatTranspose()`, `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse`, `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, `MAT_INPLACE_MATRIX` 5264 @*/ 5265 PetscErrorCode MatTransposeSymbolic(Mat A,Mat *B) 5266 { 5267 PetscFunctionBegin; 5268 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5269 PetscValidType(A,1); 5270 PetscCheck(A->assembled,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5271 PetscCheck(!A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5272 PetscCheck(A->ops->transposesymbolic,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 5273 PetscCall(PetscLogEventBegin(MAT_Transpose,A,0,0,0)); 5274 PetscCall((*A->ops->transposesymbolic)(A,B)); 5275 PetscCall(PetscLogEventEnd(MAT_Transpose,A,0,0,0)); 5276 5277 PetscCall(MatTransposeSetPrecursor(A,*B)); 5278 PetscFunctionReturn(0); 5279 } 5280 5281 PetscErrorCode MatTransposeCheckNonzeroState_Private(Mat A,Mat B) 5282 { 5283 PetscContainer rB; 5284 MatParentState *rb; 5285 5286 PetscFunctionBegin; 5287 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5288 PetscValidType(A,1); 5289 PetscCheck(A->assembled,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5290 PetscCheck(!A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5291 PetscCall(PetscObjectQuery((PetscObject)B,"MatTransposeParent",(PetscObject*)&rB)); 5292 PetscCheck(rB,PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONG,"Reuse matrix used was not generated from call to MatTranspose()"); 5293 PetscCall(PetscContainerGetPointer(rB,(void**)&rb)); 5294 PetscCheck(rb->id == ((PetscObject)A)->id,PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONG,"Reuse matrix used was not generated from input matrix"); 5295 PetscCheck(rb->nonzerostate == A->nonzerostate,PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Reuse matrix has changed nonzero structure"); 5296 PetscFunctionReturn(0); 5297 } 5298 5299 /*@ 5300 MatIsTranspose - Test whether a matrix is another one's transpose, 5301 or its own, in which case it tests symmetry. 5302 5303 Collective on Mat 5304 5305 Input Parameters: 5306 + A - the matrix to test 5307 - B - the matrix to test against, this can equal the first parameter 5308 5309 Output Parameters: 5310 . flg - the result 5311 5312 Notes: 5313 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 5314 has a running time of the order of the number of nonzeros; the parallel 5315 test involves parallel copies of the block-offdiagonal parts of the matrix. 5316 5317 Level: intermediate 5318 5319 .seealso: `MatTranspose()`, `MatIsSymmetric()`, `MatIsHermitian()` 5320 @*/ 5321 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 5322 { 5323 PetscErrorCode (*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 5324 5325 PetscFunctionBegin; 5326 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5327 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5328 PetscValidBoolPointer(flg,4); 5329 PetscCall(PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f)); 5330 PetscCall(PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g)); 5331 *flg = PETSC_FALSE; 5332 if (f && g) { 5333 PetscCheck(f == g,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test"); 5334 PetscCall((*f)(A,B,tol,flg)); 5335 } else { 5336 MatType mattype; 5337 5338 PetscCall(MatGetType(f ? B : A,&mattype)); 5339 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for transpose",mattype); 5340 } 5341 PetscFunctionReturn(0); 5342 } 5343 5344 /*@ 5345 MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate. 5346 5347 Collective on Mat 5348 5349 Input Parameters: 5350 + mat - the matrix to transpose and complex conjugate 5351 - reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX 5352 5353 Output Parameter: 5354 . B - the Hermitian 5355 5356 Level: intermediate 5357 5358 .seealso: `MatTranspose()`, `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse` 5359 @*/ 5360 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B) 5361 { 5362 PetscFunctionBegin; 5363 PetscCall(MatTranspose(mat,reuse,B)); 5364 #if defined(PETSC_USE_COMPLEX) 5365 PetscCall(MatConjugate(*B)); 5366 #endif 5367 PetscFunctionReturn(0); 5368 } 5369 5370 /*@ 5371 MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose, 5372 5373 Collective on Mat 5374 5375 Input Parameters: 5376 + A - the matrix to test 5377 - B - the matrix to test against, this can equal the first parameter 5378 5379 Output Parameters: 5380 . flg - the result 5381 5382 Notes: 5383 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 5384 has a running time of the order of the number of nonzeros; the parallel 5385 test involves parallel copies of the block-offdiagonal parts of the matrix. 5386 5387 Level: intermediate 5388 5389 .seealso: `MatTranspose()`, `MatIsSymmetric()`, `MatIsHermitian()`, `MatIsTranspose()` 5390 @*/ 5391 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 5392 { 5393 PetscErrorCode (*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 5394 5395 PetscFunctionBegin; 5396 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5397 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5398 PetscValidBoolPointer(flg,4); 5399 PetscCall(PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f)); 5400 PetscCall(PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g)); 5401 if (f && g) { 5402 PetscCheck(f != g,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test"); 5403 PetscCall((*f)(A,B,tol,flg)); 5404 } 5405 PetscFunctionReturn(0); 5406 } 5407 5408 /*@ 5409 MatPermute - Creates a new matrix with rows and columns permuted from the 5410 original. 5411 5412 Collective on Mat 5413 5414 Input Parameters: 5415 + mat - the matrix to permute 5416 . row - row permutation, each processor supplies only the permutation for its rows 5417 - col - column permutation, each processor supplies only the permutation for its columns 5418 5419 Output Parameters: 5420 . B - the permuted matrix 5421 5422 Level: advanced 5423 5424 Note: 5425 The index sets map from row/col of permuted matrix to row/col of original matrix. 5426 The index sets should be on the same communicator as Mat and have the same local sizes. 5427 5428 Developer Note: 5429 If you want to implement MatPermute for a matrix type, and your approach doesn't 5430 exploit the fact that row and col are permutations, consider implementing the 5431 more general MatCreateSubMatrix() instead. 5432 5433 .seealso: `MatGetOrdering()`, `ISAllGather()` 5434 5435 @*/ 5436 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B) 5437 { 5438 PetscFunctionBegin; 5439 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5440 PetscValidType(mat,1); 5441 PetscValidHeaderSpecific(row,IS_CLASSID,2); 5442 PetscValidHeaderSpecific(col,IS_CLASSID,3); 5443 PetscValidPointer(B,4); 5444 PetscCheckSameComm(mat,1,row,2); 5445 if (row != col) PetscCheckSameComm(row,2,col,3); 5446 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5447 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5448 PetscCheck(mat->ops->permute || mat->ops->createsubmatrix,PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name); 5449 MatCheckPreallocated(mat,1); 5450 5451 if (mat->ops->permute) { 5452 PetscCall((*mat->ops->permute)(mat,row,col,B)); 5453 PetscCall(PetscObjectStateIncrease((PetscObject)*B)); 5454 } else { 5455 PetscCall(MatCreateSubMatrix(mat, row, col, MAT_INITIAL_MATRIX, B)); 5456 } 5457 PetscFunctionReturn(0); 5458 } 5459 5460 /*@ 5461 MatEqual - Compares two matrices. 5462 5463 Collective on Mat 5464 5465 Input Parameters: 5466 + A - the first matrix 5467 - B - the second matrix 5468 5469 Output Parameter: 5470 . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise. 5471 5472 Level: intermediate 5473 5474 @*/ 5475 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool *flg) 5476 { 5477 PetscFunctionBegin; 5478 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5479 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5480 PetscValidType(A,1); 5481 PetscValidType(B,2); 5482 PetscValidBoolPointer(flg,3); 5483 PetscCheckSameComm(A,1,B,2); 5484 MatCheckPreallocated(A,1); 5485 MatCheckPreallocated(B,2); 5486 PetscCheck(A->assembled,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5487 PetscCheck(B->assembled,PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5488 PetscCheck(A->rmap->N == B->rmap->N && A->cmap->N == B->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT,A->rmap->N,B->rmap->N,A->cmap->N,B->cmap->N); 5489 if (A->ops->equal && A->ops->equal == B->ops->equal) { 5490 PetscCall((*A->ops->equal)(A,B,flg)); 5491 } else { 5492 PetscCall(MatMultEqual(A,B,10,flg)); 5493 } 5494 PetscFunctionReturn(0); 5495 } 5496 5497 /*@ 5498 MatDiagonalScale - Scales a matrix on the left and right by diagonal 5499 matrices that are stored as vectors. Either of the two scaling 5500 matrices can be NULL. 5501 5502 Collective on Mat 5503 5504 Input Parameters: 5505 + mat - the matrix to be scaled 5506 . l - the left scaling vector (or NULL) 5507 - r - the right scaling vector (or NULL) 5508 5509 Notes: 5510 MatDiagonalScale() computes A = LAR, where 5511 L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector) 5512 The L scales the rows of the matrix, the R scales the columns of the matrix. 5513 5514 Level: intermediate 5515 5516 .seealso: `MatScale()`, `MatShift()`, `MatDiagonalSet()` 5517 @*/ 5518 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r) 5519 { 5520 PetscFunctionBegin; 5521 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5522 PetscValidType(mat,1); 5523 if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);} 5524 if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);} 5525 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5526 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5527 MatCheckPreallocated(mat,1); 5528 if (!l && !r) PetscFunctionReturn(0); 5529 5530 PetscCheck(mat->ops->diagonalscale,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5531 PetscCall(PetscLogEventBegin(MAT_Scale,mat,0,0,0)); 5532 PetscCall((*mat->ops->diagonalscale)(mat,l,r)); 5533 PetscCall(PetscLogEventEnd(MAT_Scale,mat,0,0,0)); 5534 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5535 if (l != r) mat->symmetric = PETSC_BOOL3_FALSE; 5536 PetscFunctionReturn(0); 5537 } 5538 5539 /*@ 5540 MatScale - Scales all elements of a matrix by a given number. 5541 5542 Logically Collective on Mat 5543 5544 Input Parameters: 5545 + mat - the matrix to be scaled 5546 - a - the scaling value 5547 5548 Output Parameter: 5549 . mat - the scaled matrix 5550 5551 Level: intermediate 5552 5553 .seealso: `MatDiagonalScale()` 5554 @*/ 5555 PetscErrorCode MatScale(Mat mat,PetscScalar a) 5556 { 5557 PetscFunctionBegin; 5558 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5559 PetscValidType(mat,1); 5560 PetscCheck(a == (PetscScalar)1.0 || mat->ops->scale,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5561 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5562 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5563 PetscValidLogicalCollectiveScalar(mat,a,2); 5564 MatCheckPreallocated(mat,1); 5565 5566 PetscCall(PetscLogEventBegin(MAT_Scale,mat,0,0,0)); 5567 if (a != (PetscScalar)1.0) { 5568 PetscCall((*mat->ops->scale)(mat,a)); 5569 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5570 } 5571 PetscCall(PetscLogEventEnd(MAT_Scale,mat,0,0,0)); 5572 PetscFunctionReturn(0); 5573 } 5574 5575 /*@ 5576 MatNorm - Calculates various norms of a matrix. 5577 5578 Collective on Mat 5579 5580 Input Parameters: 5581 + mat - the matrix 5582 - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY 5583 5584 Output Parameter: 5585 . nrm - the resulting norm 5586 5587 Level: intermediate 5588 5589 @*/ 5590 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm) 5591 { 5592 PetscFunctionBegin; 5593 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5594 PetscValidType(mat,1); 5595 PetscValidRealPointer(nrm,3); 5596 5597 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5598 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5599 PetscCheck(mat->ops->norm,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5600 MatCheckPreallocated(mat,1); 5601 5602 PetscCall((*mat->ops->norm)(mat,type,nrm)); 5603 PetscFunctionReturn(0); 5604 } 5605 5606 /* 5607 This variable is used to prevent counting of MatAssemblyBegin() that 5608 are called from within a MatAssemblyEnd(). 5609 */ 5610 static PetscInt MatAssemblyEnd_InUse = 0; 5611 /*@ 5612 MatAssemblyBegin - Begins assembling the matrix. This routine should 5613 be called after completing all calls to MatSetValues(). 5614 5615 Collective on Mat 5616 5617 Input Parameters: 5618 + mat - the matrix 5619 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5620 5621 Notes: 5622 MatSetValues() generally caches the values. The matrix is ready to 5623 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5624 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5625 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5626 using the matrix. 5627 5628 ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the 5629 same flag of MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY for all processes. Thus you CANNOT locally change from ADD_VALUES to INSERT_VALUES, that is 5630 a global collective operation requring all processes that share the matrix. 5631 5632 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5633 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5634 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5635 5636 Level: beginner 5637 5638 .seealso: `MatAssemblyEnd()`, `MatSetValues()`, `MatAssembled()` 5639 @*/ 5640 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type) 5641 { 5642 PetscFunctionBegin; 5643 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5644 PetscValidType(mat,1); 5645 MatCheckPreallocated(mat,1); 5646 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?"); 5647 if (mat->assembled) { 5648 mat->was_assembled = PETSC_TRUE; 5649 mat->assembled = PETSC_FALSE; 5650 } 5651 5652 if (!MatAssemblyEnd_InUse) { 5653 PetscCall(PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0)); 5654 if (mat->ops->assemblybegin) PetscCall((*mat->ops->assemblybegin)(mat,type)); 5655 PetscCall(PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0)); 5656 } else if (mat->ops->assemblybegin) PetscCall((*mat->ops->assemblybegin)(mat,type)); 5657 PetscFunctionReturn(0); 5658 } 5659 5660 /*@ 5661 MatAssembled - Indicates if a matrix has been assembled and is ready for 5662 use; for example, in matrix-vector product. 5663 5664 Not Collective 5665 5666 Input Parameter: 5667 . mat - the matrix 5668 5669 Output Parameter: 5670 . assembled - PETSC_TRUE or PETSC_FALSE 5671 5672 Level: advanced 5673 5674 .seealso: `MatAssemblyEnd()`, `MatSetValues()`, `MatAssemblyBegin()` 5675 @*/ 5676 PetscErrorCode MatAssembled(Mat mat,PetscBool *assembled) 5677 { 5678 PetscFunctionBegin; 5679 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5680 PetscValidBoolPointer(assembled,2); 5681 *assembled = mat->assembled; 5682 PetscFunctionReturn(0); 5683 } 5684 5685 /*@ 5686 MatAssemblyEnd - Completes assembling the matrix. This routine should 5687 be called after MatAssemblyBegin(). 5688 5689 Collective on Mat 5690 5691 Input Parameters: 5692 + mat - the matrix 5693 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5694 5695 Options Database Keys: 5696 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly() 5697 . -mat_view ::ascii_info_detail - Prints more detailed info 5698 . -mat_view - Prints matrix in ASCII format 5699 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 5700 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 5701 . -display <name> - Sets display name (default is host) 5702 . -draw_pause <sec> - Sets number of seconds to pause after display 5703 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab) 5704 . -viewer_socket_machine <machine> - Machine to use for socket 5705 . -viewer_socket_port <port> - Port number to use for socket 5706 - -mat_view binary:filename[:append] - Save matrix to file in binary format 5707 5708 Notes: 5709 MatSetValues() generally caches the values. The matrix is ready to 5710 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5711 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5712 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5713 using the matrix. 5714 5715 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5716 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5717 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5718 5719 Level: beginner 5720 5721 .seealso: `MatAssemblyBegin()`, `MatSetValues()`, `PetscDrawOpenX()`, `PetscDrawCreate()`, `MatView()`, `MatAssembled()`, `PetscViewerSocketOpen()` 5722 @*/ 5723 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type) 5724 { 5725 static PetscInt inassm = 0; 5726 PetscBool flg = PETSC_FALSE; 5727 5728 PetscFunctionBegin; 5729 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5730 PetscValidType(mat,1); 5731 5732 inassm++; 5733 MatAssemblyEnd_InUse++; 5734 if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */ 5735 PetscCall(PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0)); 5736 if (mat->ops->assemblyend) PetscCall((*mat->ops->assemblyend)(mat,type)); 5737 PetscCall(PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0)); 5738 } else if (mat->ops->assemblyend) PetscCall((*mat->ops->assemblyend)(mat,type)); 5739 5740 /* Flush assembly is not a true assembly */ 5741 if (type != MAT_FLUSH_ASSEMBLY) { 5742 if (mat->num_ass) { 5743 if (!mat->symmetry_eternal) { 5744 mat->symmetric = PETSC_BOOL3_UNKNOWN; 5745 mat->hermitian = PETSC_BOOL3_UNKNOWN; 5746 } 5747 if (!mat->structural_symmetry_eternal && mat->ass_nonzerostate != mat->nonzerostate) { 5748 mat->structurally_symmetric = PETSC_BOOL3_UNKNOWN; 5749 } 5750 if (!mat->spd_eternal) mat->spd = PETSC_BOOL3_UNKNOWN; 5751 } 5752 mat->num_ass++; 5753 mat->assembled = PETSC_TRUE; 5754 mat->ass_nonzerostate = mat->nonzerostate; 5755 } 5756 5757 mat->insertmode = NOT_SET_VALUES; 5758 MatAssemblyEnd_InUse--; 5759 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5760 if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) { 5761 PetscCall(MatViewFromOptions(mat,NULL,"-mat_view")); 5762 5763 if (mat->checksymmetryonassembly) { 5764 PetscCall(MatIsSymmetric(mat,mat->checksymmetrytol,&flg)); 5765 if (flg) { 5766 PetscCall(PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol)); 5767 } else { 5768 PetscCall(PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol)); 5769 } 5770 } 5771 if (mat->nullsp && mat->checknullspaceonassembly) { 5772 PetscCall(MatNullSpaceTest(mat->nullsp,mat,NULL)); 5773 } 5774 } 5775 inassm--; 5776 PetscFunctionReturn(0); 5777 } 5778 5779 /*@ 5780 MatSetOption - Sets a parameter option for a matrix. Some options 5781 may be specific to certain storage formats. Some options 5782 determine how values will be inserted (or added). Sorted, 5783 row-oriented input will generally assemble the fastest. The default 5784 is row-oriented. 5785 5786 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5787 5788 Input Parameters: 5789 + mat - the matrix 5790 . option - the option, one of those listed below (and possibly others), 5791 - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5792 5793 Options Describing Matrix Structure: 5794 + MAT_SPD - symmetric positive definite 5795 . MAT_SYMMETRIC - symmetric in terms of both structure and value 5796 . MAT_HERMITIAN - transpose is the complex conjugation 5797 . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure 5798 . MAT_SYMMETRY_ETERNAL - indicates the symmetry (or Hermitian structure) or its absence will persist through any changes to the matrix 5799 . MAT_STRUCTURAL_SYMMETRY_ETERNAL - indicates the structural symmetry or its absence will persist through any changes to the matrix 5800 - MAT_SPD_ETERNAL - indicates the value of MAT_SPD (true or false) will persist through any changes to the matrix 5801 5802 These are not really options of the matrix, they are knowledge about the structure of the matrix that users may provide so that they 5803 do not need to be computed (usually at a high cost) 5804 5805 Options For Use with MatSetValues(): 5806 Insert a logically dense subblock, which can be 5807 . MAT_ROW_ORIENTED - row-oriented (default) 5808 5809 Note these options reflect the data you pass in with MatSetValues(); it has 5810 nothing to do with how the data is stored internally in the matrix 5811 data structure. 5812 5813 When (re)assembling a matrix, we can restrict the input for 5814 efficiency/debugging purposes. These options include 5815 + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow) 5816 . MAT_FORCE_DIAGONAL_ENTRIES - forces diagonal entries to be allocated 5817 . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries 5818 . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry 5819 . MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly 5820 . MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if 5821 any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves 5822 performance for very large process counts. 5823 - MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset 5824 of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly 5825 functions, instead sending only neighbor messages. 5826 5827 Notes: 5828 Except for MAT_UNUSED_NONZERO_LOCATION_ERR and MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg! 5829 5830 Some options are relevant only for particular matrix types and 5831 are thus ignored by others. Other options are not supported by 5832 certain matrix types and will generate an error message if set. 5833 5834 If using a Fortran 77 module to compute a matrix, one may need to 5835 use the column-oriented option (or convert to the row-oriented 5836 format). 5837 5838 MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion 5839 that would generate a new entry in the nonzero structure is instead 5840 ignored. Thus, if memory has not alredy been allocated for this particular 5841 data, then the insertion is ignored. For dense matrices, in which 5842 the entire array is allocated, no entries are ever ignored. 5843 Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5844 5845 MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5846 that would generate a new entry in the nonzero structure instead produces 5847 an error. (Currently supported for AIJ and BAIJ formats only.) If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5848 5849 MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5850 that would generate a new entry that has not been preallocated will 5851 instead produce an error. (Currently supported for AIJ and BAIJ formats 5852 only.) This is a useful flag when debugging matrix memory preallocation. 5853 If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5854 5855 MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for 5856 other processors should be dropped, rather than stashed. 5857 This is useful if you know that the "owning" processor is also 5858 always generating the correct matrix entries, so that PETSc need 5859 not transfer duplicate entries generated on another processor. 5860 5861 MAT_USE_HASH_TABLE indicates that a hash table be used to improve the 5862 searches during matrix assembly. When this flag is set, the hash table 5863 is created during the first Matrix Assembly. This hash table is 5864 used the next time through, during MatSetVaules()/MatSetVaulesBlocked() 5865 to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag 5866 should be used with MAT_USE_HASH_TABLE flag. This option is currently 5867 supported by MATMPIBAIJ format only. 5868 5869 MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries 5870 are kept in the nonzero structure 5871 5872 MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating 5873 a zero location in the matrix 5874 5875 MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types 5876 5877 MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the 5878 zero row routines and thus improves performance for very large process counts. 5879 5880 MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular 5881 part of the matrix (since they should match the upper triangular part). 5882 5883 MAT_SORTED_FULL - each process provides exactly its local rows; all column indices for a given row are passed in a 5884 single call to MatSetValues(), preallocation is perfect, row oriented, INSERT_VALUES is used. Common 5885 with finite difference schemes with non-periodic boundary conditions. 5886 5887 Developer Note: 5888 MAT_SYMMETRY_ETERNAL, MAT_STRUCTURAL_SYMMETRY_ETERNAL, and MAT_SPD_ETERNAL are used by MatAssemblyEnd() and in other 5889 places where otherwise the value of MAT_SYMMETRIC, MAT_STRUCTURAL_SYMMETRIC or MAT_SPD would need to be changed back 5890 to PETSC_BOOL3_UNKNOWN because the matrix values had changed so the code cannot be certain that the related property had 5891 not changed. 5892 5893 Level: intermediate 5894 5895 .seealso: `MatOption`, `Mat`, `MatGetOption()` 5896 5897 @*/ 5898 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg) 5899 { 5900 PetscFunctionBegin; 5901 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5902 if (op > 0) { 5903 PetscValidLogicalCollectiveEnum(mat,op,2); 5904 PetscValidLogicalCollectiveBool(mat,flg,3); 5905 } 5906 5907 PetscCheck(((int) op) > MAT_OPTION_MIN && ((int) op) < MAT_OPTION_MAX,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Options %d is out of range",(int)op); 5908 5909 switch (op) { 5910 case MAT_FORCE_DIAGONAL_ENTRIES: 5911 mat->force_diagonals = flg; 5912 PetscFunctionReturn(0); 5913 case MAT_NO_OFF_PROC_ENTRIES: 5914 mat->nooffprocentries = flg; 5915 PetscFunctionReturn(0); 5916 case MAT_SUBSET_OFF_PROC_ENTRIES: 5917 mat->assembly_subset = flg; 5918 if (!mat->assembly_subset) { /* See the same logic in VecAssembly wrt VEC_SUBSET_OFF_PROC_ENTRIES */ 5919 #if !defined(PETSC_HAVE_MPIUNI) 5920 PetscCall(MatStashScatterDestroy_BTS(&mat->stash)); 5921 #endif 5922 mat->stash.first_assembly_done = PETSC_FALSE; 5923 } 5924 PetscFunctionReturn(0); 5925 case MAT_NO_OFF_PROC_ZERO_ROWS: 5926 mat->nooffproczerorows = flg; 5927 PetscFunctionReturn(0); 5928 case MAT_SPD: 5929 if (flg) { 5930 mat->spd = PETSC_BOOL3_TRUE; 5931 mat->symmetric = PETSC_BOOL3_TRUE; 5932 mat->structurally_symmetric = PETSC_BOOL3_TRUE; 5933 } else { 5934 mat->spd = PETSC_BOOL3_FALSE; 5935 } 5936 break; 5937 case MAT_SYMMETRIC: 5938 mat->symmetric = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5939 if (flg) mat->structurally_symmetric = PETSC_BOOL3_TRUE; 5940 #if !defined(PETSC_USE_COMPLEX) 5941 mat->hermitian = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5942 #endif 5943 break; 5944 case MAT_HERMITIAN: 5945 mat->hermitian = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5946 if (flg) mat->structurally_symmetric = PETSC_BOOL3_TRUE; 5947 #if !defined(PETSC_USE_COMPLEX) 5948 mat->symmetric = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5949 #endif 5950 break; 5951 case MAT_STRUCTURALLY_SYMMETRIC: 5952 mat->structurally_symmetric = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5953 break; 5954 case MAT_SYMMETRY_ETERNAL: 5955 mat->symmetry_eternal = flg ? PETSC_TRUE : PETSC_FALSE; 5956 if (flg) mat->structural_symmetry_eternal = PETSC_TRUE; 5957 break; 5958 case MAT_STRUCTURAL_SYMMETRY_ETERNAL: 5959 mat->structural_symmetry_eternal = flg; 5960 break; 5961 case MAT_SPD_ETERNAL: 5962 mat->spd_eternal = flg; 5963 if (flg) { 5964 mat->structural_symmetry_eternal = PETSC_TRUE; 5965 mat->symmetry_eternal = PETSC_TRUE; 5966 } 5967 break; 5968 case MAT_STRUCTURE_ONLY: 5969 mat->structure_only = flg; 5970 break; 5971 case MAT_SORTED_FULL: 5972 mat->sortedfull = flg; 5973 break; 5974 default: 5975 break; 5976 } 5977 if (mat->ops->setoption) PetscCall((*mat->ops->setoption)(mat,op,flg)); 5978 PetscFunctionReturn(0); 5979 } 5980 5981 /*@ 5982 MatGetOption - Gets a parameter option that has been set for a matrix. 5983 5984 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5985 5986 Input Parameters: 5987 + mat - the matrix 5988 - option - the option, this only responds to certain options, check the code for which ones 5989 5990 Output Parameter: 5991 . flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5992 5993 Notes: 5994 Can only be called after MatSetSizes() and MatSetType() have been set. 5995 5996 Certain option values may be unknown, for those use the routines `MatIsSymmetric()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, or 5997 `MatIsSymmetricKnown()`, `MatIsHermitianKnown()`, `MatIsStructurallySymmetricKnown()` 5998 5999 Level: intermediate 6000 6001 .seealso: `MatOption`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, 6002 `MatIsSymmetricKnown()`, `MatIsHermitianKnown()`, `MatIsStructurallySymmetricKnown()` 6003 6004 @*/ 6005 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg) 6006 { 6007 PetscFunctionBegin; 6008 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6009 PetscValidType(mat,1); 6010 6011 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); 6012 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()"); 6013 6014 switch (op) { 6015 case MAT_NO_OFF_PROC_ENTRIES: 6016 *flg = mat->nooffprocentries; 6017 break; 6018 case MAT_NO_OFF_PROC_ZERO_ROWS: 6019 *flg = mat->nooffproczerorows; 6020 break; 6021 case MAT_SYMMETRIC: 6022 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Use MatIsSymmetric() or MatIsSymmetricKnown()"); 6023 break; 6024 case MAT_HERMITIAN: 6025 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Use MatIsHermitian() or MatIsHermitianKnown()"); 6026 break; 6027 case MAT_STRUCTURALLY_SYMMETRIC: 6028 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Use MatIsStructurallySymmetric() or MatIsStructurallySymmetricKnown()"); 6029 break; 6030 case MAT_SPD: 6031 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Use MatIsSPDKnown()"); 6032 break; 6033 case MAT_SYMMETRY_ETERNAL: 6034 *flg = mat->symmetry_eternal; 6035 break; 6036 case MAT_STRUCTURAL_SYMMETRY_ETERNAL: 6037 *flg = mat->symmetry_eternal; 6038 break; 6039 default: 6040 break; 6041 } 6042 PetscFunctionReturn(0); 6043 } 6044 6045 /*@ 6046 MatZeroEntries - Zeros all entries of a matrix. For sparse matrices 6047 this routine retains the old nonzero structure. 6048 6049 Logically Collective on Mat 6050 6051 Input Parameters: 6052 . mat - the matrix 6053 6054 Level: intermediate 6055 6056 Notes: 6057 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. 6058 See the Performance chapter of the users manual for information on preallocating matrices. 6059 6060 .seealso: `MatZeroRows()` 6061 @*/ 6062 PetscErrorCode MatZeroEntries(Mat mat) 6063 { 6064 PetscFunctionBegin; 6065 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6066 PetscValidType(mat,1); 6067 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6068 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"); 6069 PetscCheck(mat->ops->zeroentries,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6070 MatCheckPreallocated(mat,1); 6071 6072 PetscCall(PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0)); 6073 PetscCall((*mat->ops->zeroentries)(mat)); 6074 PetscCall(PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0)); 6075 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6076 PetscFunctionReturn(0); 6077 } 6078 6079 /*@ 6080 MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal) 6081 of a set of rows and columns of a matrix. 6082 6083 Collective on Mat 6084 6085 Input Parameters: 6086 + mat - the matrix 6087 . numRows - the number of rows to remove 6088 . rows - the global row indices 6089 . diag - value put in the diagonal of the eliminated rows 6090 . x - optional vector of solutions for zeroed rows (other entries in vector are not used), these must be set before this call 6091 - b - optional vector of right hand side, that will be adjusted by provided solution 6092 6093 Notes: 6094 This routine, along with `MatZeroRows()`, is typically used to eliminate known Dirichlet boundary conditions from a linear system. 6095 6096 For each zeroed row, the value of the corresponding b is set to diag times the value of the corresponding x. 6097 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 6098 6099 If the resulting linear system is to be solved with KSP then one can (but does not have to) call `KSPSetInitialGuessNonzero()` to allow the 6100 Krylov method to take advantage of the known solution on the zeroed rows. 6101 6102 For the parallel case, all processes that share the matrix (i.e., 6103 those in the communicator used for matrix creation) MUST call this 6104 routine, regardless of whether any rows being zeroed are owned by 6105 them. 6106 6107 Unlike `MatZeroRows()` this does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 6108 6109 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6110 list only rows local to itself). 6111 6112 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 6113 6114 Level: intermediate 6115 6116 .seealso: `MatZeroRowsIS()`, `MatZeroRows()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6117 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6118 @*/ 6119 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6120 { 6121 PetscFunctionBegin; 6122 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6123 PetscValidType(mat,1); 6124 if (numRows) PetscValidIntPointer(rows,3); 6125 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6126 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6127 PetscCheck(mat->ops->zerorowscolumns,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6128 MatCheckPreallocated(mat,1); 6129 6130 PetscCall((*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b)); 6131 PetscCall(MatViewFromOptions(mat,NULL,"-mat_view")); 6132 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6133 PetscFunctionReturn(0); 6134 } 6135 6136 /*@ 6137 MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal) 6138 of a set of rows and columns of a matrix. 6139 6140 Collective on Mat 6141 6142 Input Parameters: 6143 + mat - the matrix 6144 . is - the rows to zero 6145 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6146 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6147 - b - optional vector of right hand side, that will be adjusted by provided solution 6148 6149 Note: 6150 See `MatZeroRowsColumns()` for details on how this routine operates. 6151 6152 Level: intermediate 6153 6154 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6155 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRows()`, `MatZeroRowsColumnsStencil()` 6156 @*/ 6157 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6158 { 6159 PetscInt numRows; 6160 const PetscInt *rows; 6161 6162 PetscFunctionBegin; 6163 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6164 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6165 PetscValidType(mat,1); 6166 PetscValidType(is,2); 6167 PetscCall(ISGetLocalSize(is,&numRows)); 6168 PetscCall(ISGetIndices(is,&rows)); 6169 PetscCall(MatZeroRowsColumns(mat,numRows,rows,diag,x,b)); 6170 PetscCall(ISRestoreIndices(is,&rows)); 6171 PetscFunctionReturn(0); 6172 } 6173 6174 /*@ 6175 MatZeroRows - Zeros all entries (except possibly the main diagonal) 6176 of a set of rows of a matrix. 6177 6178 Collective on Mat 6179 6180 Input Parameters: 6181 + mat - the matrix 6182 . numRows - the number of rows to remove 6183 . rows - the global row indices 6184 . diag - value put in the diagonal of the eliminated rows 6185 . x - optional vector of solutions for zeroed rows (other entries in vector are not used), these must be set before this call 6186 - b - optional vector of right hand side, that will be adjusted by provided solution 6187 6188 Notes: 6189 This routine, along with `MatZeroRowsColumns()`, is typically used to eliminate known Dirichlet boundary conditions from a linear system. 6190 6191 For each zeroed row, the value of the corresponding b is set to diag times the value of the corresponding x. 6192 6193 If the resulting linear system is to be solved with KSP then one can (but does not have to) call `KSPSetInitialGuessNonzero()` to allow the 6194 Krylov method to take advantage of the known solution on the zeroed rows. 6195 6196 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) 6197 from the matrix. 6198 6199 Unlike `MatZeroRowsColumns()` for the AIJ and BAIJ matrix formats this removes the old nonzero structure, from the eliminated rows of the matrix 6200 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 6201 formats this does not alter the nonzero structure. 6202 6203 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6204 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6205 merely zeroed. 6206 6207 The user can set a value in the diagonal entry (or for the AIJ and 6208 row formats can optionally remove the main diagonal entry from the 6209 nonzero structure as well, by passing 0.0 as the final argument). 6210 6211 For the parallel case, all processes that share the matrix (i.e., 6212 those in the communicator used for matrix creation) MUST call this 6213 routine, regardless of whether any rows being zeroed are owned by 6214 them. 6215 6216 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6217 list only rows local to itself). 6218 6219 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6220 owns that are to be zeroed. This saves a global synchronization in the implementation. 6221 6222 Level: intermediate 6223 6224 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6225 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()`, `PCREDISTRIBUTE` 6226 @*/ 6227 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6228 { 6229 PetscFunctionBegin; 6230 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6231 PetscValidType(mat,1); 6232 if (numRows) PetscValidIntPointer(rows,3); 6233 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6234 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6235 PetscCheck(mat->ops->zerorows,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6236 MatCheckPreallocated(mat,1); 6237 6238 PetscCall((*mat->ops->zerorows)(mat,numRows,rows,diag,x,b)); 6239 PetscCall(MatViewFromOptions(mat,NULL,"-mat_view")); 6240 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6241 PetscFunctionReturn(0); 6242 } 6243 6244 /*@ 6245 MatZeroRowsIS - Zeros all entries (except possibly the main diagonal) 6246 of a set of rows of a matrix. 6247 6248 Collective on Mat 6249 6250 Input Parameters: 6251 + mat - the matrix 6252 . is - index set of rows to remove (if NULL then no row is removed) 6253 . diag - value put in all diagonals of eliminated rows 6254 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6255 - b - optional vector of right hand side, that will be adjusted by provided solution 6256 6257 Note: 6258 See `MatZeroRows()` for details on how this routine operates. 6259 6260 Level: intermediate 6261 6262 .seealso: `MatZeroRows()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6263 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6264 @*/ 6265 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6266 { 6267 PetscInt numRows = 0; 6268 const PetscInt *rows = NULL; 6269 6270 PetscFunctionBegin; 6271 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6272 PetscValidType(mat,1); 6273 if (is) { 6274 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6275 PetscCall(ISGetLocalSize(is,&numRows)); 6276 PetscCall(ISGetIndices(is,&rows)); 6277 } 6278 PetscCall(MatZeroRows(mat,numRows,rows,diag,x,b)); 6279 if (is) { 6280 PetscCall(ISRestoreIndices(is,&rows)); 6281 } 6282 PetscFunctionReturn(0); 6283 } 6284 6285 /*@ 6286 MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal) 6287 of a set of rows of a matrix. These rows must be local to the process. 6288 6289 Collective on Mat 6290 6291 Input Parameters: 6292 + mat - the matrix 6293 . numRows - the number of rows to remove 6294 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 6295 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6296 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6297 - b - optional vector of right hand side, that will be adjusted by provided solution 6298 6299 Notes: 6300 See `MatZeroRows()` for details on how this routine operates. 6301 6302 The grid coordinates are across the entire grid, not just the local portion 6303 6304 In Fortran idxm and idxn should be declared as 6305 $ MatStencil idxm(4,m) 6306 and the values inserted using 6307 $ idxm(MatStencil_i,1) = i 6308 $ idxm(MatStencil_j,1) = j 6309 $ idxm(MatStencil_k,1) = k 6310 $ idxm(MatStencil_c,1) = c 6311 etc 6312 6313 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6314 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6315 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6316 DM_BOUNDARY_PERIODIC boundary type. 6317 6318 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 6319 a single value per point) you can skip filling those indices. 6320 6321 Level: intermediate 6322 6323 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsl()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6324 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6325 @*/ 6326 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 6327 { 6328 PetscInt dim = mat->stencil.dim; 6329 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 6330 PetscInt *dims = mat->stencil.dims+1; 6331 PetscInt *starts = mat->stencil.starts; 6332 PetscInt *dxm = (PetscInt*) rows; 6333 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6334 6335 PetscFunctionBegin; 6336 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6337 PetscValidType(mat,1); 6338 if (numRows) PetscValidPointer(rows,3); 6339 6340 PetscCall(PetscMalloc1(numRows, &jdxm)); 6341 for (i = 0; i < numRows; ++i) { 6342 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6343 for (j = 0; j < 3-sdim; ++j) dxm++; 6344 /* Local index in X dir */ 6345 tmp = *dxm++ - starts[0]; 6346 /* Loop over remaining dimensions */ 6347 for (j = 0; j < dim-1; ++j) { 6348 /* If nonlocal, set index to be negative */ 6349 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6350 /* Update local index */ 6351 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6352 } 6353 /* Skip component slot if necessary */ 6354 if (mat->stencil.noc) dxm++; 6355 /* Local row number */ 6356 if (tmp >= 0) { 6357 jdxm[numNewRows++] = tmp; 6358 } 6359 } 6360 PetscCall(MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b)); 6361 PetscCall(PetscFree(jdxm)); 6362 PetscFunctionReturn(0); 6363 } 6364 6365 /*@ 6366 MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal) 6367 of a set of rows and columns of a matrix. 6368 6369 Collective on Mat 6370 6371 Input Parameters: 6372 + mat - the matrix 6373 . numRows - the number of rows/columns to remove 6374 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 6375 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6376 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6377 - b - optional vector of right hand side, that will be adjusted by provided solution 6378 6379 Notes: 6380 See `MatZeroRowsColumns()` for details on how this routine operates. 6381 6382 The grid coordinates are across the entire grid, not just the local portion 6383 6384 In Fortran idxm and idxn should be declared as 6385 $ MatStencil idxm(4,m) 6386 and the values inserted using 6387 $ idxm(MatStencil_i,1) = i 6388 $ idxm(MatStencil_j,1) = j 6389 $ idxm(MatStencil_k,1) = k 6390 $ idxm(MatStencil_c,1) = c 6391 etc 6392 6393 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6394 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6395 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6396 DM_BOUNDARY_PERIODIC boundary type. 6397 6398 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 6399 a single value per point) you can skip filling those indices. 6400 6401 Level: intermediate 6402 6403 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6404 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRows()` 6405 @*/ 6406 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 6407 { 6408 PetscInt dim = mat->stencil.dim; 6409 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 6410 PetscInt *dims = mat->stencil.dims+1; 6411 PetscInt *starts = mat->stencil.starts; 6412 PetscInt *dxm = (PetscInt*) rows; 6413 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6414 6415 PetscFunctionBegin; 6416 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6417 PetscValidType(mat,1); 6418 if (numRows) PetscValidPointer(rows,3); 6419 6420 PetscCall(PetscMalloc1(numRows, &jdxm)); 6421 for (i = 0; i < numRows; ++i) { 6422 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6423 for (j = 0; j < 3-sdim; ++j) dxm++; 6424 /* Local index in X dir */ 6425 tmp = *dxm++ - starts[0]; 6426 /* Loop over remaining dimensions */ 6427 for (j = 0; j < dim-1; ++j) { 6428 /* If nonlocal, set index to be negative */ 6429 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6430 /* Update local index */ 6431 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6432 } 6433 /* Skip component slot if necessary */ 6434 if (mat->stencil.noc) dxm++; 6435 /* Local row number */ 6436 if (tmp >= 0) { 6437 jdxm[numNewRows++] = tmp; 6438 } 6439 } 6440 PetscCall(MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b)); 6441 PetscCall(PetscFree(jdxm)); 6442 PetscFunctionReturn(0); 6443 } 6444 6445 /*@C 6446 MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal) 6447 of a set of rows of a matrix; using local numbering of rows. 6448 6449 Collective on Mat 6450 6451 Input Parameters: 6452 + mat - the matrix 6453 . numRows - the number of rows to remove 6454 . rows - the local row indices 6455 . diag - value put in all diagonals of eliminated rows 6456 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6457 - b - optional vector of right hand side, that will be adjusted by provided solution 6458 6459 Notes: 6460 Before calling `MatZeroRowsLocal()`, the user must first set the 6461 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6462 6463 See `MatZeroRows()` for details on how this routine operates. 6464 6465 Level: intermediate 6466 6467 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRows()`, `MatSetOption()`, 6468 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6469 @*/ 6470 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6471 { 6472 PetscFunctionBegin; 6473 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6474 PetscValidType(mat,1); 6475 if (numRows) PetscValidIntPointer(rows,3); 6476 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6477 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6478 MatCheckPreallocated(mat,1); 6479 6480 if (mat->ops->zerorowslocal) { 6481 PetscCall((*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b)); 6482 } else { 6483 IS is, newis; 6484 const PetscInt *newRows; 6485 6486 PetscCheck(mat->rmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6487 PetscCall(ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is)); 6488 PetscCall(ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis)); 6489 PetscCall(ISGetIndices(newis,&newRows)); 6490 PetscCall((*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b)); 6491 PetscCall(ISRestoreIndices(newis,&newRows)); 6492 PetscCall(ISDestroy(&newis)); 6493 PetscCall(ISDestroy(&is)); 6494 } 6495 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6496 PetscFunctionReturn(0); 6497 } 6498 6499 /*@ 6500 MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal) 6501 of a set of rows of a matrix; using local numbering of rows. 6502 6503 Collective on Mat 6504 6505 Input Parameters: 6506 + mat - the matrix 6507 . is - index set of rows to remove 6508 . diag - value put in all diagonals of eliminated rows 6509 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6510 - b - optional vector of right hand side, that will be adjusted by provided solution 6511 6512 Notes: 6513 Before calling `MatZeroRowsLocalIS()`, the user must first set the 6514 local-to-global mapping by calling `MatSetLocalToGlobalMapping()`. 6515 6516 See `MatZeroRows()` for details on how this routine operates. 6517 6518 Level: intermediate 6519 6520 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRows()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6521 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6522 @*/ 6523 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6524 { 6525 PetscInt numRows; 6526 const PetscInt *rows; 6527 6528 PetscFunctionBegin; 6529 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6530 PetscValidType(mat,1); 6531 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6532 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6533 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6534 MatCheckPreallocated(mat,1); 6535 6536 PetscCall(ISGetLocalSize(is,&numRows)); 6537 PetscCall(ISGetIndices(is,&rows)); 6538 PetscCall(MatZeroRowsLocal(mat,numRows,rows,diag,x,b)); 6539 PetscCall(ISRestoreIndices(is,&rows)); 6540 PetscFunctionReturn(0); 6541 } 6542 6543 /*@ 6544 MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal) 6545 of a set of rows and columns of a matrix; using local numbering of rows. 6546 6547 Collective on Mat 6548 6549 Input Parameters: 6550 + mat - the matrix 6551 . numRows - the number of rows to remove 6552 . rows - the global row indices 6553 . diag - value put in all diagonals of eliminated rows 6554 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6555 - b - optional vector of right hand side, that will be adjusted by provided solution 6556 6557 Notes: 6558 Before calling MatZeroRowsColumnsLocal(), the user must first set the 6559 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6560 6561 See `MatZeroRowsColumns()` for details on how this routine operates. 6562 6563 Level: intermediate 6564 6565 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6566 `MatZeroRows()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6567 @*/ 6568 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6569 { 6570 IS is, newis; 6571 const PetscInt *newRows; 6572 6573 PetscFunctionBegin; 6574 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6575 PetscValidType(mat,1); 6576 if (numRows) PetscValidIntPointer(rows,3); 6577 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6578 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6579 MatCheckPreallocated(mat,1); 6580 6581 PetscCheck(mat->cmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6582 PetscCall(ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is)); 6583 PetscCall(ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis)); 6584 PetscCall(ISGetIndices(newis,&newRows)); 6585 PetscCall((*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b)); 6586 PetscCall(ISRestoreIndices(newis,&newRows)); 6587 PetscCall(ISDestroy(&newis)); 6588 PetscCall(ISDestroy(&is)); 6589 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6590 PetscFunctionReturn(0); 6591 } 6592 6593 /*@ 6594 MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal) 6595 of a set of rows and columns of a matrix; using local numbering of rows. 6596 6597 Collective on Mat 6598 6599 Input Parameters: 6600 + mat - the matrix 6601 . is - index set of rows to remove 6602 . diag - value put in all diagonals of eliminated rows 6603 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6604 - b - optional vector of right hand side, that will be adjusted by provided solution 6605 6606 Notes: 6607 Before calling `MatZeroRowsColumnsLocalIS()`, the user must first set the 6608 local-to-global mapping by calling `MatSetLocalToGlobalMapping()`. 6609 6610 See `MatZeroRowsColumns()` for details on how this routine operates. 6611 6612 Level: intermediate 6613 6614 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6615 `MatZeroRowsColumnsLocal()`, `MatZeroRows()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6616 @*/ 6617 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6618 { 6619 PetscInt numRows; 6620 const PetscInt *rows; 6621 6622 PetscFunctionBegin; 6623 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6624 PetscValidType(mat,1); 6625 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6626 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6627 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6628 MatCheckPreallocated(mat,1); 6629 6630 PetscCall(ISGetLocalSize(is,&numRows)); 6631 PetscCall(ISGetIndices(is,&rows)); 6632 PetscCall(MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b)); 6633 PetscCall(ISRestoreIndices(is,&rows)); 6634 PetscFunctionReturn(0); 6635 } 6636 6637 /*@C 6638 MatGetSize - Returns the numbers of rows and columns in a matrix. 6639 6640 Not Collective 6641 6642 Input Parameter: 6643 . mat - the matrix 6644 6645 Output Parameters: 6646 + m - the number of global rows 6647 - n - the number of global columns 6648 6649 Note: both output parameters can be NULL on input. 6650 6651 Level: beginner 6652 6653 .seealso: `MatGetLocalSize()` 6654 @*/ 6655 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n) 6656 { 6657 PetscFunctionBegin; 6658 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6659 if (m) *m = mat->rmap->N; 6660 if (n) *n = mat->cmap->N; 6661 PetscFunctionReturn(0); 6662 } 6663 6664 /*@C 6665 MatGetLocalSize - For most matrix formats, excluding `MATELEMENTAL` and `MATSCALAPACK`, Returns the number of local rows and local columns 6666 of a matrix. For all matrices this is the local size of the left and right vectors as returned by MatCreateVecs(). 6667 6668 Not Collective 6669 6670 Input Parameter: 6671 . mat - the matrix 6672 6673 Output Parameters: 6674 + m - the number of local rows, use `NULL` to not obtain this value 6675 - n - the number of local columns, use `NULL` to not obtain this value 6676 6677 Level: beginner 6678 6679 .seealso: `MatGetSize()` 6680 @*/ 6681 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n) 6682 { 6683 PetscFunctionBegin; 6684 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6685 if (m) PetscValidIntPointer(m,2); 6686 if (n) PetscValidIntPointer(n,3); 6687 if (m) *m = mat->rmap->n; 6688 if (n) *n = mat->cmap->n; 6689 PetscFunctionReturn(0); 6690 } 6691 6692 /*@C 6693 MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies this matrix by that are owned by 6694 this processor. (The columns of the "diagonal block" for most sparse matrix formats). See :any:`<sec_matlayout>` for details on matrix layouts. 6695 6696 Not Collective, unless matrix has not been allocated, then collective on Mat 6697 6698 Input Parameter: 6699 . mat - the matrix 6700 6701 Output Parameters: 6702 + m - the global index of the first local column, use `NULL` to not obtain this value 6703 - n - one more than the global index of the last local column, use `NULL` to not obtain this value 6704 6705 Level: developer 6706 6707 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRanges()`, `MatGetOwnershipRangesColumn()`, `PetscLayout` 6708 6709 @*/ 6710 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n) 6711 { 6712 PetscFunctionBegin; 6713 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6714 PetscValidType(mat,1); 6715 if (m) PetscValidIntPointer(m,2); 6716 if (n) PetscValidIntPointer(n,3); 6717 MatCheckPreallocated(mat,1); 6718 if (m) *m = mat->cmap->rstart; 6719 if (n) *n = mat->cmap->rend; 6720 PetscFunctionReturn(0); 6721 } 6722 6723 /*@C 6724 MatGetOwnershipRange - For matrices that own values by row, excludes `MATELEMENTAL` and `MATSCALAPACK`, returns the range of matrix rows owned by 6725 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 6726 vector product with this matrix. See :any:`<sec_matlayout>` for details on matrix layouts 6727 6728 Not Collective 6729 6730 Input Parameter: 6731 . mat - the matrix 6732 6733 Output Parameters: 6734 + m - the global index of the first local row, use `NULL` to not obtain this value 6735 - n - one more than the global index of the last local row, use `NULL` to not obtain this value 6736 6737 Note: 6738 This function requires that the matrix be preallocated. If you have not preallocated, consider using 6739 `PetscSplitOwnership`(`MPI_Comm` comm, `PetscInt` *n, `PetscInt` *N) 6740 and then `MPI_Scan()` to calculate prefix sums of the local sizes. 6741 6742 Level: beginner 6743 6744 .seealso: `MatGetOwnershipRanges()`, `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRangesColumn()`, `PetscSplitOwnership()`, `PetscSplitOwnershipBlock()`, 6745 `PetscLayout` 6746 6747 @*/ 6748 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n) 6749 { 6750 PetscFunctionBegin; 6751 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6752 PetscValidType(mat,1); 6753 if (m) PetscValidIntPointer(m,2); 6754 if (n) PetscValidIntPointer(n,3); 6755 MatCheckPreallocated(mat,1); 6756 if (m) *m = mat->rmap->rstart; 6757 if (n) *n = mat->rmap->rend; 6758 PetscFunctionReturn(0); 6759 } 6760 6761 /*@C 6762 MatGetOwnershipRanges - For matrices that own values by row, excludes `MATELEMENTAL` and `MATSCALAPACK`, returns the range of matrix rows owned by 6763 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 6764 vector product with this matrix. See :any:`<sec_matlayout>` for details on matrix layouts 6765 6766 Not Collective, unless matrix has not been allocated, then collective on Mat 6767 6768 Input Parameters: 6769 . mat - the matrix 6770 6771 Output Parameters: 6772 . ranges - start of each processors portion plus one more than the total length at the end 6773 6774 Level: beginner 6775 6776 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRangesColumn()`, `PetscLayout` 6777 6778 @*/ 6779 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges) 6780 { 6781 PetscFunctionBegin; 6782 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6783 PetscValidType(mat,1); 6784 MatCheckPreallocated(mat,1); 6785 PetscCall(PetscLayoutGetRanges(mat->rmap,ranges)); 6786 PetscFunctionReturn(0); 6787 } 6788 6789 /*@C 6790 MatGetOwnershipRangesColumn - Returns the ranges of matrix columns associated with rows of a vector one multiplies this vector by that are owned by 6791 each processor. (The columns of the "diagonal blocks", for most sparse matrix formats). See :any:`<sec_matlayout>` for details on matrix layouts. 6792 6793 Not Collective, unless matrix has not been allocated, then collective on Mat 6794 6795 Input Parameters: 6796 . mat - the matrix 6797 6798 Output Parameters: 6799 . ranges - start of each processors portion plus one more then the total length at the end 6800 6801 Level: beginner 6802 6803 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRanges()` 6804 6805 @*/ 6806 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges) 6807 { 6808 PetscFunctionBegin; 6809 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6810 PetscValidType(mat,1); 6811 MatCheckPreallocated(mat,1); 6812 PetscCall(PetscLayoutGetRanges(mat->cmap,ranges)); 6813 PetscFunctionReturn(0); 6814 } 6815 6816 /*@C 6817 MatGetOwnershipIS - Get row and column ownership of a matrices' values as index sets. For most matrices, excluding `MATELEMENTAL` and `MATSCALAPACK`, this 6818 corresponds to values returned by `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`. For `MATELEMENTAL` and `MATSCALAPACK` the ownership 6819 is more complicated. See :any:`<sec_matlayout>` for details on matrix layouts. 6820 6821 Not Collective 6822 6823 Input Parameter: 6824 . A - matrix 6825 6826 Output Parameters: 6827 + rows - rows in which this process owns elements, , use `NULL` to not obtain this value 6828 - cols - columns in which this process owns elements, use `NULL` to not obtain this value 6829 6830 Level: intermediate 6831 6832 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`, `MatSetValues()`, ``MATELEMENTAL``, ``MATSCALAPACK`` 6833 @*/ 6834 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols) 6835 { 6836 PetscErrorCode (*f)(Mat,IS*,IS*); 6837 6838 PetscFunctionBegin; 6839 MatCheckPreallocated(A,1); 6840 PetscCall(PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f)); 6841 if (f) { 6842 PetscCall((*f)(A,rows,cols)); 6843 } else { /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */ 6844 if (rows) PetscCall(ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows)); 6845 if (cols) PetscCall(ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols)); 6846 } 6847 PetscFunctionReturn(0); 6848 } 6849 6850 /*@C 6851 MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix. 6852 Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric() 6853 to complete the factorization. 6854 6855 Collective on Mat 6856 6857 Input Parameters: 6858 + mat - the matrix 6859 . row - row permutation 6860 . column - column permutation 6861 - info - structure containing 6862 $ levels - number of levels of fill. 6863 $ expected fill - as ratio of original fill. 6864 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 6865 missing diagonal entries) 6866 6867 Output Parameters: 6868 . fact - new matrix that has been symbolically factored 6869 6870 Notes: 6871 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 6872 6873 Most users should employ the simplified KSP interface for linear solvers 6874 instead of working directly with matrix algebra routines such as this. 6875 See, e.g., KSPCreate(). 6876 6877 Level: developer 6878 6879 .seealso: `MatLUFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()` 6880 `MatGetOrdering()`, `MatFactorInfo` 6881 6882 Note: this uses the definition of level of fill as in Y. Saad, 2003 6883 6884 Developer Note: fortran interface is not autogenerated as the f90 6885 interface definition cannot be generated correctly [due to MatFactorInfo] 6886 6887 References: 6888 . * - Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6889 @*/ 6890 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 6891 { 6892 PetscFunctionBegin; 6893 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 6894 PetscValidType(mat,2); 6895 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,3); 6896 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,4); 6897 PetscValidPointer(info,5); 6898 PetscValidPointer(fact,1); 6899 PetscCheck(info->levels >= 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %" PetscInt_FMT,(PetscInt)info->levels); 6900 PetscCheck(info->fill >= 1.0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6901 if (!fact->ops->ilufactorsymbolic) { 6902 MatSolverType stype; 6903 PetscCall(MatFactorGetSolverType(fact,&stype)); 6904 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver type %s",((PetscObject)mat)->type_name,stype); 6905 } 6906 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6907 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6908 MatCheckPreallocated(mat,2); 6909 6910 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0)); 6911 PetscCall((fact->ops->ilufactorsymbolic)(fact,mat,row,col,info)); 6912 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0)); 6913 PetscFunctionReturn(0); 6914 } 6915 6916 /*@C 6917 MatICCFactorSymbolic - Performs symbolic incomplete 6918 Cholesky factorization for a symmetric matrix. Use 6919 MatCholeskyFactorNumeric() to complete the factorization. 6920 6921 Collective on Mat 6922 6923 Input Parameters: 6924 + mat - the matrix 6925 . perm - row and column permutation 6926 - info - structure containing 6927 $ levels - number of levels of fill. 6928 $ expected fill - as ratio of original fill. 6929 6930 Output Parameter: 6931 . fact - the factored matrix 6932 6933 Notes: 6934 Most users should employ the KSP interface for linear solvers 6935 instead of working directly with matrix algebra routines such as this. 6936 See, e.g., KSPCreate(). 6937 6938 Level: developer 6939 6940 .seealso: `MatCholeskyFactorNumeric()`, `MatCholeskyFactor()`, `MatFactorInfo` 6941 6942 Note: this uses the definition of level of fill as in Y. Saad, 2003 6943 6944 Developer Note: fortran interface is not autogenerated as the f90 6945 interface definition cannot be generated correctly [due to MatFactorInfo] 6946 6947 References: 6948 . * - Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6949 @*/ 6950 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 6951 { 6952 PetscFunctionBegin; 6953 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 6954 PetscValidType(mat,2); 6955 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,3); 6956 PetscValidPointer(info,4); 6957 PetscValidPointer(fact,1); 6958 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6959 PetscCheck(info->levels >= 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %" PetscInt_FMT,(PetscInt) info->levels); 6960 PetscCheck(info->fill >= 1.0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6961 if (!(fact)->ops->iccfactorsymbolic) { 6962 MatSolverType stype; 6963 PetscCall(MatFactorGetSolverType(fact,&stype)); 6964 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver type %s",((PetscObject)mat)->type_name,stype); 6965 } 6966 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6967 MatCheckPreallocated(mat,2); 6968 6969 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0)); 6970 PetscCall((fact->ops->iccfactorsymbolic)(fact,mat,perm,info)); 6971 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0)); 6972 PetscFunctionReturn(0); 6973 } 6974 6975 /*@C 6976 MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat 6977 points to an array of valid matrices, they may be reused to store the new 6978 submatrices. 6979 6980 Collective on Mat 6981 6982 Input Parameters: 6983 + mat - the matrix 6984 . n - the number of submatrixes to be extracted (on this processor, may be zero) 6985 . irow, icol - index sets of rows and columns to extract 6986 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6987 6988 Output Parameter: 6989 . submat - the array of submatrices 6990 6991 Notes: 6992 MatCreateSubMatrices() can extract ONLY sequential submatrices 6993 (from both sequential and parallel matrices). Use MatCreateSubMatrix() 6994 to extract a parallel submatrix. 6995 6996 Some matrix types place restrictions on the row and column 6997 indices, such as that they be sorted or that they be equal to each other. 6998 6999 The index sets may not have duplicate entries. 7000 7001 When extracting submatrices from a parallel matrix, each processor can 7002 form a different submatrix by setting the rows and columns of its 7003 individual index sets according to the local submatrix desired. 7004 7005 When finished using the submatrices, the user should destroy 7006 them with MatDestroySubMatrices(). 7007 7008 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 7009 original matrix has not changed from that last call to MatCreateSubMatrices(). 7010 7011 This routine creates the matrices in submat; you should NOT create them before 7012 calling it. It also allocates the array of matrix pointers submat. 7013 7014 For BAIJ matrices the index sets must respect the block structure, that is if they 7015 request one row/column in a block, they must request all rows/columns that are in 7016 that block. For example, if the block size is 2 you cannot request just row 0 and 7017 column 0. 7018 7019 Fortran Note: 7020 The Fortran interface is slightly different from that given below; it 7021 requires one to pass in as submat a Mat (integer) array of size at least n+1. 7022 7023 Level: advanced 7024 7025 .seealso: `MatDestroySubMatrices()`, `MatCreateSubMatrix()`, `MatGetRow()`, `MatGetDiagonal()`, `MatReuse` 7026 @*/ 7027 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 7028 { 7029 PetscInt i; 7030 PetscBool eq; 7031 7032 PetscFunctionBegin; 7033 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7034 PetscValidType(mat,1); 7035 if (n) { 7036 PetscValidPointer(irow,3); 7037 for (i=0; i<n; i++) PetscValidHeaderSpecific(irow[i],IS_CLASSID,3); 7038 PetscValidPointer(icol,4); 7039 for (i=0; i<n; i++) PetscValidHeaderSpecific(icol[i],IS_CLASSID,4); 7040 } 7041 PetscValidPointer(submat,6); 7042 if (n && scall == MAT_REUSE_MATRIX) { 7043 PetscValidPointer(*submat,6); 7044 for (i=0; i<n; i++) PetscValidHeaderSpecific((*submat)[i],MAT_CLASSID,6); 7045 } 7046 PetscCheck(mat->ops->createsubmatrices,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7047 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7048 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7049 MatCheckPreallocated(mat,1); 7050 PetscCall(PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0)); 7051 PetscCall((*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat)); 7052 PetscCall(PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0)); 7053 for (i=0; i<n; i++) { 7054 (*submat)[i]->factortype = MAT_FACTOR_NONE; /* in case in place factorization was previously done on submatrix */ 7055 PetscCall(ISEqualUnsorted(irow[i],icol[i],&eq)); 7056 if (eq) { 7057 PetscCall(MatPropagateSymmetryOptions(mat,(*submat)[i])); 7058 } 7059 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 7060 if (mat->boundtocpu && mat->bindingpropagates) { 7061 PetscCall(MatBindToCPU((*submat)[i],PETSC_TRUE)); 7062 PetscCall(MatSetBindingPropagates((*submat)[i],PETSC_TRUE)); 7063 } 7064 #endif 7065 } 7066 PetscFunctionReturn(0); 7067 } 7068 7069 /*@C 7070 MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms). 7071 7072 Collective on Mat 7073 7074 Input Parameters: 7075 + mat - the matrix 7076 . n - the number of submatrixes to be extracted 7077 . irow, icol - index sets of rows and columns to extract 7078 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 7079 7080 Output Parameter: 7081 . submat - the array of submatrices 7082 7083 Level: advanced 7084 7085 .seealso: `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRow()`, `MatGetDiagonal()`, `MatReuse` 7086 @*/ 7087 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 7088 { 7089 PetscInt i; 7090 PetscBool eq; 7091 7092 PetscFunctionBegin; 7093 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7094 PetscValidType(mat,1); 7095 if (n) { 7096 PetscValidPointer(irow,3); 7097 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 7098 PetscValidPointer(icol,4); 7099 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 7100 } 7101 PetscValidPointer(submat,6); 7102 if (n && scall == MAT_REUSE_MATRIX) { 7103 PetscValidPointer(*submat,6); 7104 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 7105 } 7106 PetscCheck(mat->ops->createsubmatricesmpi,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7107 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7108 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7109 MatCheckPreallocated(mat,1); 7110 7111 PetscCall(PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0)); 7112 PetscCall((*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat)); 7113 PetscCall(PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0)); 7114 for (i=0; i<n; i++) { 7115 PetscCall(ISEqualUnsorted(irow[i],icol[i],&eq)); 7116 if (eq) { 7117 PetscCall(MatPropagateSymmetryOptions(mat,(*submat)[i])); 7118 } 7119 } 7120 PetscFunctionReturn(0); 7121 } 7122 7123 /*@C 7124 MatDestroyMatrices - Destroys an array of matrices. 7125 7126 Collective on Mat 7127 7128 Input Parameters: 7129 + n - the number of local matrices 7130 - mat - the matrices (note that this is a pointer to the array of matrices) 7131 7132 Level: advanced 7133 7134 Notes: 7135 Frees not only the matrices, but also the array that contains the matrices 7136 In Fortran will not free the array. 7137 7138 .seealso: `MatCreateSubMatrices()` `MatDestroySubMatrices()` 7139 @*/ 7140 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[]) 7141 { 7142 PetscInt i; 7143 7144 PetscFunctionBegin; 7145 if (!*mat) PetscFunctionReturn(0); 7146 PetscCheck(n >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %" PetscInt_FMT,n); 7147 PetscValidPointer(mat,2); 7148 7149 for (i=0; i<n; i++) { 7150 PetscCall(MatDestroy(&(*mat)[i])); 7151 } 7152 7153 /* memory is allocated even if n = 0 */ 7154 PetscCall(PetscFree(*mat)); 7155 PetscFunctionReturn(0); 7156 } 7157 7158 /*@C 7159 MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices(). 7160 7161 Collective on Mat 7162 7163 Input Parameters: 7164 + n - the number of local matrices 7165 - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling 7166 sequence of MatCreateSubMatrices()) 7167 7168 Level: advanced 7169 7170 Notes: 7171 Frees not only the matrices, but also the array that contains the matrices 7172 In Fortran will not free the array. 7173 7174 .seealso: `MatCreateSubMatrices()` 7175 @*/ 7176 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[]) 7177 { 7178 Mat mat0; 7179 7180 PetscFunctionBegin; 7181 if (!*mat) PetscFunctionReturn(0); 7182 /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */ 7183 PetscCheck(n >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %" PetscInt_FMT,n); 7184 PetscValidPointer(mat,2); 7185 7186 mat0 = (*mat)[0]; 7187 if (mat0 && mat0->ops->destroysubmatrices) { 7188 PetscCall((mat0->ops->destroysubmatrices)(n,mat)); 7189 } else { 7190 PetscCall(MatDestroyMatrices(n,mat)); 7191 } 7192 PetscFunctionReturn(0); 7193 } 7194 7195 /*@C 7196 MatGetSeqNonzeroStructure - Extracts the nonzero structure from a matrix and stores it, in its entirety, on each process 7197 7198 Collective on Mat 7199 7200 Input Parameters: 7201 . mat - the matrix 7202 7203 Output Parameter: 7204 . matstruct - the sequential matrix with the nonzero structure of mat 7205 7206 Level: intermediate 7207 7208 .seealso: `MatDestroySeqNonzeroStructure()`, `MatCreateSubMatrices()`, `MatDestroyMatrices()` 7209 @*/ 7210 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct) 7211 { 7212 PetscFunctionBegin; 7213 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7214 PetscValidPointer(matstruct,2); 7215 7216 PetscValidType(mat,1); 7217 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7218 MatCheckPreallocated(mat,1); 7219 7220 PetscCheck(mat->ops->getseqnonzerostructure,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s",((PetscObject)mat)->type_name); 7221 PetscCall(PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0)); 7222 PetscCall((*mat->ops->getseqnonzerostructure)(mat,matstruct)); 7223 PetscCall(PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0)); 7224 PetscFunctionReturn(0); 7225 } 7226 7227 /*@C 7228 MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure(). 7229 7230 Collective on Mat 7231 7232 Input Parameters: 7233 . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling 7234 sequence of MatGetSequentialNonzeroStructure()) 7235 7236 Level: advanced 7237 7238 Notes: 7239 Frees not only the matrices, but also the array that contains the matrices 7240 7241 .seealso: `MatGetSeqNonzeroStructure()` 7242 @*/ 7243 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat) 7244 { 7245 PetscFunctionBegin; 7246 PetscValidPointer(mat,1); 7247 PetscCall(MatDestroy(mat)); 7248 PetscFunctionReturn(0); 7249 } 7250 7251 /*@ 7252 MatIncreaseOverlap - Given a set of submatrices indicated by index sets, 7253 replaces the index sets by larger ones that represent submatrices with 7254 additional overlap. 7255 7256 Collective on Mat 7257 7258 Input Parameters: 7259 + mat - the matrix 7260 . n - the number of index sets 7261 . is - the array of index sets (these index sets will changed during the call) 7262 - ov - the additional overlap requested 7263 7264 Options Database: 7265 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7266 7267 Level: developer 7268 7269 Developer Note: 7270 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. 7271 7272 .seealso: `MatCreateSubMatrices()` 7273 @*/ 7274 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov) 7275 { 7276 PetscInt i,bs,cbs; 7277 7278 PetscFunctionBegin; 7279 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7280 PetscValidType(mat,1); 7281 PetscValidLogicalCollectiveInt(mat,n,2); 7282 PetscCheck(n >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %" PetscInt_FMT,n); 7283 if (n) { 7284 PetscValidPointer(is,3); 7285 for (i = 0; i < n; i++) PetscValidHeaderSpecific(is[i],IS_CLASSID,3); 7286 } 7287 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7288 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7289 MatCheckPreallocated(mat,1); 7290 7291 if (!ov || !n) PetscFunctionReturn(0); 7292 PetscCheck(mat->ops->increaseoverlap,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7293 PetscCall(PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0)); 7294 PetscCall((*mat->ops->increaseoverlap)(mat,n,is,ov)); 7295 PetscCall(PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0)); 7296 PetscCall(MatGetBlockSizes(mat,&bs,&cbs)); 7297 if (bs == cbs) { 7298 for (i=0; i<n; i++) { 7299 PetscCall(ISSetBlockSize(is[i],bs)); 7300 } 7301 } 7302 PetscFunctionReturn(0); 7303 } 7304 7305 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt); 7306 7307 /*@ 7308 MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across 7309 a sub communicator, replaces the index sets by larger ones that represent submatrices with 7310 additional overlap. 7311 7312 Collective on Mat 7313 7314 Input Parameters: 7315 + mat - the matrix 7316 . n - the number of index sets 7317 . is - the array of index sets (these index sets will changed during the call) 7318 - ov - the additional overlap requested 7319 7320 Options Database: 7321 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7322 7323 Level: developer 7324 7325 .seealso: `MatCreateSubMatrices()` 7326 @*/ 7327 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov) 7328 { 7329 PetscInt i; 7330 7331 PetscFunctionBegin; 7332 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7333 PetscValidType(mat,1); 7334 PetscCheck(n >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %" PetscInt_FMT,n); 7335 if (n) { 7336 PetscValidPointer(is,3); 7337 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 7338 } 7339 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7340 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7341 MatCheckPreallocated(mat,1); 7342 if (!ov) PetscFunctionReturn(0); 7343 PetscCall(PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0)); 7344 for (i=0; i<n; i++) { 7345 PetscCall(MatIncreaseOverlapSplit_Single(mat,&is[i],ov)); 7346 } 7347 PetscCall(PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0)); 7348 PetscFunctionReturn(0); 7349 } 7350 7351 /*@ 7352 MatGetBlockSize - Returns the matrix block size. 7353 7354 Not Collective 7355 7356 Input Parameter: 7357 . mat - the matrix 7358 7359 Output Parameter: 7360 . bs - block size 7361 7362 Notes: 7363 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7364 7365 If the block size has not been set yet this routine returns 1. 7366 7367 Level: intermediate 7368 7369 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSizes()` 7370 @*/ 7371 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs) 7372 { 7373 PetscFunctionBegin; 7374 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7375 PetscValidIntPointer(bs,2); 7376 *bs = PetscAbs(mat->rmap->bs); 7377 PetscFunctionReturn(0); 7378 } 7379 7380 /*@ 7381 MatGetBlockSizes - Returns the matrix block row and column sizes. 7382 7383 Not Collective 7384 7385 Input Parameter: 7386 . mat - the matrix 7387 7388 Output Parameters: 7389 + rbs - row block size 7390 - cbs - column block size 7391 7392 Notes: 7393 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7394 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7395 7396 If a block size has not been set yet this routine returns 1. 7397 7398 Level: intermediate 7399 7400 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSize()`, `MatSetBlockSizes()` 7401 @*/ 7402 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs) 7403 { 7404 PetscFunctionBegin; 7405 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7406 if (rbs) PetscValidIntPointer(rbs,2); 7407 if (cbs) PetscValidIntPointer(cbs,3); 7408 if (rbs) *rbs = PetscAbs(mat->rmap->bs); 7409 if (cbs) *cbs = PetscAbs(mat->cmap->bs); 7410 PetscFunctionReturn(0); 7411 } 7412 7413 /*@ 7414 MatSetBlockSize - Sets the matrix block size. 7415 7416 Logically Collective on Mat 7417 7418 Input Parameters: 7419 + mat - the matrix 7420 - bs - block size 7421 7422 Notes: 7423 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7424 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7425 7426 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size 7427 is compatible with the matrix local sizes. 7428 7429 Level: intermediate 7430 7431 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`, `MatGetBlockSizes()` 7432 @*/ 7433 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs) 7434 { 7435 PetscFunctionBegin; 7436 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7437 PetscValidLogicalCollectiveInt(mat,bs,2); 7438 PetscCall(MatSetBlockSizes(mat,bs,bs)); 7439 PetscFunctionReturn(0); 7440 } 7441 7442 typedef struct { 7443 PetscInt n; 7444 IS *is; 7445 Mat *mat; 7446 PetscObjectState nonzerostate; 7447 Mat C; 7448 } EnvelopeData; 7449 7450 static PetscErrorCode EnvelopeDataDestroy(EnvelopeData *edata) 7451 { 7452 for (PetscInt i=0; i<edata->n; i++) { 7453 PetscCall(ISDestroy(&edata->is[i])); 7454 } 7455 PetscCall(PetscFree(edata->is)); 7456 PetscCall(PetscFree(edata)); 7457 return 0; 7458 } 7459 7460 /* 7461 MatComputeVariableBlockEnvelope - Given a matrix whose nonzeros are in blocks along the diagonal this computes and stores 7462 the sizes of these blocks in the matrix. An individual block may lie over several processes. 7463 7464 Collective on mat 7465 7466 Input Parameter: 7467 . mat - the matrix 7468 7469 Notes: 7470 There can be zeros within the blocks 7471 7472 The blocks can overlap between processes, including laying on more than two processes 7473 7474 */ 7475 static PetscErrorCode MatComputeVariableBlockEnvelope(Mat mat) 7476 { 7477 PetscInt n,*sizes,*starts,i = 0,env = 0, tbs = 0, lblocks = 0,rstart,II,ln = 0,cnt = 0,cstart,cend; 7478 PetscInt *diag,*odiag,sc; 7479 VecScatter scatter; 7480 PetscScalar *seqv; 7481 const PetscScalar *parv; 7482 const PetscInt *ia,*ja; 7483 PetscBool set,flag,done; 7484 Mat AA = mat,A; 7485 MPI_Comm comm; 7486 PetscMPIInt rank,size,tag; 7487 MPI_Status status; 7488 PetscContainer container; 7489 EnvelopeData *edata; 7490 Vec seq,par; 7491 IS isglobal; 7492 7493 PetscFunctionBegin; 7494 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7495 PetscCall(MatIsSymmetricKnown(mat,&set,&flag)); 7496 if (!set || !flag) { 7497 /* TOO: only needs nonzero structure of transpose */ 7498 PetscCall(MatTranspose(mat,MAT_INITIAL_MATRIX,&AA)); 7499 PetscCall(MatAXPY(AA,1.0,mat,DIFFERENT_NONZERO_PATTERN)); 7500 } 7501 PetscCall(MatAIJGetLocalMat(AA,&A)); 7502 PetscCall(MatGetRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ia,&ja,&done)); 7503 PetscCheck(done,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Unable to get IJ structure from matrix"); 7504 7505 PetscCall(MatGetLocalSize(mat,&n,NULL)); 7506 PetscCall(PetscObjectGetNewTag((PetscObject)mat,&tag)); 7507 PetscCall(PetscObjectGetComm((PetscObject)mat,&comm)); 7508 PetscCallMPI(MPI_Comm_size(comm,&size)); 7509 PetscCallMPI(MPI_Comm_rank(comm,&rank)); 7510 7511 PetscCall(PetscMalloc2(n,&sizes,n,&starts)); 7512 7513 if (rank > 0) { 7514 PetscCallMPI(MPI_Recv(&env,1,MPIU_INT,rank-1,tag,comm,&status)); 7515 PetscCallMPI(MPI_Recv(&tbs,1,MPIU_INT,rank-1,tag,comm,&status)); 7516 } 7517 PetscCall(MatGetOwnershipRange(mat,&rstart,NULL)); 7518 for (i=0; i<n; i++) { 7519 env = PetscMax(env,ja[ia[i+1]-1]); 7520 II = rstart + i; 7521 if (env == II) { 7522 starts[lblocks] = tbs; 7523 sizes[lblocks++] = 1 + II - tbs; 7524 tbs = 1 + II; 7525 } 7526 } 7527 if (rank < size-1) { 7528 PetscCallMPI(MPI_Send(&env,1,MPIU_INT,rank+1,tag,comm)); 7529 PetscCallMPI(MPI_Send(&tbs,1,MPIU_INT,rank+1,tag,comm)); 7530 } 7531 7532 PetscCall(MatRestoreRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ia,&ja,&done)); 7533 if (!set || !flag) { 7534 PetscCall(MatDestroy(&AA)); 7535 } 7536 PetscCall(MatDestroy(&A)); 7537 7538 PetscCall(PetscNew(&edata)); 7539 PetscCall(MatGetNonzeroState(mat,&edata->nonzerostate)); 7540 edata->n = lblocks; 7541 /* create IS needed for extracting blocks from the original matrix */ 7542 PetscCall(PetscMalloc1(lblocks,&edata->is)); 7543 for (PetscInt i=0; i<lblocks; i++) { 7544 PetscCall(ISCreateStride(PETSC_COMM_SELF,sizes[i],starts[i],1,&edata->is[i])); 7545 } 7546 7547 /* Create the resulting inverse matrix structure with preallocation information */ 7548 PetscCall(MatCreate(PetscObjectComm((PetscObject)mat),&edata->C)); 7549 PetscCall(MatSetSizes(edata->C,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N)); 7550 PetscCall(MatSetBlockSizesFromMats(edata->C,mat,mat)); 7551 PetscCall(MatSetType(edata->C,MATAIJ)); 7552 7553 /* Communicate the start and end of each row, from each block to the correct rank */ 7554 /* TODO: Use PetscSF instead of VecScatter */ 7555 for (PetscInt i=0; i<lblocks; i++) ln += sizes[i]; 7556 PetscCall(VecCreateSeq(PETSC_COMM_SELF,2*ln,&seq)); 7557 PetscCall(VecGetArrayWrite(seq,&seqv)); 7558 for (PetscInt i=0; i<lblocks; i++) { 7559 for (PetscInt j=0; j<sizes[i]; j++) { 7560 seqv[cnt] = starts[i]; 7561 seqv[cnt+1] = starts[i] + sizes[i]; 7562 cnt += 2; 7563 } 7564 } 7565 PetscCall(VecRestoreArrayWrite(seq,&seqv)); 7566 PetscCallMPI(MPI_Scan(&cnt,&sc,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat))); 7567 sc -= cnt; 7568 PetscCall(VecCreateMPI(PetscObjectComm((PetscObject)mat),2*mat->rmap->n,2*mat->rmap->N,&par)); 7569 PetscCall(ISCreateStride(PETSC_COMM_SELF,cnt,sc,1,&isglobal)); 7570 PetscCall(VecScatterCreate(seq, NULL ,par, isglobal,&scatter)); 7571 PetscCall(ISDestroy(&isglobal)); 7572 PetscCall(VecScatterBegin(scatter,seq,par,INSERT_VALUES,SCATTER_FORWARD)); 7573 PetscCall(VecScatterEnd(scatter,seq,par,INSERT_VALUES,SCATTER_FORWARD)); 7574 PetscCall(VecScatterDestroy(&scatter)); 7575 PetscCall(VecDestroy(&seq)); 7576 PetscCall(MatGetOwnershipRangeColumn(mat,&cstart,&cend)); 7577 PetscCall(PetscMalloc2(mat->rmap->n,&diag,mat->rmap->n,&odiag)); 7578 PetscCall(VecGetArrayRead(par,&parv)); 7579 cnt = 0; 7580 PetscCall(MatGetSize(mat,NULL,&n)); 7581 for (PetscInt i=0; i<mat->rmap->n; i++) { 7582 PetscInt start,end,d = 0,od = 0; 7583 7584 start = (PetscInt)PetscRealPart(parv[cnt]); 7585 end = (PetscInt)PetscRealPart(parv[cnt+1]); 7586 cnt += 2; 7587 7588 if (start < cstart) {od += cstart - start + n - cend; d += cend - cstart;} 7589 else if (start < cend) {od += n - cend; d += cend - start;} 7590 else od += n - start; 7591 if (end <= cstart) {od -= cstart - end + n - cend; d -= cend - cstart;} 7592 else if (end < cend) {od -= n - cend; d -= cend - end;} 7593 else od -= n - end; 7594 7595 odiag[i] = od; 7596 diag[i] = d; 7597 } 7598 PetscCall(VecRestoreArrayRead(par,&parv)); 7599 PetscCall(VecDestroy(&par)); 7600 PetscCall(MatXAIJSetPreallocation(edata->C,mat->rmap->bs,diag,odiag,NULL,NULL)); 7601 PetscCall(PetscFree2(diag,odiag)); 7602 PetscCall(PetscFree2(sizes,starts)); 7603 7604 PetscCall(PetscContainerCreate(PETSC_COMM_SELF,&container)); 7605 PetscCall(PetscContainerSetPointer(container,edata)); 7606 PetscCall(PetscContainerSetUserDestroy(container,(PetscErrorCode (*)(void*))EnvelopeDataDestroy)); 7607 PetscCall(PetscObjectCompose((PetscObject)mat,"EnvelopeData",(PetscObject)container)); 7608 PetscCall(PetscObjectDereference((PetscObject)container)); 7609 PetscFunctionReturn(0); 7610 } 7611 7612 /*@ 7613 MatInvertVariableBlockEnvelope - set matrix C to be the inverted block diagonal of matrix A 7614 7615 Collective on Mat 7616 7617 Input Parameters: 7618 . A - the matrix 7619 7620 Output Parameters: 7621 . C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set. 7622 7623 Notes: 7624 For efficiency the matrix A should have all the nonzero entries clustered in smallish blocks along the diagonal. 7625 7626 Level: advanced 7627 7628 .seealso: MatInvertBlockDiagonal(), MatComputeBlockDiagonal() 7629 @*/ 7630 PetscErrorCode MatInvertVariableBlockEnvelope(Mat A,MatReuse reuse, Mat *C) 7631 { 7632 PetscContainer container; 7633 EnvelopeData *edata; 7634 PetscObjectState nonzerostate; 7635 7636 PetscFunctionBegin; 7637 PetscCall(PetscObjectQuery((PetscObject)A,"EnvelopeData",(PetscObject*)&container)); 7638 if (!container) { 7639 PetscCall(MatComputeVariableBlockEnvelope(A)); 7640 PetscCall(PetscObjectQuery((PetscObject)A,"EnvelopeData",(PetscObject*)&container)); 7641 } 7642 PetscCall(PetscContainerGetPointer(container,(void**)&edata)); 7643 PetscCall(MatGetNonzeroState(A,&nonzerostate)); 7644 PetscCheck(nonzerostate <= edata->nonzerostate,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Cannot handle changes to matrix nonzero structure"); 7645 PetscCheck(reuse != MAT_REUSE_MATRIX || *C == edata->C,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C matrix must be the same as previously output"); 7646 7647 PetscCall(MatCreateSubMatrices(A,edata->n,edata->is,edata->is,MAT_INITIAL_MATRIX,&edata->mat)); 7648 *C = edata->C; 7649 7650 for (PetscInt i=0; i<edata->n; i++) { 7651 Mat D; 7652 PetscScalar *dvalues; 7653 7654 PetscCall(MatConvert(edata->mat[i], MATSEQDENSE,MAT_INITIAL_MATRIX,&D)); 7655 PetscCall(MatSetOption(*C,MAT_ROW_ORIENTED,PETSC_FALSE)); 7656 PetscCall(MatSeqDenseInvert(D)); 7657 PetscCall(MatDenseGetArray(D,&dvalues)); 7658 PetscCall(MatSetValuesIS(*C,edata->is[i],edata->is[i],dvalues,INSERT_VALUES)); 7659 PetscCall(MatDestroy(&D)); 7660 } 7661 PetscCall(MatDestroySubMatrices(edata->n,&edata->mat)); 7662 PetscCall(MatAssemblyBegin(*C,MAT_FINAL_ASSEMBLY)); 7663 PetscCall(MatAssemblyEnd(*C,MAT_FINAL_ASSEMBLY)); 7664 PetscFunctionReturn(0); 7665 } 7666 7667 /*@ 7668 MatSetVariableBlockSizes - Sets diagonal point-blocks of the matrix that need not be of the same size 7669 7670 Logically Collective on Mat 7671 7672 Input Parameters: 7673 + mat - the matrix 7674 . nblocks - the number of blocks on this process, each block can only exist on a single process 7675 - bsizes - the block sizes 7676 7677 Notes: 7678 Currently used by PCVPBJACOBI for AIJ matrices 7679 7680 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. 7681 7682 Level: intermediate 7683 7684 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`, `MatGetBlockSizes()`, `MatGetVariableBlockSizes()`, `MatComputeVariableBlockEnvelope()`, `PCVPBJACOBI` 7685 @*/ 7686 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes) 7687 { 7688 PetscInt i,ncnt = 0, nlocal; 7689 7690 PetscFunctionBegin; 7691 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7692 PetscCheck(nblocks >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero"); 7693 PetscCall(MatGetLocalSize(mat,&nlocal,NULL)); 7694 for (i=0; i<nblocks; i++) ncnt += bsizes[i]; 7695 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); 7696 PetscCall(PetscFree(mat->bsizes)); 7697 mat->nblocks = nblocks; 7698 PetscCall(PetscMalloc1(nblocks,&mat->bsizes)); 7699 PetscCall(PetscArraycpy(mat->bsizes,bsizes,nblocks)); 7700 PetscFunctionReturn(0); 7701 } 7702 7703 /*@C 7704 MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size 7705 7706 Logically Collective on Mat 7707 7708 Input Parameter: 7709 . mat - the matrix 7710 7711 Output Parameters: 7712 + nblocks - the number of blocks on this process 7713 - bsizes - the block sizes 7714 7715 Notes: Currently not supported from Fortran 7716 7717 Level: intermediate 7718 7719 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`, `MatGetBlockSizes()`, `MatSetVariableBlockSizes()`, `MatComputeVariableBlockEnvelope()` 7720 @*/ 7721 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes) 7722 { 7723 PetscFunctionBegin; 7724 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7725 *nblocks = mat->nblocks; 7726 *bsizes = mat->bsizes; 7727 PetscFunctionReturn(0); 7728 } 7729 7730 /*@ 7731 MatSetBlockSizes - Sets the matrix block row and column sizes. 7732 7733 Logically Collective on Mat 7734 7735 Input Parameters: 7736 + mat - the matrix 7737 . rbs - row block size 7738 - cbs - column block size 7739 7740 Notes: 7741 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7742 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7743 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7744 7745 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes 7746 are compatible with the matrix local sizes. 7747 7748 The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs(). 7749 7750 Level: intermediate 7751 7752 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSize()`, `MatGetBlockSizes()` 7753 @*/ 7754 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs) 7755 { 7756 PetscFunctionBegin; 7757 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7758 PetscValidLogicalCollectiveInt(mat,rbs,2); 7759 PetscValidLogicalCollectiveInt(mat,cbs,3); 7760 if (mat->ops->setblocksizes) PetscCall((*mat->ops->setblocksizes)(mat,rbs,cbs)); 7761 if (mat->rmap->refcnt) { 7762 ISLocalToGlobalMapping l2g = NULL; 7763 PetscLayout nmap = NULL; 7764 7765 PetscCall(PetscLayoutDuplicate(mat->rmap,&nmap)); 7766 if (mat->rmap->mapping) { 7767 PetscCall(ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g)); 7768 } 7769 PetscCall(PetscLayoutDestroy(&mat->rmap)); 7770 mat->rmap = nmap; 7771 mat->rmap->mapping = l2g; 7772 } 7773 if (mat->cmap->refcnt) { 7774 ISLocalToGlobalMapping l2g = NULL; 7775 PetscLayout nmap = NULL; 7776 7777 PetscCall(PetscLayoutDuplicate(mat->cmap,&nmap)); 7778 if (mat->cmap->mapping) { 7779 PetscCall(ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g)); 7780 } 7781 PetscCall(PetscLayoutDestroy(&mat->cmap)); 7782 mat->cmap = nmap; 7783 mat->cmap->mapping = l2g; 7784 } 7785 PetscCall(PetscLayoutSetBlockSize(mat->rmap,rbs)); 7786 PetscCall(PetscLayoutSetBlockSize(mat->cmap,cbs)); 7787 PetscFunctionReturn(0); 7788 } 7789 7790 /*@ 7791 MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices 7792 7793 Logically Collective on Mat 7794 7795 Input Parameters: 7796 + mat - the matrix 7797 . fromRow - matrix from which to copy row block size 7798 - fromCol - matrix from which to copy column block size (can be same as fromRow) 7799 7800 Level: developer 7801 7802 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()` 7803 @*/ 7804 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol) 7805 { 7806 PetscFunctionBegin; 7807 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7808 PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2); 7809 PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3); 7810 if (fromRow->rmap->bs > 0) PetscCall(PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs)); 7811 if (fromCol->cmap->bs > 0) PetscCall(PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs)); 7812 PetscFunctionReturn(0); 7813 } 7814 7815 /*@ 7816 MatResidual - Default routine to calculate the residual. 7817 7818 Collective on Mat 7819 7820 Input Parameters: 7821 + mat - the matrix 7822 . b - the right-hand-side 7823 - x - the approximate solution 7824 7825 Output Parameter: 7826 . r - location to store the residual 7827 7828 Level: developer 7829 7830 .seealso: `PCMGSetResidual()` 7831 @*/ 7832 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r) 7833 { 7834 PetscFunctionBegin; 7835 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7836 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 7837 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 7838 PetscValidHeaderSpecific(r,VEC_CLASSID,4); 7839 PetscValidType(mat,1); 7840 MatCheckPreallocated(mat,1); 7841 PetscCall(PetscLogEventBegin(MAT_Residual,mat,0,0,0)); 7842 if (!mat->ops->residual) { 7843 PetscCall(MatMult(mat,x,r)); 7844 PetscCall(VecAYPX(r,-1.0,b)); 7845 } else { 7846 PetscCall((*mat->ops->residual)(mat,b,x,r)); 7847 } 7848 PetscCall(PetscLogEventEnd(MAT_Residual,mat,0,0,0)); 7849 PetscFunctionReturn(0); 7850 } 7851 7852 /*@C 7853 MatGetRowIJ - Returns the compressed row storage i and j indices for the local rows of a sparse matrix 7854 7855 Collective on Mat 7856 7857 Input Parameters: 7858 + mat - the matrix 7859 . shift - 0 or 1 indicating we want the indices starting at 0 or 1 7860 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized 7861 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7862 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7863 always used. 7864 7865 Output Parameters: 7866 + n - number of local rows in the (possibly compressed) matrix 7867 . ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix 7868 . ja - the column indices 7869 - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers 7870 are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set 7871 7872 Level: developer 7873 7874 Notes: 7875 You CANNOT change any of the ia[] or ja[] values. 7876 7877 Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values. 7878 7879 Fortran Notes: 7880 In Fortran use 7881 $ 7882 $ PetscInt ia(1), ja(1) 7883 $ PetscOffset iia, jja 7884 $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr) 7885 $ ! Access the ith and jth entries via ia(iia + i) and ja(jja + j) 7886 7887 or 7888 $ 7889 $ PetscInt, pointer :: ia(:),ja(:) 7890 $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr) 7891 $ ! Access the ith and jth entries via ia(i) and ja(j) 7892 7893 .seealso: `MatGetColumnIJ()`, `MatRestoreRowIJ()`, `MatSeqAIJGetArray()` 7894 @*/ 7895 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7896 { 7897 PetscFunctionBegin; 7898 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7899 PetscValidType(mat,1); 7900 if (n) PetscValidIntPointer(n,5); 7901 if (ia) PetscValidPointer(ia,6); 7902 if (ja) PetscValidPointer(ja,7); 7903 if (done) PetscValidBoolPointer(done,8); 7904 MatCheckPreallocated(mat,1); 7905 if (!mat->ops->getrowij && done) *done = PETSC_FALSE; 7906 else { 7907 if (done) *done = PETSC_TRUE; 7908 PetscCall(PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0)); 7909 PetscCall((*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done)); 7910 PetscCall(PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0)); 7911 } 7912 PetscFunctionReturn(0); 7913 } 7914 7915 /*@C 7916 MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices. 7917 7918 Collective on Mat 7919 7920 Input Parameters: 7921 + mat - the matrix 7922 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7923 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7924 symmetrized 7925 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7926 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7927 always used. 7928 . n - number of columns in the (possibly compressed) matrix 7929 . ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix 7930 - ja - the row indices 7931 7932 Output Parameters: 7933 . done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned 7934 7935 Level: developer 7936 7937 .seealso: `MatGetRowIJ()`, `MatRestoreColumnIJ()` 7938 @*/ 7939 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7940 { 7941 PetscFunctionBegin; 7942 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7943 PetscValidType(mat,1); 7944 PetscValidIntPointer(n,5); 7945 if (ia) PetscValidPointer(ia,6); 7946 if (ja) PetscValidPointer(ja,7); 7947 PetscValidBoolPointer(done,8); 7948 MatCheckPreallocated(mat,1); 7949 if (!mat->ops->getcolumnij) *done = PETSC_FALSE; 7950 else { 7951 *done = PETSC_TRUE; 7952 PetscCall((*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done)); 7953 } 7954 PetscFunctionReturn(0); 7955 } 7956 7957 /*@C 7958 MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with 7959 MatGetRowIJ(). 7960 7961 Collective on Mat 7962 7963 Input Parameters: 7964 + mat - the matrix 7965 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7966 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7967 symmetrized 7968 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7969 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7970 always used. 7971 . n - size of (possibly compressed) matrix 7972 . ia - the row pointers 7973 - ja - the column indices 7974 7975 Output Parameters: 7976 . done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7977 7978 Note: 7979 This routine zeros out n, ia, and ja. This is to prevent accidental 7980 us of the array after it has been restored. If you pass NULL, it will 7981 not zero the pointers. Use of ia or ja after MatRestoreRowIJ() is invalid. 7982 7983 Level: developer 7984 7985 .seealso: `MatGetRowIJ()`, `MatRestoreColumnIJ()` 7986 @*/ 7987 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7988 { 7989 PetscFunctionBegin; 7990 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7991 PetscValidType(mat,1); 7992 if (ia) PetscValidPointer(ia,6); 7993 if (ja) PetscValidPointer(ja,7); 7994 if (done) PetscValidBoolPointer(done,8); 7995 MatCheckPreallocated(mat,1); 7996 7997 if (!mat->ops->restorerowij && done) *done = PETSC_FALSE; 7998 else { 7999 if (done) *done = PETSC_TRUE; 8000 PetscCall((*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done)); 8001 if (n) *n = 0; 8002 if (ia) *ia = NULL; 8003 if (ja) *ja = NULL; 8004 } 8005 PetscFunctionReturn(0); 8006 } 8007 8008 /*@C 8009 MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with 8010 MatGetColumnIJ(). 8011 8012 Collective on Mat 8013 8014 Input Parameters: 8015 + mat - the matrix 8016 . shift - 1 or zero indicating we want the indices starting at 0 or 1 8017 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 8018 symmetrized 8019 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 8020 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 8021 always used. 8022 8023 Output Parameters: 8024 + n - size of (possibly compressed) matrix 8025 . ia - the column pointers 8026 . ja - the row indices 8027 - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 8028 8029 Level: developer 8030 8031 .seealso: `MatGetColumnIJ()`, `MatRestoreRowIJ()` 8032 @*/ 8033 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 8034 { 8035 PetscFunctionBegin; 8036 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8037 PetscValidType(mat,1); 8038 if (ia) PetscValidPointer(ia,6); 8039 if (ja) PetscValidPointer(ja,7); 8040 PetscValidBoolPointer(done,8); 8041 MatCheckPreallocated(mat,1); 8042 8043 if (!mat->ops->restorecolumnij) *done = PETSC_FALSE; 8044 else { 8045 *done = PETSC_TRUE; 8046 PetscCall((*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done)); 8047 if (n) *n = 0; 8048 if (ia) *ia = NULL; 8049 if (ja) *ja = NULL; 8050 } 8051 PetscFunctionReturn(0); 8052 } 8053 8054 /*@C 8055 MatColoringPatch -Used inside matrix coloring routines that 8056 use MatGetRowIJ() and/or MatGetColumnIJ(). 8057 8058 Collective on Mat 8059 8060 Input Parameters: 8061 + mat - the matrix 8062 . ncolors - max color value 8063 . n - number of entries in colorarray 8064 - colorarray - array indicating color for each column 8065 8066 Output Parameters: 8067 . iscoloring - coloring generated using colorarray information 8068 8069 Level: developer 8070 8071 .seealso: `MatGetRowIJ()`, `MatGetColumnIJ()` 8072 8073 @*/ 8074 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring) 8075 { 8076 PetscFunctionBegin; 8077 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8078 PetscValidType(mat,1); 8079 PetscValidIntPointer(colorarray,4); 8080 PetscValidPointer(iscoloring,5); 8081 MatCheckPreallocated(mat,1); 8082 8083 if (!mat->ops->coloringpatch) { 8084 PetscCall(ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring)); 8085 } else { 8086 PetscCall((*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring)); 8087 } 8088 PetscFunctionReturn(0); 8089 } 8090 8091 /*@ 8092 MatSetUnfactored - Resets a factored matrix to be treated as unfactored. 8093 8094 Logically Collective on Mat 8095 8096 Input Parameter: 8097 . mat - the factored matrix to be reset 8098 8099 Notes: 8100 This routine should be used only with factored matrices formed by in-place 8101 factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE 8102 format). This option can save memory, for example, when solving nonlinear 8103 systems with a matrix-free Newton-Krylov method and a matrix-based, in-place 8104 ILU(0) preconditioner. 8105 8106 Note that one can specify in-place ILU(0) factorization by calling 8107 .vb 8108 PCType(pc,PCILU); 8109 PCFactorSeUseInPlace(pc); 8110 .ve 8111 or by using the options -pc_type ilu -pc_factor_in_place 8112 8113 In-place factorization ILU(0) can also be used as a local 8114 solver for the blocks within the block Jacobi or additive Schwarz 8115 methods (runtime option: -sub_pc_factor_in_place). See Users-Manual: ch_pc 8116 for details on setting local solver options. 8117 8118 Most users should employ the simplified KSP interface for linear solvers 8119 instead of working directly with matrix algebra routines such as this. 8120 See, e.g., KSPCreate(). 8121 8122 Level: developer 8123 8124 .seealso: `PCFactorSetUseInPlace()`, `PCFactorGetUseInPlace()` 8125 8126 @*/ 8127 PetscErrorCode MatSetUnfactored(Mat mat) 8128 { 8129 PetscFunctionBegin; 8130 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8131 PetscValidType(mat,1); 8132 MatCheckPreallocated(mat,1); 8133 mat->factortype = MAT_FACTOR_NONE; 8134 if (!mat->ops->setunfactored) PetscFunctionReturn(0); 8135 PetscCall((*mat->ops->setunfactored)(mat)); 8136 PetscFunctionReturn(0); 8137 } 8138 8139 /*MC 8140 MatDenseGetArrayF90 - Accesses a matrix array from Fortran90. 8141 8142 Synopsis: 8143 MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 8144 8145 Not collective 8146 8147 Input Parameter: 8148 . x - matrix 8149 8150 Output Parameters: 8151 + xx_v - the Fortran90 pointer to the array 8152 - ierr - error code 8153 8154 Example of Usage: 8155 .vb 8156 PetscScalar, pointer xx_v(:,:) 8157 .... 8158 call MatDenseGetArrayF90(x,xx_v,ierr) 8159 a = xx_v(3) 8160 call MatDenseRestoreArrayF90(x,xx_v,ierr) 8161 .ve 8162 8163 Level: advanced 8164 8165 .seealso: `MatDenseRestoreArrayF90()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatSeqAIJGetArrayF90()` 8166 8167 M*/ 8168 8169 /*MC 8170 MatDenseRestoreArrayF90 - Restores a matrix array that has been 8171 accessed with MatDenseGetArrayF90(). 8172 8173 Synopsis: 8174 MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 8175 8176 Not collective 8177 8178 Input Parameters: 8179 + x - matrix 8180 - xx_v - the Fortran90 pointer to the array 8181 8182 Output Parameter: 8183 . ierr - error code 8184 8185 Example of Usage: 8186 .vb 8187 PetscScalar, pointer xx_v(:,:) 8188 .... 8189 call MatDenseGetArrayF90(x,xx_v,ierr) 8190 a = xx_v(3) 8191 call MatDenseRestoreArrayF90(x,xx_v,ierr) 8192 .ve 8193 8194 Level: advanced 8195 8196 .seealso: `MatDenseGetArrayF90()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatSeqAIJRestoreArrayF90()` 8197 8198 M*/ 8199 8200 /*MC 8201 MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90. 8202 8203 Synopsis: 8204 MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 8205 8206 Not collective 8207 8208 Input Parameter: 8209 . x - matrix 8210 8211 Output Parameters: 8212 + xx_v - the Fortran90 pointer to the array 8213 - ierr - error code 8214 8215 Example of Usage: 8216 .vb 8217 PetscScalar, pointer xx_v(:) 8218 .... 8219 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 8220 a = xx_v(3) 8221 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 8222 .ve 8223 8224 Level: advanced 8225 8226 .seealso: `MatSeqAIJRestoreArrayF90()`, `MatSeqAIJGetArray()`, `MatSeqAIJRestoreArray()`, `MatDenseGetArrayF90()` 8227 8228 M*/ 8229 8230 /*MC 8231 MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been 8232 accessed with MatSeqAIJGetArrayF90(). 8233 8234 Synopsis: 8235 MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 8236 8237 Not collective 8238 8239 Input Parameters: 8240 + x - matrix 8241 - xx_v - the Fortran90 pointer to the array 8242 8243 Output Parameter: 8244 . ierr - error code 8245 8246 Example of Usage: 8247 .vb 8248 PetscScalar, pointer xx_v(:) 8249 .... 8250 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 8251 a = xx_v(3) 8252 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 8253 .ve 8254 8255 Level: advanced 8256 8257 .seealso: `MatSeqAIJGetArrayF90()`, `MatSeqAIJGetArray()`, `MatSeqAIJRestoreArray()`, `MatDenseRestoreArrayF90()` 8258 8259 M*/ 8260 8261 /*@ 8262 MatCreateSubMatrix - Gets a single submatrix on the same number of processors 8263 as the original matrix. 8264 8265 Collective on Mat 8266 8267 Input Parameters: 8268 + mat - the original matrix 8269 . isrow - parallel IS containing the rows this processor should obtain 8270 . 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. 8271 - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 8272 8273 Output Parameter: 8274 . newmat - the new submatrix, of the same type as the old 8275 8276 Level: advanced 8277 8278 Notes: 8279 The submatrix will be able to be multiplied with vectors using the same layout as iscol. 8280 8281 Some matrix types place restrictions on the row and column indices, such 8282 as that they be sorted or that they be equal to each other. 8283 8284 The index sets may not have duplicate entries. 8285 8286 The first time this is called you should use a cll of MAT_INITIAL_MATRIX, 8287 the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls 8288 to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX 8289 will reuse the matrix generated the first time. You should call MatDestroy() on newmat when 8290 you are finished using it. 8291 8292 The communicator of the newly obtained matrix is ALWAYS the same as the communicator of 8293 the input matrix. 8294 8295 If iscol is NULL then all columns are obtained (not supported in Fortran). 8296 8297 Example usage: 8298 Consider the following 8x8 matrix with 34 non-zero values, that is 8299 assembled across 3 processors. Let's assume that proc0 owns 3 rows, 8300 proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown 8301 as follows: 8302 8303 .vb 8304 1 2 0 | 0 3 0 | 0 4 8305 Proc0 0 5 6 | 7 0 0 | 8 0 8306 9 0 10 | 11 0 0 | 12 0 8307 ------------------------------------- 8308 13 0 14 | 15 16 17 | 0 0 8309 Proc1 0 18 0 | 19 20 21 | 0 0 8310 0 0 0 | 22 23 0 | 24 0 8311 ------------------------------------- 8312 Proc2 25 26 27 | 0 0 28 | 29 0 8313 30 0 0 | 31 32 33 | 0 34 8314 .ve 8315 8316 Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is 8317 8318 .vb 8319 2 0 | 0 3 0 | 0 8320 Proc0 5 6 | 7 0 0 | 8 8321 ------------------------------- 8322 Proc1 18 0 | 19 20 21 | 0 8323 ------------------------------- 8324 Proc2 26 27 | 0 0 28 | 29 8325 0 0 | 31 32 33 | 0 8326 .ve 8327 8328 .seealso: `MatCreateSubMatrices()`, `MatCreateSubMatricesMPI()`, `MatCreateSubMatrixVirtual()`, `MatSubMatrixVirtualUpdate()` 8329 @*/ 8330 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat) 8331 { 8332 PetscMPIInt size; 8333 Mat *local; 8334 IS iscoltmp; 8335 PetscBool flg; 8336 8337 PetscFunctionBegin; 8338 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8339 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 8340 if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 8341 PetscValidPointer(newmat,5); 8342 if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5); 8343 PetscValidType(mat,1); 8344 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8345 PetscCheck(cll != MAT_IGNORE_MATRIX,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX"); 8346 8347 MatCheckPreallocated(mat,1); 8348 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 8349 8350 if (!iscol || isrow == iscol) { 8351 PetscBool stride; 8352 PetscMPIInt grabentirematrix = 0,grab; 8353 PetscCall(PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride)); 8354 if (stride) { 8355 PetscInt first,step,n,rstart,rend; 8356 PetscCall(ISStrideGetInfo(isrow,&first,&step)); 8357 if (step == 1) { 8358 PetscCall(MatGetOwnershipRange(mat,&rstart,&rend)); 8359 if (rstart == first) { 8360 PetscCall(ISGetLocalSize(isrow,&n)); 8361 if (n == rend-rstart) { 8362 grabentirematrix = 1; 8363 } 8364 } 8365 } 8366 } 8367 PetscCall(MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat))); 8368 if (grab) { 8369 PetscCall(PetscInfo(mat,"Getting entire matrix as submatrix\n")); 8370 if (cll == MAT_INITIAL_MATRIX) { 8371 *newmat = mat; 8372 PetscCall(PetscObjectReference((PetscObject)mat)); 8373 } 8374 PetscFunctionReturn(0); 8375 } 8376 } 8377 8378 if (!iscol) { 8379 PetscCall(ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp)); 8380 } else { 8381 iscoltmp = iscol; 8382 } 8383 8384 /* if original matrix is on just one processor then use submatrix generated */ 8385 if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) { 8386 PetscCall(MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat)); 8387 goto setproperties; 8388 } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) { 8389 PetscCall(MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local)); 8390 *newmat = *local; 8391 PetscCall(PetscFree(local)); 8392 goto setproperties; 8393 } else if (!mat->ops->createsubmatrix) { 8394 /* Create a new matrix type that implements the operation using the full matrix */ 8395 PetscCall(PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0)); 8396 switch (cll) { 8397 case MAT_INITIAL_MATRIX: 8398 PetscCall(MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat)); 8399 break; 8400 case MAT_REUSE_MATRIX: 8401 PetscCall(MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp)); 8402 break; 8403 default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX"); 8404 } 8405 PetscCall(PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0)); 8406 goto setproperties; 8407 } 8408 8409 PetscCheck(mat->ops->createsubmatrix,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8410 PetscCall(PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0)); 8411 PetscCall((*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat)); 8412 PetscCall(PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0)); 8413 8414 setproperties: 8415 PetscCall(ISEqualUnsorted(isrow,iscoltmp,&flg)); 8416 if (flg) PetscCall(MatPropagateSymmetryOptions(mat,*newmat)); 8417 if (!iscol) PetscCall(ISDestroy(&iscoltmp)); 8418 if (*newmat && cll == MAT_INITIAL_MATRIX) PetscCall(PetscObjectStateIncrease((PetscObject)*newmat)); 8419 PetscFunctionReturn(0); 8420 } 8421 8422 /*@ 8423 MatPropagateSymmetryOptions - Propagates symmetry options set on a matrix to another matrix 8424 8425 Not Collective 8426 8427 Input Parameters: 8428 + A - the matrix we wish to propagate options from 8429 - B - the matrix we wish to propagate options to 8430 8431 Level: beginner 8432 8433 Notes: 8434 Propagates the options associated to `MAT_SYMMETRY_ETERNAL`, `MAT_STRUCTURALLY_SYMMETRIC`, `MAT_HERMITIAN`, `MAT_SPD`, `MAT_SYMMETRIC`, and `MAT_STRUCTURAL_SYMMETRY_ETERNAL` 8435 8436 .seealso: `MatSetOption()`, `MatIsSymmetricKnown()`, `MatIsSPDKnown()`, `MatIsHermitianKnown()`, MatIsStructurallySymmetricKnown()` 8437 @*/ 8438 PetscErrorCode MatPropagateSymmetryOptions(Mat A, Mat B) 8439 { 8440 PetscFunctionBegin; 8441 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8442 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 8443 B->symmetry_eternal = A->symmetry_eternal; 8444 B->structural_symmetry_eternal = A->structural_symmetry_eternal; 8445 B->symmetric = A->symmetric; 8446 B->structurally_symmetric = A->structurally_symmetric; 8447 B->spd = A->spd; 8448 B->hermitian = A->hermitian; 8449 PetscFunctionReturn(0); 8450 } 8451 8452 /*@ 8453 MatStashSetInitialSize - sets the sizes of the matrix stash, that is 8454 used during the assembly process to store values that belong to 8455 other processors. 8456 8457 Not Collective 8458 8459 Input Parameters: 8460 + mat - the matrix 8461 . size - the initial size of the stash. 8462 - bsize - the initial size of the block-stash(if used). 8463 8464 Options Database Keys: 8465 + -matstash_initial_size <size> or <size0,size1,...sizep-1> 8466 - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1> 8467 8468 Level: intermediate 8469 8470 Notes: 8471 The block-stash is used for values set with MatSetValuesBlocked() while 8472 the stash is used for values set with MatSetValues() 8473 8474 Run with the option -info and look for output of the form 8475 MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs. 8476 to determine the appropriate value, MM, to use for size and 8477 MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs. 8478 to determine the value, BMM to use for bsize 8479 8480 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `Mat`, `MatStashGetInfo()` 8481 8482 @*/ 8483 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize) 8484 { 8485 PetscFunctionBegin; 8486 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8487 PetscValidType(mat,1); 8488 PetscCall(MatStashSetInitialSize_Private(&mat->stash,size)); 8489 PetscCall(MatStashSetInitialSize_Private(&mat->bstash,bsize)); 8490 PetscFunctionReturn(0); 8491 } 8492 8493 /*@ 8494 MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 8495 the matrix 8496 8497 Neighbor-wise Collective on Mat 8498 8499 Input Parameters: 8500 + mat - the matrix 8501 . x,y - the vectors 8502 - w - where the result is stored 8503 8504 Level: intermediate 8505 8506 Notes: 8507 w may be the same vector as y. 8508 8509 This allows one to use either the restriction or interpolation (its transpose) 8510 matrix to do the interpolation 8511 8512 .seealso: `MatMultAdd()`, `MatMultTransposeAdd()`, `MatRestrict()` 8513 8514 @*/ 8515 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w) 8516 { 8517 PetscInt M,N,Ny; 8518 8519 PetscFunctionBegin; 8520 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8521 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8522 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8523 PetscValidHeaderSpecific(w,VEC_CLASSID,4); 8524 PetscCall(MatGetSize(A,&M,&N)); 8525 PetscCall(VecGetSize(y,&Ny)); 8526 if (M == Ny) { 8527 PetscCall(MatMultAdd(A,x,y,w)); 8528 } else { 8529 PetscCall(MatMultTransposeAdd(A,x,y,w)); 8530 } 8531 PetscFunctionReturn(0); 8532 } 8533 8534 /*@ 8535 MatInterpolate - y = A*x or A'*x depending on the shape of 8536 the matrix 8537 8538 Neighbor-wise Collective on Mat 8539 8540 Input Parameters: 8541 + mat - the matrix 8542 - x,y - the vectors 8543 8544 Level: intermediate 8545 8546 Notes: 8547 This allows one to use either the restriction or interpolation (its transpose) 8548 matrix to do the interpolation 8549 8550 .seealso: `MatMultAdd()`, `MatMultTransposeAdd()`, `MatRestrict()` 8551 8552 @*/ 8553 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y) 8554 { 8555 PetscInt M,N,Ny; 8556 8557 PetscFunctionBegin; 8558 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8559 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8560 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8561 PetscCall(MatGetSize(A,&M,&N)); 8562 PetscCall(VecGetSize(y,&Ny)); 8563 if (M == Ny) { 8564 PetscCall(MatMult(A,x,y)); 8565 } else { 8566 PetscCall(MatMultTranspose(A,x,y)); 8567 } 8568 PetscFunctionReturn(0); 8569 } 8570 8571 /*@ 8572 MatRestrict - y = A*x or A'*x 8573 8574 Neighbor-wise Collective on Mat 8575 8576 Input Parameters: 8577 + mat - the matrix 8578 - x,y - the vectors 8579 8580 Level: intermediate 8581 8582 Notes: 8583 This allows one to use either the restriction or interpolation (its transpose) 8584 matrix to do the restriction 8585 8586 .seealso: `MatMultAdd()`, `MatMultTransposeAdd()`, `MatInterpolate()` 8587 8588 @*/ 8589 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y) 8590 { 8591 PetscInt M,N,Ny; 8592 8593 PetscFunctionBegin; 8594 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8595 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8596 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8597 PetscCall(MatGetSize(A,&M,&N)); 8598 PetscCall(VecGetSize(y,&Ny)); 8599 if (M == Ny) { 8600 PetscCall(MatMult(A,x,y)); 8601 } else { 8602 PetscCall(MatMultTranspose(A,x,y)); 8603 } 8604 PetscFunctionReturn(0); 8605 } 8606 8607 /*@ 8608 MatMatInterpolateAdd - Y = W + A*X or W + A'*X 8609 8610 Neighbor-wise Collective on Mat 8611 8612 Input Parameters: 8613 + mat - the matrix 8614 - w, x - the input dense matrices 8615 8616 Output Parameters: 8617 . y - the output dense matrix 8618 8619 Level: intermediate 8620 8621 Notes: 8622 This allows one to use either the restriction or interpolation (its transpose) 8623 matrix to do the interpolation. y matrix can be reused if already created with the proper sizes, 8624 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8625 8626 .seealso: `MatInterpolateAdd()`, `MatMatInterpolate()`, `MatMatRestrict()` 8627 8628 @*/ 8629 PetscErrorCode MatMatInterpolateAdd(Mat A,Mat x,Mat w,Mat *y) 8630 { 8631 PetscInt M,N,Mx,Nx,Mo,My = 0,Ny = 0; 8632 PetscBool trans = PETSC_TRUE; 8633 MatReuse reuse = MAT_INITIAL_MATRIX; 8634 8635 PetscFunctionBegin; 8636 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8637 PetscValidHeaderSpecific(x,MAT_CLASSID,2); 8638 PetscValidType(x,2); 8639 if (w) PetscValidHeaderSpecific(w,MAT_CLASSID,3); 8640 if (*y) PetscValidHeaderSpecific(*y,MAT_CLASSID,4); 8641 PetscCall(MatGetSize(A,&M,&N)); 8642 PetscCall(MatGetSize(x,&Mx,&Nx)); 8643 if (N == Mx) trans = PETSC_FALSE; 8644 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); 8645 Mo = trans ? N : M; 8646 if (*y) { 8647 PetscCall(MatGetSize(*y,&My,&Ny)); 8648 if (Mo == My && Nx == Ny) { reuse = MAT_REUSE_MATRIX; } 8649 else { 8650 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); 8651 PetscCall(MatDestroy(y)); 8652 } 8653 } 8654 8655 if (w && *y == w) { /* this is to minimize changes in PCMG */ 8656 PetscBool flg; 8657 8658 PetscCall(PetscObjectQuery((PetscObject)*y,"__MatMatIntAdd_w",(PetscObject*)&w)); 8659 if (w) { 8660 PetscInt My,Ny,Mw,Nw; 8661 8662 PetscCall(PetscObjectTypeCompare((PetscObject)*y,((PetscObject)w)->type_name,&flg)); 8663 PetscCall(MatGetSize(*y,&My,&Ny)); 8664 PetscCall(MatGetSize(w,&Mw,&Nw)); 8665 if (!flg || My != Mw || Ny != Nw) w = NULL; 8666 } 8667 if (!w) { 8668 PetscCall(MatDuplicate(*y,MAT_COPY_VALUES,&w)); 8669 PetscCall(PetscObjectCompose((PetscObject)*y,"__MatMatIntAdd_w",(PetscObject)w)); 8670 PetscCall(PetscLogObjectParent((PetscObject)*y,(PetscObject)w)); 8671 PetscCall(PetscObjectDereference((PetscObject)w)); 8672 } else { 8673 PetscCall(MatCopy(*y,w,UNKNOWN_NONZERO_PATTERN)); 8674 } 8675 } 8676 if (!trans) { 8677 PetscCall(MatMatMult(A,x,reuse,PETSC_DEFAULT,y)); 8678 } else { 8679 PetscCall(MatTransposeMatMult(A,x,reuse,PETSC_DEFAULT,y)); 8680 } 8681 if (w) PetscCall(MatAXPY(*y,1.0,w,UNKNOWN_NONZERO_PATTERN)); 8682 PetscFunctionReturn(0); 8683 } 8684 8685 /*@ 8686 MatMatInterpolate - Y = A*X or A'*X 8687 8688 Neighbor-wise Collective on Mat 8689 8690 Input Parameters: 8691 + mat - the matrix 8692 - x - the input dense matrix 8693 8694 Output Parameters: 8695 . y - the output dense matrix 8696 8697 Level: intermediate 8698 8699 Notes: 8700 This allows one to use either the restriction or interpolation (its transpose) 8701 matrix to do the interpolation. y matrix can be reused if already created with the proper sizes, 8702 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8703 8704 .seealso: `MatInterpolate()`, `MatRestrict()`, `MatMatRestrict()` 8705 8706 @*/ 8707 PetscErrorCode MatMatInterpolate(Mat A,Mat x,Mat *y) 8708 { 8709 PetscFunctionBegin; 8710 PetscCall(MatMatInterpolateAdd(A,x,NULL,y)); 8711 PetscFunctionReturn(0); 8712 } 8713 8714 /*@ 8715 MatMatRestrict - Y = A*X or A'*X 8716 8717 Neighbor-wise Collective on Mat 8718 8719 Input Parameters: 8720 + mat - the matrix 8721 - x - the input dense matrix 8722 8723 Output Parameters: 8724 . y - the output dense matrix 8725 8726 Level: intermediate 8727 8728 Notes: 8729 This allows one to use either the restriction or interpolation (its transpose) 8730 matrix to do the restriction. y matrix can be reused if already created with the proper sizes, 8731 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8732 8733 .seealso: `MatRestrict()`, `MatInterpolate()`, `MatMatInterpolate()` 8734 @*/ 8735 PetscErrorCode MatMatRestrict(Mat A,Mat x,Mat *y) 8736 { 8737 PetscFunctionBegin; 8738 PetscCall(MatMatInterpolateAdd(A,x,NULL,y)); 8739 PetscFunctionReturn(0); 8740 } 8741 8742 /*@ 8743 MatGetNullSpace - retrieves the null space of a matrix. 8744 8745 Logically Collective on Mat 8746 8747 Input Parameters: 8748 + mat - the matrix 8749 - nullsp - the null space object 8750 8751 Level: developer 8752 8753 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatSetNullSpace()` 8754 @*/ 8755 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp) 8756 { 8757 PetscFunctionBegin; 8758 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8759 PetscValidPointer(nullsp,2); 8760 *nullsp = (mat->symmetric == PETSC_BOOL3_TRUE && !mat->nullsp) ? mat->transnullsp : mat->nullsp; 8761 PetscFunctionReturn(0); 8762 } 8763 8764 /*@ 8765 MatSetNullSpace - attaches a null space to a matrix. 8766 8767 Logically Collective on Mat 8768 8769 Input Parameters: 8770 + mat - the matrix 8771 - nullsp - the null space object 8772 8773 Level: advanced 8774 8775 Notes: 8776 This null space is used by the KSP linear solvers to solve singular systems. 8777 8778 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 8779 8780 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 8781 to zero but the linear system will still be solved in a least squares sense. 8782 8783 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8784 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). 8785 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 8786 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 8787 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). 8788 This \hat{b} can be obtained by calling MatNullSpaceRemove() with the null space of the transpose of the matrix. 8789 8790 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 8791 routine also automatically calls MatSetTransposeNullSpace(). 8792 8793 The user should call `MatNullSpaceDestroy()`. 8794 8795 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatGetNullSpace()`, `MatSetTransposeNullSpace()`, `MatGetTransposeNullSpace()`, `MatNullSpaceRemove()`, 8796 `KSPSetPCSide()` 8797 @*/ 8798 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp) 8799 { 8800 PetscFunctionBegin; 8801 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8802 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8803 if (nullsp) PetscCall(PetscObjectReference((PetscObject)nullsp)); 8804 PetscCall(MatNullSpaceDestroy(&mat->nullsp)); 8805 mat->nullsp = nullsp; 8806 if (mat->symmetric == PETSC_BOOL3_TRUE) { 8807 PetscCall(MatSetTransposeNullSpace(mat,nullsp)); 8808 } 8809 PetscFunctionReturn(0); 8810 } 8811 8812 /*@ 8813 MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix. 8814 8815 Logically Collective on Mat 8816 8817 Input Parameters: 8818 + mat - the matrix 8819 - nullsp - the null space object 8820 8821 Level: developer 8822 8823 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatSetTransposeNullSpace()`, `MatSetNullSpace()`, `MatGetNullSpace()` 8824 @*/ 8825 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp) 8826 { 8827 PetscFunctionBegin; 8828 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8829 PetscValidType(mat,1); 8830 PetscValidPointer(nullsp,2); 8831 *nullsp = (mat->symmetric == PETSC_BOOL3_TRUE && !mat->transnullsp) ? mat->nullsp : mat->transnullsp; 8832 PetscFunctionReturn(0); 8833 } 8834 8835 /*@ 8836 MatSetTransposeNullSpace - attaches the null space of a transpose of a matrix to the matrix 8837 8838 Logically Collective on Mat 8839 8840 Input Parameters: 8841 + mat - the matrix 8842 - nullsp - the null space object 8843 8844 Level: advanced 8845 8846 Notes: 8847 This allows solving singular linear systems defined by the transpose of the matrix using KSP solvers with left preconditioning. 8848 8849 See MatSetNullSpace() 8850 8851 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatGetNullSpace()`, `MatSetNullSpace()`, `MatGetTransposeNullSpace()`, `MatNullSpaceRemove()`, `KSPSetPCSide()` 8852 @*/ 8853 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp) 8854 { 8855 PetscFunctionBegin; 8856 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8857 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8858 if (nullsp) PetscCall(PetscObjectReference((PetscObject)nullsp)); 8859 PetscCall(MatNullSpaceDestroy(&mat->transnullsp)); 8860 mat->transnullsp = nullsp; 8861 PetscFunctionReturn(0); 8862 } 8863 8864 /*@ 8865 MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions 8866 This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix. 8867 8868 Logically Collective on Mat 8869 8870 Input Parameters: 8871 + mat - the matrix 8872 - nullsp - the null space object 8873 8874 Level: advanced 8875 8876 Notes: 8877 Overwrites any previous near null space that may have been attached 8878 8879 You can remove the null space by calling this routine with an nullsp of NULL 8880 8881 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNullSpace()`, `MatNullSpaceCreateRigidBody()`, `MatGetNearNullSpace()` 8882 @*/ 8883 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp) 8884 { 8885 PetscFunctionBegin; 8886 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8887 PetscValidType(mat,1); 8888 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8889 MatCheckPreallocated(mat,1); 8890 if (nullsp) PetscCall(PetscObjectReference((PetscObject)nullsp)); 8891 PetscCall(MatNullSpaceDestroy(&mat->nearnullsp)); 8892 mat->nearnullsp = nullsp; 8893 PetscFunctionReturn(0); 8894 } 8895 8896 /*@ 8897 MatGetNearNullSpace - Get null space attached with MatSetNearNullSpace() 8898 8899 Not Collective 8900 8901 Input Parameter: 8902 . mat - the matrix 8903 8904 Output Parameter: 8905 . nullsp - the null space object, NULL if not set 8906 8907 Level: developer 8908 8909 .seealso: `MatSetNearNullSpace()`, `MatGetNullSpace()`, `MatNullSpaceCreate()` 8910 @*/ 8911 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp) 8912 { 8913 PetscFunctionBegin; 8914 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8915 PetscValidType(mat,1); 8916 PetscValidPointer(nullsp,2); 8917 MatCheckPreallocated(mat,1); 8918 *nullsp = mat->nearnullsp; 8919 PetscFunctionReturn(0); 8920 } 8921 8922 /*@C 8923 MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix. 8924 8925 Collective on Mat 8926 8927 Input Parameters: 8928 + mat - the matrix 8929 . row - row/column permutation 8930 . fill - expected fill factor >= 1.0 8931 - level - level of fill, for ICC(k) 8932 8933 Notes: 8934 Probably really in-place only when level of fill is zero, otherwise allocates 8935 new space to store factored matrix and deletes previous memory. 8936 8937 Most users should employ the simplified KSP interface for linear solvers 8938 instead of working directly with matrix algebra routines such as this. 8939 See, e.g., KSPCreate(). 8940 8941 Level: developer 8942 8943 .seealso: `MatICCFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()` 8944 8945 Developer Note: fortran interface is not autogenerated as the f90 8946 interface definition cannot be generated correctly [due to MatFactorInfo] 8947 8948 @*/ 8949 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info) 8950 { 8951 PetscFunctionBegin; 8952 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8953 PetscValidType(mat,1); 8954 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 8955 PetscValidPointer(info,3); 8956 PetscCheck(mat->rmap->N == mat->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 8957 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8958 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8959 PetscCheck(mat->ops->iccfactor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8960 MatCheckPreallocated(mat,1); 8961 PetscCall((*mat->ops->iccfactor)(mat,row,info)); 8962 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 8963 PetscFunctionReturn(0); 8964 } 8965 8966 /*@ 8967 MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 8968 ghosted ones. 8969 8970 Not Collective 8971 8972 Input Parameters: 8973 + mat - the matrix 8974 - diag - the diagonal values, including ghost ones 8975 8976 Level: developer 8977 8978 Notes: 8979 Works only for MPIAIJ and MPIBAIJ matrices 8980 8981 .seealso: `MatDiagonalScale()` 8982 @*/ 8983 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag) 8984 { 8985 PetscMPIInt size; 8986 8987 PetscFunctionBegin; 8988 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8989 PetscValidHeaderSpecific(diag,VEC_CLASSID,2); 8990 PetscValidType(mat,1); 8991 8992 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled"); 8993 PetscCall(PetscLogEventBegin(MAT_Scale,mat,0,0,0)); 8994 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 8995 if (size == 1) { 8996 PetscInt n,m; 8997 PetscCall(VecGetSize(diag,&n)); 8998 PetscCall(MatGetSize(mat,NULL,&m)); 8999 if (m == n) { 9000 PetscCall(MatDiagonalScale(mat,NULL,diag)); 9001 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions"); 9002 } else { 9003 PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag)); 9004 } 9005 PetscCall(PetscLogEventEnd(MAT_Scale,mat,0,0,0)); 9006 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 9007 PetscFunctionReturn(0); 9008 } 9009 9010 /*@ 9011 MatGetInertia - Gets the inertia from a factored matrix 9012 9013 Collective on Mat 9014 9015 Input Parameter: 9016 . mat - the matrix 9017 9018 Output Parameters: 9019 + nneg - number of negative eigenvalues 9020 . nzero - number of zero eigenvalues 9021 - npos - number of positive eigenvalues 9022 9023 Level: advanced 9024 9025 Notes: 9026 Matrix must have been factored by MatCholeskyFactor() 9027 9028 @*/ 9029 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos) 9030 { 9031 PetscFunctionBegin; 9032 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9033 PetscValidType(mat,1); 9034 PetscCheck(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 9035 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled"); 9036 PetscCheck(mat->ops->getinertia,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 9037 PetscCall((*mat->ops->getinertia)(mat,nneg,nzero,npos)); 9038 PetscFunctionReturn(0); 9039 } 9040 9041 /* ----------------------------------------------------------------*/ 9042 /*@C 9043 MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors 9044 9045 Neighbor-wise Collective on Mats 9046 9047 Input Parameters: 9048 + mat - the factored matrix 9049 - b - the right-hand-side vectors 9050 9051 Output Parameter: 9052 . x - the result vectors 9053 9054 Notes: 9055 The vectors b and x cannot be the same. I.e., one cannot 9056 call MatSolves(A,x,x). 9057 9058 Notes: 9059 Most users should employ the simplified KSP interface for linear solvers 9060 instead of working directly with matrix algebra routines such as this. 9061 See, e.g., KSPCreate(). 9062 9063 Level: developer 9064 9065 .seealso: `MatSolveAdd()`, `MatSolveTranspose()`, `MatSolveTransposeAdd()`, `MatSolve()` 9066 @*/ 9067 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x) 9068 { 9069 PetscFunctionBegin; 9070 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9071 PetscValidType(mat,1); 9072 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 9073 PetscCheck(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 9074 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 9075 9076 PetscCheck(mat->ops->solves,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 9077 MatCheckPreallocated(mat,1); 9078 PetscCall(PetscLogEventBegin(MAT_Solves,mat,0,0,0)); 9079 PetscCall((*mat->ops->solves)(mat,b,x)); 9080 PetscCall(PetscLogEventEnd(MAT_Solves,mat,0,0,0)); 9081 PetscFunctionReturn(0); 9082 } 9083 9084 /*@ 9085 MatIsSymmetric - Test whether a matrix is symmetric 9086 9087 Collective on Mat 9088 9089 Input Parameters: 9090 + A - the matrix to test 9091 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose) 9092 9093 Output Parameters: 9094 . flg - the result 9095 9096 Notes: 9097 For real numbers MatIsSymmetric() and MatIsHermitian() return identical results 9098 9099 If the matrix does not yet know if it is symmetric or not this can be an expensive operation, also available `MatIsSymmetricKnown()` 9100 9101 Level: intermediate 9102 9103 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetricKnown()` 9104 @*/ 9105 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg) 9106 { 9107 PetscFunctionBegin; 9108 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9109 PetscValidBoolPointer(flg,3); 9110 9111 if (A->symmetric == PETSC_BOOL3_TRUE) *flg = PETSC_TRUE; 9112 else if (A->symmetric == PETSC_BOOL3_FALSE) *flg = PETSC_FALSE; 9113 else { 9114 if (!A->ops->issymmetric) { 9115 MatType mattype; 9116 PetscCall(MatGetType(A,&mattype)); 9117 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for symmetric",mattype); 9118 } 9119 PetscCall((*A->ops->issymmetric)(A,tol,flg)); 9120 if (!tol) PetscCall(MatSetOption(A,MAT_SYMMETRIC,*flg)); 9121 } 9122 PetscFunctionReturn(0); 9123 } 9124 9125 /*@ 9126 MatIsHermitian - Test whether a matrix is Hermitian 9127 9128 Collective on Mat 9129 9130 Input Parameters: 9131 + A - the matrix to test 9132 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian) 9133 9134 Output Parameters: 9135 . flg - the result 9136 9137 Level: intermediate 9138 9139 Notes: 9140 For real numbers MatIsSymmetric() and MatIsHermitian() return identical results 9141 9142 If the matrix does not yet know if it is hermitian or not this can be an expensive operation, also available `MatIsHermitianKnown()` 9143 9144 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitianKnown()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, 9145 `MatIsSymmetricKnown()`, `MatIsSymmetric()` 9146 @*/ 9147 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg) 9148 { 9149 PetscFunctionBegin; 9150 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9151 PetscValidBoolPointer(flg,3); 9152 9153 if (A->hermitian == PETSC_BOOL3_TRUE) *flg = PETSC_TRUE; 9154 else if (A->hermitian == PETSC_BOOL3_FALSE) *flg = PETSC_FALSE; 9155 else { 9156 if (!A->ops->ishermitian) { 9157 MatType mattype; 9158 PetscCall(MatGetType(A,&mattype)); 9159 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for hermitian",mattype); 9160 } 9161 PetscCall((*A->ops->ishermitian)(A,tol,flg)); 9162 if (!tol) PetscCall(MatSetOption(A,MAT_HERMITIAN,*flg)); 9163 } 9164 PetscFunctionReturn(0); 9165 } 9166 9167 /*@ 9168 MatIsSymmetricKnown - Checks if a matrix knows if it is symmetric or not and its symmetric state 9169 9170 Not Collective 9171 9172 Input Parameter: 9173 . A - the matrix to check 9174 9175 Output Parameters: 9176 + set - PETSC_TRUE if the matrix knows its symmetry state (this tells you if the next flag is valid) 9177 - flg - the result (only valid if set is PETSC_TRUE) 9178 9179 Level: advanced 9180 9181 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric() 9182 if you want it explicitly checked 9183 9184 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitianKnown()` 9185 @*/ 9186 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg) 9187 { 9188 PetscFunctionBegin; 9189 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9190 PetscValidBoolPointer(set,2); 9191 PetscValidBoolPointer(flg,3); 9192 if (A->symmetric != PETSC_BOOL3_UNKNOWN) { 9193 *set = PETSC_TRUE; 9194 *flg = PetscBool3ToBool(A->symmetric); 9195 } else { 9196 *set = PETSC_FALSE; 9197 } 9198 PetscFunctionReturn(0); 9199 } 9200 9201 /*@ 9202 MatIsSPDKnown - Checks if a matrix knows if it is symmetric positive definite or not and its symmetric positive definite state 9203 9204 Not Collective 9205 9206 Input Parameter: 9207 . A - the matrix to check 9208 9209 Output Parameters: 9210 + set - PETSC_TRUE if the matrix knows its symmetric positive definite state (this tells you if the next flag is valid) 9211 - flg - the result (only valid if set is PETSC_TRUE) 9212 9213 Level: advanced 9214 9215 Note: 9216 Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). 9217 9218 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitianKnown()` 9219 @*/ 9220 PetscErrorCode MatIsSPDKnown(Mat A,PetscBool *set,PetscBool *flg) 9221 { 9222 PetscFunctionBegin; 9223 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9224 PetscValidBoolPointer(set,2); 9225 PetscValidBoolPointer(flg,3); 9226 if (A->spd != PETSC_BOOL3_UNKNOWN) { 9227 *set = PETSC_TRUE; 9228 *flg = PetscBool3ToBool(A->spd); 9229 } else { 9230 *set = PETSC_FALSE; 9231 } 9232 PetscFunctionReturn(0); 9233 } 9234 9235 /*@ 9236 MatIsHermitianKnown - Checks if a matrix knows if it is Hermitian or not and its Hermitian state 9237 9238 Not Collective 9239 9240 Input Parameter: 9241 . A - the matrix to check 9242 9243 Output Parameters: 9244 + set - PETSC_TRUE if the matrix knows its Hermitian state (this tells you if the next flag is valid) 9245 - flg - the result (only valid if set is PETSC_TRUE) 9246 9247 Level: advanced 9248 9249 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian() 9250 if you want it explicitly checked 9251 9252 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()` 9253 @*/ 9254 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg) 9255 { 9256 PetscFunctionBegin; 9257 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9258 PetscValidBoolPointer(set,2); 9259 PetscValidBoolPointer(flg,3); 9260 if (A->hermitian != PETSC_BOOL3_UNKNOWN) { 9261 *set = PETSC_TRUE; 9262 *flg = PetscBool3ToBool(A->hermitian); 9263 } else { 9264 *set = PETSC_FALSE; 9265 } 9266 PetscFunctionReturn(0); 9267 } 9268 9269 /*@ 9270 MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric 9271 9272 Collective on Mat 9273 9274 Input Parameter: 9275 . A - the matrix to test 9276 9277 Output Parameters: 9278 . flg - the result 9279 9280 Notes: 9281 If the matrix does yet know it is structurally symmetric this can be an expensive operation, also available `MatIsStructurallySymmetricKnown()` 9282 9283 Level: intermediate 9284 9285 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsSymmetric()`, `MatSetOption()`, `MatIsStructurallySymmetricKnown()` 9286 @*/ 9287 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg) 9288 { 9289 PetscFunctionBegin; 9290 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9291 PetscValidBoolPointer(flg,2); 9292 if (A->structurally_symmetric != PETSC_BOOL3_UNKNOWN) { 9293 *flg = PetscBool3ToBool(A->structurally_symmetric); 9294 } else { 9295 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); 9296 PetscCall((*A->ops->isstructurallysymmetric)(A,flg)); 9297 PetscCall(MatSetOption(A,MAT_STRUCTURALLY_SYMMETRIC,*flg)); 9298 } 9299 PetscFunctionReturn(0); 9300 } 9301 9302 /*@ 9303 MatIsStructurallySymmetricKnown - Checks if a matrix knows if it is structurally symmetric or not and its structurally symmetric state 9304 9305 Not Collective 9306 9307 Input Parameter: 9308 . A - the matrix to check 9309 9310 Output Parameters: 9311 + set - PETSC_TRUE if the matrix knows its structurally symmetric state (this tells you if the next flag is valid) 9312 - flg - the result (only valid if set is PETSC_TRUE) 9313 9314 Level: advanced 9315 9316 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitianKnown()` 9317 @*/ 9318 PetscErrorCode MatIsStructurallySymmetricKnown(Mat A,PetscBool *set,PetscBool *flg) 9319 { 9320 PetscFunctionBegin; 9321 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9322 PetscValidBoolPointer(set,2); 9323 PetscValidBoolPointer(flg,3); 9324 if (A->structurally_symmetric != PETSC_BOOL3_UNKNOWN) { 9325 *set = PETSC_TRUE; 9326 *flg = PetscBool3ToBool(A->structurally_symmetric); 9327 } else { 9328 *set = PETSC_FALSE; 9329 } 9330 PetscFunctionReturn(0); 9331 } 9332 9333 /*@ 9334 MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need 9335 to be communicated to other processors during the MatAssemblyBegin/End() process 9336 9337 Not collective 9338 9339 Input Parameter: 9340 . vec - the vector 9341 9342 Output Parameters: 9343 + nstash - the size of the stash 9344 . reallocs - the number of additional mallocs incurred. 9345 . bnstash - the size of the block stash 9346 - breallocs - the number of additional mallocs incurred.in the block stash 9347 9348 Level: advanced 9349 9350 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `Mat`, `MatStashSetInitialSize()` 9351 9352 @*/ 9353 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs) 9354 { 9355 PetscFunctionBegin; 9356 PetscCall(MatStashGetInfo_Private(&mat->stash,nstash,reallocs)); 9357 PetscCall(MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs)); 9358 PetscFunctionReturn(0); 9359 } 9360 9361 /*@C 9362 MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same 9363 parallel layout 9364 9365 Collective on Mat 9366 9367 Input Parameter: 9368 . mat - the matrix 9369 9370 Output Parameters: 9371 + right - (optional) vector that the matrix can be multiplied against 9372 - left - (optional) vector that the matrix vector product can be stored in 9373 9374 Notes: 9375 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(). 9376 9377 Notes: 9378 These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed 9379 9380 Level: advanced 9381 9382 .seealso: `MatCreate()`, `VecDestroy()` 9383 @*/ 9384 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left) 9385 { 9386 PetscFunctionBegin; 9387 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9388 PetscValidType(mat,1); 9389 if (mat->ops->getvecs) { 9390 PetscCall((*mat->ops->getvecs)(mat,right,left)); 9391 } else { 9392 PetscInt rbs,cbs; 9393 PetscCall(MatGetBlockSizes(mat,&rbs,&cbs)); 9394 if (right) { 9395 PetscCheck(mat->cmap->n >= 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup"); 9396 PetscCall(VecCreate(PetscObjectComm((PetscObject)mat),right)); 9397 PetscCall(VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE)); 9398 PetscCall(VecSetBlockSize(*right,cbs)); 9399 PetscCall(VecSetType(*right,mat->defaultvectype)); 9400 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 9401 if (mat->boundtocpu && mat->bindingpropagates) { 9402 PetscCall(VecSetBindingPropagates(*right,PETSC_TRUE)); 9403 PetscCall(VecBindToCPU(*right,PETSC_TRUE)); 9404 } 9405 #endif 9406 PetscCall(PetscLayoutReference(mat->cmap,&(*right)->map)); 9407 } 9408 if (left) { 9409 PetscCheck(mat->rmap->n >= 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup"); 9410 PetscCall(VecCreate(PetscObjectComm((PetscObject)mat),left)); 9411 PetscCall(VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE)); 9412 PetscCall(VecSetBlockSize(*left,rbs)); 9413 PetscCall(VecSetType(*left,mat->defaultvectype)); 9414 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 9415 if (mat->boundtocpu && mat->bindingpropagates) { 9416 PetscCall(VecSetBindingPropagates(*left,PETSC_TRUE)); 9417 PetscCall(VecBindToCPU(*left,PETSC_TRUE)); 9418 } 9419 #endif 9420 PetscCall(PetscLayoutReference(mat->rmap,&(*left)->map)); 9421 } 9422 } 9423 PetscFunctionReturn(0); 9424 } 9425 9426 /*@C 9427 MatFactorInfoInitialize - Initializes a MatFactorInfo data structure 9428 with default values. 9429 9430 Not Collective 9431 9432 Input Parameters: 9433 . info - the MatFactorInfo data structure 9434 9435 Notes: 9436 The solvers are generally used through the KSP and PC objects, for example 9437 PCLU, PCILU, PCCHOLESKY, PCICC 9438 9439 Level: developer 9440 9441 .seealso: `MatFactorInfo` 9442 9443 Developer Note: fortran interface is not autogenerated as the f90 9444 interface definition cannot be generated correctly [due to MatFactorInfo] 9445 9446 @*/ 9447 9448 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info) 9449 { 9450 PetscFunctionBegin; 9451 PetscCall(PetscMemzero(info,sizeof(MatFactorInfo))); 9452 PetscFunctionReturn(0); 9453 } 9454 9455 /*@ 9456 MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed 9457 9458 Collective on Mat 9459 9460 Input Parameters: 9461 + mat - the factored matrix 9462 - is - the index set defining the Schur indices (0-based) 9463 9464 Notes: 9465 Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system. 9466 9467 You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call. 9468 9469 Level: developer 9470 9471 .seealso: `MatGetFactor()`, `MatFactorGetSchurComplement()`, `MatFactorRestoreSchurComplement()`, `MatFactorCreateSchurComplement()`, `MatFactorSolveSchurComplement()`, 9472 `MatFactorSolveSchurComplementTranspose()`, `MatFactorSolveSchurComplement()` 9473 9474 @*/ 9475 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is) 9476 { 9477 PetscErrorCode (*f)(Mat,IS); 9478 9479 PetscFunctionBegin; 9480 PetscValidType(mat,1); 9481 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9482 PetscValidType(is,2); 9483 PetscValidHeaderSpecific(is,IS_CLASSID,2); 9484 PetscCheckSameComm(mat,1,is,2); 9485 PetscCheck(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 9486 PetscCall(PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f)); 9487 PetscCheck(f,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"The selected MatSolverType does not support Schur complement computation. You should use MATSOLVERMUMPS or MATSOLVERMKL_PARDISO"); 9488 PetscCall(MatDestroy(&mat->schur)); 9489 PetscCall((*f)(mat,is)); 9490 PetscCheck(mat->schur,PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created"); 9491 PetscFunctionReturn(0); 9492 } 9493 9494 /*@ 9495 MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step 9496 9497 Logically Collective on Mat 9498 9499 Input Parameters: 9500 + F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface 9501 . S - location where to return the Schur complement, can be NULL 9502 - status - the status of the Schur complement matrix, can be NULL 9503 9504 Notes: 9505 You must call MatFactorSetSchurIS() before calling this routine. 9506 9507 The routine provides a copy of the Schur matrix stored within the solver data structures. 9508 The caller must destroy the object when it is no longer needed. 9509 If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse. 9510 9511 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) 9512 9513 Developer Notes: 9514 The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc 9515 matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix. 9516 9517 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 9518 9519 Level: advanced 9520 9521 References: 9522 9523 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorGetSchurComplement()`, `MatFactorSchurStatus` 9524 @*/ 9525 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 9526 { 9527 PetscFunctionBegin; 9528 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9529 if (S) PetscValidPointer(S,2); 9530 if (status) PetscValidPointer(status,3); 9531 if (S) { 9532 PetscErrorCode (*f)(Mat,Mat*); 9533 9534 PetscCall(PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f)); 9535 if (f) { 9536 PetscCall((*f)(F,S)); 9537 } else { 9538 PetscCall(MatDuplicate(F->schur,MAT_COPY_VALUES,S)); 9539 } 9540 } 9541 if (status) *status = F->schur_status; 9542 PetscFunctionReturn(0); 9543 } 9544 9545 /*@ 9546 MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix 9547 9548 Logically Collective on Mat 9549 9550 Input Parameters: 9551 + F - the factored matrix obtained by calling MatGetFactor() 9552 . *S - location where to return the Schur complement, can be NULL 9553 - status - the status of the Schur complement matrix, can be NULL 9554 9555 Notes: 9556 You must call MatFactorSetSchurIS() before calling this routine. 9557 9558 Schur complement mode is currently implemented for sequential matrices. 9559 The routine returns a the Schur Complement stored within the data strutures of the solver. 9560 If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement. 9561 The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed. 9562 9563 Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix 9564 9565 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 9566 9567 Level: advanced 9568 9569 References: 9570 9571 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorRestoreSchurComplement()`, `MatFactorCreateSchurComplement()`, `MatFactorSchurStatus` 9572 @*/ 9573 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 9574 { 9575 PetscFunctionBegin; 9576 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9577 if (S) PetscValidPointer(S,2); 9578 if (status) PetscValidPointer(status,3); 9579 if (S) *S = F->schur; 9580 if (status) *status = F->schur_status; 9581 PetscFunctionReturn(0); 9582 } 9583 9584 /*@ 9585 MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement 9586 9587 Logically Collective on Mat 9588 9589 Input Parameters: 9590 + F - the factored matrix obtained by calling MatGetFactor() 9591 . *S - location where the Schur complement is stored 9592 - status - the status of the Schur complement matrix (see MatFactorSchurStatus) 9593 9594 Notes: 9595 9596 Level: advanced 9597 9598 References: 9599 9600 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorRestoreSchurComplement()`, `MatFactorCreateSchurComplement()`, `MatFactorSchurStatus` 9601 @*/ 9602 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status) 9603 { 9604 PetscFunctionBegin; 9605 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9606 if (S) { 9607 PetscValidHeaderSpecific(*S,MAT_CLASSID,2); 9608 *S = NULL; 9609 } 9610 F->schur_status = status; 9611 PetscCall(MatFactorUpdateSchurStatus_Private(F)); 9612 PetscFunctionReturn(0); 9613 } 9614 9615 /*@ 9616 MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step 9617 9618 Logically Collective on Mat 9619 9620 Input Parameters: 9621 + F - the factored matrix obtained by calling MatGetFactor() 9622 . rhs - location where the right hand side of the Schur complement system is stored 9623 - sol - location where the solution of the Schur complement system has to be returned 9624 9625 Notes: 9626 The sizes of the vectors should match the size of the Schur complement 9627 9628 Must be called after MatFactorSetSchurIS() 9629 9630 Level: advanced 9631 9632 References: 9633 9634 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorSolveSchurComplement()` 9635 @*/ 9636 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol) 9637 { 9638 PetscFunctionBegin; 9639 PetscValidType(F,1); 9640 PetscValidType(rhs,2); 9641 PetscValidType(sol,3); 9642 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9643 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9644 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9645 PetscCheckSameComm(F,1,rhs,2); 9646 PetscCheckSameComm(F,1,sol,3); 9647 PetscCall(MatFactorFactorizeSchurComplement(F)); 9648 switch (F->schur_status) { 9649 case MAT_FACTOR_SCHUR_FACTORED: 9650 PetscCall(MatSolveTranspose(F->schur,rhs,sol)); 9651 break; 9652 case MAT_FACTOR_SCHUR_INVERTED: 9653 PetscCall(MatMultTranspose(F->schur,rhs,sol)); 9654 break; 9655 default: 9656 SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %d",F->schur_status); 9657 } 9658 PetscFunctionReturn(0); 9659 } 9660 9661 /*@ 9662 MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step 9663 9664 Logically Collective on Mat 9665 9666 Input Parameters: 9667 + F - the factored matrix obtained by calling MatGetFactor() 9668 . rhs - location where the right hand side of the Schur complement system is stored 9669 - sol - location where the solution of the Schur complement system has to be returned 9670 9671 Notes: 9672 The sizes of the vectors should match the size of the Schur complement 9673 9674 Must be called after MatFactorSetSchurIS() 9675 9676 Level: advanced 9677 9678 References: 9679 9680 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorSolveSchurComplementTranspose()` 9681 @*/ 9682 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol) 9683 { 9684 PetscFunctionBegin; 9685 PetscValidType(F,1); 9686 PetscValidType(rhs,2); 9687 PetscValidType(sol,3); 9688 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9689 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9690 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9691 PetscCheckSameComm(F,1,rhs,2); 9692 PetscCheckSameComm(F,1,sol,3); 9693 PetscCall(MatFactorFactorizeSchurComplement(F)); 9694 switch (F->schur_status) { 9695 case MAT_FACTOR_SCHUR_FACTORED: 9696 PetscCall(MatSolve(F->schur,rhs,sol)); 9697 break; 9698 case MAT_FACTOR_SCHUR_INVERTED: 9699 PetscCall(MatMult(F->schur,rhs,sol)); 9700 break; 9701 default: 9702 SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %d",F->schur_status); 9703 } 9704 PetscFunctionReturn(0); 9705 } 9706 9707 /*@ 9708 MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step 9709 9710 Logically Collective on Mat 9711 9712 Input Parameters: 9713 . F - the factored matrix obtained by calling MatGetFactor() 9714 9715 Notes: 9716 Must be called after MatFactorSetSchurIS(). 9717 9718 Call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it. 9719 9720 Level: advanced 9721 9722 References: 9723 9724 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorGetSchurComplement()`, `MatFactorCreateSchurComplement()` 9725 @*/ 9726 PetscErrorCode MatFactorInvertSchurComplement(Mat F) 9727 { 9728 PetscFunctionBegin; 9729 PetscValidType(F,1); 9730 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9731 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0); 9732 PetscCall(MatFactorFactorizeSchurComplement(F)); 9733 PetscCall(MatFactorInvertSchurComplement_Private(F)); 9734 F->schur_status = MAT_FACTOR_SCHUR_INVERTED; 9735 PetscFunctionReturn(0); 9736 } 9737 9738 /*@ 9739 MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step 9740 9741 Logically Collective on Mat 9742 9743 Input Parameters: 9744 . F - the factored matrix obtained by calling MatGetFactor() 9745 9746 Notes: 9747 Must be called after MatFactorSetSchurIS(). 9748 9749 Level: advanced 9750 9751 References: 9752 9753 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorInvertSchurComplement()` 9754 @*/ 9755 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F) 9756 { 9757 PetscFunctionBegin; 9758 PetscValidType(F,1); 9759 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9760 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0); 9761 PetscCall(MatFactorFactorizeSchurComplement_Private(F)); 9762 F->schur_status = MAT_FACTOR_SCHUR_FACTORED; 9763 PetscFunctionReturn(0); 9764 } 9765 9766 /*@ 9767 MatPtAP - Creates the matrix product C = P^T * A * P 9768 9769 Neighbor-wise Collective on Mat 9770 9771 Input Parameters: 9772 + A - the matrix 9773 . P - the projection matrix 9774 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9775 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate 9776 if the result is a dense matrix this is irrelevant 9777 9778 Output Parameters: 9779 . C - the product matrix 9780 9781 Notes: 9782 C will be created and must be destroyed by the user with MatDestroy(). 9783 9784 For matrix types without special implementation the function fallbacks to MatMatMult() followed by MatTransposeMatMult(). 9785 9786 Level: intermediate 9787 9788 .seealso: `MatMatMult()`, `MatRARt()` 9789 @*/ 9790 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 9791 { 9792 PetscFunctionBegin; 9793 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*C,5); 9794 PetscCheck(scall != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9795 9796 if (scall == MAT_INITIAL_MATRIX) { 9797 PetscCall(MatProductCreate(A,P,NULL,C)); 9798 PetscCall(MatProductSetType(*C,MATPRODUCT_PtAP)); 9799 PetscCall(MatProductSetAlgorithm(*C,"default")); 9800 PetscCall(MatProductSetFill(*C,fill)); 9801 9802 (*C)->product->api_user = PETSC_TRUE; 9803 PetscCall(MatProductSetFromOptions(*C)); 9804 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); 9805 PetscCall(MatProductSymbolic(*C)); 9806 } else { /* scall == MAT_REUSE_MATRIX */ 9807 PetscCall(MatProductReplaceMats(A,P,NULL,*C)); 9808 } 9809 9810 PetscCall(MatProductNumeric(*C)); 9811 (*C)->symmetric = A->symmetric; 9812 (*C)->spd = A->spd; 9813 PetscFunctionReturn(0); 9814 } 9815 9816 /*@ 9817 MatRARt - Creates the matrix product C = R * A * R^T 9818 9819 Neighbor-wise Collective on Mat 9820 9821 Input Parameters: 9822 + A - the matrix 9823 . R - the projection matrix 9824 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9825 - fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate 9826 if the result is a dense matrix this is irrelevant 9827 9828 Output Parameters: 9829 . C - the product matrix 9830 9831 Notes: 9832 C will be created and must be destroyed by the user with MatDestroy(). 9833 9834 This routine is currently only implemented for pairs of AIJ matrices and classes 9835 which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes, 9836 parallel MatRARt is implemented via explicit transpose of R, which could be very expensive. 9837 We recommend using MatPtAP(). 9838 9839 Level: intermediate 9840 9841 .seealso: `MatMatMult()`, `MatPtAP()` 9842 @*/ 9843 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C) 9844 { 9845 PetscFunctionBegin; 9846 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*C,5); 9847 PetscCheck(scall != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9848 9849 if (scall == MAT_INITIAL_MATRIX) { 9850 PetscCall(MatProductCreate(A,R,NULL,C)); 9851 PetscCall(MatProductSetType(*C,MATPRODUCT_RARt)); 9852 PetscCall(MatProductSetAlgorithm(*C,"default")); 9853 PetscCall(MatProductSetFill(*C,fill)); 9854 9855 (*C)->product->api_user = PETSC_TRUE; 9856 PetscCall(MatProductSetFromOptions(*C)); 9857 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); 9858 PetscCall(MatProductSymbolic(*C)); 9859 } else { /* scall == MAT_REUSE_MATRIX */ 9860 PetscCall(MatProductReplaceMats(A,R,NULL,*C)); 9861 } 9862 9863 PetscCall(MatProductNumeric(*C)); 9864 if (A->symmetric == PETSC_BOOL3_TRUE) { 9865 PetscCall(MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE)); 9866 } 9867 PetscFunctionReturn(0); 9868 } 9869 9870 static PetscErrorCode MatProduct_Private(Mat A,Mat B,MatReuse scall,PetscReal fill,MatProductType ptype, Mat *C) 9871 { 9872 PetscFunctionBegin; 9873 PetscCheck(scall != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9874 9875 if (scall == MAT_INITIAL_MATRIX) { 9876 PetscCall(PetscInfo(A,"Calling MatProduct API with MAT_INITIAL_MATRIX and product type %s\n",MatProductTypes[ptype])); 9877 PetscCall(MatProductCreate(A,B,NULL,C)); 9878 PetscCall(MatProductSetType(*C,ptype)); 9879 PetscCall(MatProductSetAlgorithm(*C,MATPRODUCTALGORITHMDEFAULT)); 9880 PetscCall(MatProductSetFill(*C,fill)); 9881 9882 (*C)->product->api_user = PETSC_TRUE; 9883 PetscCall(MatProductSetFromOptions(*C)); 9884 PetscCall(MatProductSymbolic(*C)); 9885 } else { /* scall == MAT_REUSE_MATRIX */ 9886 Mat_Product *product = (*C)->product; 9887 PetscBool isdense; 9888 9889 PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)(*C),&isdense,MATSEQDENSE,MATMPIDENSE,"")); 9890 if (isdense && product && product->type != ptype) { 9891 PetscCall(MatProductClear(*C)); 9892 product = NULL; 9893 } 9894 PetscCall(PetscInfo(A,"Calling MatProduct API with MAT_REUSE_MATRIX %s product present and product type %s\n",product ? "with" : "without",MatProductTypes[ptype])); 9895 if (!product) { /* user provide the dense matrix *C without calling MatProductCreate() or reusing it from previous calls */ 9896 if (isdense) { 9897 PetscCall(MatProductCreate_Private(A,B,NULL,*C)); 9898 product = (*C)->product; 9899 product->fill = fill; 9900 product->api_user = PETSC_TRUE; 9901 product->clear = PETSC_TRUE; 9902 9903 PetscCall(MatProductSetType(*C,ptype)); 9904 PetscCall(MatProductSetFromOptions(*C)); 9905 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); 9906 PetscCall(MatProductSymbolic(*C)); 9907 } else SETERRQ(PetscObjectComm((PetscObject)(*C)),PETSC_ERR_SUP,"Call MatProductCreate() first"); 9908 } else { /* user may change input matrices A or B when REUSE */ 9909 PetscCall(MatProductReplaceMats(A,B,NULL,*C)); 9910 } 9911 } 9912 PetscCall(MatProductNumeric(*C)); 9913 PetscFunctionReturn(0); 9914 } 9915 9916 /*@ 9917 MatMatMult - Performs Matrix-Matrix Multiplication C=A*B. 9918 9919 Neighbor-wise Collective on Mat 9920 9921 Input Parameters: 9922 + A - the left matrix 9923 . B - the right matrix 9924 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9925 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate 9926 if the result is a dense matrix this is irrelevant 9927 9928 Output Parameters: 9929 . C - the product matrix 9930 9931 Notes: 9932 Unless scall is MAT_REUSE_MATRIX C will be created. 9933 9934 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 9935 call to this function with MAT_INITIAL_MATRIX. 9936 9937 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value actually needed. 9938 9939 If you have many matrices with the same non-zero structure to multiply, you should use MatProductCreate()/MatProductSymbolic()/MatProductReplaceMats(), and call MatProductNumeric() repeatedly. 9940 9941 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. 9942 9943 Example of Usage: 9944 .vb 9945 MatProductCreate(A,B,NULL,&C); 9946 MatProductSetType(C,MATPRODUCT_AB); 9947 MatProductSymbolic(C); 9948 MatProductNumeric(C); // compute C=A * B 9949 MatProductReplaceMats(A1,B1,NULL,C); // compute C=A1 * B1 9950 MatProductNumeric(C); 9951 MatProductReplaceMats(A2,NULL,NULL,C); // compute C=A2 * B1 9952 MatProductNumeric(C); 9953 .ve 9954 9955 Level: intermediate 9956 9957 .seealso: `MatTransposeMatMult()`, `MatMatTransposeMult()`, `MatPtAP()`, `MatProductCreate()`, `MatProductSymbolic()`, `MatProductReplaceMats()`, `MatProductNumeric()` 9958 @*/ 9959 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9960 { 9961 PetscFunctionBegin; 9962 PetscCall(MatProduct_Private(A,B,scall,fill,MATPRODUCT_AB,C)); 9963 PetscFunctionReturn(0); 9964 } 9965 9966 /*@ 9967 MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T. 9968 9969 Neighbor-wise Collective on Mat 9970 9971 Input Parameters: 9972 + A - the left matrix 9973 . B - the right matrix 9974 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9975 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9976 9977 Output Parameters: 9978 . C - the product matrix 9979 9980 Notes: 9981 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9982 9983 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9984 9985 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9986 actually needed. 9987 9988 This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class, 9989 and for pairs of MPIDense matrices. 9990 9991 Options Database Keys: 9992 . -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorithms for MPIDense matrices: the 9993 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity; 9994 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity. 9995 9996 Level: intermediate 9997 9998 .seealso: `MatMatMult()`, `MatTransposeMatMult()` `MatPtAP()` 9999 @*/ 10000 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 10001 { 10002 PetscFunctionBegin; 10003 PetscCall(MatProduct_Private(A,B,scall,fill,MATPRODUCT_ABt,C)); 10004 if (A == B) { 10005 PetscCall(MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE)); 10006 } 10007 PetscFunctionReturn(0); 10008 } 10009 10010 /*@ 10011 MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B. 10012 10013 Neighbor-wise Collective on Mat 10014 10015 Input Parameters: 10016 + A - the left matrix 10017 . B - the right matrix 10018 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10019 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 10020 10021 Output Parameters: 10022 . C - the product matrix 10023 10024 Notes: 10025 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 10026 10027 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call. 10028 10029 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 10030 actually needed. 10031 10032 This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes 10033 which inherit from SeqAIJ. C will be of the same type as the input matrices. 10034 10035 Level: intermediate 10036 10037 .seealso: `MatMatMult()`, `MatMatTransposeMult()`, `MatPtAP()` 10038 @*/ 10039 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 10040 { 10041 PetscFunctionBegin; 10042 PetscCall(MatProduct_Private(A,B,scall,fill,MATPRODUCT_AtB,C)); 10043 PetscFunctionReturn(0); 10044 } 10045 10046 /*@ 10047 MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C. 10048 10049 Neighbor-wise Collective on Mat 10050 10051 Input Parameters: 10052 + A - the left matrix 10053 . B - the middle matrix 10054 . C - the right matrix 10055 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10056 - 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 10057 if the result is a dense matrix this is irrelevant 10058 10059 Output Parameters: 10060 . D - the product matrix 10061 10062 Notes: 10063 Unless scall is MAT_REUSE_MATRIX D will be created. 10064 10065 MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call 10066 10067 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 10068 actually needed. 10069 10070 If you have many matrices with the same non-zero structure to multiply, you 10071 should use MAT_REUSE_MATRIX in all calls but the first 10072 10073 Level: intermediate 10074 10075 .seealso: `MatMatMult`, `MatPtAP()`, `MatMatTransposeMult()`, `MatTransposeMatMult()` 10076 @*/ 10077 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D) 10078 { 10079 PetscFunctionBegin; 10080 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*D,6); 10081 PetscCheck(scall != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 10082 10083 if (scall == MAT_INITIAL_MATRIX) { 10084 PetscCall(MatProductCreate(A,B,C,D)); 10085 PetscCall(MatProductSetType(*D,MATPRODUCT_ABC)); 10086 PetscCall(MatProductSetAlgorithm(*D,"default")); 10087 PetscCall(MatProductSetFill(*D,fill)); 10088 10089 (*D)->product->api_user = PETSC_TRUE; 10090 PetscCall(MatProductSetFromOptions(*D)); 10091 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); 10092 PetscCall(MatProductSymbolic(*D)); 10093 } else { /* user may change input matrices when REUSE */ 10094 PetscCall(MatProductReplaceMats(A,B,C,*D)); 10095 } 10096 PetscCall(MatProductNumeric(*D)); 10097 PetscFunctionReturn(0); 10098 } 10099 10100 /*@ 10101 MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators. 10102 10103 Collective on Mat 10104 10105 Input Parameters: 10106 + mat - the matrix 10107 . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices) 10108 . subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used) 10109 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10110 10111 Output Parameter: 10112 . matredundant - redundant matrix 10113 10114 Notes: 10115 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 10116 original matrix has not changed from that last call to MatCreateRedundantMatrix(). 10117 10118 This routine creates the duplicated matrices in the subcommunicators; you should NOT create them before 10119 calling it. 10120 10121 Level: advanced 10122 10123 .seealso: `MatDestroy()` 10124 @*/ 10125 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant) 10126 { 10127 MPI_Comm comm; 10128 PetscMPIInt size; 10129 PetscInt mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs; 10130 Mat_Redundant *redund=NULL; 10131 PetscSubcomm psubcomm=NULL; 10132 MPI_Comm subcomm_in=subcomm; 10133 Mat *matseq; 10134 IS isrow,iscol; 10135 PetscBool newsubcomm=PETSC_FALSE; 10136 10137 PetscFunctionBegin; 10138 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10139 if (nsubcomm && reuse == MAT_REUSE_MATRIX) { 10140 PetscValidPointer(*matredundant,5); 10141 PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5); 10142 } 10143 10144 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 10145 if (size == 1 || nsubcomm == 1) { 10146 if (reuse == MAT_INITIAL_MATRIX) { 10147 PetscCall(MatDuplicate(mat,MAT_COPY_VALUES,matredundant)); 10148 } else { 10149 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"); 10150 PetscCall(MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN)); 10151 } 10152 PetscFunctionReturn(0); 10153 } 10154 10155 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10156 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10157 MatCheckPreallocated(mat,1); 10158 10159 PetscCall(PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0)); 10160 if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */ 10161 /* create psubcomm, then get subcomm */ 10162 PetscCall(PetscObjectGetComm((PetscObject)mat,&comm)); 10163 PetscCallMPI(MPI_Comm_size(comm,&size)); 10164 PetscCheck(nsubcomm >= 1 && nsubcomm <= size,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %d",size); 10165 10166 PetscCall(PetscSubcommCreate(comm,&psubcomm)); 10167 PetscCall(PetscSubcommSetNumber(psubcomm,nsubcomm)); 10168 PetscCall(PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS)); 10169 PetscCall(PetscSubcommSetFromOptions(psubcomm)); 10170 PetscCall(PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL)); 10171 newsubcomm = PETSC_TRUE; 10172 PetscCall(PetscSubcommDestroy(&psubcomm)); 10173 } 10174 10175 /* get isrow, iscol and a local sequential matrix matseq[0] */ 10176 if (reuse == MAT_INITIAL_MATRIX) { 10177 mloc_sub = PETSC_DECIDE; 10178 nloc_sub = PETSC_DECIDE; 10179 if (bs < 1) { 10180 PetscCall(PetscSplitOwnership(subcomm,&mloc_sub,&M)); 10181 PetscCall(PetscSplitOwnership(subcomm,&nloc_sub,&N)); 10182 } else { 10183 PetscCall(PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M)); 10184 PetscCall(PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N)); 10185 } 10186 PetscCallMPI(MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm)); 10187 rstart = rend - mloc_sub; 10188 PetscCall(ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow)); 10189 PetscCall(ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol)); 10190 } else { /* reuse == MAT_REUSE_MATRIX */ 10191 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"); 10192 /* retrieve subcomm */ 10193 PetscCall(PetscObjectGetComm((PetscObject)(*matredundant),&subcomm)); 10194 redund = (*matredundant)->redundant; 10195 isrow = redund->isrow; 10196 iscol = redund->iscol; 10197 matseq = redund->matseq; 10198 } 10199 PetscCall(MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq)); 10200 10201 /* get matredundant over subcomm */ 10202 if (reuse == MAT_INITIAL_MATRIX) { 10203 PetscCall(MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant)); 10204 10205 /* create a supporting struct and attach it to C for reuse */ 10206 PetscCall(PetscNewLog(*matredundant,&redund)); 10207 (*matredundant)->redundant = redund; 10208 redund->isrow = isrow; 10209 redund->iscol = iscol; 10210 redund->matseq = matseq; 10211 if (newsubcomm) { 10212 redund->subcomm = subcomm; 10213 } else { 10214 redund->subcomm = MPI_COMM_NULL; 10215 } 10216 } else { 10217 PetscCall(MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant)); 10218 } 10219 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 10220 if (matseq[0]->boundtocpu && matseq[0]->bindingpropagates) { 10221 PetscCall(MatBindToCPU(*matredundant,PETSC_TRUE)); 10222 PetscCall(MatSetBindingPropagates(*matredundant,PETSC_TRUE)); 10223 } 10224 #endif 10225 PetscCall(PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0)); 10226 PetscFunctionReturn(0); 10227 } 10228 10229 /*@C 10230 MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from 10231 a given 'mat' object. Each submatrix can span multiple procs. 10232 10233 Collective on Mat 10234 10235 Input Parameters: 10236 + mat - the matrix 10237 . subcomm - the subcommunicator obtained by com_split(comm) 10238 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10239 10240 Output Parameter: 10241 . subMat - 'parallel submatrices each spans a given subcomm 10242 10243 Notes: 10244 The submatrix partition across processors is dictated by 'subComm' a 10245 communicator obtained by MPI_comm_split(). The subComm 10246 is not restriced to be grouped with consecutive original ranks. 10247 10248 Due the MPI_Comm_split() usage, the parallel layout of the submatrices 10249 map directly to the layout of the original matrix [wrt the local 10250 row,col partitioning]. So the original 'DiagonalMat' naturally maps 10251 into the 'DiagonalMat' of the subMat, hence it is used directly from 10252 the subMat. However the offDiagMat looses some columns - and this is 10253 reconstructed with MatSetValues() 10254 10255 Level: advanced 10256 10257 .seealso: `MatCreateSubMatrices()` 10258 @*/ 10259 PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat) 10260 { 10261 PetscMPIInt commsize,subCommSize; 10262 10263 PetscFunctionBegin; 10264 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize)); 10265 PetscCallMPI(MPI_Comm_size(subComm,&subCommSize)); 10266 PetscCheck(subCommSize <= commsize,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %d < SubCommZize %d",commsize,subCommSize); 10267 10268 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"); 10269 PetscCall(PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0)); 10270 PetscCall((*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat)); 10271 PetscCall(PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0)); 10272 PetscFunctionReturn(0); 10273 } 10274 10275 /*@ 10276 MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering 10277 10278 Not Collective 10279 10280 Input Parameters: 10281 + mat - matrix to extract local submatrix from 10282 . isrow - local row indices for submatrix 10283 - iscol - local column indices for submatrix 10284 10285 Output Parameter: 10286 . submat - the submatrix 10287 10288 Level: intermediate 10289 10290 Notes: 10291 The submat should be returned with MatRestoreLocalSubMatrix(). 10292 10293 Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be 10294 the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's. 10295 10296 The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then 10297 MatSetValuesBlockedLocal() will also be implemented. 10298 10299 The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that 10300 matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided. 10301 10302 .seealso: `MatRestoreLocalSubMatrix()`, `MatCreateLocalRef()`, `MatSetLocalToGlobalMapping()` 10303 @*/ 10304 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10305 { 10306 PetscFunctionBegin; 10307 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10308 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10309 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10310 PetscCheckSameComm(isrow,2,iscol,3); 10311 PetscValidPointer(submat,4); 10312 PetscCheck(mat->rmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call"); 10313 10314 if (mat->ops->getlocalsubmatrix) { 10315 PetscCall((*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat)); 10316 } else { 10317 PetscCall(MatCreateLocalRef(mat,isrow,iscol,submat)); 10318 } 10319 PetscFunctionReturn(0); 10320 } 10321 10322 /*@ 10323 MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering 10324 10325 Not Collective 10326 10327 Input Parameters: 10328 + mat - matrix to extract local submatrix from 10329 . isrow - local row indices for submatrix 10330 . iscol - local column indices for submatrix 10331 - submat - the submatrix 10332 10333 Level: intermediate 10334 10335 .seealso: `MatGetLocalSubMatrix()` 10336 @*/ 10337 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10338 { 10339 PetscFunctionBegin; 10340 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10341 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10342 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10343 PetscCheckSameComm(isrow,2,iscol,3); 10344 PetscValidPointer(submat,4); 10345 if (*submat) { 10346 PetscValidHeaderSpecific(*submat,MAT_CLASSID,4); 10347 } 10348 10349 if (mat->ops->restorelocalsubmatrix) { 10350 PetscCall((*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat)); 10351 } else { 10352 PetscCall(MatDestroy(submat)); 10353 } 10354 *submat = NULL; 10355 PetscFunctionReturn(0); 10356 } 10357 10358 /* --------------------------------------------------------*/ 10359 /*@ 10360 MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix 10361 10362 Collective on Mat 10363 10364 Input Parameter: 10365 . mat - the matrix 10366 10367 Output Parameter: 10368 . is - if any rows have zero diagonals this contains the list of them 10369 10370 Level: developer 10371 10372 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 10373 @*/ 10374 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is) 10375 { 10376 PetscFunctionBegin; 10377 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10378 PetscValidType(mat,1); 10379 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10380 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10381 10382 if (!mat->ops->findzerodiagonals) { 10383 Vec diag; 10384 const PetscScalar *a; 10385 PetscInt *rows; 10386 PetscInt rStart, rEnd, r, nrow = 0; 10387 10388 PetscCall(MatCreateVecs(mat, &diag, NULL)); 10389 PetscCall(MatGetDiagonal(mat, diag)); 10390 PetscCall(MatGetOwnershipRange(mat, &rStart, &rEnd)); 10391 PetscCall(VecGetArrayRead(diag, &a)); 10392 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow; 10393 PetscCall(PetscMalloc1(nrow, &rows)); 10394 nrow = 0; 10395 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart; 10396 PetscCall(VecRestoreArrayRead(diag, &a)); 10397 PetscCall(VecDestroy(&diag)); 10398 PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is)); 10399 } else { 10400 PetscCall((*mat->ops->findzerodiagonals)(mat, is)); 10401 } 10402 PetscFunctionReturn(0); 10403 } 10404 10405 /*@ 10406 MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size) 10407 10408 Collective on Mat 10409 10410 Input Parameter: 10411 . mat - the matrix 10412 10413 Output Parameter: 10414 . is - contains the list of rows with off block diagonal entries 10415 10416 Level: developer 10417 10418 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 10419 @*/ 10420 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is) 10421 { 10422 PetscFunctionBegin; 10423 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10424 PetscValidType(mat,1); 10425 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10426 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10427 10428 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); 10429 PetscCall((*mat->ops->findoffblockdiagonalentries)(mat,is)); 10430 PetscFunctionReturn(0); 10431 } 10432 10433 /*@C 10434 MatInvertBlockDiagonal - Inverts the block diagonal entries. 10435 10436 Collective on Mat 10437 10438 Input Parameters: 10439 . mat - the matrix 10440 10441 Output Parameters: 10442 . values - the block inverses in column major order (FORTRAN-like) 10443 10444 Note: 10445 The size of the blocks is determined by the block size of the matrix. 10446 10447 Fortran Note: 10448 This routine is not available from Fortran. 10449 10450 Level: advanced 10451 10452 .seealso: `MatInvertVariableBlockEnvelope()`, `MatInvertBlockDiagonalMat()` 10453 @*/ 10454 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values) 10455 { 10456 PetscFunctionBegin; 10457 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10458 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10459 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10460 PetscCheck(mat->ops->invertblockdiagonal,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for type %s",((PetscObject)mat)->type_name); 10461 PetscCall((*mat->ops->invertblockdiagonal)(mat,values)); 10462 PetscFunctionReturn(0); 10463 } 10464 10465 /*@C 10466 MatInvertVariableBlockDiagonal - Inverts the point block diagonal entries. 10467 10468 Collective on Mat 10469 10470 Input Parameters: 10471 + mat - the matrix 10472 . nblocks - the number of blocks on the process, set with MatSetVariableBlockSizes() 10473 - bsizes - the size of each block on the process, set with MatSetVariableBlockSizes() 10474 10475 Output Parameters: 10476 . values - the block inverses in column major order (FORTRAN-like) 10477 10478 Note: 10479 This routine is not available from Fortran. 10480 10481 Level: advanced 10482 10483 .seealso: `MatInvertBlockDiagonal()`, `MatSetVariableBlockSizes()`, `MatInvertVariableBlockEnvelope()` 10484 @*/ 10485 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values) 10486 { 10487 PetscFunctionBegin; 10488 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10489 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10490 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10491 PetscCheck(mat->ops->invertvariableblockdiagonal,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for type %s",((PetscObject)mat)->type_name); 10492 PetscCall((*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values)); 10493 PetscFunctionReturn(0); 10494 } 10495 10496 /*@ 10497 MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A 10498 10499 Collective on Mat 10500 10501 Input Parameters: 10502 . A - the matrix 10503 10504 Output Parameters: 10505 . C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set. 10506 10507 Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C 10508 10509 Level: advanced 10510 10511 .seealso: `MatInvertBlockDiagonal()` 10512 @*/ 10513 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C) 10514 { 10515 const PetscScalar *vals; 10516 PetscInt *dnnz; 10517 PetscInt m,rstart,rend,bs,i,j; 10518 10519 PetscFunctionBegin; 10520 PetscCall(MatInvertBlockDiagonal(A,&vals)); 10521 PetscCall(MatGetBlockSize(A,&bs)); 10522 PetscCall(MatGetLocalSize(A,&m,NULL)); 10523 PetscCall(MatSetLayouts(C,A->rmap,A->cmap)); 10524 PetscCall(PetscMalloc1(m/bs,&dnnz)); 10525 for (j = 0; j < m/bs; j++) dnnz[j] = 1; 10526 PetscCall(MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL)); 10527 PetscCall(PetscFree(dnnz)); 10528 PetscCall(MatGetOwnershipRange(C,&rstart,&rend)); 10529 PetscCall(MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE)); 10530 for (i = rstart/bs; i < rend/bs; i++) { 10531 PetscCall(MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES)); 10532 } 10533 PetscCall(MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY)); 10534 PetscCall(MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY)); 10535 PetscCall(MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE)); 10536 PetscFunctionReturn(0); 10537 } 10538 10539 /*@C 10540 MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created 10541 via MatTransposeColoringCreate(). 10542 10543 Collective on MatTransposeColoring 10544 10545 Input Parameter: 10546 . c - coloring context 10547 10548 Level: intermediate 10549 10550 .seealso: `MatTransposeColoringCreate()` 10551 @*/ 10552 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c) 10553 { 10554 MatTransposeColoring matcolor=*c; 10555 10556 PetscFunctionBegin; 10557 if (!matcolor) PetscFunctionReturn(0); 10558 if (--((PetscObject)matcolor)->refct > 0) {matcolor = NULL; PetscFunctionReturn(0);} 10559 10560 PetscCall(PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow)); 10561 PetscCall(PetscFree(matcolor->rows)); 10562 PetscCall(PetscFree(matcolor->den2sp)); 10563 PetscCall(PetscFree(matcolor->colorforcol)); 10564 PetscCall(PetscFree(matcolor->columns)); 10565 if (matcolor->brows>0) PetscCall(PetscFree(matcolor->lstart)); 10566 PetscCall(PetscHeaderDestroy(c)); 10567 PetscFunctionReturn(0); 10568 } 10569 10570 /*@C 10571 MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which 10572 a MatTransposeColoring context has been created, computes a dense B^T by Apply 10573 MatTransposeColoring to sparse B. 10574 10575 Collective on MatTransposeColoring 10576 10577 Input Parameters: 10578 + B - sparse matrix B 10579 . Btdense - symbolic dense matrix B^T 10580 - coloring - coloring context created with MatTransposeColoringCreate() 10581 10582 Output Parameter: 10583 . Btdense - dense matrix B^T 10584 10585 Level: advanced 10586 10587 Notes: 10588 These are used internally for some implementations of MatRARt() 10589 10590 .seealso: `MatTransposeColoringCreate()`, `MatTransposeColoringDestroy()`, `MatTransColoringApplyDenToSp()` 10591 10592 @*/ 10593 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense) 10594 { 10595 PetscFunctionBegin; 10596 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 10597 PetscValidHeaderSpecific(Btdense,MAT_CLASSID,3); 10598 PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,1); 10599 10600 PetscCheck(B->ops->transcoloringapplysptoden,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name); 10601 PetscCall((B->ops->transcoloringapplysptoden)(coloring,B,Btdense)); 10602 PetscFunctionReturn(0); 10603 } 10604 10605 /*@C 10606 MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which 10607 a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense 10608 in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix 10609 Csp from Cden. 10610 10611 Collective on MatTransposeColoring 10612 10613 Input Parameters: 10614 + coloring - coloring context created with MatTransposeColoringCreate() 10615 - Cden - matrix product of a sparse matrix and a dense matrix Btdense 10616 10617 Output Parameter: 10618 . Csp - sparse matrix 10619 10620 Level: advanced 10621 10622 Notes: 10623 These are used internally for some implementations of MatRARt() 10624 10625 .seealso: `MatTransposeColoringCreate()`, `MatTransposeColoringDestroy()`, `MatTransColoringApplySpToDen()` 10626 10627 @*/ 10628 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp) 10629 { 10630 PetscFunctionBegin; 10631 PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1); 10632 PetscValidHeaderSpecific(Cden,MAT_CLASSID,2); 10633 PetscValidHeaderSpecific(Csp,MAT_CLASSID,3); 10634 10635 PetscCheck(Csp->ops->transcoloringapplydentosp,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name); 10636 PetscCall((Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp)); 10637 PetscCall(MatAssemblyBegin(Csp,MAT_FINAL_ASSEMBLY)); 10638 PetscCall(MatAssemblyEnd(Csp,MAT_FINAL_ASSEMBLY)); 10639 PetscFunctionReturn(0); 10640 } 10641 10642 /*@C 10643 MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T. 10644 10645 Collective on Mat 10646 10647 Input Parameters: 10648 + mat - the matrix product C 10649 - iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring() 10650 10651 Output Parameter: 10652 . color - the new coloring context 10653 10654 Level: intermediate 10655 10656 .seealso: `MatTransposeColoringDestroy()`, `MatTransColoringApplySpToDen()`, 10657 `MatTransColoringApplyDenToSp()` 10658 @*/ 10659 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color) 10660 { 10661 MatTransposeColoring c; 10662 MPI_Comm comm; 10663 10664 PetscFunctionBegin; 10665 PetscCall(PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0)); 10666 PetscCall(PetscObjectGetComm((PetscObject)mat,&comm)); 10667 PetscCall(PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL)); 10668 10669 c->ctype = iscoloring->ctype; 10670 if (mat->ops->transposecoloringcreate) { 10671 PetscCall((*mat->ops->transposecoloringcreate)(mat,iscoloring,c)); 10672 } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for matrix type %s",((PetscObject)mat)->type_name); 10673 10674 *color = c; 10675 PetscCall(PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0)); 10676 PetscFunctionReturn(0); 10677 } 10678 10679 /*@ 10680 MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the 10681 matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the 10682 same, otherwise it will be larger 10683 10684 Not Collective 10685 10686 Input Parameter: 10687 . A - the matrix 10688 10689 Output Parameter: 10690 . state - the current state 10691 10692 Notes: 10693 You can only compare states from two different calls to the SAME matrix, you cannot compare calls between 10694 different matrices 10695 10696 Level: intermediate 10697 10698 .seealso: `PetscObjectStateGet()` 10699 @*/ 10700 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state) 10701 { 10702 PetscFunctionBegin; 10703 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10704 *state = mat->nonzerostate; 10705 PetscFunctionReturn(0); 10706 } 10707 10708 /*@ 10709 MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential 10710 matrices from each processor 10711 10712 Collective 10713 10714 Input Parameters: 10715 + comm - the communicators the parallel matrix will live on 10716 . seqmat - the input sequential matrices 10717 . n - number of local columns (or PETSC_DECIDE) 10718 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10719 10720 Output Parameter: 10721 . mpimat - the parallel matrix generated 10722 10723 Level: advanced 10724 10725 Notes: 10726 The number of columns of the matrix in EACH processor MUST be the same. 10727 10728 @*/ 10729 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat) 10730 { 10731 PetscMPIInt size; 10732 10733 PetscFunctionBegin; 10734 PetscCallMPI(MPI_Comm_size(comm,&size)); 10735 if (size == 1) { 10736 if (reuse == MAT_INITIAL_MATRIX) { 10737 PetscCall(MatDuplicate(seqmat,MAT_COPY_VALUES,mpimat)); 10738 } else { 10739 PetscCall(MatCopy(seqmat,*mpimat,SAME_NONZERO_PATTERN)); 10740 } 10741 PetscFunctionReturn(0); 10742 } 10743 10744 PetscCheck(seqmat->ops->creatempimatconcatenateseqmat,PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name); 10745 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"); 10746 10747 PetscCall(PetscLogEventBegin(MAT_Merge,seqmat,0,0,0)); 10748 PetscCall((*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat)); 10749 PetscCall(PetscLogEventEnd(MAT_Merge,seqmat,0,0,0)); 10750 PetscFunctionReturn(0); 10751 } 10752 10753 /*@ 10754 MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent 10755 ranks' ownership ranges. 10756 10757 Collective on A 10758 10759 Input Parameters: 10760 + A - the matrix to create subdomains from 10761 - N - requested number of subdomains 10762 10763 Output Parameters: 10764 + n - number of subdomains resulting on this rank 10765 - iss - IS list with indices of subdomains on this rank 10766 10767 Level: advanced 10768 10769 Notes: 10770 number of subdomains must be smaller than the communicator size 10771 @*/ 10772 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[]) 10773 { 10774 MPI_Comm comm,subcomm; 10775 PetscMPIInt size,rank,color; 10776 PetscInt rstart,rend,k; 10777 10778 PetscFunctionBegin; 10779 PetscCall(PetscObjectGetComm((PetscObject)A,&comm)); 10780 PetscCallMPI(MPI_Comm_size(comm,&size)); 10781 PetscCallMPI(MPI_Comm_rank(comm,&rank)); 10782 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); 10783 *n = 1; 10784 k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */ 10785 color = rank/k; 10786 PetscCallMPI(MPI_Comm_split(comm,color,rank,&subcomm)); 10787 PetscCall(PetscMalloc1(1,iss)); 10788 PetscCall(MatGetOwnershipRange(A,&rstart,&rend)); 10789 PetscCall(ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0])); 10790 PetscCallMPI(MPI_Comm_free(&subcomm)); 10791 PetscFunctionReturn(0); 10792 } 10793 10794 /*@ 10795 MatGalerkin - Constructs the coarse grid problem via Galerkin projection. 10796 10797 If the interpolation and restriction operators are the same, uses MatPtAP. 10798 If they are not the same, use MatMatMatMult. 10799 10800 Once the coarse grid problem is constructed, correct for interpolation operators 10801 that are not of full rank, which can legitimately happen in the case of non-nested 10802 geometric multigrid. 10803 10804 Input Parameters: 10805 + restrct - restriction operator 10806 . dA - fine grid matrix 10807 . interpolate - interpolation operator 10808 . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10809 - fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate 10810 10811 Output Parameters: 10812 . A - the Galerkin coarse matrix 10813 10814 Options Database Key: 10815 . -pc_mg_galerkin <both,pmat,mat,none> - for what matrices the Galerkin process should be used 10816 10817 Level: developer 10818 10819 .seealso: `MatPtAP()`, `MatMatMatMult()` 10820 @*/ 10821 PetscErrorCode MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A) 10822 { 10823 IS zerorows; 10824 Vec diag; 10825 10826 PetscFunctionBegin; 10827 PetscCheck(reuse != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 10828 /* Construct the coarse grid matrix */ 10829 if (interpolate == restrct) { 10830 PetscCall(MatPtAP(dA,interpolate,reuse,fill,A)); 10831 } else { 10832 PetscCall(MatMatMatMult(restrct,dA,interpolate,reuse,fill,A)); 10833 } 10834 10835 /* If the interpolation matrix is not of full rank, A will have zero rows. 10836 This can legitimately happen in the case of non-nested geometric multigrid. 10837 In that event, we set the rows of the matrix to the rows of the identity, 10838 ignoring the equations (as the RHS will also be zero). */ 10839 10840 PetscCall(MatFindZeroRows(*A, &zerorows)); 10841 10842 if (zerorows != NULL) { /* if there are any zero rows */ 10843 PetscCall(MatCreateVecs(*A, &diag, NULL)); 10844 PetscCall(MatGetDiagonal(*A, diag)); 10845 PetscCall(VecISSet(diag, zerorows, 1.0)); 10846 PetscCall(MatDiagonalSet(*A, diag, INSERT_VALUES)); 10847 PetscCall(VecDestroy(&diag)); 10848 PetscCall(ISDestroy(&zerorows)); 10849 } 10850 PetscFunctionReturn(0); 10851 } 10852 10853 /*@C 10854 MatSetOperation - Allows user to set a matrix operation for any matrix type 10855 10856 Logically Collective on Mat 10857 10858 Input Parameters: 10859 + mat - the matrix 10860 . op - the name of the operation 10861 - f - the function that provides the operation 10862 10863 Level: developer 10864 10865 Usage: 10866 $ extern PetscErrorCode usermult(Mat,Vec,Vec); 10867 $ PetscCall(MatCreateXXX(comm,...&A); 10868 $ PetscCall(MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult); 10869 10870 Notes: 10871 See the file include/petscmat.h for a complete list of matrix 10872 operations, which all have the form MATOP_<OPERATION>, where 10873 <OPERATION> is the name (in all capital letters) of the 10874 user interface routine (e.g., MatMult() -> MATOP_MULT). 10875 10876 All user-provided functions (except for MATOP_DESTROY) should have the same calling 10877 sequence as the usual matrix interface routines, since they 10878 are intended to be accessed via the usual matrix interface 10879 routines, e.g., 10880 $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 10881 10882 In particular each function MUST return an error code of 0 on success and 10883 nonzero on failure. 10884 10885 This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type. 10886 10887 .seealso: `MatGetOperation()`, `MatCreateShell()`, `MatShellSetContext()`, `MatShellSetOperation()` 10888 @*/ 10889 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void)) 10890 { 10891 PetscFunctionBegin; 10892 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10893 if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) { 10894 mat->ops->viewnative = mat->ops->view; 10895 } 10896 (((void(**)(void))mat->ops)[op]) = f; 10897 PetscFunctionReturn(0); 10898 } 10899 10900 /*@C 10901 MatGetOperation - Gets a matrix operation for any matrix type. 10902 10903 Not Collective 10904 10905 Input Parameters: 10906 + mat - the matrix 10907 - op - the name of the operation 10908 10909 Output Parameter: 10910 . f - the function that provides the operation 10911 10912 Level: developer 10913 10914 Usage: 10915 $ PetscErrorCode (*usermult)(Mat,Vec,Vec); 10916 $ MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult); 10917 10918 Notes: 10919 See the file include/petscmat.h for a complete list of matrix 10920 operations, which all have the form MATOP_<OPERATION>, where 10921 <OPERATION> is the name (in all capital letters) of the 10922 user interface routine (e.g., MatMult() -> MATOP_MULT). 10923 10924 This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type. 10925 10926 .seealso: `MatSetOperation()`, `MatCreateShell()`, `MatShellGetContext()`, `MatShellGetOperation()` 10927 @*/ 10928 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void)) 10929 { 10930 PetscFunctionBegin; 10931 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10932 *f = (((void (**)(void))mat->ops)[op]); 10933 PetscFunctionReturn(0); 10934 } 10935 10936 /*@ 10937 MatHasOperation - Determines whether the given matrix supports the particular 10938 operation. 10939 10940 Not Collective 10941 10942 Input Parameters: 10943 + mat - the matrix 10944 - op - the operation, for example, MATOP_GET_DIAGONAL 10945 10946 Output Parameter: 10947 . has - either PETSC_TRUE or PETSC_FALSE 10948 10949 Level: advanced 10950 10951 Notes: 10952 See the file include/petscmat.h for a complete list of matrix 10953 operations, which all have the form MATOP_<OPERATION>, where 10954 <OPERATION> is the name (in all capital letters) of the 10955 user-level routine. E.g., MatNorm() -> MATOP_NORM. 10956 10957 .seealso: `MatCreateShell()` 10958 @*/ 10959 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has) 10960 { 10961 PetscFunctionBegin; 10962 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10963 PetscValidBoolPointer(has,3); 10964 if (mat->ops->hasoperation) { 10965 PetscCall((*mat->ops->hasoperation)(mat,op,has)); 10966 } else { 10967 if (((void**)mat->ops)[op]) *has = PETSC_TRUE; 10968 else { 10969 *has = PETSC_FALSE; 10970 if (op == MATOP_CREATE_SUBMATRIX) { 10971 PetscMPIInt size; 10972 10973 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 10974 if (size == 1) { 10975 PetscCall(MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has)); 10976 } 10977 } 10978 } 10979 } 10980 PetscFunctionReturn(0); 10981 } 10982 10983 /*@ 10984 MatHasCongruentLayouts - Determines whether the rows and columns layouts 10985 of the matrix are congruent 10986 10987 Collective on mat 10988 10989 Input Parameters: 10990 . mat - the matrix 10991 10992 Output Parameter: 10993 . cong - either PETSC_TRUE or PETSC_FALSE 10994 10995 Level: beginner 10996 10997 Notes: 10998 10999 .seealso: `MatCreate()`, `MatSetSizes()` 11000 @*/ 11001 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong) 11002 { 11003 PetscFunctionBegin; 11004 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 11005 PetscValidType(mat,1); 11006 PetscValidBoolPointer(cong,2); 11007 if (!mat->rmap || !mat->cmap) { 11008 *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE; 11009 PetscFunctionReturn(0); 11010 } 11011 if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */ 11012 PetscCall(PetscLayoutSetUp(mat->rmap)); 11013 PetscCall(PetscLayoutSetUp(mat->cmap)); 11014 PetscCall(PetscLayoutCompare(mat->rmap,mat->cmap,cong)); 11015 if (*cong) mat->congruentlayouts = 1; 11016 else mat->congruentlayouts = 0; 11017 } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE; 11018 PetscFunctionReturn(0); 11019 } 11020 11021 PetscErrorCode MatSetInf(Mat A) 11022 { 11023 PetscFunctionBegin; 11024 PetscCheck(A->ops->setinf,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"No support for this operation for this matrix type"); 11025 PetscCall((*A->ops->setinf)(A)); 11026 PetscFunctionReturn(0); 11027 } 11028 11029 /*C 11030 MatCreateGraph - create a scalar matrix, for use in graph algorithms 11031 11032 Collective on mat 11033 11034 Input Parameters: 11035 + A - the matrix 11036 - sym - PETSC_TRUE indicates that the graph will be symmetrized 11037 . scale - PETSC_TRUE indicates that the graph will be scaled with the diagonal 11038 11039 Output Parameter: 11040 . graph - the resulting graph 11041 11042 Level: advanced 11043 11044 Notes: 11045 11046 .seealso: `MatCreate()`, `MatFilter()` 11047 */ 11048 PETSC_EXTERN PetscErrorCode MatCreateGraph(Mat A, PetscBool sym, PetscBool scale, Mat *graph) 11049 { 11050 PetscFunctionBegin; 11051 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 11052 PetscValidType(A,1); 11053 PetscValidPointer(graph,3); 11054 PetscCheck(A->ops->creategraph,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"No support for this operation for this matrix type"); 11055 PetscCall((*A->ops->creategraph)(A,sym,scale,graph)); 11056 PetscFunctionReturn(0); 11057 } 11058 11059 /*C 11060 MatFilter - filters a Mat values with an absolut value equal to or below a give threshold 11061 11062 Collective on mat 11063 11064 Input Parameter: 11065 . value - filter value - < 0: does nothing; == 0: removes only 0.0 entries; otherwise: removes entries <= value 11066 11067 Input/Output Parameter: 11068 . A - the Mat to filter in place 11069 11070 Level: advanced 11071 11072 Notes: 11073 11074 .seealso: `MatCreate()`, `MatCreateGraph()` 11075 */ 11076 PETSC_EXTERN PetscErrorCode MatFilter(Mat G,PetscReal value,Mat *F) 11077 { 11078 PetscFunctionBegin; 11079 PetscValidHeaderSpecific(G,MAT_CLASSID,1); 11080 PetscValidType(G,1); 11081 PetscValidPointer(F,3); 11082 if (value >= 0.0) { 11083 PetscCheck(G->ops->filter,PetscObjectComm((PetscObject)G),PETSC_ERR_SUP,"No support for this operation for this matrix type"); 11084 PetscCall((G->ops->filter)(G,value,F)); 11085 } 11086 PetscFunctionReturn(0); 11087 } 11088