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 MatTranspose - Computes an in-place or out-of-place transpose of a matrix. 5142 5143 Collective on Mat 5144 5145 Input Parameters: 5146 + mat - the matrix to transpose 5147 - reuse - either `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, or `MAT_INPLACE_MATRIX` 5148 5149 Output Parameter: 5150 . B - the transpose 5151 5152 Notes: 5153 If you use `MAT_INPLACE_MATRIX` then you must pass in &mat for B 5154 5155 `MAT_REUSE_MATRIX` uses the B matrix from a previous call to this function with `MAT_INITIAL_MATRIX`. If the nonzero structure of mat 5156 changed from the previous call to this function with the same matrices an error will be generated for some matrix types. 5157 5158 Consider using `MatCreateTranspose()` instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed. 5159 5160 If mat is unchanged from the last call this function returns immediately without recomputing the result 5161 5162 Level: intermediate 5163 5164 .seealso: `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse`, `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, `MAT_INPLACE_MATRIX` 5165 @*/ 5166 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B) 5167 { 5168 PetscFunctionBegin; 5169 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5170 PetscValidType(mat,1); 5171 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5172 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5173 PetscCheck(mat->ops->transpose,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5174 PetscCheck(reuse != MAT_INPLACE_MATRIX || mat == *B,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first"); 5175 PetscCheck(reuse != MAT_REUSE_MATRIX || mat != *B,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX"); 5176 MatCheckPreallocated(mat,1); 5177 5178 PetscCall(PetscLogEventBegin(MAT_Transpose,mat,0,0,0)); 5179 PetscCall((*mat->ops->transpose)(mat,reuse,B)); 5180 PetscCall(PetscLogEventEnd(MAT_Transpose,mat,0,0,0)); 5181 if (B) PetscCall(PetscObjectStateIncrease((PetscObject)*B)); 5182 PetscFunctionReturn(0); 5183 } 5184 5185 /*@ 5186 MatIsTranspose - Test whether a matrix is another one's transpose, 5187 or its own, in which case it tests symmetry. 5188 5189 Collective on Mat 5190 5191 Input Parameters: 5192 + A - the matrix to test 5193 - B - the matrix to test against, this can equal the first parameter 5194 5195 Output Parameters: 5196 . flg - the result 5197 5198 Notes: 5199 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 5200 has a running time of the order of the number of nonzeros; the parallel 5201 test involves parallel copies of the block-offdiagonal parts of the matrix. 5202 5203 Level: intermediate 5204 5205 .seealso: `MatTranspose()`, `MatIsSymmetric()`, `MatIsHermitian()` 5206 @*/ 5207 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 5208 { 5209 PetscErrorCode (*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 5210 5211 PetscFunctionBegin; 5212 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5213 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5214 PetscValidBoolPointer(flg,4); 5215 PetscCall(PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f)); 5216 PetscCall(PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g)); 5217 *flg = PETSC_FALSE; 5218 if (f && g) { 5219 PetscCheck(f == g,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test"); 5220 PetscCall((*f)(A,B,tol,flg)); 5221 } else { 5222 MatType mattype; 5223 5224 PetscCall(MatGetType(f ? B : A,&mattype)); 5225 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for transpose",mattype); 5226 } 5227 PetscFunctionReturn(0); 5228 } 5229 5230 /*@ 5231 MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate. 5232 5233 Collective on Mat 5234 5235 Input Parameters: 5236 + mat - the matrix to transpose and complex conjugate 5237 - reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX 5238 5239 Output Parameter: 5240 . B - the Hermitian 5241 5242 Level: intermediate 5243 5244 .seealso: `MatTranspose()`, `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse` 5245 @*/ 5246 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B) 5247 { 5248 PetscFunctionBegin; 5249 PetscCall(MatTranspose(mat,reuse,B)); 5250 #if defined(PETSC_USE_COMPLEX) 5251 PetscCall(MatConjugate(*B)); 5252 #endif 5253 PetscFunctionReturn(0); 5254 } 5255 5256 /*@ 5257 MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose, 5258 5259 Collective on Mat 5260 5261 Input Parameters: 5262 + A - the matrix to test 5263 - B - the matrix to test against, this can equal the first parameter 5264 5265 Output Parameters: 5266 . flg - the result 5267 5268 Notes: 5269 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 5270 has a running time of the order of the number of nonzeros; the parallel 5271 test involves parallel copies of the block-offdiagonal parts of the matrix. 5272 5273 Level: intermediate 5274 5275 .seealso: `MatTranspose()`, `MatIsSymmetric()`, `MatIsHermitian()`, `MatIsTranspose()` 5276 @*/ 5277 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 5278 { 5279 PetscErrorCode (*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 5280 5281 PetscFunctionBegin; 5282 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5283 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5284 PetscValidBoolPointer(flg,4); 5285 PetscCall(PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f)); 5286 PetscCall(PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g)); 5287 if (f && g) { 5288 PetscCheck(f != g,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test"); 5289 PetscCall((*f)(A,B,tol,flg)); 5290 } 5291 PetscFunctionReturn(0); 5292 } 5293 5294 /*@ 5295 MatPermute - Creates a new matrix with rows and columns permuted from the 5296 original. 5297 5298 Collective on Mat 5299 5300 Input Parameters: 5301 + mat - the matrix to permute 5302 . row - row permutation, each processor supplies only the permutation for its rows 5303 - col - column permutation, each processor supplies only the permutation for its columns 5304 5305 Output Parameters: 5306 . B - the permuted matrix 5307 5308 Level: advanced 5309 5310 Note: 5311 The index sets map from row/col of permuted matrix to row/col of original matrix. 5312 The index sets should be on the same communicator as Mat and have the same local sizes. 5313 5314 Developer Note: 5315 If you want to implement MatPermute for a matrix type, and your approach doesn't 5316 exploit the fact that row and col are permutations, consider implementing the 5317 more general MatCreateSubMatrix() instead. 5318 5319 .seealso: `MatGetOrdering()`, `ISAllGather()` 5320 5321 @*/ 5322 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B) 5323 { 5324 PetscFunctionBegin; 5325 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5326 PetscValidType(mat,1); 5327 PetscValidHeaderSpecific(row,IS_CLASSID,2); 5328 PetscValidHeaderSpecific(col,IS_CLASSID,3); 5329 PetscValidPointer(B,4); 5330 PetscCheckSameComm(mat,1,row,2); 5331 if (row != col) PetscCheckSameComm(row,2,col,3); 5332 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5333 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5334 PetscCheck(mat->ops->permute || mat->ops->createsubmatrix,PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name); 5335 MatCheckPreallocated(mat,1); 5336 5337 if (mat->ops->permute) { 5338 PetscCall((*mat->ops->permute)(mat,row,col,B)); 5339 PetscCall(PetscObjectStateIncrease((PetscObject)*B)); 5340 } else { 5341 PetscCall(MatCreateSubMatrix(mat, row, col, MAT_INITIAL_MATRIX, B)); 5342 } 5343 PetscFunctionReturn(0); 5344 } 5345 5346 /*@ 5347 MatEqual - Compares two matrices. 5348 5349 Collective on Mat 5350 5351 Input Parameters: 5352 + A - the first matrix 5353 - B - the second matrix 5354 5355 Output Parameter: 5356 . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise. 5357 5358 Level: intermediate 5359 5360 @*/ 5361 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool *flg) 5362 { 5363 PetscFunctionBegin; 5364 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5365 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5366 PetscValidType(A,1); 5367 PetscValidType(B,2); 5368 PetscValidBoolPointer(flg,3); 5369 PetscCheckSameComm(A,1,B,2); 5370 MatCheckPreallocated(A,1); 5371 MatCheckPreallocated(B,2); 5372 PetscCheck(A->assembled,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5373 PetscCheck(B->assembled,PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5374 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); 5375 if (A->ops->equal && A->ops->equal == B->ops->equal) { 5376 PetscCall((*A->ops->equal)(A,B,flg)); 5377 } else { 5378 PetscCall(MatMultEqual(A,B,10,flg)); 5379 } 5380 PetscFunctionReturn(0); 5381 } 5382 5383 /*@ 5384 MatDiagonalScale - Scales a matrix on the left and right by diagonal 5385 matrices that are stored as vectors. Either of the two scaling 5386 matrices can be NULL. 5387 5388 Collective on Mat 5389 5390 Input Parameters: 5391 + mat - the matrix to be scaled 5392 . l - the left scaling vector (or NULL) 5393 - r - the right scaling vector (or NULL) 5394 5395 Notes: 5396 MatDiagonalScale() computes A = LAR, where 5397 L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector) 5398 The L scales the rows of the matrix, the R scales the columns of the matrix. 5399 5400 Level: intermediate 5401 5402 .seealso: `MatScale()`, `MatShift()`, `MatDiagonalSet()` 5403 @*/ 5404 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r) 5405 { 5406 PetscFunctionBegin; 5407 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5408 PetscValidType(mat,1); 5409 if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);} 5410 if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);} 5411 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5412 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5413 MatCheckPreallocated(mat,1); 5414 if (!l && !r) PetscFunctionReturn(0); 5415 5416 PetscCheck(mat->ops->diagonalscale,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5417 PetscCall(PetscLogEventBegin(MAT_Scale,mat,0,0,0)); 5418 PetscCall((*mat->ops->diagonalscale)(mat,l,r)); 5419 PetscCall(PetscLogEventEnd(MAT_Scale,mat,0,0,0)); 5420 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5421 if (l != r) mat->symmetric = PETSC_BOOL3_FALSE; 5422 PetscFunctionReturn(0); 5423 } 5424 5425 /*@ 5426 MatScale - Scales all elements of a matrix by a given number. 5427 5428 Logically Collective on Mat 5429 5430 Input Parameters: 5431 + mat - the matrix to be scaled 5432 - a - the scaling value 5433 5434 Output Parameter: 5435 . mat - the scaled matrix 5436 5437 Level: intermediate 5438 5439 .seealso: `MatDiagonalScale()` 5440 @*/ 5441 PetscErrorCode MatScale(Mat mat,PetscScalar a) 5442 { 5443 PetscFunctionBegin; 5444 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5445 PetscValidType(mat,1); 5446 PetscCheck(a == (PetscScalar)1.0 || mat->ops->scale,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5447 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5448 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5449 PetscValidLogicalCollectiveScalar(mat,a,2); 5450 MatCheckPreallocated(mat,1); 5451 5452 PetscCall(PetscLogEventBegin(MAT_Scale,mat,0,0,0)); 5453 if (a != (PetscScalar)1.0) { 5454 PetscCall((*mat->ops->scale)(mat,a)); 5455 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5456 } 5457 PetscCall(PetscLogEventEnd(MAT_Scale,mat,0,0,0)); 5458 PetscFunctionReturn(0); 5459 } 5460 5461 /*@ 5462 MatNorm - Calculates various norms of a matrix. 5463 5464 Collective on Mat 5465 5466 Input Parameters: 5467 + mat - the matrix 5468 - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY 5469 5470 Output Parameter: 5471 . nrm - the resulting norm 5472 5473 Level: intermediate 5474 5475 @*/ 5476 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm) 5477 { 5478 PetscFunctionBegin; 5479 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5480 PetscValidType(mat,1); 5481 PetscValidRealPointer(nrm,3); 5482 5483 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5484 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5485 PetscCheck(mat->ops->norm,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5486 MatCheckPreallocated(mat,1); 5487 5488 PetscCall((*mat->ops->norm)(mat,type,nrm)); 5489 PetscFunctionReturn(0); 5490 } 5491 5492 /* 5493 This variable is used to prevent counting of MatAssemblyBegin() that 5494 are called from within a MatAssemblyEnd(). 5495 */ 5496 static PetscInt MatAssemblyEnd_InUse = 0; 5497 /*@ 5498 MatAssemblyBegin - Begins assembling the matrix. This routine should 5499 be called after completing all calls to MatSetValues(). 5500 5501 Collective on Mat 5502 5503 Input Parameters: 5504 + mat - the matrix 5505 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5506 5507 Notes: 5508 MatSetValues() generally caches the values. The matrix is ready to 5509 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5510 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5511 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5512 using the matrix. 5513 5514 ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the 5515 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 5516 a global collective operation requring all processes that share the matrix. 5517 5518 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5519 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5520 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5521 5522 Level: beginner 5523 5524 .seealso: `MatAssemblyEnd()`, `MatSetValues()`, `MatAssembled()` 5525 @*/ 5526 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type) 5527 { 5528 PetscFunctionBegin; 5529 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5530 PetscValidType(mat,1); 5531 MatCheckPreallocated(mat,1); 5532 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?"); 5533 if (mat->assembled) { 5534 mat->was_assembled = PETSC_TRUE; 5535 mat->assembled = PETSC_FALSE; 5536 } 5537 5538 if (!MatAssemblyEnd_InUse) { 5539 PetscCall(PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0)); 5540 if (mat->ops->assemblybegin) PetscCall((*mat->ops->assemblybegin)(mat,type)); 5541 PetscCall(PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0)); 5542 } else if (mat->ops->assemblybegin) PetscCall((*mat->ops->assemblybegin)(mat,type)); 5543 PetscFunctionReturn(0); 5544 } 5545 5546 /*@ 5547 MatAssembled - Indicates if a matrix has been assembled and is ready for 5548 use; for example, in matrix-vector product. 5549 5550 Not Collective 5551 5552 Input Parameter: 5553 . mat - the matrix 5554 5555 Output Parameter: 5556 . assembled - PETSC_TRUE or PETSC_FALSE 5557 5558 Level: advanced 5559 5560 .seealso: `MatAssemblyEnd()`, `MatSetValues()`, `MatAssemblyBegin()` 5561 @*/ 5562 PetscErrorCode MatAssembled(Mat mat,PetscBool *assembled) 5563 { 5564 PetscFunctionBegin; 5565 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5566 PetscValidBoolPointer(assembled,2); 5567 *assembled = mat->assembled; 5568 PetscFunctionReturn(0); 5569 } 5570 5571 /*@ 5572 MatAssemblyEnd - Completes assembling the matrix. This routine should 5573 be called after MatAssemblyBegin(). 5574 5575 Collective on Mat 5576 5577 Input Parameters: 5578 + mat - the matrix 5579 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5580 5581 Options Database Keys: 5582 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly() 5583 . -mat_view ::ascii_info_detail - Prints more detailed info 5584 . -mat_view - Prints matrix in ASCII format 5585 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 5586 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 5587 . -display <name> - Sets display name (default is host) 5588 . -draw_pause <sec> - Sets number of seconds to pause after display 5589 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab) 5590 . -viewer_socket_machine <machine> - Machine to use for socket 5591 . -viewer_socket_port <port> - Port number to use for socket 5592 - -mat_view binary:filename[:append] - Save matrix to file in binary format 5593 5594 Notes: 5595 MatSetValues() generally caches the values. The matrix is ready to 5596 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5597 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5598 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5599 using the matrix. 5600 5601 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5602 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5603 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5604 5605 Level: beginner 5606 5607 .seealso: `MatAssemblyBegin()`, `MatSetValues()`, `PetscDrawOpenX()`, `PetscDrawCreate()`, `MatView()`, `MatAssembled()`, `PetscViewerSocketOpen()` 5608 @*/ 5609 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type) 5610 { 5611 static PetscInt inassm = 0; 5612 PetscBool flg = PETSC_FALSE; 5613 5614 PetscFunctionBegin; 5615 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5616 PetscValidType(mat,1); 5617 5618 inassm++; 5619 MatAssemblyEnd_InUse++; 5620 if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */ 5621 PetscCall(PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0)); 5622 if (mat->ops->assemblyend) PetscCall((*mat->ops->assemblyend)(mat,type)); 5623 PetscCall(PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0)); 5624 } else if (mat->ops->assemblyend) PetscCall((*mat->ops->assemblyend)(mat,type)); 5625 5626 /* Flush assembly is not a true assembly */ 5627 if (type != MAT_FLUSH_ASSEMBLY) { 5628 if (mat->num_ass) { 5629 if (!mat->symmetry_eternal) { 5630 mat->symmetric = PETSC_BOOL3_UNKNOWN; 5631 mat->hermitian = PETSC_BOOL3_UNKNOWN; 5632 } 5633 if (!mat->structural_symmetry_eternal && mat->ass_nonzerostate != mat->nonzerostate) { 5634 mat->structurally_symmetric = PETSC_BOOL3_UNKNOWN; 5635 } 5636 if (!mat->spd_eternal) mat->spd = PETSC_BOOL3_UNKNOWN; 5637 } 5638 mat->num_ass++; 5639 mat->assembled = PETSC_TRUE; 5640 mat->ass_nonzerostate = mat->nonzerostate; 5641 } 5642 5643 mat->insertmode = NOT_SET_VALUES; 5644 MatAssemblyEnd_InUse--; 5645 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5646 if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) { 5647 PetscCall(MatViewFromOptions(mat,NULL,"-mat_view")); 5648 5649 if (mat->checksymmetryonassembly) { 5650 PetscCall(MatIsSymmetric(mat,mat->checksymmetrytol,&flg)); 5651 if (flg) { 5652 PetscCall(PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol)); 5653 } else { 5654 PetscCall(PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol)); 5655 } 5656 } 5657 if (mat->nullsp && mat->checknullspaceonassembly) { 5658 PetscCall(MatNullSpaceTest(mat->nullsp,mat,NULL)); 5659 } 5660 } 5661 inassm--; 5662 PetscFunctionReturn(0); 5663 } 5664 5665 /*@ 5666 MatSetOption - Sets a parameter option for a matrix. Some options 5667 may be specific to certain storage formats. Some options 5668 determine how values will be inserted (or added). Sorted, 5669 row-oriented input will generally assemble the fastest. The default 5670 is row-oriented. 5671 5672 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5673 5674 Input Parameters: 5675 + mat - the matrix 5676 . option - the option, one of those listed below (and possibly others), 5677 - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5678 5679 Options Describing Matrix Structure: 5680 + MAT_SPD - symmetric positive definite 5681 . MAT_SYMMETRIC - symmetric in terms of both structure and value 5682 . MAT_HERMITIAN - transpose is the complex conjugation 5683 . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure 5684 - MAT_SYMMETRY_ETERNAL - indicates the symmetry (or Hermitian structure) or its absence will persist through any changes to the matrix 5685 - MAT_STRUCTURAL_SYMMETRY_ETERNAL - indicates the structural symmetry or its absence will persist through any changes to the matrix 5686 5687 These are not really options of the matrix, they are knowledge about the structure of the matrix that users may provide so that they 5688 do not need to be computed (usually at a high cost) 5689 5690 Options For Use with MatSetValues(): 5691 Insert a logically dense subblock, which can be 5692 . MAT_ROW_ORIENTED - row-oriented (default) 5693 5694 Note these options reflect the data you pass in with MatSetValues(); it has 5695 nothing to do with how the data is stored internally in the matrix 5696 data structure. 5697 5698 When (re)assembling a matrix, we can restrict the input for 5699 efficiency/debugging purposes. These options include 5700 + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow) 5701 . MAT_FORCE_DIAGONAL_ENTRIES - forces diagonal entries to be allocated 5702 . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries 5703 . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry 5704 . MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly 5705 . MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if 5706 any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves 5707 performance for very large process counts. 5708 - MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset 5709 of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly 5710 functions, instead sending only neighbor messages. 5711 5712 Notes: 5713 Except for MAT_UNUSED_NONZERO_LOCATION_ERR and MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg! 5714 5715 Some options are relevant only for particular matrix types and 5716 are thus ignored by others. Other options are not supported by 5717 certain matrix types and will generate an error message if set. 5718 5719 If using a Fortran 77 module to compute a matrix, one may need to 5720 use the column-oriented option (or convert to the row-oriented 5721 format). 5722 5723 MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion 5724 that would generate a new entry in the nonzero structure is instead 5725 ignored. Thus, if memory has not alredy been allocated for this particular 5726 data, then the insertion is ignored. For dense matrices, in which 5727 the entire array is allocated, no entries are ever ignored. 5728 Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5729 5730 MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5731 that would generate a new entry in the nonzero structure instead produces 5732 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 5733 5734 MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5735 that would generate a new entry that has not been preallocated will 5736 instead produce an error. (Currently supported for AIJ and BAIJ formats 5737 only.) This is a useful flag when debugging matrix memory preallocation. 5738 If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5739 5740 MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for 5741 other processors should be dropped, rather than stashed. 5742 This is useful if you know that the "owning" processor is also 5743 always generating the correct matrix entries, so that PETSc need 5744 not transfer duplicate entries generated on another processor. 5745 5746 MAT_USE_HASH_TABLE indicates that a hash table be used to improve the 5747 searches during matrix assembly. When this flag is set, the hash table 5748 is created during the first Matrix Assembly. This hash table is 5749 used the next time through, during MatSetVaules()/MatSetVaulesBlocked() 5750 to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag 5751 should be used with MAT_USE_HASH_TABLE flag. This option is currently 5752 supported by MATMPIBAIJ format only. 5753 5754 MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries 5755 are kept in the nonzero structure 5756 5757 MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating 5758 a zero location in the matrix 5759 5760 MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types 5761 5762 MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the 5763 zero row routines and thus improves performance for very large process counts. 5764 5765 MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular 5766 part of the matrix (since they should match the upper triangular part). 5767 5768 MAT_SORTED_FULL - each process provides exactly its local rows; all column indices for a given row are passed in a 5769 single call to MatSetValues(), preallocation is perfect, row oriented, INSERT_VALUES is used. Common 5770 with finite difference schemes with non-periodic boundary conditions. 5771 5772 Level: intermediate 5773 5774 .seealso: `MatOption`, `Mat`, `MatGetOption()` 5775 5776 @*/ 5777 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg) 5778 { 5779 PetscFunctionBegin; 5780 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5781 if (op > 0) { 5782 PetscValidLogicalCollectiveEnum(mat,op,2); 5783 PetscValidLogicalCollectiveBool(mat,flg,3); 5784 } 5785 5786 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); 5787 5788 switch (op) { 5789 case MAT_FORCE_DIAGONAL_ENTRIES: 5790 mat->force_diagonals = flg; 5791 PetscFunctionReturn(0); 5792 case MAT_NO_OFF_PROC_ENTRIES: 5793 mat->nooffprocentries = flg; 5794 PetscFunctionReturn(0); 5795 case MAT_SUBSET_OFF_PROC_ENTRIES: 5796 mat->assembly_subset = flg; 5797 if (!mat->assembly_subset) { /* See the same logic in VecAssembly wrt VEC_SUBSET_OFF_PROC_ENTRIES */ 5798 #if !defined(PETSC_HAVE_MPIUNI) 5799 PetscCall(MatStashScatterDestroy_BTS(&mat->stash)); 5800 #endif 5801 mat->stash.first_assembly_done = PETSC_FALSE; 5802 } 5803 PetscFunctionReturn(0); 5804 case MAT_NO_OFF_PROC_ZERO_ROWS: 5805 mat->nooffproczerorows = flg; 5806 PetscFunctionReturn(0); 5807 case MAT_SPD: 5808 if (flg) { 5809 mat->spd = PETSC_BOOL3_TRUE; 5810 mat->symmetric = PETSC_BOOL3_TRUE; 5811 mat->structurally_symmetric = PETSC_BOOL3_TRUE; 5812 } else { 5813 mat->spd = PETSC_BOOL3_FALSE; 5814 } 5815 break; 5816 case MAT_SYMMETRIC: 5817 mat->symmetric = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5818 if (flg) mat->structurally_symmetric = PETSC_BOOL3_TRUE; 5819 #if !defined(PETSC_USE_COMPLEX) 5820 mat->hermitian = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5821 #endif 5822 break; 5823 case MAT_HERMITIAN: 5824 mat->hermitian = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5825 if (flg) mat->structurally_symmetric = PETSC_BOOL3_TRUE; 5826 #if !defined(PETSC_USE_COMPLEX) 5827 mat->symmetric = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5828 #endif 5829 break; 5830 case MAT_STRUCTURALLY_SYMMETRIC: 5831 mat->structurally_symmetric = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5832 break; 5833 case MAT_SYMMETRY_ETERNAL: 5834 mat->symmetry_eternal = flg ? PETSC_TRUE : PETSC_FALSE; 5835 if (flg) mat->structural_symmetry_eternal = PETSC_TRUE; 5836 break; 5837 case MAT_STRUCTURAL_SYMMETRY_ETERNAL: 5838 mat->structural_symmetry_eternal = flg; 5839 break; 5840 case MAT_SPD_ETERNAL: 5841 mat->spd_eternal = flg; 5842 if (flg) { 5843 mat->structural_symmetry_eternal = PETSC_TRUE; 5844 mat->symmetry_eternal = PETSC_TRUE; 5845 } 5846 break; 5847 case MAT_STRUCTURE_ONLY: 5848 mat->structure_only = flg; 5849 break; 5850 case MAT_SORTED_FULL: 5851 mat->sortedfull = flg; 5852 break; 5853 default: 5854 break; 5855 } 5856 if (mat->ops->setoption) PetscCall((*mat->ops->setoption)(mat,op,flg)); 5857 PetscFunctionReturn(0); 5858 } 5859 5860 /*@ 5861 MatGetOption - Gets a parameter option that has been set for a matrix. 5862 5863 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5864 5865 Input Parameters: 5866 + mat - the matrix 5867 - option - the option, this only responds to certain options, check the code for which ones 5868 5869 Output Parameter: 5870 . flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5871 5872 Notes: 5873 Can only be called after MatSetSizes() and MatSetType() have been set. 5874 5875 Certain option values may be unknown, for those use the routines `MatIsSymmetric()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, or 5876 `MatIsSymmetricKnown()`, `MatIsHermitianKnown()`, `MatIsStructurallySymmetricKnown()` 5877 5878 Level: intermediate 5879 5880 .seealso: `MatOption`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, 5881 `MatIsSymmetricKnown()`, `MatIsHermitianKnown()`, `MatIsStructurallySymmetricKnown()` 5882 5883 @*/ 5884 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg) 5885 { 5886 PetscFunctionBegin; 5887 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5888 PetscValidType(mat,1); 5889 5890 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); 5891 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()"); 5892 5893 switch (op) { 5894 case MAT_NO_OFF_PROC_ENTRIES: 5895 *flg = mat->nooffprocentries; 5896 break; 5897 case MAT_NO_OFF_PROC_ZERO_ROWS: 5898 *flg = mat->nooffproczerorows; 5899 break; 5900 case MAT_SYMMETRIC: 5901 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Use MatIsSymmetric() or MatIsSymmetricKnown()"); 5902 break; 5903 case MAT_HERMITIAN: 5904 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Use MatIsHermitian() or MatIsHermitianKnown()"); 5905 break; 5906 case MAT_STRUCTURALLY_SYMMETRIC: 5907 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Use MatIsStructurallySymmetric() or MatIsStructurallySymmetricKnown()"); 5908 break; 5909 case MAT_SPD: 5910 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Use MatIsSPDKnown()"); 5911 break; 5912 case MAT_SYMMETRY_ETERNAL: 5913 *flg = mat->symmetry_eternal; 5914 break; 5915 case MAT_STRUCTURAL_SYMMETRY_ETERNAL: 5916 *flg = mat->symmetry_eternal; 5917 break; 5918 default: 5919 break; 5920 } 5921 PetscFunctionReturn(0); 5922 } 5923 5924 /*@ 5925 MatZeroEntries - Zeros all entries of a matrix. For sparse matrices 5926 this routine retains the old nonzero structure. 5927 5928 Logically Collective on Mat 5929 5930 Input Parameters: 5931 . mat - the matrix 5932 5933 Level: intermediate 5934 5935 Notes: 5936 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. 5937 See the Performance chapter of the users manual for information on preallocating matrices. 5938 5939 .seealso: `MatZeroRows()` 5940 @*/ 5941 PetscErrorCode MatZeroEntries(Mat mat) 5942 { 5943 PetscFunctionBegin; 5944 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5945 PetscValidType(mat,1); 5946 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5947 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"); 5948 PetscCheck(mat->ops->zeroentries,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5949 MatCheckPreallocated(mat,1); 5950 5951 PetscCall(PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0)); 5952 PetscCall((*mat->ops->zeroentries)(mat)); 5953 PetscCall(PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0)); 5954 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5955 PetscFunctionReturn(0); 5956 } 5957 5958 /*@ 5959 MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal) 5960 of a set of rows and columns of a matrix. 5961 5962 Collective on Mat 5963 5964 Input Parameters: 5965 + mat - the matrix 5966 . numRows - the number of rows to remove 5967 . rows - the global row indices 5968 . diag - value put in the diagonal of the eliminated rows 5969 . x - optional vector of solutions for zeroed rows (other entries in vector are not used), these must be set before this call 5970 - b - optional vector of right hand side, that will be adjusted by provided solution 5971 5972 Notes: 5973 This routine, along with `MatZeroRows()`, is typically used to eliminate known Dirichlet boundary conditions from a linear system. 5974 5975 For each zeroed row, the value of the corresponding b is set to diag times the value of the corresponding x. 5976 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 5977 5978 If the resulting linear system is to be solved with KSP then one can (but does not have to) call `KSPSetInitialGuessNonzero()` to allow the 5979 Krylov method to take advantage of the known solution on the zeroed rows. 5980 5981 For the parallel case, all processes that share the matrix (i.e., 5982 those in the communicator used for matrix creation) MUST call this 5983 routine, regardless of whether any rows being zeroed are owned by 5984 them. 5985 5986 Unlike `MatZeroRows()` this does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5987 5988 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5989 list only rows local to itself). 5990 5991 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 5992 5993 Level: intermediate 5994 5995 .seealso: `MatZeroRowsIS()`, `MatZeroRows()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 5996 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 5997 @*/ 5998 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5999 { 6000 PetscFunctionBegin; 6001 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6002 PetscValidType(mat,1); 6003 if (numRows) PetscValidIntPointer(rows,3); 6004 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6005 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6006 PetscCheck(mat->ops->zerorowscolumns,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6007 MatCheckPreallocated(mat,1); 6008 6009 PetscCall((*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b)); 6010 PetscCall(MatViewFromOptions(mat,NULL,"-mat_view")); 6011 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6012 PetscFunctionReturn(0); 6013 } 6014 6015 /*@ 6016 MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal) 6017 of a set of rows and columns of a matrix. 6018 6019 Collective on Mat 6020 6021 Input Parameters: 6022 + mat - the matrix 6023 . is - the rows to zero 6024 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6025 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6026 - b - optional vector of right hand side, that will be adjusted by provided solution 6027 6028 Note: 6029 See `MatZeroRowsColumns()` for details on how this routine operates. 6030 6031 Level: intermediate 6032 6033 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6034 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRows()`, `MatZeroRowsColumnsStencil()` 6035 @*/ 6036 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6037 { 6038 PetscInt numRows; 6039 const PetscInt *rows; 6040 6041 PetscFunctionBegin; 6042 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6043 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6044 PetscValidType(mat,1); 6045 PetscValidType(is,2); 6046 PetscCall(ISGetLocalSize(is,&numRows)); 6047 PetscCall(ISGetIndices(is,&rows)); 6048 PetscCall(MatZeroRowsColumns(mat,numRows,rows,diag,x,b)); 6049 PetscCall(ISRestoreIndices(is,&rows)); 6050 PetscFunctionReturn(0); 6051 } 6052 6053 /*@ 6054 MatZeroRows - Zeros all entries (except possibly the main diagonal) 6055 of a set of rows of a matrix. 6056 6057 Collective on Mat 6058 6059 Input Parameters: 6060 + mat - the matrix 6061 . numRows - the number of rows to remove 6062 . rows - the global row indices 6063 . diag - value put in the diagonal of the eliminated rows 6064 . x - optional vector of solutions for zeroed rows (other entries in vector are not used), these must be set before this call 6065 - b - optional vector of right hand side, that will be adjusted by provided solution 6066 6067 Notes: 6068 This routine, along with `MatZeroRowsColumns()`, is typically used to eliminate known Dirichlet boundary conditions from a linear system. 6069 6070 For each zeroed row, the value of the corresponding b is set to diag times the value of the corresponding x. 6071 6072 If the resulting linear system is to be solved with KSP then one can (but does not have to) call `KSPSetInitialGuessNonzero()` to allow the 6073 Krylov method to take advantage of the known solution on the zeroed rows. 6074 6075 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) 6076 from the matrix. 6077 6078 Unlike `MatZeroRowsColumns()` for the AIJ and BAIJ matrix formats this removes the old nonzero structure, from the eliminated rows of the matrix 6079 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 6080 formats this does not alter the nonzero structure. 6081 6082 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6083 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6084 merely zeroed. 6085 6086 The user can set a value in the diagonal entry (or for the AIJ and 6087 row formats can optionally remove the main diagonal entry from the 6088 nonzero structure as well, by passing 0.0 as the final argument). 6089 6090 For the parallel case, all processes that share the matrix (i.e., 6091 those in the communicator used for matrix creation) MUST call this 6092 routine, regardless of whether any rows being zeroed are owned by 6093 them. 6094 6095 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6096 list only rows local to itself). 6097 6098 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6099 owns that are to be zeroed. This saves a global synchronization in the implementation. 6100 6101 Level: intermediate 6102 6103 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6104 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()`, `PCREDISTRIBUTE` 6105 @*/ 6106 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6107 { 6108 PetscFunctionBegin; 6109 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6110 PetscValidType(mat,1); 6111 if (numRows) PetscValidIntPointer(rows,3); 6112 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6113 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6114 PetscCheck(mat->ops->zerorows,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6115 MatCheckPreallocated(mat,1); 6116 6117 PetscCall((*mat->ops->zerorows)(mat,numRows,rows,diag,x,b)); 6118 PetscCall(MatViewFromOptions(mat,NULL,"-mat_view")); 6119 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6120 PetscFunctionReturn(0); 6121 } 6122 6123 /*@ 6124 MatZeroRowsIS - Zeros all entries (except possibly the main diagonal) 6125 of a set of rows of a matrix. 6126 6127 Collective on Mat 6128 6129 Input Parameters: 6130 + mat - the matrix 6131 . is - index set of rows to remove (if NULL then no row is removed) 6132 . diag - value put in all diagonals of eliminated rows 6133 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6134 - b - optional vector of right hand side, that will be adjusted by provided solution 6135 6136 Note: 6137 See `MatZeroRows()` for details on how this routine operates. 6138 6139 Level: intermediate 6140 6141 .seealso: `MatZeroRows()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6142 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6143 @*/ 6144 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6145 { 6146 PetscInt numRows = 0; 6147 const PetscInt *rows = NULL; 6148 6149 PetscFunctionBegin; 6150 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6151 PetscValidType(mat,1); 6152 if (is) { 6153 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6154 PetscCall(ISGetLocalSize(is,&numRows)); 6155 PetscCall(ISGetIndices(is,&rows)); 6156 } 6157 PetscCall(MatZeroRows(mat,numRows,rows,diag,x,b)); 6158 if (is) { 6159 PetscCall(ISRestoreIndices(is,&rows)); 6160 } 6161 PetscFunctionReturn(0); 6162 } 6163 6164 /*@ 6165 MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal) 6166 of a set of rows of a matrix. These rows must be local to the process. 6167 6168 Collective on Mat 6169 6170 Input Parameters: 6171 + mat - the matrix 6172 . numRows - the number of rows to remove 6173 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 6174 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6175 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6176 - b - optional vector of right hand side, that will be adjusted by provided solution 6177 6178 Notes: 6179 See `MatZeroRows()` for details on how this routine operates. 6180 6181 The grid coordinates are across the entire grid, not just the local portion 6182 6183 In Fortran idxm and idxn should be declared as 6184 $ MatStencil idxm(4,m) 6185 and the values inserted using 6186 $ idxm(MatStencil_i,1) = i 6187 $ idxm(MatStencil_j,1) = j 6188 $ idxm(MatStencil_k,1) = k 6189 $ idxm(MatStencil_c,1) = c 6190 etc 6191 6192 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6193 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6194 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6195 DM_BOUNDARY_PERIODIC boundary type. 6196 6197 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 6198 a single value per point) you can skip filling those indices. 6199 6200 Level: intermediate 6201 6202 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsl()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6203 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6204 @*/ 6205 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 6206 { 6207 PetscInt dim = mat->stencil.dim; 6208 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 6209 PetscInt *dims = mat->stencil.dims+1; 6210 PetscInt *starts = mat->stencil.starts; 6211 PetscInt *dxm = (PetscInt*) rows; 6212 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6213 6214 PetscFunctionBegin; 6215 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6216 PetscValidType(mat,1); 6217 if (numRows) PetscValidPointer(rows,3); 6218 6219 PetscCall(PetscMalloc1(numRows, &jdxm)); 6220 for (i = 0; i < numRows; ++i) { 6221 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6222 for (j = 0; j < 3-sdim; ++j) dxm++; 6223 /* Local index in X dir */ 6224 tmp = *dxm++ - starts[0]; 6225 /* Loop over remaining dimensions */ 6226 for (j = 0; j < dim-1; ++j) { 6227 /* If nonlocal, set index to be negative */ 6228 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6229 /* Update local index */ 6230 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6231 } 6232 /* Skip component slot if necessary */ 6233 if (mat->stencil.noc) dxm++; 6234 /* Local row number */ 6235 if (tmp >= 0) { 6236 jdxm[numNewRows++] = tmp; 6237 } 6238 } 6239 PetscCall(MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b)); 6240 PetscCall(PetscFree(jdxm)); 6241 PetscFunctionReturn(0); 6242 } 6243 6244 /*@ 6245 MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal) 6246 of a set of rows and columns of a matrix. 6247 6248 Collective on Mat 6249 6250 Input Parameters: 6251 + mat - the matrix 6252 . numRows - the number of rows/columns to remove 6253 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 6254 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6255 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6256 - b - optional vector of right hand side, that will be adjusted by provided solution 6257 6258 Notes: 6259 See `MatZeroRowsColumns()` for details on how this routine operates. 6260 6261 The grid coordinates are across the entire grid, not just the local portion 6262 6263 In Fortran idxm and idxn should be declared as 6264 $ MatStencil idxm(4,m) 6265 and the values inserted using 6266 $ idxm(MatStencil_i,1) = i 6267 $ idxm(MatStencil_j,1) = j 6268 $ idxm(MatStencil_k,1) = k 6269 $ idxm(MatStencil_c,1) = c 6270 etc 6271 6272 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6273 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6274 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6275 DM_BOUNDARY_PERIODIC boundary type. 6276 6277 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 6278 a single value per point) you can skip filling those indices. 6279 6280 Level: intermediate 6281 6282 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6283 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRows()` 6284 @*/ 6285 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 6286 { 6287 PetscInt dim = mat->stencil.dim; 6288 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 6289 PetscInt *dims = mat->stencil.dims+1; 6290 PetscInt *starts = mat->stencil.starts; 6291 PetscInt *dxm = (PetscInt*) rows; 6292 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6293 6294 PetscFunctionBegin; 6295 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6296 PetscValidType(mat,1); 6297 if (numRows) PetscValidPointer(rows,3); 6298 6299 PetscCall(PetscMalloc1(numRows, &jdxm)); 6300 for (i = 0; i < numRows; ++i) { 6301 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6302 for (j = 0; j < 3-sdim; ++j) dxm++; 6303 /* Local index in X dir */ 6304 tmp = *dxm++ - starts[0]; 6305 /* Loop over remaining dimensions */ 6306 for (j = 0; j < dim-1; ++j) { 6307 /* If nonlocal, set index to be negative */ 6308 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6309 /* Update local index */ 6310 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6311 } 6312 /* Skip component slot if necessary */ 6313 if (mat->stencil.noc) dxm++; 6314 /* Local row number */ 6315 if (tmp >= 0) { 6316 jdxm[numNewRows++] = tmp; 6317 } 6318 } 6319 PetscCall(MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b)); 6320 PetscCall(PetscFree(jdxm)); 6321 PetscFunctionReturn(0); 6322 } 6323 6324 /*@C 6325 MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal) 6326 of a set of rows of a matrix; using local numbering of rows. 6327 6328 Collective on Mat 6329 6330 Input Parameters: 6331 + mat - the matrix 6332 . numRows - the number of rows to remove 6333 . rows - the local row indices 6334 . diag - value put in all diagonals of eliminated rows 6335 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6336 - b - optional vector of right hand side, that will be adjusted by provided solution 6337 6338 Notes: 6339 Before calling `MatZeroRowsLocal()`, the user must first set the 6340 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6341 6342 See `MatZeroRows()` for details on how this routine operates. 6343 6344 Level: intermediate 6345 6346 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRows()`, `MatSetOption()`, 6347 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6348 @*/ 6349 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6350 { 6351 PetscFunctionBegin; 6352 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6353 PetscValidType(mat,1); 6354 if (numRows) PetscValidIntPointer(rows,3); 6355 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6356 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6357 MatCheckPreallocated(mat,1); 6358 6359 if (mat->ops->zerorowslocal) { 6360 PetscCall((*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b)); 6361 } else { 6362 IS is, newis; 6363 const PetscInt *newRows; 6364 6365 PetscCheck(mat->rmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6366 PetscCall(ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is)); 6367 PetscCall(ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis)); 6368 PetscCall(ISGetIndices(newis,&newRows)); 6369 PetscCall((*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b)); 6370 PetscCall(ISRestoreIndices(newis,&newRows)); 6371 PetscCall(ISDestroy(&newis)); 6372 PetscCall(ISDestroy(&is)); 6373 } 6374 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6375 PetscFunctionReturn(0); 6376 } 6377 6378 /*@ 6379 MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal) 6380 of a set of rows of a matrix; using local numbering of rows. 6381 6382 Collective on Mat 6383 6384 Input Parameters: 6385 + mat - the matrix 6386 . is - index set of rows to remove 6387 . diag - value put in all diagonals of eliminated rows 6388 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6389 - b - optional vector of right hand side, that will be adjusted by provided solution 6390 6391 Notes: 6392 Before calling `MatZeroRowsLocalIS()`, the user must first set the 6393 local-to-global mapping by calling `MatSetLocalToGlobalMapping()`. 6394 6395 See `MatZeroRows()` for details on how this routine operates. 6396 6397 Level: intermediate 6398 6399 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRows()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6400 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6401 @*/ 6402 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6403 { 6404 PetscInt numRows; 6405 const PetscInt *rows; 6406 6407 PetscFunctionBegin; 6408 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6409 PetscValidType(mat,1); 6410 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6411 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6412 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6413 MatCheckPreallocated(mat,1); 6414 6415 PetscCall(ISGetLocalSize(is,&numRows)); 6416 PetscCall(ISGetIndices(is,&rows)); 6417 PetscCall(MatZeroRowsLocal(mat,numRows,rows,diag,x,b)); 6418 PetscCall(ISRestoreIndices(is,&rows)); 6419 PetscFunctionReturn(0); 6420 } 6421 6422 /*@ 6423 MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal) 6424 of a set of rows and columns of a matrix; using local numbering of rows. 6425 6426 Collective on Mat 6427 6428 Input Parameters: 6429 + mat - the matrix 6430 . numRows - the number of rows to remove 6431 . rows - the global row indices 6432 . diag - value put in all diagonals of eliminated rows 6433 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6434 - b - optional vector of right hand side, that will be adjusted by provided solution 6435 6436 Notes: 6437 Before calling MatZeroRowsColumnsLocal(), the user must first set the 6438 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6439 6440 See `MatZeroRowsColumns()` for details on how this routine operates. 6441 6442 Level: intermediate 6443 6444 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6445 `MatZeroRows()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6446 @*/ 6447 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6448 { 6449 IS is, newis; 6450 const PetscInt *newRows; 6451 6452 PetscFunctionBegin; 6453 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6454 PetscValidType(mat,1); 6455 if (numRows) PetscValidIntPointer(rows,3); 6456 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6457 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6458 MatCheckPreallocated(mat,1); 6459 6460 PetscCheck(mat->cmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6461 PetscCall(ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is)); 6462 PetscCall(ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis)); 6463 PetscCall(ISGetIndices(newis,&newRows)); 6464 PetscCall((*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b)); 6465 PetscCall(ISRestoreIndices(newis,&newRows)); 6466 PetscCall(ISDestroy(&newis)); 6467 PetscCall(ISDestroy(&is)); 6468 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6469 PetscFunctionReturn(0); 6470 } 6471 6472 /*@ 6473 MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal) 6474 of a set of rows and columns of a matrix; using local numbering of rows. 6475 6476 Collective on Mat 6477 6478 Input Parameters: 6479 + mat - the matrix 6480 . is - index set of rows to remove 6481 . diag - value put in all diagonals of eliminated rows 6482 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6483 - b - optional vector of right hand side, that will be adjusted by provided solution 6484 6485 Notes: 6486 Before calling `MatZeroRowsColumnsLocalIS()`, the user must first set the 6487 local-to-global mapping by calling `MatSetLocalToGlobalMapping()`. 6488 6489 See `MatZeroRowsColumns()` for details on how this routine operates. 6490 6491 Level: intermediate 6492 6493 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6494 `MatZeroRowsColumnsLocal()`, `MatZeroRows()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6495 @*/ 6496 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6497 { 6498 PetscInt numRows; 6499 const PetscInt *rows; 6500 6501 PetscFunctionBegin; 6502 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6503 PetscValidType(mat,1); 6504 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6505 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6506 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6507 MatCheckPreallocated(mat,1); 6508 6509 PetscCall(ISGetLocalSize(is,&numRows)); 6510 PetscCall(ISGetIndices(is,&rows)); 6511 PetscCall(MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b)); 6512 PetscCall(ISRestoreIndices(is,&rows)); 6513 PetscFunctionReturn(0); 6514 } 6515 6516 /*@C 6517 MatGetSize - Returns the numbers of rows and columns in a matrix. 6518 6519 Not Collective 6520 6521 Input Parameter: 6522 . mat - the matrix 6523 6524 Output Parameters: 6525 + m - the number of global rows 6526 - n - the number of global columns 6527 6528 Note: both output parameters can be NULL on input. 6529 6530 Level: beginner 6531 6532 .seealso: `MatGetLocalSize()` 6533 @*/ 6534 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n) 6535 { 6536 PetscFunctionBegin; 6537 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6538 if (m) *m = mat->rmap->N; 6539 if (n) *n = mat->cmap->N; 6540 PetscFunctionReturn(0); 6541 } 6542 6543 /*@C 6544 MatGetLocalSize - For most matrix formats, excluding `MATELEMENTAL` and `MATSCALAPACK`, Returns the number of local rows and local columns 6545 of a matrix. For all matrices this is the local size of the left and right vectors as returned by MatCreateVecs(). 6546 6547 Not Collective 6548 6549 Input Parameter: 6550 . mat - the matrix 6551 6552 Output Parameters: 6553 + m - the number of local rows, use `NULL` to not obtain this value 6554 - n - the number of local columns, use `NULL` to not obtain this value 6555 6556 Level: beginner 6557 6558 .seealso: `MatGetSize()` 6559 @*/ 6560 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n) 6561 { 6562 PetscFunctionBegin; 6563 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6564 if (m) PetscValidIntPointer(m,2); 6565 if (n) PetscValidIntPointer(n,3); 6566 if (m) *m = mat->rmap->n; 6567 if (n) *n = mat->cmap->n; 6568 PetscFunctionReturn(0); 6569 } 6570 6571 /*@C 6572 MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies this matrix by that are owned by 6573 this processor. (The columns of the "diagonal block" for most sparse matrix formats). See :any:`<sec_matlayout>` for details on matrix layouts. 6574 6575 Not Collective, unless matrix has not been allocated, then collective on Mat 6576 6577 Input Parameter: 6578 . mat - the matrix 6579 6580 Output Parameters: 6581 + m - the global index of the first local column, use `NULL` to not obtain this value 6582 - n - one more than the global index of the last local column, use `NULL` to not obtain this value 6583 6584 Level: developer 6585 6586 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRanges()`, `MatGetOwnershipRangesColumn()`, `PetscLayout` 6587 6588 @*/ 6589 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n) 6590 { 6591 PetscFunctionBegin; 6592 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6593 PetscValidType(mat,1); 6594 if (m) PetscValidIntPointer(m,2); 6595 if (n) PetscValidIntPointer(n,3); 6596 MatCheckPreallocated(mat,1); 6597 if (m) *m = mat->cmap->rstart; 6598 if (n) *n = mat->cmap->rend; 6599 PetscFunctionReturn(0); 6600 } 6601 6602 /*@C 6603 MatGetOwnershipRange - For matrices that own values by row, excludes `MATELEMENTAL` and `MATSCALAPACK`, returns the range of matrix rows owned by 6604 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 6605 vector product with this matrix. See :any:`<sec_matlayout>` for details on matrix layouts 6606 6607 Not Collective 6608 6609 Input Parameter: 6610 . mat - the matrix 6611 6612 Output Parameters: 6613 + m - the global index of the first local row, use `NULL` to not obtain this value 6614 - n - one more than the global index of the last local row, use `NULL` to not obtain this value 6615 6616 Note: 6617 This function requires that the matrix be preallocated. If you have not preallocated, consider using 6618 `PetscSplitOwnership`(`MPI_Comm` comm, `PetscInt` *n, `PetscInt` *N) 6619 and then `MPI_Scan()` to calculate prefix sums of the local sizes. 6620 6621 Level: beginner 6622 6623 .seealso: `MatGetOwnershipRanges()`, `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRangesColumn()`, `PetscSplitOwnership()`, `PetscSplitOwnershipBlock()`, 6624 `PetscLayout` 6625 6626 @*/ 6627 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n) 6628 { 6629 PetscFunctionBegin; 6630 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6631 PetscValidType(mat,1); 6632 if (m) PetscValidIntPointer(m,2); 6633 if (n) PetscValidIntPointer(n,3); 6634 MatCheckPreallocated(mat,1); 6635 if (m) *m = mat->rmap->rstart; 6636 if (n) *n = mat->rmap->rend; 6637 PetscFunctionReturn(0); 6638 } 6639 6640 /*@C 6641 MatGetOwnershipRanges - For matrices that own values by row, excludes `MATELEMENTAL` and `MATSCALAPACK`, returns the range of matrix rows owned by 6642 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 6643 vector product with this matrix. See :any:`<sec_matlayout>` for details on matrix layouts 6644 6645 Not Collective, unless matrix has not been allocated, then collective on Mat 6646 6647 Input Parameters: 6648 . mat - the matrix 6649 6650 Output Parameters: 6651 . ranges - start of each processors portion plus one more than the total length at the end 6652 6653 Level: beginner 6654 6655 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRangesColumn()`, `PetscLayout` 6656 6657 @*/ 6658 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges) 6659 { 6660 PetscFunctionBegin; 6661 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6662 PetscValidType(mat,1); 6663 MatCheckPreallocated(mat,1); 6664 PetscCall(PetscLayoutGetRanges(mat->rmap,ranges)); 6665 PetscFunctionReturn(0); 6666 } 6667 6668 /*@C 6669 MatGetOwnershipRangesColumn - Returns the ranges of matrix columns associated with rows of a vector one multiplies this vector by that are owned by 6670 each processor. (The columns of the "diagonal blocks", for most sparse matrix formats). See :any:`<sec_matlayout>` for details on matrix layouts. 6671 6672 Not Collective, unless matrix has not been allocated, then collective on Mat 6673 6674 Input Parameters: 6675 . mat - the matrix 6676 6677 Output Parameters: 6678 . ranges - start of each processors portion plus one more then the total length at the end 6679 6680 Level: beginner 6681 6682 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRanges()` 6683 6684 @*/ 6685 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges) 6686 { 6687 PetscFunctionBegin; 6688 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6689 PetscValidType(mat,1); 6690 MatCheckPreallocated(mat,1); 6691 PetscCall(PetscLayoutGetRanges(mat->cmap,ranges)); 6692 PetscFunctionReturn(0); 6693 } 6694 6695 /*@C 6696 MatGetOwnershipIS - Get row and column ownership of a matrices' values as index sets. For most matrices, excluding `MATELEMENTAL` and `MATSCALAPACK`, this 6697 corresponds to values returned by `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`. For `MATELEMENTAL` and `MATSCALAPACK` the ownership 6698 is more complicated. See :any:`<sec_matlayout>` for details on matrix layouts. 6699 6700 Not Collective 6701 6702 Input Parameter: 6703 . A - matrix 6704 6705 Output Parameters: 6706 + rows - rows in which this process owns elements, , use `NULL` to not obtain this value 6707 - cols - columns in which this process owns elements, use `NULL` to not obtain this value 6708 6709 Level: intermediate 6710 6711 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`, `MatSetValues()`, ``MATELEMENTAL``, ``MATSCALAPACK`` 6712 @*/ 6713 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols) 6714 { 6715 PetscErrorCode (*f)(Mat,IS*,IS*); 6716 6717 PetscFunctionBegin; 6718 MatCheckPreallocated(A,1); 6719 PetscCall(PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f)); 6720 if (f) { 6721 PetscCall((*f)(A,rows,cols)); 6722 } else { /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */ 6723 if (rows) PetscCall(ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows)); 6724 if (cols) PetscCall(ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols)); 6725 } 6726 PetscFunctionReturn(0); 6727 } 6728 6729 /*@C 6730 MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix. 6731 Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric() 6732 to complete the factorization. 6733 6734 Collective on Mat 6735 6736 Input Parameters: 6737 + mat - the matrix 6738 . row - row permutation 6739 . column - column permutation 6740 - info - structure containing 6741 $ levels - number of levels of fill. 6742 $ expected fill - as ratio of original fill. 6743 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 6744 missing diagonal entries) 6745 6746 Output Parameters: 6747 . fact - new matrix that has been symbolically factored 6748 6749 Notes: 6750 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 6751 6752 Most users should employ the simplified KSP interface for linear solvers 6753 instead of working directly with matrix algebra routines such as this. 6754 See, e.g., KSPCreate(). 6755 6756 Level: developer 6757 6758 .seealso: `MatLUFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()` 6759 `MatGetOrdering()`, `MatFactorInfo` 6760 6761 Note: this uses the definition of level of fill as in Y. Saad, 2003 6762 6763 Developer Note: fortran interface is not autogenerated as the f90 6764 interface definition cannot be generated correctly [due to MatFactorInfo] 6765 6766 References: 6767 . * - Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6768 @*/ 6769 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 6770 { 6771 PetscFunctionBegin; 6772 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 6773 PetscValidType(mat,2); 6774 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,3); 6775 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,4); 6776 PetscValidPointer(info,5); 6777 PetscValidPointer(fact,1); 6778 PetscCheck(info->levels >= 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %" PetscInt_FMT,(PetscInt)info->levels); 6779 PetscCheck(info->fill >= 1.0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6780 if (!fact->ops->ilufactorsymbolic) { 6781 MatSolverType stype; 6782 PetscCall(MatFactorGetSolverType(fact,&stype)); 6783 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver type %s",((PetscObject)mat)->type_name,stype); 6784 } 6785 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6786 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6787 MatCheckPreallocated(mat,2); 6788 6789 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0)); 6790 PetscCall((fact->ops->ilufactorsymbolic)(fact,mat,row,col,info)); 6791 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0)); 6792 PetscFunctionReturn(0); 6793 } 6794 6795 /*@C 6796 MatICCFactorSymbolic - Performs symbolic incomplete 6797 Cholesky factorization for a symmetric matrix. Use 6798 MatCholeskyFactorNumeric() to complete the factorization. 6799 6800 Collective on Mat 6801 6802 Input Parameters: 6803 + mat - the matrix 6804 . perm - row and column permutation 6805 - info - structure containing 6806 $ levels - number of levels of fill. 6807 $ expected fill - as ratio of original fill. 6808 6809 Output Parameter: 6810 . fact - the factored matrix 6811 6812 Notes: 6813 Most users should employ the KSP interface for linear solvers 6814 instead of working directly with matrix algebra routines such as this. 6815 See, e.g., KSPCreate(). 6816 6817 Level: developer 6818 6819 .seealso: `MatCholeskyFactorNumeric()`, `MatCholeskyFactor()`, `MatFactorInfo` 6820 6821 Note: this uses the definition of level of fill as in Y. Saad, 2003 6822 6823 Developer Note: fortran interface is not autogenerated as the f90 6824 interface definition cannot be generated correctly [due to MatFactorInfo] 6825 6826 References: 6827 . * - Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6828 @*/ 6829 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 6830 { 6831 PetscFunctionBegin; 6832 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 6833 PetscValidType(mat,2); 6834 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,3); 6835 PetscValidPointer(info,4); 6836 PetscValidPointer(fact,1); 6837 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6838 PetscCheck(info->levels >= 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %" PetscInt_FMT,(PetscInt) info->levels); 6839 PetscCheck(info->fill >= 1.0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6840 if (!(fact)->ops->iccfactorsymbolic) { 6841 MatSolverType stype; 6842 PetscCall(MatFactorGetSolverType(fact,&stype)); 6843 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver type %s",((PetscObject)mat)->type_name,stype); 6844 } 6845 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6846 MatCheckPreallocated(mat,2); 6847 6848 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0)); 6849 PetscCall((fact->ops->iccfactorsymbolic)(fact,mat,perm,info)); 6850 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0)); 6851 PetscFunctionReturn(0); 6852 } 6853 6854 /*@C 6855 MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat 6856 points to an array of valid matrices, they may be reused to store the new 6857 submatrices. 6858 6859 Collective on Mat 6860 6861 Input Parameters: 6862 + mat - the matrix 6863 . n - the number of submatrixes to be extracted (on this processor, may be zero) 6864 . irow, icol - index sets of rows and columns to extract 6865 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6866 6867 Output Parameter: 6868 . submat - the array of submatrices 6869 6870 Notes: 6871 MatCreateSubMatrices() can extract ONLY sequential submatrices 6872 (from both sequential and parallel matrices). Use MatCreateSubMatrix() 6873 to extract a parallel submatrix. 6874 6875 Some matrix types place restrictions on the row and column 6876 indices, such as that they be sorted or that they be equal to each other. 6877 6878 The index sets may not have duplicate entries. 6879 6880 When extracting submatrices from a parallel matrix, each processor can 6881 form a different submatrix by setting the rows and columns of its 6882 individual index sets according to the local submatrix desired. 6883 6884 When finished using the submatrices, the user should destroy 6885 them with MatDestroySubMatrices(). 6886 6887 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 6888 original matrix has not changed from that last call to MatCreateSubMatrices(). 6889 6890 This routine creates the matrices in submat; you should NOT create them before 6891 calling it. It also allocates the array of matrix pointers submat. 6892 6893 For BAIJ matrices the index sets must respect the block structure, that is if they 6894 request one row/column in a block, they must request all rows/columns that are in 6895 that block. For example, if the block size is 2 you cannot request just row 0 and 6896 column 0. 6897 6898 Fortran Note: 6899 The Fortran interface is slightly different from that given below; it 6900 requires one to pass in as submat a Mat (integer) array of size at least n+1. 6901 6902 Level: advanced 6903 6904 .seealso: `MatDestroySubMatrices()`, `MatCreateSubMatrix()`, `MatGetRow()`, `MatGetDiagonal()`, `MatReuse` 6905 @*/ 6906 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 6907 { 6908 PetscInt i; 6909 PetscBool eq; 6910 6911 PetscFunctionBegin; 6912 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6913 PetscValidType(mat,1); 6914 if (n) { 6915 PetscValidPointer(irow,3); 6916 for (i=0; i<n; i++) PetscValidHeaderSpecific(irow[i],IS_CLASSID,3); 6917 PetscValidPointer(icol,4); 6918 for (i=0; i<n; i++) PetscValidHeaderSpecific(icol[i],IS_CLASSID,4); 6919 } 6920 PetscValidPointer(submat,6); 6921 if (n && scall == MAT_REUSE_MATRIX) { 6922 PetscValidPointer(*submat,6); 6923 for (i=0; i<n; i++) PetscValidHeaderSpecific((*submat)[i],MAT_CLASSID,6); 6924 } 6925 PetscCheck(mat->ops->createsubmatrices,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6926 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6927 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6928 MatCheckPreallocated(mat,1); 6929 PetscCall(PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0)); 6930 PetscCall((*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat)); 6931 PetscCall(PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0)); 6932 for (i=0; i<n; i++) { 6933 (*submat)[i]->factortype = MAT_FACTOR_NONE; /* in case in place factorization was previously done on submatrix */ 6934 PetscCall(ISEqualUnsorted(irow[i],icol[i],&eq)); 6935 if (eq) { 6936 PetscCall(MatPropagateSymmetryOptions(mat,(*submat)[i])); 6937 } 6938 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 6939 if (mat->boundtocpu && mat->bindingpropagates) { 6940 PetscCall(MatBindToCPU((*submat)[i],PETSC_TRUE)); 6941 PetscCall(MatSetBindingPropagates((*submat)[i],PETSC_TRUE)); 6942 } 6943 #endif 6944 } 6945 PetscFunctionReturn(0); 6946 } 6947 6948 /*@C 6949 MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms). 6950 6951 Collective on Mat 6952 6953 Input Parameters: 6954 + mat - the matrix 6955 . n - the number of submatrixes to be extracted 6956 . irow, icol - index sets of rows and columns to extract 6957 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6958 6959 Output Parameter: 6960 . submat - the array of submatrices 6961 6962 Level: advanced 6963 6964 .seealso: `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRow()`, `MatGetDiagonal()`, `MatReuse` 6965 @*/ 6966 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 6967 { 6968 PetscInt i; 6969 PetscBool eq; 6970 6971 PetscFunctionBegin; 6972 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6973 PetscValidType(mat,1); 6974 if (n) { 6975 PetscValidPointer(irow,3); 6976 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 6977 PetscValidPointer(icol,4); 6978 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 6979 } 6980 PetscValidPointer(submat,6); 6981 if (n && scall == MAT_REUSE_MATRIX) { 6982 PetscValidPointer(*submat,6); 6983 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 6984 } 6985 PetscCheck(mat->ops->createsubmatricesmpi,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6986 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6987 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6988 MatCheckPreallocated(mat,1); 6989 6990 PetscCall(PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0)); 6991 PetscCall((*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat)); 6992 PetscCall(PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0)); 6993 for (i=0; i<n; i++) { 6994 PetscCall(ISEqualUnsorted(irow[i],icol[i],&eq)); 6995 if (eq) { 6996 PetscCall(MatPropagateSymmetryOptions(mat,(*submat)[i])); 6997 } 6998 } 6999 PetscFunctionReturn(0); 7000 } 7001 7002 /*@C 7003 MatDestroyMatrices - Destroys an array of matrices. 7004 7005 Collective on Mat 7006 7007 Input Parameters: 7008 + n - the number of local matrices 7009 - mat - the matrices (note that this is a pointer to the array of matrices) 7010 7011 Level: advanced 7012 7013 Notes: 7014 Frees not only the matrices, but also the array that contains the matrices 7015 In Fortran will not free the array. 7016 7017 .seealso: `MatCreateSubMatrices()` `MatDestroySubMatrices()` 7018 @*/ 7019 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[]) 7020 { 7021 PetscInt i; 7022 7023 PetscFunctionBegin; 7024 if (!*mat) PetscFunctionReturn(0); 7025 PetscCheck(n >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %" PetscInt_FMT,n); 7026 PetscValidPointer(mat,2); 7027 7028 for (i=0; i<n; i++) { 7029 PetscCall(MatDestroy(&(*mat)[i])); 7030 } 7031 7032 /* memory is allocated even if n = 0 */ 7033 PetscCall(PetscFree(*mat)); 7034 PetscFunctionReturn(0); 7035 } 7036 7037 /*@C 7038 MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices(). 7039 7040 Collective on Mat 7041 7042 Input Parameters: 7043 + n - the number of local matrices 7044 - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling 7045 sequence of MatCreateSubMatrices()) 7046 7047 Level: advanced 7048 7049 Notes: 7050 Frees not only the matrices, but also the array that contains the matrices 7051 In Fortran will not free the array. 7052 7053 .seealso: `MatCreateSubMatrices()` 7054 @*/ 7055 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[]) 7056 { 7057 Mat mat0; 7058 7059 PetscFunctionBegin; 7060 if (!*mat) PetscFunctionReturn(0); 7061 /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */ 7062 PetscCheck(n >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %" PetscInt_FMT,n); 7063 PetscValidPointer(mat,2); 7064 7065 mat0 = (*mat)[0]; 7066 if (mat0 && mat0->ops->destroysubmatrices) { 7067 PetscCall((mat0->ops->destroysubmatrices)(n,mat)); 7068 } else { 7069 PetscCall(MatDestroyMatrices(n,mat)); 7070 } 7071 PetscFunctionReturn(0); 7072 } 7073 7074 /*@C 7075 MatGetSeqNonzeroStructure - Extracts the nonzero structure from a matrix and stores it, in its entirety, on each process 7076 7077 Collective on Mat 7078 7079 Input Parameters: 7080 . mat - the matrix 7081 7082 Output Parameter: 7083 . matstruct - the sequential matrix with the nonzero structure of mat 7084 7085 Level: intermediate 7086 7087 .seealso: `MatDestroySeqNonzeroStructure()`, `MatCreateSubMatrices()`, `MatDestroyMatrices()` 7088 @*/ 7089 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct) 7090 { 7091 PetscFunctionBegin; 7092 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7093 PetscValidPointer(matstruct,2); 7094 7095 PetscValidType(mat,1); 7096 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7097 MatCheckPreallocated(mat,1); 7098 7099 PetscCheck(mat->ops->getseqnonzerostructure,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s",((PetscObject)mat)->type_name); 7100 PetscCall(PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0)); 7101 PetscCall((*mat->ops->getseqnonzerostructure)(mat,matstruct)); 7102 PetscCall(PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0)); 7103 PetscFunctionReturn(0); 7104 } 7105 7106 /*@C 7107 MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure(). 7108 7109 Collective on Mat 7110 7111 Input Parameters: 7112 . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling 7113 sequence of MatGetSequentialNonzeroStructure()) 7114 7115 Level: advanced 7116 7117 Notes: 7118 Frees not only the matrices, but also the array that contains the matrices 7119 7120 .seealso: `MatGetSeqNonzeroStructure()` 7121 @*/ 7122 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat) 7123 { 7124 PetscFunctionBegin; 7125 PetscValidPointer(mat,1); 7126 PetscCall(MatDestroy(mat)); 7127 PetscFunctionReturn(0); 7128 } 7129 7130 /*@ 7131 MatIncreaseOverlap - Given a set of submatrices indicated by index sets, 7132 replaces the index sets by larger ones that represent submatrices with 7133 additional overlap. 7134 7135 Collective on Mat 7136 7137 Input Parameters: 7138 + mat - the matrix 7139 . n - the number of index sets 7140 . is - the array of index sets (these index sets will changed during the call) 7141 - ov - the additional overlap requested 7142 7143 Options Database: 7144 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7145 7146 Level: developer 7147 7148 Developer Note: 7149 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. 7150 7151 .seealso: `MatCreateSubMatrices()` 7152 @*/ 7153 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov) 7154 { 7155 PetscInt i,bs,cbs; 7156 7157 PetscFunctionBegin; 7158 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7159 PetscValidType(mat,1); 7160 PetscValidLogicalCollectiveInt(mat,n,2); 7161 PetscCheck(n >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %" PetscInt_FMT,n); 7162 if (n) { 7163 PetscValidPointer(is,3); 7164 for (i = 0; i < n; i++) PetscValidHeaderSpecific(is[i],IS_CLASSID,3); 7165 } 7166 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7167 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7168 MatCheckPreallocated(mat,1); 7169 7170 if (!ov || !n) PetscFunctionReturn(0); 7171 PetscCheck(mat->ops->increaseoverlap,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7172 PetscCall(PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0)); 7173 PetscCall((*mat->ops->increaseoverlap)(mat,n,is,ov)); 7174 PetscCall(PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0)); 7175 PetscCall(MatGetBlockSizes(mat,&bs,&cbs)); 7176 if (bs == cbs) { 7177 for (i=0; i<n; i++) { 7178 PetscCall(ISSetBlockSize(is[i],bs)); 7179 } 7180 } 7181 PetscFunctionReturn(0); 7182 } 7183 7184 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt); 7185 7186 /*@ 7187 MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across 7188 a sub communicator, replaces the index sets by larger ones that represent submatrices with 7189 additional overlap. 7190 7191 Collective on Mat 7192 7193 Input Parameters: 7194 + mat - the matrix 7195 . n - the number of index sets 7196 . is - the array of index sets (these index sets will changed during the call) 7197 - ov - the additional overlap requested 7198 7199 Options Database: 7200 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7201 7202 Level: developer 7203 7204 .seealso: `MatCreateSubMatrices()` 7205 @*/ 7206 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov) 7207 { 7208 PetscInt i; 7209 7210 PetscFunctionBegin; 7211 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7212 PetscValidType(mat,1); 7213 PetscCheck(n >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %" PetscInt_FMT,n); 7214 if (n) { 7215 PetscValidPointer(is,3); 7216 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 7217 } 7218 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7219 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7220 MatCheckPreallocated(mat,1); 7221 if (!ov) PetscFunctionReturn(0); 7222 PetscCall(PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0)); 7223 for (i=0; i<n; i++) { 7224 PetscCall(MatIncreaseOverlapSplit_Single(mat,&is[i],ov)); 7225 } 7226 PetscCall(PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0)); 7227 PetscFunctionReturn(0); 7228 } 7229 7230 /*@ 7231 MatGetBlockSize - Returns the matrix block size. 7232 7233 Not Collective 7234 7235 Input Parameter: 7236 . mat - the matrix 7237 7238 Output Parameter: 7239 . bs - block size 7240 7241 Notes: 7242 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7243 7244 If the block size has not been set yet this routine returns 1. 7245 7246 Level: intermediate 7247 7248 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSizes()` 7249 @*/ 7250 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs) 7251 { 7252 PetscFunctionBegin; 7253 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7254 PetscValidIntPointer(bs,2); 7255 *bs = PetscAbs(mat->rmap->bs); 7256 PetscFunctionReturn(0); 7257 } 7258 7259 /*@ 7260 MatGetBlockSizes - Returns the matrix block row and column sizes. 7261 7262 Not Collective 7263 7264 Input Parameter: 7265 . mat - the matrix 7266 7267 Output Parameters: 7268 + rbs - row block size 7269 - cbs - column block size 7270 7271 Notes: 7272 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7273 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7274 7275 If a block size has not been set yet this routine returns 1. 7276 7277 Level: intermediate 7278 7279 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSize()`, `MatSetBlockSizes()` 7280 @*/ 7281 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs) 7282 { 7283 PetscFunctionBegin; 7284 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7285 if (rbs) PetscValidIntPointer(rbs,2); 7286 if (cbs) PetscValidIntPointer(cbs,3); 7287 if (rbs) *rbs = PetscAbs(mat->rmap->bs); 7288 if (cbs) *cbs = PetscAbs(mat->cmap->bs); 7289 PetscFunctionReturn(0); 7290 } 7291 7292 /*@ 7293 MatSetBlockSize - Sets the matrix block size. 7294 7295 Logically Collective on Mat 7296 7297 Input Parameters: 7298 + mat - the matrix 7299 - bs - block size 7300 7301 Notes: 7302 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7303 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7304 7305 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size 7306 is compatible with the matrix local sizes. 7307 7308 Level: intermediate 7309 7310 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`, `MatGetBlockSizes()` 7311 @*/ 7312 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs) 7313 { 7314 PetscFunctionBegin; 7315 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7316 PetscValidLogicalCollectiveInt(mat,bs,2); 7317 PetscCall(MatSetBlockSizes(mat,bs,bs)); 7318 PetscFunctionReturn(0); 7319 } 7320 7321 typedef struct { 7322 PetscInt n; 7323 IS *is; 7324 Mat *mat; 7325 PetscObjectState nonzerostate; 7326 Mat C; 7327 } EnvelopeData; 7328 7329 static PetscErrorCode EnvelopeDataDestroy(EnvelopeData *edata) 7330 { 7331 for (PetscInt i=0; i<edata->n; i++) { 7332 PetscCall(ISDestroy(&edata->is[i])); 7333 } 7334 PetscCall(PetscFree(edata->is)); 7335 PetscCall(PetscFree(edata)); 7336 return 0; 7337 } 7338 7339 /* 7340 MatComputeVariableBlockEnvelope - Given a matrix whose nonzeros are in blocks along the diagonal this computes and stores 7341 the sizes of these blocks in the matrix. An individual block may lie over several processes. 7342 7343 Collective on mat 7344 7345 Input Parameter: 7346 . mat - the matrix 7347 7348 Notes: 7349 There can be zeros within the blocks 7350 7351 The blocks can overlap between processes, including laying on more than two processes 7352 7353 */ 7354 static PetscErrorCode MatComputeVariableBlockEnvelope(Mat mat) 7355 { 7356 PetscInt n,*sizes,*starts,i = 0,env = 0, tbs = 0, lblocks = 0,rstart,II,ln = 0,cnt = 0,cstart,cend; 7357 PetscInt *diag,*odiag,sc; 7358 VecScatter scatter; 7359 PetscScalar *seqv; 7360 const PetscScalar *parv; 7361 const PetscInt *ia,*ja; 7362 PetscBool set,flag,done; 7363 Mat AA = mat,A; 7364 MPI_Comm comm; 7365 PetscMPIInt rank,size,tag; 7366 MPI_Status status; 7367 PetscContainer container; 7368 EnvelopeData *edata; 7369 Vec seq,par; 7370 IS isglobal; 7371 7372 PetscFunctionBegin; 7373 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7374 PetscCall(MatIsSymmetricKnown(mat,&set,&flag)); 7375 if (!set || !flag) { 7376 /* TOO: only needs nonzero structure of transpose */ 7377 PetscCall(MatTranspose(mat,MAT_INITIAL_MATRIX,&AA)); 7378 PetscCall(MatAXPY(AA,1.0,mat,DIFFERENT_NONZERO_PATTERN)); 7379 } 7380 PetscCall(MatAIJGetLocalMat(AA,&A)); 7381 PetscCall(MatGetRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ia,&ja,&done)); 7382 PetscCheck(done,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Unable to get IJ structure from matrix"); 7383 7384 PetscCall(MatGetLocalSize(mat,&n,NULL)); 7385 PetscCall(PetscObjectGetNewTag((PetscObject)mat,&tag)); 7386 PetscCall(PetscObjectGetComm((PetscObject)mat,&comm)); 7387 PetscCallMPI(MPI_Comm_size(comm,&size)); 7388 PetscCallMPI(MPI_Comm_rank(comm,&rank)); 7389 7390 PetscCall(PetscMalloc2(n,&sizes,n,&starts)); 7391 7392 if (rank > 0) { 7393 PetscCallMPI(MPI_Recv(&env,1,MPIU_INT,rank-1,tag,comm,&status)); 7394 PetscCallMPI(MPI_Recv(&tbs,1,MPIU_INT,rank-1,tag,comm,&status)); 7395 } 7396 PetscCall(MatGetOwnershipRange(mat,&rstart,NULL)); 7397 for (i=0; i<n; i++) { 7398 env = PetscMax(env,ja[ia[i+1]-1]); 7399 II = rstart + i; 7400 if (env == II) { 7401 starts[lblocks] = tbs; 7402 sizes[lblocks++] = 1 + II - tbs; 7403 tbs = 1 + II; 7404 } 7405 } 7406 if (rank < size-1) { 7407 PetscCallMPI(MPI_Send(&env,1,MPIU_INT,rank+1,tag,comm)); 7408 PetscCallMPI(MPI_Send(&tbs,1,MPIU_INT,rank+1,tag,comm)); 7409 } 7410 7411 PetscCall(MatRestoreRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ia,&ja,&done)); 7412 if (!set || !flag) { 7413 PetscCall(MatDestroy(&AA)); 7414 } 7415 PetscCall(MatDestroy(&A)); 7416 7417 PetscCall(PetscNew(&edata)); 7418 PetscCall(MatGetNonzeroState(mat,&edata->nonzerostate)); 7419 edata->n = lblocks; 7420 /* create IS needed for extracting blocks from the original matrix */ 7421 PetscCall(PetscMalloc1(lblocks,&edata->is)); 7422 for (PetscInt i=0; i<lblocks; i++) { 7423 PetscCall(ISCreateStride(PETSC_COMM_SELF,sizes[i],starts[i],1,&edata->is[i])); 7424 } 7425 7426 /* Create the resulting inverse matrix structure with preallocation information */ 7427 PetscCall(MatCreate(PetscObjectComm((PetscObject)mat),&edata->C)); 7428 PetscCall(MatSetSizes(edata->C,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N)); 7429 PetscCall(MatSetBlockSizesFromMats(edata->C,mat,mat)); 7430 PetscCall(MatSetType(edata->C,MATAIJ)); 7431 7432 /* Communicate the start and end of each row, from each block to the correct rank */ 7433 /* TODO: Use PetscSF instead of VecScatter */ 7434 for (PetscInt i=0; i<lblocks; i++) ln += sizes[i]; 7435 PetscCall(VecCreateSeq(PETSC_COMM_SELF,2*ln,&seq)); 7436 PetscCall(VecGetArrayWrite(seq,&seqv)); 7437 for (PetscInt i=0; i<lblocks; i++) { 7438 for (PetscInt j=0; j<sizes[i]; j++) { 7439 seqv[cnt] = starts[i]; 7440 seqv[cnt+1] = starts[i] + sizes[i]; 7441 cnt += 2; 7442 } 7443 } 7444 PetscCall(VecRestoreArrayWrite(seq,&seqv)); 7445 PetscCallMPI(MPI_Scan(&cnt,&sc,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat))); 7446 sc -= cnt; 7447 PetscCall(VecCreateMPI(PetscObjectComm((PetscObject)mat),2*mat->rmap->n,2*mat->rmap->N,&par)); 7448 PetscCall(ISCreateStride(PETSC_COMM_SELF,cnt,sc,1,&isglobal)); 7449 PetscCall(VecScatterCreate(seq, NULL ,par, isglobal,&scatter)); 7450 PetscCall(ISDestroy(&isglobal)); 7451 PetscCall(VecScatterBegin(scatter,seq,par,INSERT_VALUES,SCATTER_FORWARD)); 7452 PetscCall(VecScatterEnd(scatter,seq,par,INSERT_VALUES,SCATTER_FORWARD)); 7453 PetscCall(VecScatterDestroy(&scatter)); 7454 PetscCall(VecDestroy(&seq)); 7455 PetscCall(MatGetOwnershipRangeColumn(mat,&cstart,&cend)); 7456 PetscCall(PetscMalloc2(mat->rmap->n,&diag,mat->rmap->n,&odiag)); 7457 PetscCall(VecGetArrayRead(par,&parv)); 7458 cnt = 0; 7459 PetscCall(MatGetSize(mat,NULL,&n)); 7460 for (PetscInt i=0; i<mat->rmap->n; i++) { 7461 PetscInt start,end,d = 0,od = 0; 7462 7463 start = (PetscInt)PetscRealPart(parv[cnt]); 7464 end = (PetscInt)PetscRealPart(parv[cnt+1]); 7465 cnt += 2; 7466 7467 if (start < cstart) {od += cstart - start + n - cend; d += cend - cstart;} 7468 else if (start < cend) {od += n - cend; d += cend - start;} 7469 else od += n - start; 7470 if (end <= cstart) {od -= cstart - end + n - cend; d -= cend - cstart;} 7471 else if (end < cend) {od -= n - cend; d -= cend - end;} 7472 else od -= n - end; 7473 7474 odiag[i] = od; 7475 diag[i] = d; 7476 } 7477 PetscCall(VecRestoreArrayRead(par,&parv)); 7478 PetscCall(VecDestroy(&par)); 7479 PetscCall(MatXAIJSetPreallocation(edata->C,mat->rmap->bs,diag,odiag,NULL,NULL)); 7480 PetscCall(PetscFree2(diag,odiag)); 7481 PetscCall(PetscFree2(sizes,starts)); 7482 7483 PetscCall(PetscContainerCreate(PETSC_COMM_SELF,&container)); 7484 PetscCall(PetscContainerSetPointer(container,edata)); 7485 PetscCall(PetscContainerSetUserDestroy(container,(PetscErrorCode (*)(void*))EnvelopeDataDestroy)); 7486 PetscCall(PetscObjectCompose((PetscObject)mat,"EnvelopeData",(PetscObject)container)); 7487 PetscCall(PetscObjectDereference((PetscObject)container)); 7488 PetscFunctionReturn(0); 7489 } 7490 7491 /*@ 7492 MatInvertVariableBlockEnvelope - set matrix C to be the inverted block diagonal of matrix A 7493 7494 Collective on Mat 7495 7496 Input Parameters: 7497 . A - the matrix 7498 7499 Output Parameters: 7500 . C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set. 7501 7502 Notes: 7503 For efficiency the matrix A should have all the nonzero entries clustered in smallish blocks along the diagonal. 7504 7505 Level: advanced 7506 7507 .seealso: MatInvertBlockDiagonal(), MatComputeBlockDiagonal() 7508 @*/ 7509 PetscErrorCode MatInvertVariableBlockEnvelope(Mat A,MatReuse reuse, Mat *C) 7510 { 7511 PetscContainer container; 7512 EnvelopeData *edata; 7513 PetscObjectState nonzerostate; 7514 7515 PetscFunctionBegin; 7516 PetscCall(PetscObjectQuery((PetscObject)A,"EnvelopeData",(PetscObject*)&container)); 7517 if (!container) { 7518 PetscCall(MatComputeVariableBlockEnvelope(A)); 7519 PetscCall(PetscObjectQuery((PetscObject)A,"EnvelopeData",(PetscObject*)&container)); 7520 } 7521 PetscCall(PetscContainerGetPointer(container,(void**)&edata)); 7522 PetscCall(MatGetNonzeroState(A,&nonzerostate)); 7523 PetscCheck(nonzerostate <= edata->nonzerostate,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Cannot handle changes to matrix nonzero structure"); 7524 PetscCheck(reuse != MAT_REUSE_MATRIX || *C == edata->C,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C matrix must be the same as previously output"); 7525 7526 PetscCall(MatCreateSubMatrices(A,edata->n,edata->is,edata->is,MAT_INITIAL_MATRIX,&edata->mat)); 7527 *C = edata->C; 7528 7529 for (PetscInt i=0; i<edata->n; i++) { 7530 Mat D; 7531 PetscScalar *dvalues; 7532 7533 PetscCall(MatConvert(edata->mat[i], MATSEQDENSE,MAT_INITIAL_MATRIX,&D)); 7534 PetscCall(MatSetOption(*C,MAT_ROW_ORIENTED,PETSC_FALSE)); 7535 PetscCall(MatSeqDenseInvert(D)); 7536 PetscCall(MatDenseGetArray(D,&dvalues)); 7537 PetscCall(MatSetValuesIS(*C,edata->is[i],edata->is[i],dvalues,INSERT_VALUES)); 7538 PetscCall(MatDestroy(&D)); 7539 } 7540 PetscCall(MatDestroySubMatrices(edata->n,&edata->mat)); 7541 PetscCall(MatAssemblyBegin(*C,MAT_FINAL_ASSEMBLY)); 7542 PetscCall(MatAssemblyEnd(*C,MAT_FINAL_ASSEMBLY)); 7543 PetscFunctionReturn(0); 7544 } 7545 7546 /*@ 7547 MatSetVariableBlockSizes - Sets diagonal point-blocks of the matrix that need not be of the same size 7548 7549 Logically Collective on Mat 7550 7551 Input Parameters: 7552 + mat - the matrix 7553 . nblocks - the number of blocks on this process, each block can only exist on a single process 7554 - bsizes - the block sizes 7555 7556 Notes: 7557 Currently used by PCVPBJACOBI for AIJ matrices 7558 7559 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. 7560 7561 Level: intermediate 7562 7563 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`, `MatGetBlockSizes()`, `MatGetVariableBlockSizes()`, `MatComputeVariableBlockEnvelope()`, `PCVPBJACOBI` 7564 @*/ 7565 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes) 7566 { 7567 PetscInt i,ncnt = 0, nlocal; 7568 7569 PetscFunctionBegin; 7570 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7571 PetscCheck(nblocks >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero"); 7572 PetscCall(MatGetLocalSize(mat,&nlocal,NULL)); 7573 for (i=0; i<nblocks; i++) ncnt += bsizes[i]; 7574 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); 7575 PetscCall(PetscFree(mat->bsizes)); 7576 mat->nblocks = nblocks; 7577 PetscCall(PetscMalloc1(nblocks,&mat->bsizes)); 7578 PetscCall(PetscArraycpy(mat->bsizes,bsizes,nblocks)); 7579 PetscFunctionReturn(0); 7580 } 7581 7582 /*@C 7583 MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size 7584 7585 Logically Collective on Mat 7586 7587 Input Parameter: 7588 . mat - the matrix 7589 7590 Output Parameters: 7591 + nblocks - the number of blocks on this process 7592 - bsizes - the block sizes 7593 7594 Notes: Currently not supported from Fortran 7595 7596 Level: intermediate 7597 7598 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`, `MatGetBlockSizes()`, `MatSetVariableBlockSizes()`, `MatComputeVariableBlockEnvelope()` 7599 @*/ 7600 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes) 7601 { 7602 PetscFunctionBegin; 7603 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7604 *nblocks = mat->nblocks; 7605 *bsizes = mat->bsizes; 7606 PetscFunctionReturn(0); 7607 } 7608 7609 /*@ 7610 MatSetBlockSizes - Sets the matrix block row and column sizes. 7611 7612 Logically Collective on Mat 7613 7614 Input Parameters: 7615 + mat - the matrix 7616 . rbs - row block size 7617 - cbs - column block size 7618 7619 Notes: 7620 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7621 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7622 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7623 7624 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes 7625 are compatible with the matrix local sizes. 7626 7627 The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs(). 7628 7629 Level: intermediate 7630 7631 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSize()`, `MatGetBlockSizes()` 7632 @*/ 7633 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs) 7634 { 7635 PetscFunctionBegin; 7636 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7637 PetscValidLogicalCollectiveInt(mat,rbs,2); 7638 PetscValidLogicalCollectiveInt(mat,cbs,3); 7639 if (mat->ops->setblocksizes) PetscCall((*mat->ops->setblocksizes)(mat,rbs,cbs)); 7640 if (mat->rmap->refcnt) { 7641 ISLocalToGlobalMapping l2g = NULL; 7642 PetscLayout nmap = NULL; 7643 7644 PetscCall(PetscLayoutDuplicate(mat->rmap,&nmap)); 7645 if (mat->rmap->mapping) { 7646 PetscCall(ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g)); 7647 } 7648 PetscCall(PetscLayoutDestroy(&mat->rmap)); 7649 mat->rmap = nmap; 7650 mat->rmap->mapping = l2g; 7651 } 7652 if (mat->cmap->refcnt) { 7653 ISLocalToGlobalMapping l2g = NULL; 7654 PetscLayout nmap = NULL; 7655 7656 PetscCall(PetscLayoutDuplicate(mat->cmap,&nmap)); 7657 if (mat->cmap->mapping) { 7658 PetscCall(ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g)); 7659 } 7660 PetscCall(PetscLayoutDestroy(&mat->cmap)); 7661 mat->cmap = nmap; 7662 mat->cmap->mapping = l2g; 7663 } 7664 PetscCall(PetscLayoutSetBlockSize(mat->rmap,rbs)); 7665 PetscCall(PetscLayoutSetBlockSize(mat->cmap,cbs)); 7666 PetscFunctionReturn(0); 7667 } 7668 7669 /*@ 7670 MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices 7671 7672 Logically Collective on Mat 7673 7674 Input Parameters: 7675 + mat - the matrix 7676 . fromRow - matrix from which to copy row block size 7677 - fromCol - matrix from which to copy column block size (can be same as fromRow) 7678 7679 Level: developer 7680 7681 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()` 7682 @*/ 7683 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol) 7684 { 7685 PetscFunctionBegin; 7686 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7687 PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2); 7688 PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3); 7689 if (fromRow->rmap->bs > 0) PetscCall(PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs)); 7690 if (fromCol->cmap->bs > 0) PetscCall(PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs)); 7691 PetscFunctionReturn(0); 7692 } 7693 7694 /*@ 7695 MatResidual - Default routine to calculate the residual. 7696 7697 Collective on Mat 7698 7699 Input Parameters: 7700 + mat - the matrix 7701 . b - the right-hand-side 7702 - x - the approximate solution 7703 7704 Output Parameter: 7705 . r - location to store the residual 7706 7707 Level: developer 7708 7709 .seealso: `PCMGSetResidual()` 7710 @*/ 7711 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r) 7712 { 7713 PetscFunctionBegin; 7714 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7715 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 7716 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 7717 PetscValidHeaderSpecific(r,VEC_CLASSID,4); 7718 PetscValidType(mat,1); 7719 MatCheckPreallocated(mat,1); 7720 PetscCall(PetscLogEventBegin(MAT_Residual,mat,0,0,0)); 7721 if (!mat->ops->residual) { 7722 PetscCall(MatMult(mat,x,r)); 7723 PetscCall(VecAYPX(r,-1.0,b)); 7724 } else { 7725 PetscCall((*mat->ops->residual)(mat,b,x,r)); 7726 } 7727 PetscCall(PetscLogEventEnd(MAT_Residual,mat,0,0,0)); 7728 PetscFunctionReturn(0); 7729 } 7730 7731 /*@C 7732 MatGetRowIJ - Returns the compressed row storage i and j indices for the local rows of a sparse matrix 7733 7734 Collective on Mat 7735 7736 Input Parameters: 7737 + mat - the matrix 7738 . shift - 0 or 1 indicating we want the indices starting at 0 or 1 7739 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized 7740 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7741 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7742 always used. 7743 7744 Output Parameters: 7745 + n - number of local rows in the (possibly compressed) matrix 7746 . ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix 7747 . ja - the column indices 7748 - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers 7749 are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set 7750 7751 Level: developer 7752 7753 Notes: 7754 You CANNOT change any of the ia[] or ja[] values. 7755 7756 Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values. 7757 7758 Fortran Notes: 7759 In Fortran use 7760 $ 7761 $ PetscInt ia(1), ja(1) 7762 $ PetscOffset iia, jja 7763 $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr) 7764 $ ! Access the ith and jth entries via ia(iia + i) and ja(jja + j) 7765 7766 or 7767 $ 7768 $ PetscInt, pointer :: ia(:),ja(:) 7769 $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr) 7770 $ ! Access the ith and jth entries via ia(i) and ja(j) 7771 7772 .seealso: `MatGetColumnIJ()`, `MatRestoreRowIJ()`, `MatSeqAIJGetArray()` 7773 @*/ 7774 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7775 { 7776 PetscFunctionBegin; 7777 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7778 PetscValidType(mat,1); 7779 if (n) PetscValidIntPointer(n,5); 7780 if (ia) PetscValidPointer(ia,6); 7781 if (ja) PetscValidPointer(ja,7); 7782 if (done) PetscValidBoolPointer(done,8); 7783 MatCheckPreallocated(mat,1); 7784 if (!mat->ops->getrowij && done) *done = PETSC_FALSE; 7785 else { 7786 if (done) *done = PETSC_TRUE; 7787 PetscCall(PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0)); 7788 PetscCall((*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done)); 7789 PetscCall(PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0)); 7790 } 7791 PetscFunctionReturn(0); 7792 } 7793 7794 /*@C 7795 MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices. 7796 7797 Collective on Mat 7798 7799 Input Parameters: 7800 + mat - the matrix 7801 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7802 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7803 symmetrized 7804 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7805 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7806 always used. 7807 . n - number of columns in the (possibly compressed) matrix 7808 . ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix 7809 - ja - the row indices 7810 7811 Output Parameters: 7812 . done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned 7813 7814 Level: developer 7815 7816 .seealso: `MatGetRowIJ()`, `MatRestoreColumnIJ()` 7817 @*/ 7818 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7819 { 7820 PetscFunctionBegin; 7821 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7822 PetscValidType(mat,1); 7823 PetscValidIntPointer(n,5); 7824 if (ia) PetscValidPointer(ia,6); 7825 if (ja) PetscValidPointer(ja,7); 7826 PetscValidBoolPointer(done,8); 7827 MatCheckPreallocated(mat,1); 7828 if (!mat->ops->getcolumnij) *done = PETSC_FALSE; 7829 else { 7830 *done = PETSC_TRUE; 7831 PetscCall((*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done)); 7832 } 7833 PetscFunctionReturn(0); 7834 } 7835 7836 /*@C 7837 MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with 7838 MatGetRowIJ(). 7839 7840 Collective on Mat 7841 7842 Input Parameters: 7843 + mat - the matrix 7844 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7845 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7846 symmetrized 7847 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7848 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7849 always used. 7850 . n - size of (possibly compressed) matrix 7851 . ia - the row pointers 7852 - ja - the column indices 7853 7854 Output Parameters: 7855 . done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7856 7857 Note: 7858 This routine zeros out n, ia, and ja. This is to prevent accidental 7859 us of the array after it has been restored. If you pass NULL, it will 7860 not zero the pointers. Use of ia or ja after MatRestoreRowIJ() is invalid. 7861 7862 Level: developer 7863 7864 .seealso: `MatGetRowIJ()`, `MatRestoreColumnIJ()` 7865 @*/ 7866 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7867 { 7868 PetscFunctionBegin; 7869 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7870 PetscValidType(mat,1); 7871 if (ia) PetscValidPointer(ia,6); 7872 if (ja) PetscValidPointer(ja,7); 7873 if (done) PetscValidBoolPointer(done,8); 7874 MatCheckPreallocated(mat,1); 7875 7876 if (!mat->ops->restorerowij && done) *done = PETSC_FALSE; 7877 else { 7878 if (done) *done = PETSC_TRUE; 7879 PetscCall((*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done)); 7880 if (n) *n = 0; 7881 if (ia) *ia = NULL; 7882 if (ja) *ja = NULL; 7883 } 7884 PetscFunctionReturn(0); 7885 } 7886 7887 /*@C 7888 MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with 7889 MatGetColumnIJ(). 7890 7891 Collective on Mat 7892 7893 Input Parameters: 7894 + mat - the matrix 7895 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7896 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7897 symmetrized 7898 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7899 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7900 always used. 7901 7902 Output Parameters: 7903 + n - size of (possibly compressed) matrix 7904 . ia - the column pointers 7905 . ja - the row indices 7906 - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7907 7908 Level: developer 7909 7910 .seealso: `MatGetColumnIJ()`, `MatRestoreRowIJ()` 7911 @*/ 7912 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7913 { 7914 PetscFunctionBegin; 7915 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7916 PetscValidType(mat,1); 7917 if (ia) PetscValidPointer(ia,6); 7918 if (ja) PetscValidPointer(ja,7); 7919 PetscValidBoolPointer(done,8); 7920 MatCheckPreallocated(mat,1); 7921 7922 if (!mat->ops->restorecolumnij) *done = PETSC_FALSE; 7923 else { 7924 *done = PETSC_TRUE; 7925 PetscCall((*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done)); 7926 if (n) *n = 0; 7927 if (ia) *ia = NULL; 7928 if (ja) *ja = NULL; 7929 } 7930 PetscFunctionReturn(0); 7931 } 7932 7933 /*@C 7934 MatColoringPatch -Used inside matrix coloring routines that 7935 use MatGetRowIJ() and/or MatGetColumnIJ(). 7936 7937 Collective on Mat 7938 7939 Input Parameters: 7940 + mat - the matrix 7941 . ncolors - max color value 7942 . n - number of entries in colorarray 7943 - colorarray - array indicating color for each column 7944 7945 Output Parameters: 7946 . iscoloring - coloring generated using colorarray information 7947 7948 Level: developer 7949 7950 .seealso: `MatGetRowIJ()`, `MatGetColumnIJ()` 7951 7952 @*/ 7953 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring) 7954 { 7955 PetscFunctionBegin; 7956 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7957 PetscValidType(mat,1); 7958 PetscValidIntPointer(colorarray,4); 7959 PetscValidPointer(iscoloring,5); 7960 MatCheckPreallocated(mat,1); 7961 7962 if (!mat->ops->coloringpatch) { 7963 PetscCall(ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring)); 7964 } else { 7965 PetscCall((*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring)); 7966 } 7967 PetscFunctionReturn(0); 7968 } 7969 7970 /*@ 7971 MatSetUnfactored - Resets a factored matrix to be treated as unfactored. 7972 7973 Logically Collective on Mat 7974 7975 Input Parameter: 7976 . mat - the factored matrix to be reset 7977 7978 Notes: 7979 This routine should be used only with factored matrices formed by in-place 7980 factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE 7981 format). This option can save memory, for example, when solving nonlinear 7982 systems with a matrix-free Newton-Krylov method and a matrix-based, in-place 7983 ILU(0) preconditioner. 7984 7985 Note that one can specify in-place ILU(0) factorization by calling 7986 .vb 7987 PCType(pc,PCILU); 7988 PCFactorSeUseInPlace(pc); 7989 .ve 7990 or by using the options -pc_type ilu -pc_factor_in_place 7991 7992 In-place factorization ILU(0) can also be used as a local 7993 solver for the blocks within the block Jacobi or additive Schwarz 7994 methods (runtime option: -sub_pc_factor_in_place). See Users-Manual: ch_pc 7995 for details on setting local solver options. 7996 7997 Most users should employ the simplified KSP interface for linear solvers 7998 instead of working directly with matrix algebra routines such as this. 7999 See, e.g., KSPCreate(). 8000 8001 Level: developer 8002 8003 .seealso: `PCFactorSetUseInPlace()`, `PCFactorGetUseInPlace()` 8004 8005 @*/ 8006 PetscErrorCode MatSetUnfactored(Mat mat) 8007 { 8008 PetscFunctionBegin; 8009 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8010 PetscValidType(mat,1); 8011 MatCheckPreallocated(mat,1); 8012 mat->factortype = MAT_FACTOR_NONE; 8013 if (!mat->ops->setunfactored) PetscFunctionReturn(0); 8014 PetscCall((*mat->ops->setunfactored)(mat)); 8015 PetscFunctionReturn(0); 8016 } 8017 8018 /*MC 8019 MatDenseGetArrayF90 - Accesses a matrix array from Fortran90. 8020 8021 Synopsis: 8022 MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 8023 8024 Not collective 8025 8026 Input Parameter: 8027 . x - matrix 8028 8029 Output Parameters: 8030 + xx_v - the Fortran90 pointer to the array 8031 - ierr - error code 8032 8033 Example of Usage: 8034 .vb 8035 PetscScalar, pointer xx_v(:,:) 8036 .... 8037 call MatDenseGetArrayF90(x,xx_v,ierr) 8038 a = xx_v(3) 8039 call MatDenseRestoreArrayF90(x,xx_v,ierr) 8040 .ve 8041 8042 Level: advanced 8043 8044 .seealso: `MatDenseRestoreArrayF90()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatSeqAIJGetArrayF90()` 8045 8046 M*/ 8047 8048 /*MC 8049 MatDenseRestoreArrayF90 - Restores a matrix array that has been 8050 accessed with MatDenseGetArrayF90(). 8051 8052 Synopsis: 8053 MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 8054 8055 Not collective 8056 8057 Input Parameters: 8058 + x - matrix 8059 - xx_v - the Fortran90 pointer to the array 8060 8061 Output Parameter: 8062 . ierr - error code 8063 8064 Example of Usage: 8065 .vb 8066 PetscScalar, pointer xx_v(:,:) 8067 .... 8068 call MatDenseGetArrayF90(x,xx_v,ierr) 8069 a = xx_v(3) 8070 call MatDenseRestoreArrayF90(x,xx_v,ierr) 8071 .ve 8072 8073 Level: advanced 8074 8075 .seealso: `MatDenseGetArrayF90()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatSeqAIJRestoreArrayF90()` 8076 8077 M*/ 8078 8079 /*MC 8080 MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90. 8081 8082 Synopsis: 8083 MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 8084 8085 Not collective 8086 8087 Input Parameter: 8088 . x - matrix 8089 8090 Output Parameters: 8091 + xx_v - the Fortran90 pointer to the array 8092 - ierr - error code 8093 8094 Example of Usage: 8095 .vb 8096 PetscScalar, pointer xx_v(:) 8097 .... 8098 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 8099 a = xx_v(3) 8100 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 8101 .ve 8102 8103 Level: advanced 8104 8105 .seealso: `MatSeqAIJRestoreArrayF90()`, `MatSeqAIJGetArray()`, `MatSeqAIJRestoreArray()`, `MatDenseGetArrayF90()` 8106 8107 M*/ 8108 8109 /*MC 8110 MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been 8111 accessed with MatSeqAIJGetArrayF90(). 8112 8113 Synopsis: 8114 MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 8115 8116 Not collective 8117 8118 Input Parameters: 8119 + x - matrix 8120 - xx_v - the Fortran90 pointer to the array 8121 8122 Output Parameter: 8123 . ierr - error code 8124 8125 Example of Usage: 8126 .vb 8127 PetscScalar, pointer xx_v(:) 8128 .... 8129 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 8130 a = xx_v(3) 8131 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 8132 .ve 8133 8134 Level: advanced 8135 8136 .seealso: `MatSeqAIJGetArrayF90()`, `MatSeqAIJGetArray()`, `MatSeqAIJRestoreArray()`, `MatDenseRestoreArrayF90()` 8137 8138 M*/ 8139 8140 /*@ 8141 MatCreateSubMatrix - Gets a single submatrix on the same number of processors 8142 as the original matrix. 8143 8144 Collective on Mat 8145 8146 Input Parameters: 8147 + mat - the original matrix 8148 . isrow - parallel IS containing the rows this processor should obtain 8149 . 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. 8150 - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 8151 8152 Output Parameter: 8153 . newmat - the new submatrix, of the same type as the old 8154 8155 Level: advanced 8156 8157 Notes: 8158 The submatrix will be able to be multiplied with vectors using the same layout as iscol. 8159 8160 Some matrix types place restrictions on the row and column indices, such 8161 as that they be sorted or that they be equal to each other. 8162 8163 The index sets may not have duplicate entries. 8164 8165 The first time this is called you should use a cll of MAT_INITIAL_MATRIX, 8166 the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls 8167 to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX 8168 will reuse the matrix generated the first time. You should call MatDestroy() on newmat when 8169 you are finished using it. 8170 8171 The communicator of the newly obtained matrix is ALWAYS the same as the communicator of 8172 the input matrix. 8173 8174 If iscol is NULL then all columns are obtained (not supported in Fortran). 8175 8176 Example usage: 8177 Consider the following 8x8 matrix with 34 non-zero values, that is 8178 assembled across 3 processors. Let's assume that proc0 owns 3 rows, 8179 proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown 8180 as follows: 8181 8182 .vb 8183 1 2 0 | 0 3 0 | 0 4 8184 Proc0 0 5 6 | 7 0 0 | 8 0 8185 9 0 10 | 11 0 0 | 12 0 8186 ------------------------------------- 8187 13 0 14 | 15 16 17 | 0 0 8188 Proc1 0 18 0 | 19 20 21 | 0 0 8189 0 0 0 | 22 23 0 | 24 0 8190 ------------------------------------- 8191 Proc2 25 26 27 | 0 0 28 | 29 0 8192 30 0 0 | 31 32 33 | 0 34 8193 .ve 8194 8195 Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is 8196 8197 .vb 8198 2 0 | 0 3 0 | 0 8199 Proc0 5 6 | 7 0 0 | 8 8200 ------------------------------- 8201 Proc1 18 0 | 19 20 21 | 0 8202 ------------------------------- 8203 Proc2 26 27 | 0 0 28 | 29 8204 0 0 | 31 32 33 | 0 8205 .ve 8206 8207 .seealso: `MatCreateSubMatrices()`, `MatCreateSubMatricesMPI()`, `MatCreateSubMatrixVirtual()`, `MatSubMatrixVirtualUpdate()` 8208 @*/ 8209 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat) 8210 { 8211 PetscMPIInt size; 8212 Mat *local; 8213 IS iscoltmp; 8214 PetscBool flg; 8215 8216 PetscFunctionBegin; 8217 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8218 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 8219 if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 8220 PetscValidPointer(newmat,5); 8221 if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5); 8222 PetscValidType(mat,1); 8223 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8224 PetscCheck(cll != MAT_IGNORE_MATRIX,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX"); 8225 8226 MatCheckPreallocated(mat,1); 8227 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 8228 8229 if (!iscol || isrow == iscol) { 8230 PetscBool stride; 8231 PetscMPIInt grabentirematrix = 0,grab; 8232 PetscCall(PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride)); 8233 if (stride) { 8234 PetscInt first,step,n,rstart,rend; 8235 PetscCall(ISStrideGetInfo(isrow,&first,&step)); 8236 if (step == 1) { 8237 PetscCall(MatGetOwnershipRange(mat,&rstart,&rend)); 8238 if (rstart == first) { 8239 PetscCall(ISGetLocalSize(isrow,&n)); 8240 if (n == rend-rstart) { 8241 grabentirematrix = 1; 8242 } 8243 } 8244 } 8245 } 8246 PetscCall(MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat))); 8247 if (grab) { 8248 PetscCall(PetscInfo(mat,"Getting entire matrix as submatrix\n")); 8249 if (cll == MAT_INITIAL_MATRIX) { 8250 *newmat = mat; 8251 PetscCall(PetscObjectReference((PetscObject)mat)); 8252 } 8253 PetscFunctionReturn(0); 8254 } 8255 } 8256 8257 if (!iscol) { 8258 PetscCall(ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp)); 8259 } else { 8260 iscoltmp = iscol; 8261 } 8262 8263 /* if original matrix is on just one processor then use submatrix generated */ 8264 if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) { 8265 PetscCall(MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat)); 8266 goto setproperties; 8267 } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) { 8268 PetscCall(MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local)); 8269 *newmat = *local; 8270 PetscCall(PetscFree(local)); 8271 goto setproperties; 8272 } else if (!mat->ops->createsubmatrix) { 8273 /* Create a new matrix type that implements the operation using the full matrix */ 8274 PetscCall(PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0)); 8275 switch (cll) { 8276 case MAT_INITIAL_MATRIX: 8277 PetscCall(MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat)); 8278 break; 8279 case MAT_REUSE_MATRIX: 8280 PetscCall(MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp)); 8281 break; 8282 default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX"); 8283 } 8284 PetscCall(PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0)); 8285 goto setproperties; 8286 } 8287 8288 PetscCheck(mat->ops->createsubmatrix,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8289 PetscCall(PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0)); 8290 PetscCall((*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat)); 8291 PetscCall(PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0)); 8292 8293 setproperties: 8294 PetscCall(ISEqualUnsorted(isrow,iscoltmp,&flg)); 8295 if (flg) PetscCall(MatPropagateSymmetryOptions(mat,*newmat)); 8296 if (!iscol) PetscCall(ISDestroy(&iscoltmp)); 8297 if (*newmat && cll == MAT_INITIAL_MATRIX) PetscCall(PetscObjectStateIncrease((PetscObject)*newmat)); 8298 PetscFunctionReturn(0); 8299 } 8300 8301 /*@ 8302 MatPropagateSymmetryOptions - Propagates symmetry options set on a matrix to another matrix 8303 8304 Not Collective 8305 8306 Input Parameters: 8307 + A - the matrix we wish to propagate options from 8308 - B - the matrix we wish to propagate options to 8309 8310 Level: beginner 8311 8312 Notes: 8313 Propagates the options associated to `MAT_SYMMETRY_ETERNAL`, `MAT_STRUCTURALLY_SYMMETRIC`, `MAT_HERMITIAN`, `MAT_SPD`, `MAT_SYMMETRIC`, and `MAT_STRUCTURAL_SYMMETRY_ETERNAL` 8314 8315 .seealso: `MatSetOption()`, `MatIsSymmetricKnown()`, `MatIsSPDKnown()`, `MatIsHermitianKnown()`, MatIsStructurallySymmetricKnown()` 8316 @*/ 8317 PetscErrorCode MatPropagateSymmetryOptions(Mat A, Mat B) 8318 { 8319 PetscFunctionBegin; 8320 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8321 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 8322 B->symmetry_eternal = A->symmetry_eternal; 8323 B->structural_symmetry_eternal = A->structural_symmetry_eternal; 8324 B->symmetric = A->symmetric; 8325 B->structurally_symmetric = A->structurally_symmetric; 8326 B->spd = A->spd; 8327 B->hermitian = A->hermitian; 8328 PetscFunctionReturn(0); 8329 } 8330 8331 /*@ 8332 MatStashSetInitialSize - sets the sizes of the matrix stash, that is 8333 used during the assembly process to store values that belong to 8334 other processors. 8335 8336 Not Collective 8337 8338 Input Parameters: 8339 + mat - the matrix 8340 . size - the initial size of the stash. 8341 - bsize - the initial size of the block-stash(if used). 8342 8343 Options Database Keys: 8344 + -matstash_initial_size <size> or <size0,size1,...sizep-1> 8345 - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1> 8346 8347 Level: intermediate 8348 8349 Notes: 8350 The block-stash is used for values set with MatSetValuesBlocked() while 8351 the stash is used for values set with MatSetValues() 8352 8353 Run with the option -info and look for output of the form 8354 MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs. 8355 to determine the appropriate value, MM, to use for size and 8356 MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs. 8357 to determine the value, BMM to use for bsize 8358 8359 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `Mat`, `MatStashGetInfo()` 8360 8361 @*/ 8362 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize) 8363 { 8364 PetscFunctionBegin; 8365 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8366 PetscValidType(mat,1); 8367 PetscCall(MatStashSetInitialSize_Private(&mat->stash,size)); 8368 PetscCall(MatStashSetInitialSize_Private(&mat->bstash,bsize)); 8369 PetscFunctionReturn(0); 8370 } 8371 8372 /*@ 8373 MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 8374 the matrix 8375 8376 Neighbor-wise Collective on Mat 8377 8378 Input Parameters: 8379 + mat - the matrix 8380 . x,y - the vectors 8381 - w - where the result is stored 8382 8383 Level: intermediate 8384 8385 Notes: 8386 w may be the same vector as y. 8387 8388 This allows one to use either the restriction or interpolation (its transpose) 8389 matrix to do the interpolation 8390 8391 .seealso: `MatMultAdd()`, `MatMultTransposeAdd()`, `MatRestrict()` 8392 8393 @*/ 8394 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w) 8395 { 8396 PetscInt M,N,Ny; 8397 8398 PetscFunctionBegin; 8399 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8400 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8401 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8402 PetscValidHeaderSpecific(w,VEC_CLASSID,4); 8403 PetscCall(MatGetSize(A,&M,&N)); 8404 PetscCall(VecGetSize(y,&Ny)); 8405 if (M == Ny) { 8406 PetscCall(MatMultAdd(A,x,y,w)); 8407 } else { 8408 PetscCall(MatMultTransposeAdd(A,x,y,w)); 8409 } 8410 PetscFunctionReturn(0); 8411 } 8412 8413 /*@ 8414 MatInterpolate - y = A*x or A'*x depending on the shape of 8415 the matrix 8416 8417 Neighbor-wise Collective on Mat 8418 8419 Input Parameters: 8420 + mat - the matrix 8421 - x,y - the vectors 8422 8423 Level: intermediate 8424 8425 Notes: 8426 This allows one to use either the restriction or interpolation (its transpose) 8427 matrix to do the interpolation 8428 8429 .seealso: `MatMultAdd()`, `MatMultTransposeAdd()`, `MatRestrict()` 8430 8431 @*/ 8432 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y) 8433 { 8434 PetscInt M,N,Ny; 8435 8436 PetscFunctionBegin; 8437 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8438 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8439 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8440 PetscCall(MatGetSize(A,&M,&N)); 8441 PetscCall(VecGetSize(y,&Ny)); 8442 if (M == Ny) { 8443 PetscCall(MatMult(A,x,y)); 8444 } else { 8445 PetscCall(MatMultTranspose(A,x,y)); 8446 } 8447 PetscFunctionReturn(0); 8448 } 8449 8450 /*@ 8451 MatRestrict - y = A*x or A'*x 8452 8453 Neighbor-wise Collective on Mat 8454 8455 Input Parameters: 8456 + mat - the matrix 8457 - x,y - the vectors 8458 8459 Level: intermediate 8460 8461 Notes: 8462 This allows one to use either the restriction or interpolation (its transpose) 8463 matrix to do the restriction 8464 8465 .seealso: `MatMultAdd()`, `MatMultTransposeAdd()`, `MatInterpolate()` 8466 8467 @*/ 8468 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y) 8469 { 8470 PetscInt M,N,Ny; 8471 8472 PetscFunctionBegin; 8473 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8474 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8475 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8476 PetscCall(MatGetSize(A,&M,&N)); 8477 PetscCall(VecGetSize(y,&Ny)); 8478 if (M == Ny) { 8479 PetscCall(MatMult(A,x,y)); 8480 } else { 8481 PetscCall(MatMultTranspose(A,x,y)); 8482 } 8483 PetscFunctionReturn(0); 8484 } 8485 8486 /*@ 8487 MatMatInterpolateAdd - Y = W + A*X or W + A'*X 8488 8489 Neighbor-wise Collective on Mat 8490 8491 Input Parameters: 8492 + mat - the matrix 8493 - w, x - the input dense matrices 8494 8495 Output Parameters: 8496 . y - the output dense matrix 8497 8498 Level: intermediate 8499 8500 Notes: 8501 This allows one to use either the restriction or interpolation (its transpose) 8502 matrix to do the interpolation. y matrix can be reused if already created with the proper sizes, 8503 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8504 8505 .seealso: `MatInterpolateAdd()`, `MatMatInterpolate()`, `MatMatRestrict()` 8506 8507 @*/ 8508 PetscErrorCode MatMatInterpolateAdd(Mat A,Mat x,Mat w,Mat *y) 8509 { 8510 PetscInt M,N,Mx,Nx,Mo,My = 0,Ny = 0; 8511 PetscBool trans = PETSC_TRUE; 8512 MatReuse reuse = MAT_INITIAL_MATRIX; 8513 8514 PetscFunctionBegin; 8515 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8516 PetscValidHeaderSpecific(x,MAT_CLASSID,2); 8517 PetscValidType(x,2); 8518 if (w) PetscValidHeaderSpecific(w,MAT_CLASSID,3); 8519 if (*y) PetscValidHeaderSpecific(*y,MAT_CLASSID,4); 8520 PetscCall(MatGetSize(A,&M,&N)); 8521 PetscCall(MatGetSize(x,&Mx,&Nx)); 8522 if (N == Mx) trans = PETSC_FALSE; 8523 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); 8524 Mo = trans ? N : M; 8525 if (*y) { 8526 PetscCall(MatGetSize(*y,&My,&Ny)); 8527 if (Mo == My && Nx == Ny) { reuse = MAT_REUSE_MATRIX; } 8528 else { 8529 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); 8530 PetscCall(MatDestroy(y)); 8531 } 8532 } 8533 8534 if (w && *y == w) { /* this is to minimize changes in PCMG */ 8535 PetscBool flg; 8536 8537 PetscCall(PetscObjectQuery((PetscObject)*y,"__MatMatIntAdd_w",(PetscObject*)&w)); 8538 if (w) { 8539 PetscInt My,Ny,Mw,Nw; 8540 8541 PetscCall(PetscObjectTypeCompare((PetscObject)*y,((PetscObject)w)->type_name,&flg)); 8542 PetscCall(MatGetSize(*y,&My,&Ny)); 8543 PetscCall(MatGetSize(w,&Mw,&Nw)); 8544 if (!flg || My != Mw || Ny != Nw) w = NULL; 8545 } 8546 if (!w) { 8547 PetscCall(MatDuplicate(*y,MAT_COPY_VALUES,&w)); 8548 PetscCall(PetscObjectCompose((PetscObject)*y,"__MatMatIntAdd_w",(PetscObject)w)); 8549 PetscCall(PetscLogObjectParent((PetscObject)*y,(PetscObject)w)); 8550 PetscCall(PetscObjectDereference((PetscObject)w)); 8551 } else { 8552 PetscCall(MatCopy(*y,w,UNKNOWN_NONZERO_PATTERN)); 8553 } 8554 } 8555 if (!trans) { 8556 PetscCall(MatMatMult(A,x,reuse,PETSC_DEFAULT,y)); 8557 } else { 8558 PetscCall(MatTransposeMatMult(A,x,reuse,PETSC_DEFAULT,y)); 8559 } 8560 if (w) PetscCall(MatAXPY(*y,1.0,w,UNKNOWN_NONZERO_PATTERN)); 8561 PetscFunctionReturn(0); 8562 } 8563 8564 /*@ 8565 MatMatInterpolate - Y = A*X or A'*X 8566 8567 Neighbor-wise Collective on Mat 8568 8569 Input Parameters: 8570 + mat - the matrix 8571 - x - the input dense matrix 8572 8573 Output Parameters: 8574 . y - the output dense matrix 8575 8576 Level: intermediate 8577 8578 Notes: 8579 This allows one to use either the restriction or interpolation (its transpose) 8580 matrix to do the interpolation. y matrix can be reused if already created with the proper sizes, 8581 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8582 8583 .seealso: `MatInterpolate()`, `MatRestrict()`, `MatMatRestrict()` 8584 8585 @*/ 8586 PetscErrorCode MatMatInterpolate(Mat A,Mat x,Mat *y) 8587 { 8588 PetscFunctionBegin; 8589 PetscCall(MatMatInterpolateAdd(A,x,NULL,y)); 8590 PetscFunctionReturn(0); 8591 } 8592 8593 /*@ 8594 MatMatRestrict - Y = A*X or A'*X 8595 8596 Neighbor-wise Collective on Mat 8597 8598 Input Parameters: 8599 + mat - the matrix 8600 - x - the input dense matrix 8601 8602 Output Parameters: 8603 . y - the output dense matrix 8604 8605 Level: intermediate 8606 8607 Notes: 8608 This allows one to use either the restriction or interpolation (its transpose) 8609 matrix to do the restriction. y matrix can be reused if already created with the proper sizes, 8610 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8611 8612 .seealso: `MatRestrict()`, `MatInterpolate()`, `MatMatInterpolate()` 8613 @*/ 8614 PetscErrorCode MatMatRestrict(Mat A,Mat x,Mat *y) 8615 { 8616 PetscFunctionBegin; 8617 PetscCall(MatMatInterpolateAdd(A,x,NULL,y)); 8618 PetscFunctionReturn(0); 8619 } 8620 8621 /*@ 8622 MatGetNullSpace - retrieves the null space of a matrix. 8623 8624 Logically Collective on Mat 8625 8626 Input Parameters: 8627 + mat - the matrix 8628 - nullsp - the null space object 8629 8630 Level: developer 8631 8632 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatSetNullSpace()` 8633 @*/ 8634 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp) 8635 { 8636 PetscFunctionBegin; 8637 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8638 PetscValidPointer(nullsp,2); 8639 *nullsp = (mat->symmetric == PETSC_BOOL3_TRUE && !mat->nullsp) ? mat->transnullsp : mat->nullsp; 8640 PetscFunctionReturn(0); 8641 } 8642 8643 /*@ 8644 MatSetNullSpace - attaches a null space to a matrix. 8645 8646 Logically Collective on Mat 8647 8648 Input Parameters: 8649 + mat - the matrix 8650 - nullsp - the null space object 8651 8652 Level: advanced 8653 8654 Notes: 8655 This null space is used by the KSP linear solvers to solve singular systems. 8656 8657 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 8658 8659 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 8660 to zero but the linear system will still be solved in a least squares sense. 8661 8662 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8663 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). 8664 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 8665 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 8666 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). 8667 This \hat{b} can be obtained by calling MatNullSpaceRemove() with the null space of the transpose of the matrix. 8668 8669 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 8670 routine also automatically calls MatSetTransposeNullSpace(). 8671 8672 The user should call `MatNullSpaceDestroy()`. 8673 8674 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatGetNullSpace()`, `MatSetTransposeNullSpace()`, `MatGetTransposeNullSpace()`, `MatNullSpaceRemove()`, 8675 `KSPSetPCSide()` 8676 @*/ 8677 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp) 8678 { 8679 PetscFunctionBegin; 8680 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8681 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8682 if (nullsp) PetscCall(PetscObjectReference((PetscObject)nullsp)); 8683 PetscCall(MatNullSpaceDestroy(&mat->nullsp)); 8684 mat->nullsp = nullsp; 8685 if (mat->symmetric == PETSC_BOOL3_TRUE) { 8686 PetscCall(MatSetTransposeNullSpace(mat,nullsp)); 8687 } 8688 PetscFunctionReturn(0); 8689 } 8690 8691 /*@ 8692 MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix. 8693 8694 Logically Collective on Mat 8695 8696 Input Parameters: 8697 + mat - the matrix 8698 - nullsp - the null space object 8699 8700 Level: developer 8701 8702 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatSetTransposeNullSpace()`, `MatSetNullSpace()`, `MatGetNullSpace()` 8703 @*/ 8704 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp) 8705 { 8706 PetscFunctionBegin; 8707 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8708 PetscValidType(mat,1); 8709 PetscValidPointer(nullsp,2); 8710 *nullsp = (mat->symmetric == PETSC_BOOL3_TRUE && !mat->transnullsp) ? mat->nullsp : mat->transnullsp; 8711 PetscFunctionReturn(0); 8712 } 8713 8714 /*@ 8715 MatSetTransposeNullSpace - attaches the null space of a transpose of a matrix to the matrix 8716 8717 Logically Collective on Mat 8718 8719 Input Parameters: 8720 + mat - the matrix 8721 - nullsp - the null space object 8722 8723 Level: advanced 8724 8725 Notes: 8726 This allows solving singular linear systems defined by the transpose of the matrix using KSP solvers with left preconditioning. 8727 8728 See MatSetNullSpace() 8729 8730 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatGetNullSpace()`, `MatSetNullSpace()`, `MatGetTransposeNullSpace()`, `MatNullSpaceRemove()`, `KSPSetPCSide()` 8731 @*/ 8732 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp) 8733 { 8734 PetscFunctionBegin; 8735 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8736 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8737 if (nullsp) PetscCall(PetscObjectReference((PetscObject)nullsp)); 8738 PetscCall(MatNullSpaceDestroy(&mat->transnullsp)); 8739 mat->transnullsp = nullsp; 8740 PetscFunctionReturn(0); 8741 } 8742 8743 /*@ 8744 MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions 8745 This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix. 8746 8747 Logically Collective on Mat 8748 8749 Input Parameters: 8750 + mat - the matrix 8751 - nullsp - the null space object 8752 8753 Level: advanced 8754 8755 Notes: 8756 Overwrites any previous near null space that may have been attached 8757 8758 You can remove the null space by calling this routine with an nullsp of NULL 8759 8760 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNullSpace()`, `MatNullSpaceCreateRigidBody()`, `MatGetNearNullSpace()` 8761 @*/ 8762 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp) 8763 { 8764 PetscFunctionBegin; 8765 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8766 PetscValidType(mat,1); 8767 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8768 MatCheckPreallocated(mat,1); 8769 if (nullsp) PetscCall(PetscObjectReference((PetscObject)nullsp)); 8770 PetscCall(MatNullSpaceDestroy(&mat->nearnullsp)); 8771 mat->nearnullsp = nullsp; 8772 PetscFunctionReturn(0); 8773 } 8774 8775 /*@ 8776 MatGetNearNullSpace - Get null space attached with MatSetNearNullSpace() 8777 8778 Not Collective 8779 8780 Input Parameter: 8781 . mat - the matrix 8782 8783 Output Parameter: 8784 . nullsp - the null space object, NULL if not set 8785 8786 Level: developer 8787 8788 .seealso: `MatSetNearNullSpace()`, `MatGetNullSpace()`, `MatNullSpaceCreate()` 8789 @*/ 8790 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp) 8791 { 8792 PetscFunctionBegin; 8793 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8794 PetscValidType(mat,1); 8795 PetscValidPointer(nullsp,2); 8796 MatCheckPreallocated(mat,1); 8797 *nullsp = mat->nearnullsp; 8798 PetscFunctionReturn(0); 8799 } 8800 8801 /*@C 8802 MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix. 8803 8804 Collective on Mat 8805 8806 Input Parameters: 8807 + mat - the matrix 8808 . row - row/column permutation 8809 . fill - expected fill factor >= 1.0 8810 - level - level of fill, for ICC(k) 8811 8812 Notes: 8813 Probably really in-place only when level of fill is zero, otherwise allocates 8814 new space to store factored matrix and deletes previous memory. 8815 8816 Most users should employ the simplified KSP interface for linear solvers 8817 instead of working directly with matrix algebra routines such as this. 8818 See, e.g., KSPCreate(). 8819 8820 Level: developer 8821 8822 .seealso: `MatICCFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()` 8823 8824 Developer Note: fortran interface is not autogenerated as the f90 8825 interface definition cannot be generated correctly [due to MatFactorInfo] 8826 8827 @*/ 8828 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info) 8829 { 8830 PetscFunctionBegin; 8831 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8832 PetscValidType(mat,1); 8833 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 8834 PetscValidPointer(info,3); 8835 PetscCheck(mat->rmap->N == mat->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 8836 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8837 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8838 PetscCheck(mat->ops->iccfactor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8839 MatCheckPreallocated(mat,1); 8840 PetscCall((*mat->ops->iccfactor)(mat,row,info)); 8841 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 8842 PetscFunctionReturn(0); 8843 } 8844 8845 /*@ 8846 MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 8847 ghosted ones. 8848 8849 Not Collective 8850 8851 Input Parameters: 8852 + mat - the matrix 8853 - diag - the diagonal values, including ghost ones 8854 8855 Level: developer 8856 8857 Notes: 8858 Works only for MPIAIJ and MPIBAIJ matrices 8859 8860 .seealso: `MatDiagonalScale()` 8861 @*/ 8862 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag) 8863 { 8864 PetscMPIInt size; 8865 8866 PetscFunctionBegin; 8867 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8868 PetscValidHeaderSpecific(diag,VEC_CLASSID,2); 8869 PetscValidType(mat,1); 8870 8871 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled"); 8872 PetscCall(PetscLogEventBegin(MAT_Scale,mat,0,0,0)); 8873 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 8874 if (size == 1) { 8875 PetscInt n,m; 8876 PetscCall(VecGetSize(diag,&n)); 8877 PetscCall(MatGetSize(mat,NULL,&m)); 8878 if (m == n) { 8879 PetscCall(MatDiagonalScale(mat,NULL,diag)); 8880 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions"); 8881 } else { 8882 PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag)); 8883 } 8884 PetscCall(PetscLogEventEnd(MAT_Scale,mat,0,0,0)); 8885 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 8886 PetscFunctionReturn(0); 8887 } 8888 8889 /*@ 8890 MatGetInertia - Gets the inertia from a factored matrix 8891 8892 Collective on Mat 8893 8894 Input Parameter: 8895 . mat - the matrix 8896 8897 Output Parameters: 8898 + nneg - number of negative eigenvalues 8899 . nzero - number of zero eigenvalues 8900 - npos - number of positive eigenvalues 8901 8902 Level: advanced 8903 8904 Notes: 8905 Matrix must have been factored by MatCholeskyFactor() 8906 8907 @*/ 8908 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos) 8909 { 8910 PetscFunctionBegin; 8911 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8912 PetscValidType(mat,1); 8913 PetscCheck(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8914 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled"); 8915 PetscCheck(mat->ops->getinertia,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8916 PetscCall((*mat->ops->getinertia)(mat,nneg,nzero,npos)); 8917 PetscFunctionReturn(0); 8918 } 8919 8920 /* ----------------------------------------------------------------*/ 8921 /*@C 8922 MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors 8923 8924 Neighbor-wise Collective on Mats 8925 8926 Input Parameters: 8927 + mat - the factored matrix 8928 - b - the right-hand-side vectors 8929 8930 Output Parameter: 8931 . x - the result vectors 8932 8933 Notes: 8934 The vectors b and x cannot be the same. I.e., one cannot 8935 call MatSolves(A,x,x). 8936 8937 Notes: 8938 Most users should employ the simplified KSP interface for linear solvers 8939 instead of working directly with matrix algebra routines such as this. 8940 See, e.g., KSPCreate(). 8941 8942 Level: developer 8943 8944 .seealso: `MatSolveAdd()`, `MatSolveTranspose()`, `MatSolveTransposeAdd()`, `MatSolve()` 8945 @*/ 8946 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x) 8947 { 8948 PetscFunctionBegin; 8949 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8950 PetscValidType(mat,1); 8951 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 8952 PetscCheck(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8953 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 8954 8955 PetscCheck(mat->ops->solves,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8956 MatCheckPreallocated(mat,1); 8957 PetscCall(PetscLogEventBegin(MAT_Solves,mat,0,0,0)); 8958 PetscCall((*mat->ops->solves)(mat,b,x)); 8959 PetscCall(PetscLogEventEnd(MAT_Solves,mat,0,0,0)); 8960 PetscFunctionReturn(0); 8961 } 8962 8963 /*@ 8964 MatIsSymmetric - Test whether a matrix is symmetric 8965 8966 Collective on Mat 8967 8968 Input Parameters: 8969 + A - the matrix to test 8970 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose) 8971 8972 Output Parameters: 8973 . flg - the result 8974 8975 Notes: 8976 For real numbers MatIsSymmetric() and MatIsHermitian() return identical results 8977 8978 If the matrix does not yet know if it is symmetric or not this can be an expensive operation, also available `MatIsSymmetricKnown()` 8979 8980 Level: intermediate 8981 8982 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetricKnown()` 8983 @*/ 8984 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg) 8985 { 8986 PetscFunctionBegin; 8987 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8988 PetscValidBoolPointer(flg,3); 8989 8990 if (A->symmetric == PETSC_BOOL3_TRUE) *flg = PETSC_TRUE; 8991 else if (A->symmetric == PETSC_BOOL3_FALSE) *flg = PETSC_FALSE; 8992 else { 8993 if (!A->ops->issymmetric) { 8994 MatType mattype; 8995 PetscCall(MatGetType(A,&mattype)); 8996 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for symmetric",mattype); 8997 } 8998 PetscCall((*A->ops->issymmetric)(A,tol,flg)); 8999 if (!tol) PetscCall(MatSetOption(A,MAT_SYMMETRIC,*flg)); 9000 } 9001 PetscFunctionReturn(0); 9002 } 9003 9004 /*@ 9005 MatIsHermitian - Test whether a matrix is Hermitian 9006 9007 Collective on Mat 9008 9009 Input Parameters: 9010 + A - the matrix to test 9011 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian) 9012 9013 Output Parameters: 9014 . flg - the result 9015 9016 Level: intermediate 9017 9018 Notes: 9019 For real numbers MatIsSymmetric() and MatIsHermitian() return identical results 9020 9021 If the matrix does not yet know if it is hermitian or not this can be an expensive operation, also available `MatIsHermitianKnown()` 9022 9023 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitianKnown()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, 9024 `MatIsSymmetricKnown()`, `MatIsSymmetric()` 9025 @*/ 9026 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg) 9027 { 9028 PetscFunctionBegin; 9029 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9030 PetscValidBoolPointer(flg,3); 9031 9032 if (A->hermitian == PETSC_BOOL3_TRUE) *flg = PETSC_TRUE; 9033 else if (A->hermitian == PETSC_BOOL3_FALSE) *flg = PETSC_FALSE; 9034 else { 9035 if (!A->ops->ishermitian) { 9036 MatType mattype; 9037 PetscCall(MatGetType(A,&mattype)); 9038 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for hermitian",mattype); 9039 } 9040 PetscCall((*A->ops->ishermitian)(A,tol,flg)); 9041 if (!tol) PetscCall(MatSetOption(A,MAT_HERMITIAN,*flg)); 9042 } 9043 PetscFunctionReturn(0); 9044 } 9045 9046 /*@ 9047 MatIsSymmetricKnown - Checks if a matrix knows if it is symmetric or not and its symmetric state 9048 9049 Not Collective 9050 9051 Input Parameter: 9052 . A - the matrix to check 9053 9054 Output Parameters: 9055 + set - PETSC_TRUE if the matrix knows its symmetry state (this tells you if the next flag is valid) 9056 - flg - the result (only valid if set is PETSC_TRUE) 9057 9058 Level: advanced 9059 9060 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric() 9061 if you want it explicitly checked 9062 9063 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitianKnown()` 9064 @*/ 9065 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg) 9066 { 9067 PetscFunctionBegin; 9068 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9069 PetscValidBoolPointer(set,2); 9070 PetscValidBoolPointer(flg,3); 9071 if (A->symmetric != PETSC_BOOL3_UNKNOWN) { 9072 *set = PETSC_TRUE; 9073 *flg = PetscBool3ToBool(A->symmetric); 9074 } else { 9075 *set = PETSC_FALSE; 9076 } 9077 PetscFunctionReturn(0); 9078 } 9079 9080 /*@ 9081 MatIsSPDKnown - Checks if a matrix knows if it is symmetric positive definite or not and its symmetric positive definite state 9082 9083 Not Collective 9084 9085 Input Parameter: 9086 . A - the matrix to check 9087 9088 Output Parameters: 9089 + set - PETSC_TRUE if the matrix knows its symmetric positive definite state (this tells you if the next flag is valid) 9090 - flg - the result (only valid if set is PETSC_TRUE) 9091 9092 Level: advanced 9093 9094 Note: 9095 Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). 9096 9097 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitianKnown()` 9098 @*/ 9099 PetscErrorCode MatIsSPDKnown(Mat A,PetscBool *set,PetscBool *flg) 9100 { 9101 PetscFunctionBegin; 9102 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9103 PetscValidBoolPointer(set,2); 9104 PetscValidBoolPointer(flg,3); 9105 if (A->spd != PETSC_BOOL3_UNKNOWN) { 9106 *set = PETSC_TRUE; 9107 *flg = PetscBool3ToBool(A->spd); 9108 } else { 9109 *set = PETSC_FALSE; 9110 } 9111 PetscFunctionReturn(0); 9112 } 9113 9114 /*@ 9115 MatIsHermitianKnown - Checks if a matrix knows if it is Hermitian or not and its Hermitian state 9116 9117 Not Collective 9118 9119 Input Parameter: 9120 . A - the matrix to check 9121 9122 Output Parameters: 9123 + set - PETSC_TRUE if the matrix knows its Hermitian state (this tells you if the next flag is valid) 9124 - flg - the result (only valid if set is PETSC_TRUE) 9125 9126 Level: advanced 9127 9128 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian() 9129 if you want it explicitly checked 9130 9131 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()` 9132 @*/ 9133 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg) 9134 { 9135 PetscFunctionBegin; 9136 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9137 PetscValidBoolPointer(set,2); 9138 PetscValidBoolPointer(flg,3); 9139 if (A->hermitian != PETSC_BOOL3_UNKNOWN) { 9140 *set = PETSC_TRUE; 9141 *flg = PetscBool3ToBool(A->hermitian); 9142 } else { 9143 *set = PETSC_FALSE; 9144 } 9145 PetscFunctionReturn(0); 9146 } 9147 9148 /*@ 9149 MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric 9150 9151 Collective on Mat 9152 9153 Input Parameter: 9154 . A - the matrix to test 9155 9156 Output Parameters: 9157 . flg - the result 9158 9159 Notes: 9160 If the matrix does yet know it is structurally symmetric this can be an expensive operation, also available `MatIsStructurallySymmetricKnown()` 9161 9162 Level: intermediate 9163 9164 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsSymmetric()`, `MatSetOption()`, `MatIsStructurallySymmetricKnown()` 9165 @*/ 9166 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg) 9167 { 9168 PetscFunctionBegin; 9169 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9170 PetscValidBoolPointer(flg,2); 9171 if (A->structurally_symmetric != PETSC_BOOL3_UNKNOWN) { 9172 *flg = PetscBool3ToBool(A->structurally_symmetric); 9173 } else { 9174 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); 9175 PetscCall((*A->ops->isstructurallysymmetric)(A,flg)); 9176 PetscCall(MatSetOption(A,MAT_STRUCTURALLY_SYMMETRIC,*flg)); 9177 } 9178 PetscFunctionReturn(0); 9179 } 9180 9181 /*@ 9182 MatIsStructurallySymmetricKnown - Checks if a matrix knows if it is structurally symmetric or not and its structurally symmetric state 9183 9184 Not Collective 9185 9186 Input Parameter: 9187 . A - the matrix to check 9188 9189 Output Parameters: 9190 + set - PETSC_TRUE if the matrix knows its structurally symmetric state (this tells you if the next flag is valid) 9191 - flg - the result (only valid if set is PETSC_TRUE) 9192 9193 Level: advanced 9194 9195 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitianKnown()` 9196 @*/ 9197 PetscErrorCode MatIsStructurallySymmetricKnown(Mat A,PetscBool *set,PetscBool *flg) 9198 { 9199 PetscFunctionBegin; 9200 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9201 PetscValidBoolPointer(set,2); 9202 PetscValidBoolPointer(flg,3); 9203 if (A->structurally_symmetric != PETSC_BOOL3_UNKNOWN) { 9204 *set = PETSC_TRUE; 9205 *flg = PetscBool3ToBool(A->structurally_symmetric); 9206 } else { 9207 *set = PETSC_FALSE; 9208 } 9209 PetscFunctionReturn(0); 9210 } 9211 9212 /*@ 9213 MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need 9214 to be communicated to other processors during the MatAssemblyBegin/End() process 9215 9216 Not collective 9217 9218 Input Parameter: 9219 . vec - the vector 9220 9221 Output Parameters: 9222 + nstash - the size of the stash 9223 . reallocs - the number of additional mallocs incurred. 9224 . bnstash - the size of the block stash 9225 - breallocs - the number of additional mallocs incurred.in the block stash 9226 9227 Level: advanced 9228 9229 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `Mat`, `MatStashSetInitialSize()` 9230 9231 @*/ 9232 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs) 9233 { 9234 PetscFunctionBegin; 9235 PetscCall(MatStashGetInfo_Private(&mat->stash,nstash,reallocs)); 9236 PetscCall(MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs)); 9237 PetscFunctionReturn(0); 9238 } 9239 9240 /*@C 9241 MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same 9242 parallel layout 9243 9244 Collective on Mat 9245 9246 Input Parameter: 9247 . mat - the matrix 9248 9249 Output Parameters: 9250 + right - (optional) vector that the matrix can be multiplied against 9251 - left - (optional) vector that the matrix vector product can be stored in 9252 9253 Notes: 9254 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(). 9255 9256 Notes: 9257 These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed 9258 9259 Level: advanced 9260 9261 .seealso: `MatCreate()`, `VecDestroy()` 9262 @*/ 9263 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left) 9264 { 9265 PetscFunctionBegin; 9266 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9267 PetscValidType(mat,1); 9268 if (mat->ops->getvecs) { 9269 PetscCall((*mat->ops->getvecs)(mat,right,left)); 9270 } else { 9271 PetscInt rbs,cbs; 9272 PetscCall(MatGetBlockSizes(mat,&rbs,&cbs)); 9273 if (right) { 9274 PetscCheck(mat->cmap->n >= 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup"); 9275 PetscCall(VecCreate(PetscObjectComm((PetscObject)mat),right)); 9276 PetscCall(VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE)); 9277 PetscCall(VecSetBlockSize(*right,cbs)); 9278 PetscCall(VecSetType(*right,mat->defaultvectype)); 9279 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 9280 if (mat->boundtocpu && mat->bindingpropagates) { 9281 PetscCall(VecSetBindingPropagates(*right,PETSC_TRUE)); 9282 PetscCall(VecBindToCPU(*right,PETSC_TRUE)); 9283 } 9284 #endif 9285 PetscCall(PetscLayoutReference(mat->cmap,&(*right)->map)); 9286 } 9287 if (left) { 9288 PetscCheck(mat->rmap->n >= 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup"); 9289 PetscCall(VecCreate(PetscObjectComm((PetscObject)mat),left)); 9290 PetscCall(VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE)); 9291 PetscCall(VecSetBlockSize(*left,rbs)); 9292 PetscCall(VecSetType(*left,mat->defaultvectype)); 9293 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 9294 if (mat->boundtocpu && mat->bindingpropagates) { 9295 PetscCall(VecSetBindingPropagates(*left,PETSC_TRUE)); 9296 PetscCall(VecBindToCPU(*left,PETSC_TRUE)); 9297 } 9298 #endif 9299 PetscCall(PetscLayoutReference(mat->rmap,&(*left)->map)); 9300 } 9301 } 9302 PetscFunctionReturn(0); 9303 } 9304 9305 /*@C 9306 MatFactorInfoInitialize - Initializes a MatFactorInfo data structure 9307 with default values. 9308 9309 Not Collective 9310 9311 Input Parameters: 9312 . info - the MatFactorInfo data structure 9313 9314 Notes: 9315 The solvers are generally used through the KSP and PC objects, for example 9316 PCLU, PCILU, PCCHOLESKY, PCICC 9317 9318 Level: developer 9319 9320 .seealso: `MatFactorInfo` 9321 9322 Developer Note: fortran interface is not autogenerated as the f90 9323 interface definition cannot be generated correctly [due to MatFactorInfo] 9324 9325 @*/ 9326 9327 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info) 9328 { 9329 PetscFunctionBegin; 9330 PetscCall(PetscMemzero(info,sizeof(MatFactorInfo))); 9331 PetscFunctionReturn(0); 9332 } 9333 9334 /*@ 9335 MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed 9336 9337 Collective on Mat 9338 9339 Input Parameters: 9340 + mat - the factored matrix 9341 - is - the index set defining the Schur indices (0-based) 9342 9343 Notes: 9344 Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system. 9345 9346 You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call. 9347 9348 Level: developer 9349 9350 .seealso: `MatGetFactor()`, `MatFactorGetSchurComplement()`, `MatFactorRestoreSchurComplement()`, `MatFactorCreateSchurComplement()`, `MatFactorSolveSchurComplement()`, 9351 `MatFactorSolveSchurComplementTranspose()`, `MatFactorSolveSchurComplement()` 9352 9353 @*/ 9354 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is) 9355 { 9356 PetscErrorCode (*f)(Mat,IS); 9357 9358 PetscFunctionBegin; 9359 PetscValidType(mat,1); 9360 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9361 PetscValidType(is,2); 9362 PetscValidHeaderSpecific(is,IS_CLASSID,2); 9363 PetscCheckSameComm(mat,1,is,2); 9364 PetscCheck(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 9365 PetscCall(PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f)); 9366 PetscCheck(f,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"The selected MatSolverType does not support Schur complement computation. You should use MATSOLVERMUMPS or MATSOLVERMKL_PARDISO"); 9367 PetscCall(MatDestroy(&mat->schur)); 9368 PetscCall((*f)(mat,is)); 9369 PetscCheck(mat->schur,PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created"); 9370 PetscFunctionReturn(0); 9371 } 9372 9373 /*@ 9374 MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step 9375 9376 Logically Collective on Mat 9377 9378 Input Parameters: 9379 + F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface 9380 . S - location where to return the Schur complement, can be NULL 9381 - status - the status of the Schur complement matrix, can be NULL 9382 9383 Notes: 9384 You must call MatFactorSetSchurIS() before calling this routine. 9385 9386 The routine provides a copy of the Schur matrix stored within the solver data structures. 9387 The caller must destroy the object when it is no longer needed. 9388 If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse. 9389 9390 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) 9391 9392 Developer Notes: 9393 The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc 9394 matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix. 9395 9396 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 9397 9398 Level: advanced 9399 9400 References: 9401 9402 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorGetSchurComplement()`, `MatFactorSchurStatus` 9403 @*/ 9404 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 9405 { 9406 PetscFunctionBegin; 9407 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9408 if (S) PetscValidPointer(S,2); 9409 if (status) PetscValidPointer(status,3); 9410 if (S) { 9411 PetscErrorCode (*f)(Mat,Mat*); 9412 9413 PetscCall(PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f)); 9414 if (f) { 9415 PetscCall((*f)(F,S)); 9416 } else { 9417 PetscCall(MatDuplicate(F->schur,MAT_COPY_VALUES,S)); 9418 } 9419 } 9420 if (status) *status = F->schur_status; 9421 PetscFunctionReturn(0); 9422 } 9423 9424 /*@ 9425 MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix 9426 9427 Logically Collective on Mat 9428 9429 Input Parameters: 9430 + F - the factored matrix obtained by calling MatGetFactor() 9431 . *S - location where to return the Schur complement, can be NULL 9432 - status - the status of the Schur complement matrix, can be NULL 9433 9434 Notes: 9435 You must call MatFactorSetSchurIS() before calling this routine. 9436 9437 Schur complement mode is currently implemented for sequential matrices. 9438 The routine returns a the Schur Complement stored within the data strutures of the solver. 9439 If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement. 9440 The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed. 9441 9442 Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix 9443 9444 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 9445 9446 Level: advanced 9447 9448 References: 9449 9450 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorRestoreSchurComplement()`, `MatFactorCreateSchurComplement()`, `MatFactorSchurStatus` 9451 @*/ 9452 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 9453 { 9454 PetscFunctionBegin; 9455 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9456 if (S) PetscValidPointer(S,2); 9457 if (status) PetscValidPointer(status,3); 9458 if (S) *S = F->schur; 9459 if (status) *status = F->schur_status; 9460 PetscFunctionReturn(0); 9461 } 9462 9463 /*@ 9464 MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement 9465 9466 Logically Collective on Mat 9467 9468 Input Parameters: 9469 + F - the factored matrix obtained by calling MatGetFactor() 9470 . *S - location where the Schur complement is stored 9471 - status - the status of the Schur complement matrix (see MatFactorSchurStatus) 9472 9473 Notes: 9474 9475 Level: advanced 9476 9477 References: 9478 9479 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorRestoreSchurComplement()`, `MatFactorCreateSchurComplement()`, `MatFactorSchurStatus` 9480 @*/ 9481 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status) 9482 { 9483 PetscFunctionBegin; 9484 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9485 if (S) { 9486 PetscValidHeaderSpecific(*S,MAT_CLASSID,2); 9487 *S = NULL; 9488 } 9489 F->schur_status = status; 9490 PetscCall(MatFactorUpdateSchurStatus_Private(F)); 9491 PetscFunctionReturn(0); 9492 } 9493 9494 /*@ 9495 MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step 9496 9497 Logically Collective on Mat 9498 9499 Input Parameters: 9500 + F - the factored matrix obtained by calling MatGetFactor() 9501 . rhs - location where the right hand side of the Schur complement system is stored 9502 - sol - location where the solution of the Schur complement system has to be returned 9503 9504 Notes: 9505 The sizes of the vectors should match the size of the Schur complement 9506 9507 Must be called after MatFactorSetSchurIS() 9508 9509 Level: advanced 9510 9511 References: 9512 9513 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorSolveSchurComplement()` 9514 @*/ 9515 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol) 9516 { 9517 PetscFunctionBegin; 9518 PetscValidType(F,1); 9519 PetscValidType(rhs,2); 9520 PetscValidType(sol,3); 9521 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9522 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9523 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9524 PetscCheckSameComm(F,1,rhs,2); 9525 PetscCheckSameComm(F,1,sol,3); 9526 PetscCall(MatFactorFactorizeSchurComplement(F)); 9527 switch (F->schur_status) { 9528 case MAT_FACTOR_SCHUR_FACTORED: 9529 PetscCall(MatSolveTranspose(F->schur,rhs,sol)); 9530 break; 9531 case MAT_FACTOR_SCHUR_INVERTED: 9532 PetscCall(MatMultTranspose(F->schur,rhs,sol)); 9533 break; 9534 default: 9535 SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %d",F->schur_status); 9536 } 9537 PetscFunctionReturn(0); 9538 } 9539 9540 /*@ 9541 MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step 9542 9543 Logically Collective on Mat 9544 9545 Input Parameters: 9546 + F - the factored matrix obtained by calling MatGetFactor() 9547 . rhs - location where the right hand side of the Schur complement system is stored 9548 - sol - location where the solution of the Schur complement system has to be returned 9549 9550 Notes: 9551 The sizes of the vectors should match the size of the Schur complement 9552 9553 Must be called after MatFactorSetSchurIS() 9554 9555 Level: advanced 9556 9557 References: 9558 9559 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorSolveSchurComplementTranspose()` 9560 @*/ 9561 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol) 9562 { 9563 PetscFunctionBegin; 9564 PetscValidType(F,1); 9565 PetscValidType(rhs,2); 9566 PetscValidType(sol,3); 9567 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9568 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9569 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9570 PetscCheckSameComm(F,1,rhs,2); 9571 PetscCheckSameComm(F,1,sol,3); 9572 PetscCall(MatFactorFactorizeSchurComplement(F)); 9573 switch (F->schur_status) { 9574 case MAT_FACTOR_SCHUR_FACTORED: 9575 PetscCall(MatSolve(F->schur,rhs,sol)); 9576 break; 9577 case MAT_FACTOR_SCHUR_INVERTED: 9578 PetscCall(MatMult(F->schur,rhs,sol)); 9579 break; 9580 default: 9581 SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %d",F->schur_status); 9582 } 9583 PetscFunctionReturn(0); 9584 } 9585 9586 /*@ 9587 MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step 9588 9589 Logically Collective on Mat 9590 9591 Input Parameters: 9592 . F - the factored matrix obtained by calling MatGetFactor() 9593 9594 Notes: 9595 Must be called after MatFactorSetSchurIS(). 9596 9597 Call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it. 9598 9599 Level: advanced 9600 9601 References: 9602 9603 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorGetSchurComplement()`, `MatFactorCreateSchurComplement()` 9604 @*/ 9605 PetscErrorCode MatFactorInvertSchurComplement(Mat F) 9606 { 9607 PetscFunctionBegin; 9608 PetscValidType(F,1); 9609 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9610 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0); 9611 PetscCall(MatFactorFactorizeSchurComplement(F)); 9612 PetscCall(MatFactorInvertSchurComplement_Private(F)); 9613 F->schur_status = MAT_FACTOR_SCHUR_INVERTED; 9614 PetscFunctionReturn(0); 9615 } 9616 9617 /*@ 9618 MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step 9619 9620 Logically Collective on Mat 9621 9622 Input Parameters: 9623 . F - the factored matrix obtained by calling MatGetFactor() 9624 9625 Notes: 9626 Must be called after MatFactorSetSchurIS(). 9627 9628 Level: advanced 9629 9630 References: 9631 9632 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorInvertSchurComplement()` 9633 @*/ 9634 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F) 9635 { 9636 PetscFunctionBegin; 9637 PetscValidType(F,1); 9638 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9639 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0); 9640 PetscCall(MatFactorFactorizeSchurComplement_Private(F)); 9641 F->schur_status = MAT_FACTOR_SCHUR_FACTORED; 9642 PetscFunctionReturn(0); 9643 } 9644 9645 /*@ 9646 MatPtAP - Creates the matrix product C = P^T * A * P 9647 9648 Neighbor-wise Collective on Mat 9649 9650 Input Parameters: 9651 + A - the matrix 9652 . P - the projection matrix 9653 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9654 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate 9655 if the result is a dense matrix this is irrelevant 9656 9657 Output Parameters: 9658 . C - the product matrix 9659 9660 Notes: 9661 C will be created and must be destroyed by the user with MatDestroy(). 9662 9663 For matrix types without special implementation the function fallbacks to MatMatMult() followed by MatTransposeMatMult(). 9664 9665 Level: intermediate 9666 9667 .seealso: `MatMatMult()`, `MatRARt()` 9668 @*/ 9669 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 9670 { 9671 PetscFunctionBegin; 9672 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*C,5); 9673 PetscCheck(scall != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9674 9675 if (scall == MAT_INITIAL_MATRIX) { 9676 PetscCall(MatProductCreate(A,P,NULL,C)); 9677 PetscCall(MatProductSetType(*C,MATPRODUCT_PtAP)); 9678 PetscCall(MatProductSetAlgorithm(*C,"default")); 9679 PetscCall(MatProductSetFill(*C,fill)); 9680 9681 (*C)->product->api_user = PETSC_TRUE; 9682 PetscCall(MatProductSetFromOptions(*C)); 9683 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); 9684 PetscCall(MatProductSymbolic(*C)); 9685 } else { /* scall == MAT_REUSE_MATRIX */ 9686 PetscCall(MatProductReplaceMats(A,P,NULL,*C)); 9687 } 9688 9689 PetscCall(MatProductNumeric(*C)); 9690 (*C)->symmetric = A->symmetric; 9691 (*C)->spd = A->spd; 9692 PetscFunctionReturn(0); 9693 } 9694 9695 /*@ 9696 MatRARt - Creates the matrix product C = R * A * R^T 9697 9698 Neighbor-wise Collective on Mat 9699 9700 Input Parameters: 9701 + A - the matrix 9702 . R - the projection matrix 9703 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9704 - fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate 9705 if the result is a dense matrix this is irrelevant 9706 9707 Output Parameters: 9708 . C - the product matrix 9709 9710 Notes: 9711 C will be created and must be destroyed by the user with MatDestroy(). 9712 9713 This routine is currently only implemented for pairs of AIJ matrices and classes 9714 which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes, 9715 parallel MatRARt is implemented via explicit transpose of R, which could be very expensive. 9716 We recommend using MatPtAP(). 9717 9718 Level: intermediate 9719 9720 .seealso: `MatMatMult()`, `MatPtAP()` 9721 @*/ 9722 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C) 9723 { 9724 PetscFunctionBegin; 9725 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*C,5); 9726 PetscCheck(scall != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9727 9728 if (scall == MAT_INITIAL_MATRIX) { 9729 PetscCall(MatProductCreate(A,R,NULL,C)); 9730 PetscCall(MatProductSetType(*C,MATPRODUCT_RARt)); 9731 PetscCall(MatProductSetAlgorithm(*C,"default")); 9732 PetscCall(MatProductSetFill(*C,fill)); 9733 9734 (*C)->product->api_user = PETSC_TRUE; 9735 PetscCall(MatProductSetFromOptions(*C)); 9736 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); 9737 PetscCall(MatProductSymbolic(*C)); 9738 } else { /* scall == MAT_REUSE_MATRIX */ 9739 PetscCall(MatProductReplaceMats(A,R,NULL,*C)); 9740 } 9741 9742 PetscCall(MatProductNumeric(*C)); 9743 if (A->symmetric == PETSC_BOOL3_TRUE) { 9744 PetscCall(MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE)); 9745 } 9746 PetscFunctionReturn(0); 9747 } 9748 9749 static PetscErrorCode MatProduct_Private(Mat A,Mat B,MatReuse scall,PetscReal fill,MatProductType ptype, Mat *C) 9750 { 9751 PetscFunctionBegin; 9752 PetscCheck(scall != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9753 9754 if (scall == MAT_INITIAL_MATRIX) { 9755 PetscCall(PetscInfo(A,"Calling MatProduct API with MAT_INITIAL_MATRIX and product type %s\n",MatProductTypes[ptype])); 9756 PetscCall(MatProductCreate(A,B,NULL,C)); 9757 PetscCall(MatProductSetType(*C,ptype)); 9758 PetscCall(MatProductSetAlgorithm(*C,MATPRODUCTALGORITHMDEFAULT)); 9759 PetscCall(MatProductSetFill(*C,fill)); 9760 9761 (*C)->product->api_user = PETSC_TRUE; 9762 PetscCall(MatProductSetFromOptions(*C)); 9763 PetscCall(MatProductSymbolic(*C)); 9764 } else { /* scall == MAT_REUSE_MATRIX */ 9765 Mat_Product *product = (*C)->product; 9766 PetscBool isdense; 9767 9768 PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)(*C),&isdense,MATSEQDENSE,MATMPIDENSE,"")); 9769 if (isdense && product && product->type != ptype) { 9770 PetscCall(MatProductClear(*C)); 9771 product = NULL; 9772 } 9773 PetscCall(PetscInfo(A,"Calling MatProduct API with MAT_REUSE_MATRIX %s product present and product type %s\n",product ? "with" : "without",MatProductTypes[ptype])); 9774 if (!product) { /* user provide the dense matrix *C without calling MatProductCreate() or reusing it from previous calls */ 9775 if (isdense) { 9776 PetscCall(MatProductCreate_Private(A,B,NULL,*C)); 9777 product = (*C)->product; 9778 product->fill = fill; 9779 product->api_user = PETSC_TRUE; 9780 product->clear = PETSC_TRUE; 9781 9782 PetscCall(MatProductSetType(*C,ptype)); 9783 PetscCall(MatProductSetFromOptions(*C)); 9784 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); 9785 PetscCall(MatProductSymbolic(*C)); 9786 } else SETERRQ(PetscObjectComm((PetscObject)(*C)),PETSC_ERR_SUP,"Call MatProductCreate() first"); 9787 } else { /* user may change input matrices A or B when REUSE */ 9788 PetscCall(MatProductReplaceMats(A,B,NULL,*C)); 9789 } 9790 } 9791 PetscCall(MatProductNumeric(*C)); 9792 PetscFunctionReturn(0); 9793 } 9794 9795 /*@ 9796 MatMatMult - Performs Matrix-Matrix Multiplication C=A*B. 9797 9798 Neighbor-wise Collective on Mat 9799 9800 Input Parameters: 9801 + A - the left matrix 9802 . B - the right matrix 9803 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9804 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate 9805 if the result is a dense matrix this is irrelevant 9806 9807 Output Parameters: 9808 . C - the product matrix 9809 9810 Notes: 9811 Unless scall is MAT_REUSE_MATRIX C will be created. 9812 9813 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 9814 call to this function with MAT_INITIAL_MATRIX. 9815 9816 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value actually needed. 9817 9818 If you have many matrices with the same non-zero structure to multiply, you should use MatProductCreate()/MatProductSymbolic()/MatProductReplaceMats(), and call MatProductNumeric() repeatedly. 9819 9820 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. 9821 9822 Example of Usage: 9823 .vb 9824 MatProductCreate(A,B,NULL,&C); 9825 MatProductSetType(C,MATPRODUCT_AB); 9826 MatProductSymbolic(C); 9827 MatProductNumeric(C); // compute C=A * B 9828 MatProductReplaceMats(A1,B1,NULL,C); // compute C=A1 * B1 9829 MatProductNumeric(C); 9830 MatProductReplaceMats(A2,NULL,NULL,C); // compute C=A2 * B1 9831 MatProductNumeric(C); 9832 .ve 9833 9834 Level: intermediate 9835 9836 .seealso: `MatTransposeMatMult()`, `MatMatTransposeMult()`, `MatPtAP()`, `MatProductCreate()`, `MatProductSymbolic()`, `MatProductReplaceMats()`, `MatProductNumeric()` 9837 @*/ 9838 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9839 { 9840 PetscFunctionBegin; 9841 PetscCall(MatProduct_Private(A,B,scall,fill,MATPRODUCT_AB,C)); 9842 PetscFunctionReturn(0); 9843 } 9844 9845 /*@ 9846 MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T. 9847 9848 Neighbor-wise Collective on Mat 9849 9850 Input Parameters: 9851 + A - the left matrix 9852 . B - the right matrix 9853 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9854 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9855 9856 Output Parameters: 9857 . C - the product matrix 9858 9859 Notes: 9860 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9861 9862 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9863 9864 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9865 actually needed. 9866 9867 This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class, 9868 and for pairs of MPIDense matrices. 9869 9870 Options Database Keys: 9871 . -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorithms for MPIDense matrices: the 9872 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity; 9873 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity. 9874 9875 Level: intermediate 9876 9877 .seealso: `MatMatMult()`, `MatTransposeMatMult()` `MatPtAP()` 9878 @*/ 9879 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9880 { 9881 PetscFunctionBegin; 9882 PetscCall(MatProduct_Private(A,B,scall,fill,MATPRODUCT_ABt,C)); 9883 if (A == B) { 9884 PetscCall(MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE)); 9885 } 9886 PetscFunctionReturn(0); 9887 } 9888 9889 /*@ 9890 MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B. 9891 9892 Neighbor-wise Collective on Mat 9893 9894 Input Parameters: 9895 + A - the left matrix 9896 . B - the right matrix 9897 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9898 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9899 9900 Output Parameters: 9901 . C - the product matrix 9902 9903 Notes: 9904 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9905 9906 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call. 9907 9908 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9909 actually needed. 9910 9911 This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes 9912 which inherit from SeqAIJ. C will be of the same type as the input matrices. 9913 9914 Level: intermediate 9915 9916 .seealso: `MatMatMult()`, `MatMatTransposeMult()`, `MatPtAP()` 9917 @*/ 9918 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9919 { 9920 PetscFunctionBegin; 9921 PetscCall(MatProduct_Private(A,B,scall,fill,MATPRODUCT_AtB,C)); 9922 PetscFunctionReturn(0); 9923 } 9924 9925 /*@ 9926 MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C. 9927 9928 Neighbor-wise Collective on Mat 9929 9930 Input Parameters: 9931 + A - the left matrix 9932 . B - the middle matrix 9933 . C - the right matrix 9934 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9935 - 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 9936 if the result is a dense matrix this is irrelevant 9937 9938 Output Parameters: 9939 . D - the product matrix 9940 9941 Notes: 9942 Unless scall is MAT_REUSE_MATRIX D will be created. 9943 9944 MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call 9945 9946 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9947 actually needed. 9948 9949 If you have many matrices with the same non-zero structure to multiply, you 9950 should use MAT_REUSE_MATRIX in all calls but the first 9951 9952 Level: intermediate 9953 9954 .seealso: `MatMatMult`, `MatPtAP()`, `MatMatTransposeMult()`, `MatTransposeMatMult()` 9955 @*/ 9956 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D) 9957 { 9958 PetscFunctionBegin; 9959 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*D,6); 9960 PetscCheck(scall != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9961 9962 if (scall == MAT_INITIAL_MATRIX) { 9963 PetscCall(MatProductCreate(A,B,C,D)); 9964 PetscCall(MatProductSetType(*D,MATPRODUCT_ABC)); 9965 PetscCall(MatProductSetAlgorithm(*D,"default")); 9966 PetscCall(MatProductSetFill(*D,fill)); 9967 9968 (*D)->product->api_user = PETSC_TRUE; 9969 PetscCall(MatProductSetFromOptions(*D)); 9970 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); 9971 PetscCall(MatProductSymbolic(*D)); 9972 } else { /* user may change input matrices when REUSE */ 9973 PetscCall(MatProductReplaceMats(A,B,C,*D)); 9974 } 9975 PetscCall(MatProductNumeric(*D)); 9976 PetscFunctionReturn(0); 9977 } 9978 9979 /*@ 9980 MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators. 9981 9982 Collective on Mat 9983 9984 Input Parameters: 9985 + mat - the matrix 9986 . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices) 9987 . subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used) 9988 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9989 9990 Output Parameter: 9991 . matredundant - redundant matrix 9992 9993 Notes: 9994 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 9995 original matrix has not changed from that last call to MatCreateRedundantMatrix(). 9996 9997 This routine creates the duplicated matrices in the subcommunicators; you should NOT create them before 9998 calling it. 9999 10000 Level: advanced 10001 10002 .seealso: `MatDestroy()` 10003 @*/ 10004 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant) 10005 { 10006 MPI_Comm comm; 10007 PetscMPIInt size; 10008 PetscInt mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs; 10009 Mat_Redundant *redund=NULL; 10010 PetscSubcomm psubcomm=NULL; 10011 MPI_Comm subcomm_in=subcomm; 10012 Mat *matseq; 10013 IS isrow,iscol; 10014 PetscBool newsubcomm=PETSC_FALSE; 10015 10016 PetscFunctionBegin; 10017 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10018 if (nsubcomm && reuse == MAT_REUSE_MATRIX) { 10019 PetscValidPointer(*matredundant,5); 10020 PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5); 10021 } 10022 10023 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 10024 if (size == 1 || nsubcomm == 1) { 10025 if (reuse == MAT_INITIAL_MATRIX) { 10026 PetscCall(MatDuplicate(mat,MAT_COPY_VALUES,matredundant)); 10027 } else { 10028 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"); 10029 PetscCall(MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN)); 10030 } 10031 PetscFunctionReturn(0); 10032 } 10033 10034 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10035 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10036 MatCheckPreallocated(mat,1); 10037 10038 PetscCall(PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0)); 10039 if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */ 10040 /* create psubcomm, then get subcomm */ 10041 PetscCall(PetscObjectGetComm((PetscObject)mat,&comm)); 10042 PetscCallMPI(MPI_Comm_size(comm,&size)); 10043 PetscCheck(nsubcomm >= 1 && nsubcomm <= size,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %d",size); 10044 10045 PetscCall(PetscSubcommCreate(comm,&psubcomm)); 10046 PetscCall(PetscSubcommSetNumber(psubcomm,nsubcomm)); 10047 PetscCall(PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS)); 10048 PetscCall(PetscSubcommSetFromOptions(psubcomm)); 10049 PetscCall(PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL)); 10050 newsubcomm = PETSC_TRUE; 10051 PetscCall(PetscSubcommDestroy(&psubcomm)); 10052 } 10053 10054 /* get isrow, iscol and a local sequential matrix matseq[0] */ 10055 if (reuse == MAT_INITIAL_MATRIX) { 10056 mloc_sub = PETSC_DECIDE; 10057 nloc_sub = PETSC_DECIDE; 10058 if (bs < 1) { 10059 PetscCall(PetscSplitOwnership(subcomm,&mloc_sub,&M)); 10060 PetscCall(PetscSplitOwnership(subcomm,&nloc_sub,&N)); 10061 } else { 10062 PetscCall(PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M)); 10063 PetscCall(PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N)); 10064 } 10065 PetscCallMPI(MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm)); 10066 rstart = rend - mloc_sub; 10067 PetscCall(ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow)); 10068 PetscCall(ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol)); 10069 } else { /* reuse == MAT_REUSE_MATRIX */ 10070 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"); 10071 /* retrieve subcomm */ 10072 PetscCall(PetscObjectGetComm((PetscObject)(*matredundant),&subcomm)); 10073 redund = (*matredundant)->redundant; 10074 isrow = redund->isrow; 10075 iscol = redund->iscol; 10076 matseq = redund->matseq; 10077 } 10078 PetscCall(MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq)); 10079 10080 /* get matredundant over subcomm */ 10081 if (reuse == MAT_INITIAL_MATRIX) { 10082 PetscCall(MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant)); 10083 10084 /* create a supporting struct and attach it to C for reuse */ 10085 PetscCall(PetscNewLog(*matredundant,&redund)); 10086 (*matredundant)->redundant = redund; 10087 redund->isrow = isrow; 10088 redund->iscol = iscol; 10089 redund->matseq = matseq; 10090 if (newsubcomm) { 10091 redund->subcomm = subcomm; 10092 } else { 10093 redund->subcomm = MPI_COMM_NULL; 10094 } 10095 } else { 10096 PetscCall(MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant)); 10097 } 10098 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 10099 if (matseq[0]->boundtocpu && matseq[0]->bindingpropagates) { 10100 PetscCall(MatBindToCPU(*matredundant,PETSC_TRUE)); 10101 PetscCall(MatSetBindingPropagates(*matredundant,PETSC_TRUE)); 10102 } 10103 #endif 10104 PetscCall(PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0)); 10105 PetscFunctionReturn(0); 10106 } 10107 10108 /*@C 10109 MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from 10110 a given 'mat' object. Each submatrix can span multiple procs. 10111 10112 Collective on Mat 10113 10114 Input Parameters: 10115 + mat - the matrix 10116 . subcomm - the subcommunicator obtained by com_split(comm) 10117 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10118 10119 Output Parameter: 10120 . subMat - 'parallel submatrices each spans a given subcomm 10121 10122 Notes: 10123 The submatrix partition across processors is dictated by 'subComm' a 10124 communicator obtained by MPI_comm_split(). The subComm 10125 is not restriced to be grouped with consecutive original ranks. 10126 10127 Due the MPI_Comm_split() usage, the parallel layout of the submatrices 10128 map directly to the layout of the original matrix [wrt the local 10129 row,col partitioning]. So the original 'DiagonalMat' naturally maps 10130 into the 'DiagonalMat' of the subMat, hence it is used directly from 10131 the subMat. However the offDiagMat looses some columns - and this is 10132 reconstructed with MatSetValues() 10133 10134 Level: advanced 10135 10136 .seealso: `MatCreateSubMatrices()` 10137 @*/ 10138 PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat) 10139 { 10140 PetscMPIInt commsize,subCommSize; 10141 10142 PetscFunctionBegin; 10143 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize)); 10144 PetscCallMPI(MPI_Comm_size(subComm,&subCommSize)); 10145 PetscCheck(subCommSize <= commsize,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %d < SubCommZize %d",commsize,subCommSize); 10146 10147 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"); 10148 PetscCall(PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0)); 10149 PetscCall((*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat)); 10150 PetscCall(PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0)); 10151 PetscFunctionReturn(0); 10152 } 10153 10154 /*@ 10155 MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering 10156 10157 Not Collective 10158 10159 Input Parameters: 10160 + mat - matrix to extract local submatrix from 10161 . isrow - local row indices for submatrix 10162 - iscol - local column indices for submatrix 10163 10164 Output Parameter: 10165 . submat - the submatrix 10166 10167 Level: intermediate 10168 10169 Notes: 10170 The submat should be returned with MatRestoreLocalSubMatrix(). 10171 10172 Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be 10173 the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's. 10174 10175 The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then 10176 MatSetValuesBlockedLocal() will also be implemented. 10177 10178 The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that 10179 matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided. 10180 10181 .seealso: `MatRestoreLocalSubMatrix()`, `MatCreateLocalRef()`, `MatSetLocalToGlobalMapping()` 10182 @*/ 10183 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10184 { 10185 PetscFunctionBegin; 10186 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10187 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10188 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10189 PetscCheckSameComm(isrow,2,iscol,3); 10190 PetscValidPointer(submat,4); 10191 PetscCheck(mat->rmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call"); 10192 10193 if (mat->ops->getlocalsubmatrix) { 10194 PetscCall((*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat)); 10195 } else { 10196 PetscCall(MatCreateLocalRef(mat,isrow,iscol,submat)); 10197 } 10198 PetscFunctionReturn(0); 10199 } 10200 10201 /*@ 10202 MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering 10203 10204 Not Collective 10205 10206 Input Parameters: 10207 + mat - matrix to extract local submatrix from 10208 . isrow - local row indices for submatrix 10209 . iscol - local column indices for submatrix 10210 - submat - the submatrix 10211 10212 Level: intermediate 10213 10214 .seealso: `MatGetLocalSubMatrix()` 10215 @*/ 10216 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10217 { 10218 PetscFunctionBegin; 10219 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10220 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10221 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10222 PetscCheckSameComm(isrow,2,iscol,3); 10223 PetscValidPointer(submat,4); 10224 if (*submat) { 10225 PetscValidHeaderSpecific(*submat,MAT_CLASSID,4); 10226 } 10227 10228 if (mat->ops->restorelocalsubmatrix) { 10229 PetscCall((*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat)); 10230 } else { 10231 PetscCall(MatDestroy(submat)); 10232 } 10233 *submat = NULL; 10234 PetscFunctionReturn(0); 10235 } 10236 10237 /* --------------------------------------------------------*/ 10238 /*@ 10239 MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix 10240 10241 Collective on Mat 10242 10243 Input Parameter: 10244 . mat - the matrix 10245 10246 Output Parameter: 10247 . is - if any rows have zero diagonals this contains the list of them 10248 10249 Level: developer 10250 10251 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 10252 @*/ 10253 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is) 10254 { 10255 PetscFunctionBegin; 10256 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10257 PetscValidType(mat,1); 10258 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10259 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10260 10261 if (!mat->ops->findzerodiagonals) { 10262 Vec diag; 10263 const PetscScalar *a; 10264 PetscInt *rows; 10265 PetscInt rStart, rEnd, r, nrow = 0; 10266 10267 PetscCall(MatCreateVecs(mat, &diag, NULL)); 10268 PetscCall(MatGetDiagonal(mat, diag)); 10269 PetscCall(MatGetOwnershipRange(mat, &rStart, &rEnd)); 10270 PetscCall(VecGetArrayRead(diag, &a)); 10271 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow; 10272 PetscCall(PetscMalloc1(nrow, &rows)); 10273 nrow = 0; 10274 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart; 10275 PetscCall(VecRestoreArrayRead(diag, &a)); 10276 PetscCall(VecDestroy(&diag)); 10277 PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is)); 10278 } else { 10279 PetscCall((*mat->ops->findzerodiagonals)(mat, is)); 10280 } 10281 PetscFunctionReturn(0); 10282 } 10283 10284 /*@ 10285 MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size) 10286 10287 Collective on Mat 10288 10289 Input Parameter: 10290 . mat - the matrix 10291 10292 Output Parameter: 10293 . is - contains the list of rows with off block diagonal entries 10294 10295 Level: developer 10296 10297 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 10298 @*/ 10299 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is) 10300 { 10301 PetscFunctionBegin; 10302 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10303 PetscValidType(mat,1); 10304 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10305 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10306 10307 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); 10308 PetscCall((*mat->ops->findoffblockdiagonalentries)(mat,is)); 10309 PetscFunctionReturn(0); 10310 } 10311 10312 /*@C 10313 MatInvertBlockDiagonal - Inverts the block diagonal entries. 10314 10315 Collective on Mat 10316 10317 Input Parameters: 10318 . mat - the matrix 10319 10320 Output Parameters: 10321 . values - the block inverses in column major order (FORTRAN-like) 10322 10323 Note: 10324 The size of the blocks is determined by the block size of the matrix. 10325 10326 Fortran Note: 10327 This routine is not available from Fortran. 10328 10329 Level: advanced 10330 10331 .seealso: `MatInvertVariableBlockEnvelope()`, `MatInvertBlockDiagonalMat()` 10332 @*/ 10333 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values) 10334 { 10335 PetscFunctionBegin; 10336 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10337 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10338 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10339 PetscCheck(mat->ops->invertblockdiagonal,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for type %s",((PetscObject)mat)->type_name); 10340 PetscCall((*mat->ops->invertblockdiagonal)(mat,values)); 10341 PetscFunctionReturn(0); 10342 } 10343 10344 /*@C 10345 MatInvertVariableBlockDiagonal - Inverts the point block diagonal entries. 10346 10347 Collective on Mat 10348 10349 Input Parameters: 10350 + mat - the matrix 10351 . nblocks - the number of blocks on the process, set with MatSetVariableBlockSizes() 10352 - bsizes - the size of each block on the process, set with MatSetVariableBlockSizes() 10353 10354 Output Parameters: 10355 . values - the block inverses in column major order (FORTRAN-like) 10356 10357 Note: 10358 This routine is not available from Fortran. 10359 10360 Level: advanced 10361 10362 .seealso: `MatInvertBlockDiagonal()`, `MatSetVariableBlockSizes()`, `MatInvertVariableBlockEnvelope()` 10363 @*/ 10364 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values) 10365 { 10366 PetscFunctionBegin; 10367 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10368 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10369 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10370 PetscCheck(mat->ops->invertvariableblockdiagonal,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for type %s",((PetscObject)mat)->type_name); 10371 PetscCall((*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values)); 10372 PetscFunctionReturn(0); 10373 } 10374 10375 /*@ 10376 MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A 10377 10378 Collective on Mat 10379 10380 Input Parameters: 10381 . A - the matrix 10382 10383 Output Parameters: 10384 . C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set. 10385 10386 Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C 10387 10388 Level: advanced 10389 10390 .seealso: `MatInvertBlockDiagonal()` 10391 @*/ 10392 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C) 10393 { 10394 const PetscScalar *vals; 10395 PetscInt *dnnz; 10396 PetscInt m,rstart,rend,bs,i,j; 10397 10398 PetscFunctionBegin; 10399 PetscCall(MatInvertBlockDiagonal(A,&vals)); 10400 PetscCall(MatGetBlockSize(A,&bs)); 10401 PetscCall(MatGetLocalSize(A,&m,NULL)); 10402 PetscCall(MatSetLayouts(C,A->rmap,A->cmap)); 10403 PetscCall(PetscMalloc1(m/bs,&dnnz)); 10404 for (j = 0; j < m/bs; j++) dnnz[j] = 1; 10405 PetscCall(MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL)); 10406 PetscCall(PetscFree(dnnz)); 10407 PetscCall(MatGetOwnershipRange(C,&rstart,&rend)); 10408 PetscCall(MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE)); 10409 for (i = rstart/bs; i < rend/bs; i++) { 10410 PetscCall(MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES)); 10411 } 10412 PetscCall(MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY)); 10413 PetscCall(MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY)); 10414 PetscCall(MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE)); 10415 PetscFunctionReturn(0); 10416 } 10417 10418 /*@C 10419 MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created 10420 via MatTransposeColoringCreate(). 10421 10422 Collective on MatTransposeColoring 10423 10424 Input Parameter: 10425 . c - coloring context 10426 10427 Level: intermediate 10428 10429 .seealso: `MatTransposeColoringCreate()` 10430 @*/ 10431 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c) 10432 { 10433 MatTransposeColoring matcolor=*c; 10434 10435 PetscFunctionBegin; 10436 if (!matcolor) PetscFunctionReturn(0); 10437 if (--((PetscObject)matcolor)->refct > 0) {matcolor = NULL; PetscFunctionReturn(0);} 10438 10439 PetscCall(PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow)); 10440 PetscCall(PetscFree(matcolor->rows)); 10441 PetscCall(PetscFree(matcolor->den2sp)); 10442 PetscCall(PetscFree(matcolor->colorforcol)); 10443 PetscCall(PetscFree(matcolor->columns)); 10444 if (matcolor->brows>0) PetscCall(PetscFree(matcolor->lstart)); 10445 PetscCall(PetscHeaderDestroy(c)); 10446 PetscFunctionReturn(0); 10447 } 10448 10449 /*@C 10450 MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which 10451 a MatTransposeColoring context has been created, computes a dense B^T by Apply 10452 MatTransposeColoring to sparse B. 10453 10454 Collective on MatTransposeColoring 10455 10456 Input Parameters: 10457 + B - sparse matrix B 10458 . Btdense - symbolic dense matrix B^T 10459 - coloring - coloring context created with MatTransposeColoringCreate() 10460 10461 Output Parameter: 10462 . Btdense - dense matrix B^T 10463 10464 Level: advanced 10465 10466 Notes: 10467 These are used internally for some implementations of MatRARt() 10468 10469 .seealso: `MatTransposeColoringCreate()`, `MatTransposeColoringDestroy()`, `MatTransColoringApplyDenToSp()` 10470 10471 @*/ 10472 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense) 10473 { 10474 PetscFunctionBegin; 10475 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 10476 PetscValidHeaderSpecific(Btdense,MAT_CLASSID,3); 10477 PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,1); 10478 10479 PetscCheck(B->ops->transcoloringapplysptoden,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name); 10480 PetscCall((B->ops->transcoloringapplysptoden)(coloring,B,Btdense)); 10481 PetscFunctionReturn(0); 10482 } 10483 10484 /*@C 10485 MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which 10486 a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense 10487 in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix 10488 Csp from Cden. 10489 10490 Collective on MatTransposeColoring 10491 10492 Input Parameters: 10493 + coloring - coloring context created with MatTransposeColoringCreate() 10494 - Cden - matrix product of a sparse matrix and a dense matrix Btdense 10495 10496 Output Parameter: 10497 . Csp - sparse matrix 10498 10499 Level: advanced 10500 10501 Notes: 10502 These are used internally for some implementations of MatRARt() 10503 10504 .seealso: `MatTransposeColoringCreate()`, `MatTransposeColoringDestroy()`, `MatTransColoringApplySpToDen()` 10505 10506 @*/ 10507 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp) 10508 { 10509 PetscFunctionBegin; 10510 PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1); 10511 PetscValidHeaderSpecific(Cden,MAT_CLASSID,2); 10512 PetscValidHeaderSpecific(Csp,MAT_CLASSID,3); 10513 10514 PetscCheck(Csp->ops->transcoloringapplydentosp,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name); 10515 PetscCall((Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp)); 10516 PetscCall(MatAssemblyBegin(Csp,MAT_FINAL_ASSEMBLY)); 10517 PetscCall(MatAssemblyEnd(Csp,MAT_FINAL_ASSEMBLY)); 10518 PetscFunctionReturn(0); 10519 } 10520 10521 /*@C 10522 MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T. 10523 10524 Collective on Mat 10525 10526 Input Parameters: 10527 + mat - the matrix product C 10528 - iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring() 10529 10530 Output Parameter: 10531 . color - the new coloring context 10532 10533 Level: intermediate 10534 10535 .seealso: `MatTransposeColoringDestroy()`, `MatTransColoringApplySpToDen()`, 10536 `MatTransColoringApplyDenToSp()` 10537 @*/ 10538 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color) 10539 { 10540 MatTransposeColoring c; 10541 MPI_Comm comm; 10542 10543 PetscFunctionBegin; 10544 PetscCall(PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0)); 10545 PetscCall(PetscObjectGetComm((PetscObject)mat,&comm)); 10546 PetscCall(PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL)); 10547 10548 c->ctype = iscoloring->ctype; 10549 if (mat->ops->transposecoloringcreate) { 10550 PetscCall((*mat->ops->transposecoloringcreate)(mat,iscoloring,c)); 10551 } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for matrix type %s",((PetscObject)mat)->type_name); 10552 10553 *color = c; 10554 PetscCall(PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0)); 10555 PetscFunctionReturn(0); 10556 } 10557 10558 /*@ 10559 MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the 10560 matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the 10561 same, otherwise it will be larger 10562 10563 Not Collective 10564 10565 Input Parameter: 10566 . A - the matrix 10567 10568 Output Parameter: 10569 . state - the current state 10570 10571 Notes: 10572 You can only compare states from two different calls to the SAME matrix, you cannot compare calls between 10573 different matrices 10574 10575 Level: intermediate 10576 10577 .seealso: `PetscObjectStateGet()` 10578 @*/ 10579 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state) 10580 { 10581 PetscFunctionBegin; 10582 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10583 *state = mat->nonzerostate; 10584 PetscFunctionReturn(0); 10585 } 10586 10587 /*@ 10588 MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential 10589 matrices from each processor 10590 10591 Collective 10592 10593 Input Parameters: 10594 + comm - the communicators the parallel matrix will live on 10595 . seqmat - the input sequential matrices 10596 . n - number of local columns (or PETSC_DECIDE) 10597 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10598 10599 Output Parameter: 10600 . mpimat - the parallel matrix generated 10601 10602 Level: advanced 10603 10604 Notes: 10605 The number of columns of the matrix in EACH processor MUST be the same. 10606 10607 @*/ 10608 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat) 10609 { 10610 PetscMPIInt size; 10611 10612 PetscFunctionBegin; 10613 PetscCallMPI(MPI_Comm_size(comm,&size)); 10614 if (size == 1) { 10615 if (reuse == MAT_INITIAL_MATRIX) { 10616 PetscCall(MatDuplicate(seqmat,MAT_COPY_VALUES,mpimat)); 10617 } else { 10618 PetscCall(MatCopy(seqmat,*mpimat,SAME_NONZERO_PATTERN)); 10619 } 10620 PetscFunctionReturn(0); 10621 } 10622 10623 PetscCheck(seqmat->ops->creatempimatconcatenateseqmat,PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name); 10624 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"); 10625 10626 PetscCall(PetscLogEventBegin(MAT_Merge,seqmat,0,0,0)); 10627 PetscCall((*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat)); 10628 PetscCall(PetscLogEventEnd(MAT_Merge,seqmat,0,0,0)); 10629 PetscFunctionReturn(0); 10630 } 10631 10632 /*@ 10633 MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent 10634 ranks' ownership ranges. 10635 10636 Collective on A 10637 10638 Input Parameters: 10639 + A - the matrix to create subdomains from 10640 - N - requested number of subdomains 10641 10642 Output Parameters: 10643 + n - number of subdomains resulting on this rank 10644 - iss - IS list with indices of subdomains on this rank 10645 10646 Level: advanced 10647 10648 Notes: 10649 number of subdomains must be smaller than the communicator size 10650 @*/ 10651 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[]) 10652 { 10653 MPI_Comm comm,subcomm; 10654 PetscMPIInt size,rank,color; 10655 PetscInt rstart,rend,k; 10656 10657 PetscFunctionBegin; 10658 PetscCall(PetscObjectGetComm((PetscObject)A,&comm)); 10659 PetscCallMPI(MPI_Comm_size(comm,&size)); 10660 PetscCallMPI(MPI_Comm_rank(comm,&rank)); 10661 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); 10662 *n = 1; 10663 k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */ 10664 color = rank/k; 10665 PetscCallMPI(MPI_Comm_split(comm,color,rank,&subcomm)); 10666 PetscCall(PetscMalloc1(1,iss)); 10667 PetscCall(MatGetOwnershipRange(A,&rstart,&rend)); 10668 PetscCall(ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0])); 10669 PetscCallMPI(MPI_Comm_free(&subcomm)); 10670 PetscFunctionReturn(0); 10671 } 10672 10673 /*@ 10674 MatGalerkin - Constructs the coarse grid problem via Galerkin projection. 10675 10676 If the interpolation and restriction operators are the same, uses MatPtAP. 10677 If they are not the same, use MatMatMatMult. 10678 10679 Once the coarse grid problem is constructed, correct for interpolation operators 10680 that are not of full rank, which can legitimately happen in the case of non-nested 10681 geometric multigrid. 10682 10683 Input Parameters: 10684 + restrct - restriction operator 10685 . dA - fine grid matrix 10686 . interpolate - interpolation operator 10687 . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10688 - fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate 10689 10690 Output Parameters: 10691 . A - the Galerkin coarse matrix 10692 10693 Options Database Key: 10694 . -pc_mg_galerkin <both,pmat,mat,none> - for what matrices the Galerkin process should be used 10695 10696 Level: developer 10697 10698 .seealso: `MatPtAP()`, `MatMatMatMult()` 10699 @*/ 10700 PetscErrorCode MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A) 10701 { 10702 IS zerorows; 10703 Vec diag; 10704 10705 PetscFunctionBegin; 10706 PetscCheck(reuse != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 10707 /* Construct the coarse grid matrix */ 10708 if (interpolate == restrct) { 10709 PetscCall(MatPtAP(dA,interpolate,reuse,fill,A)); 10710 } else { 10711 PetscCall(MatMatMatMult(restrct,dA,interpolate,reuse,fill,A)); 10712 } 10713 10714 /* If the interpolation matrix is not of full rank, A will have zero rows. 10715 This can legitimately happen in the case of non-nested geometric multigrid. 10716 In that event, we set the rows of the matrix to the rows of the identity, 10717 ignoring the equations (as the RHS will also be zero). */ 10718 10719 PetscCall(MatFindZeroRows(*A, &zerorows)); 10720 10721 if (zerorows != NULL) { /* if there are any zero rows */ 10722 PetscCall(MatCreateVecs(*A, &diag, NULL)); 10723 PetscCall(MatGetDiagonal(*A, diag)); 10724 PetscCall(VecISSet(diag, zerorows, 1.0)); 10725 PetscCall(MatDiagonalSet(*A, diag, INSERT_VALUES)); 10726 PetscCall(VecDestroy(&diag)); 10727 PetscCall(ISDestroy(&zerorows)); 10728 } 10729 PetscFunctionReturn(0); 10730 } 10731 10732 /*@C 10733 MatSetOperation - Allows user to set a matrix operation for any matrix type 10734 10735 Logically Collective on Mat 10736 10737 Input Parameters: 10738 + mat - the matrix 10739 . op - the name of the operation 10740 - f - the function that provides the operation 10741 10742 Level: developer 10743 10744 Usage: 10745 $ extern PetscErrorCode usermult(Mat,Vec,Vec); 10746 $ PetscCall(MatCreateXXX(comm,...&A); 10747 $ PetscCall(MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult); 10748 10749 Notes: 10750 See the file include/petscmat.h for a complete list of matrix 10751 operations, which all have the form MATOP_<OPERATION>, where 10752 <OPERATION> is the name (in all capital letters) of the 10753 user interface routine (e.g., MatMult() -> MATOP_MULT). 10754 10755 All user-provided functions (except for MATOP_DESTROY) should have the same calling 10756 sequence as the usual matrix interface routines, since they 10757 are intended to be accessed via the usual matrix interface 10758 routines, e.g., 10759 $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 10760 10761 In particular each function MUST return an error code of 0 on success and 10762 nonzero on failure. 10763 10764 This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type. 10765 10766 .seealso: `MatGetOperation()`, `MatCreateShell()`, `MatShellSetContext()`, `MatShellSetOperation()` 10767 @*/ 10768 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void)) 10769 { 10770 PetscFunctionBegin; 10771 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10772 if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) { 10773 mat->ops->viewnative = mat->ops->view; 10774 } 10775 (((void(**)(void))mat->ops)[op]) = f; 10776 PetscFunctionReturn(0); 10777 } 10778 10779 /*@C 10780 MatGetOperation - Gets a matrix operation for any matrix type. 10781 10782 Not Collective 10783 10784 Input Parameters: 10785 + mat - the matrix 10786 - op - the name of the operation 10787 10788 Output Parameter: 10789 . f - the function that provides the operation 10790 10791 Level: developer 10792 10793 Usage: 10794 $ PetscErrorCode (*usermult)(Mat,Vec,Vec); 10795 $ MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult); 10796 10797 Notes: 10798 See the file include/petscmat.h for a complete list of matrix 10799 operations, which all have the form MATOP_<OPERATION>, where 10800 <OPERATION> is the name (in all capital letters) of the 10801 user interface routine (e.g., MatMult() -> MATOP_MULT). 10802 10803 This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type. 10804 10805 .seealso: `MatSetOperation()`, `MatCreateShell()`, `MatShellGetContext()`, `MatShellGetOperation()` 10806 @*/ 10807 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void)) 10808 { 10809 PetscFunctionBegin; 10810 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10811 *f = (((void (**)(void))mat->ops)[op]); 10812 PetscFunctionReturn(0); 10813 } 10814 10815 /*@ 10816 MatHasOperation - Determines whether the given matrix supports the particular 10817 operation. 10818 10819 Not Collective 10820 10821 Input Parameters: 10822 + mat - the matrix 10823 - op - the operation, for example, MATOP_GET_DIAGONAL 10824 10825 Output Parameter: 10826 . has - either PETSC_TRUE or PETSC_FALSE 10827 10828 Level: advanced 10829 10830 Notes: 10831 See the file include/petscmat.h for a complete list of matrix 10832 operations, which all have the form MATOP_<OPERATION>, where 10833 <OPERATION> is the name (in all capital letters) of the 10834 user-level routine. E.g., MatNorm() -> MATOP_NORM. 10835 10836 .seealso: `MatCreateShell()` 10837 @*/ 10838 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has) 10839 { 10840 PetscFunctionBegin; 10841 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10842 PetscValidBoolPointer(has,3); 10843 if (mat->ops->hasoperation) { 10844 PetscCall((*mat->ops->hasoperation)(mat,op,has)); 10845 } else { 10846 if (((void**)mat->ops)[op]) *has = PETSC_TRUE; 10847 else { 10848 *has = PETSC_FALSE; 10849 if (op == MATOP_CREATE_SUBMATRIX) { 10850 PetscMPIInt size; 10851 10852 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 10853 if (size == 1) { 10854 PetscCall(MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has)); 10855 } 10856 } 10857 } 10858 } 10859 PetscFunctionReturn(0); 10860 } 10861 10862 /*@ 10863 MatHasCongruentLayouts - Determines whether the rows and columns layouts 10864 of the matrix are congruent 10865 10866 Collective on mat 10867 10868 Input Parameters: 10869 . mat - the matrix 10870 10871 Output Parameter: 10872 . cong - either PETSC_TRUE or PETSC_FALSE 10873 10874 Level: beginner 10875 10876 Notes: 10877 10878 .seealso: `MatCreate()`, `MatSetSizes()` 10879 @*/ 10880 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong) 10881 { 10882 PetscFunctionBegin; 10883 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10884 PetscValidType(mat,1); 10885 PetscValidBoolPointer(cong,2); 10886 if (!mat->rmap || !mat->cmap) { 10887 *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE; 10888 PetscFunctionReturn(0); 10889 } 10890 if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */ 10891 PetscCall(PetscLayoutSetUp(mat->rmap)); 10892 PetscCall(PetscLayoutSetUp(mat->cmap)); 10893 PetscCall(PetscLayoutCompare(mat->rmap,mat->cmap,cong)); 10894 if (*cong) mat->congruentlayouts = 1; 10895 else mat->congruentlayouts = 0; 10896 } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE; 10897 PetscFunctionReturn(0); 10898 } 10899 10900 PetscErrorCode MatSetInf(Mat A) 10901 { 10902 PetscFunctionBegin; 10903 PetscCheck(A->ops->setinf,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"No support for this operation for this matrix type"); 10904 PetscCall((*A->ops->setinf)(A)); 10905 PetscFunctionReturn(0); 10906 } 10907 10908 /*C 10909 MatCreateGraph - create a scalar matrix, for use in graph algorithms 10910 10911 Collective on mat 10912 10913 Input Parameters: 10914 + A - the matrix 10915 - sym - PETSC_TRUE indicates that the graph will be symmetrized 10916 . scale - PETSC_TRUE indicates that the graph will be scaled with the diagonal 10917 10918 Output Parameter: 10919 . graph - the resulting graph 10920 10921 Level: advanced 10922 10923 Notes: 10924 10925 .seealso: `MatCreate()`, `MatFilter()` 10926 */ 10927 PETSC_EXTERN PetscErrorCode MatCreateGraph(Mat A, PetscBool sym, PetscBool scale, Mat *graph) 10928 { 10929 PetscFunctionBegin; 10930 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 10931 PetscValidType(A,1); 10932 PetscValidPointer(graph,3); 10933 PetscCheck(A->ops->creategraph,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"No support for this operation for this matrix type"); 10934 PetscCall((*A->ops->creategraph)(A,sym,scale,graph)); 10935 PetscFunctionReturn(0); 10936 } 10937 10938 /*C 10939 MatFilter - filters a Mat values with an absolut value equal to or below a give threshold 10940 10941 Collective on mat 10942 10943 Input Parameter: 10944 . value - filter value - < 0: does nothing; == 0: removes only 0.0 entries; otherwise: removes entries <= value 10945 10946 Input/Output Parameter: 10947 . A - the Mat to filter in place 10948 10949 Level: advanced 10950 10951 Notes: 10952 10953 .seealso: `MatCreate()`, `MatCreateGraph()` 10954 */ 10955 PETSC_EXTERN PetscErrorCode MatFilter(Mat G,PetscReal value,Mat *F) 10956 { 10957 PetscFunctionBegin; 10958 PetscValidHeaderSpecific(G,MAT_CLASSID,1); 10959 PetscValidType(G,1); 10960 PetscValidPointer(F,3); 10961 if (value >= 0.0) { 10962 PetscCheck(G->ops->filter,PetscObjectComm((PetscObject)G),PETSC_ERR_SUP,"No support for this operation for this matrix type"); 10963 PetscCall((G->ops->filter)(G,value,F)); 10964 } 10965 PetscFunctionReturn(0); 10966 } 10967