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 if (!rctx) { 83 MPI_Comm comm; 84 PetscCall(PetscObjectGetComm((PetscObject)x,&comm)); 85 PetscCall(PetscRandomCreate(comm,&randObj)); 86 PetscCall(PetscRandomSetFromOptions(randObj)); 87 rctx = randObj; 88 } 89 PetscCall(PetscLogEventBegin(MAT_SetRandom,x,rctx,0,0)); 90 PetscUseTypeMethod(x,setrandom ,rctx); 91 PetscCall(PetscLogEventEnd(MAT_SetRandom,x,rctx,0,0)); 92 93 PetscCall(MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY)); 94 PetscCall(MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY)); 95 PetscCall(PetscRandomDestroy(&randObj)); 96 PetscFunctionReturn(0); 97 } 98 99 /*@ 100 MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in 101 102 Logically Collective on Mat 103 104 Input Parameter: 105 . mat - the factored matrix 106 107 Output Parameters: 108 + pivot - the pivot value computed 109 - row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes 110 the share the matrix 111 112 Level: advanced 113 114 Notes: 115 This routine does not work for factorizations done with external packages. 116 117 This routine should only be called if `MatGetFactorError()` returns a value of `MAT_FACTOR_NUMERIC_ZEROPIVOT` 118 119 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 120 121 .seealso: `MatZeroEntries()`, `MatFactor()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()`, `MatFactorClearError()`, `MatFactorGetErrorZeroPivot()` 122 @*/ 123 PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row) 124 { 125 PetscFunctionBegin; 126 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 127 PetscValidRealPointer(pivot,2); 128 PetscValidIntPointer(row,3); 129 *pivot = mat->factorerror_zeropivot_value; 130 *row = mat->factorerror_zeropivot_row; 131 PetscFunctionReturn(0); 132 } 133 134 /*@ 135 MatFactorGetError - gets the error code from a factorization 136 137 Logically Collective on Mat 138 139 Input Parameters: 140 . mat - the factored matrix 141 142 Output Parameter: 143 . err - the error code 144 145 Level: advanced 146 147 Notes: 148 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 149 150 .seealso: `MatZeroEntries()`, `MatFactor()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()`, `MatFactorClearError()`, `MatFactorGetErrorZeroPivot()`, 151 `MatErrorCode` 152 @*/ 153 PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err) 154 { 155 PetscFunctionBegin; 156 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 157 PetscValidPointer(err,2); 158 *err = mat->factorerrortype; 159 PetscFunctionReturn(0); 160 } 161 162 /*@ 163 MatFactorClearError - clears the error code in a factorization 164 165 Logically Collective on Mat 166 167 Input Parameter: 168 . mat - the factored matrix 169 170 Level: developer 171 172 Notes: 173 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 174 175 .seealso: `MatZeroEntries()`, `MatFactor()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()`, `MatFactorGetError()`, `MatFactorGetErrorZeroPivot()`, 176 `MatGetErrorCode()`, `MatErrorCode` 177 @*/ 178 PetscErrorCode MatFactorClearError(Mat mat) 179 { 180 PetscFunctionBegin; 181 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 182 mat->factorerrortype = MAT_FACTOR_NOERROR; 183 mat->factorerror_zeropivot_value = 0.0; 184 mat->factorerror_zeropivot_row = 0; 185 PetscFunctionReturn(0); 186 } 187 188 PETSC_INTERN PetscErrorCode MatFindNonzeroRowsOrCols_Basic(Mat mat,PetscBool cols,PetscReal tol,IS *nonzero) 189 { 190 Vec r,l; 191 const PetscScalar *al; 192 PetscInt i,nz,gnz,N,n; 193 194 PetscFunctionBegin; 195 PetscCall(MatCreateVecs(mat,&r,&l)); 196 if (!cols) { /* nonzero rows */ 197 PetscCall(MatGetSize(mat,&N,NULL)); 198 PetscCall(MatGetLocalSize(mat,&n,NULL)); 199 PetscCall(VecSet(l,0.0)); 200 PetscCall(VecSetRandom(r,NULL)); 201 PetscCall(MatMult(mat,r,l)); 202 PetscCall(VecGetArrayRead(l,&al)); 203 } else { /* nonzero columns */ 204 PetscCall(MatGetSize(mat,NULL,&N)); 205 PetscCall(MatGetLocalSize(mat,NULL,&n)); 206 PetscCall(VecSet(r,0.0)); 207 PetscCall(VecSetRandom(l,NULL)); 208 PetscCall(MatMultTranspose(mat,l,r)); 209 PetscCall(VecGetArrayRead(r,&al)); 210 } 211 if (tol <= 0.0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++; } 212 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nz++; } 213 PetscCall(MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat))); 214 if (gnz != N) { 215 PetscInt *nzr; 216 PetscCall(PetscMalloc1(nz,&nzr)); 217 if (nz) { 218 if (tol < 0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; } 219 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nzr[nz++] = i; } 220 } 221 PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,nonzero)); 222 } else *nonzero = NULL; 223 if (!cols) { /* nonzero rows */ 224 PetscCall(VecRestoreArrayRead(l,&al)); 225 } else { 226 PetscCall(VecRestoreArrayRead(r,&al)); 227 } 228 PetscCall(VecDestroy(&l)); 229 PetscCall(VecDestroy(&r)); 230 PetscFunctionReturn(0); 231 } 232 233 /*@ 234 MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix 235 236 Input Parameter: 237 . A - the matrix 238 239 Output Parameter: 240 . keptrows - the rows that are not completely zero 241 242 Notes: 243 keptrows is set to NULL if all rows are nonzero. 244 245 Level: intermediate 246 247 @*/ 248 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows) 249 { 250 PetscFunctionBegin; 251 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 252 PetscValidType(mat,1); 253 PetscValidPointer(keptrows,2); 254 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 255 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 256 if (mat->ops->findnonzerorows) PetscUseTypeMethod(mat,findnonzerorows ,keptrows); 257 else PetscCall(MatFindNonzeroRowsOrCols_Basic(mat,PETSC_FALSE,0.0,keptrows)); 258 PetscFunctionReturn(0); 259 } 260 261 /*@ 262 MatFindZeroRows - Locate all rows that are completely zero in the matrix 263 264 Input Parameter: 265 . A - the matrix 266 267 Output Parameter: 268 . zerorows - the rows that are completely zero 269 270 Notes: 271 zerorows is set to NULL if no rows are zero. 272 273 Level: intermediate 274 275 @*/ 276 PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows) 277 { 278 IS keptrows; 279 PetscInt m, n; 280 281 PetscFunctionBegin; 282 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 283 PetscValidType(mat,1); 284 PetscValidPointer(zerorows,2); 285 PetscCall(MatFindNonzeroRows(mat, &keptrows)); 286 /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows. 287 In keeping with this convention, we set zerorows to NULL if there are no zero 288 rows. */ 289 if (keptrows == NULL) { 290 *zerorows = NULL; 291 } else { 292 PetscCall(MatGetOwnershipRange(mat,&m,&n)); 293 PetscCall(ISComplement(keptrows,m,n,zerorows)); 294 PetscCall(ISDestroy(&keptrows)); 295 } 296 PetscFunctionReturn(0); 297 } 298 299 /*@ 300 MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling 301 302 Not Collective 303 304 Input Parameters: 305 . A - the matrix 306 307 Output Parameters: 308 . a - the diagonal part (which is a SEQUENTIAL matrix) 309 310 Notes: 311 See the manual page for `MatCreateAIJ()` for more information on the "diagonal part" of the matrix. 312 313 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. 314 315 Level: advanced 316 317 .seelaso: `MatCreateAIJ()` 318 @*/ 319 PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a) 320 { 321 PetscFunctionBegin; 322 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 323 PetscValidType(A,1); 324 PetscValidPointer(a,2); 325 PetscCheck(!A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 326 if (A->ops->getdiagonalblock) PetscUseTypeMethod(A,getdiagonalblock ,a); 327 else { 328 PetscMPIInt size; 329 330 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)A),&size)); 331 PetscCheck(size == 1,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not for parallel matrix type %s",((PetscObject)A)->type_name); 332 *a = A; 333 } 334 PetscFunctionReturn(0); 335 } 336 337 /*@ 338 MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries. 339 340 Collective on Mat 341 342 Input Parameters: 343 . mat - the matrix 344 345 Output Parameter: 346 . trace - the sum of the diagonal entries 347 348 Level: advanced 349 350 @*/ 351 PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace) 352 { 353 Vec diag; 354 355 PetscFunctionBegin; 356 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 357 PetscValidScalarPointer(trace,2); 358 PetscCall(MatCreateVecs(mat,&diag,NULL)); 359 PetscCall(MatGetDiagonal(mat,diag)); 360 PetscCall(VecSum(diag,trace)); 361 PetscCall(VecDestroy(&diag)); 362 PetscFunctionReturn(0); 363 } 364 365 /*@ 366 MatRealPart - Zeros out the imaginary part of the matrix 367 368 Logically Collective on Mat 369 370 Input Parameters: 371 . mat - the matrix 372 373 Level: advanced 374 375 .seealso: `MatImaginaryPart()` 376 @*/ 377 PetscErrorCode MatRealPart(Mat mat) 378 { 379 PetscFunctionBegin; 380 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 381 PetscValidType(mat,1); 382 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 383 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 384 MatCheckPreallocated(mat,1); 385 PetscUseTypeMethod(mat,realpart); 386 PetscFunctionReturn(0); 387 } 388 389 /*@C 390 MatGetGhosts - Get the global indices of all ghost nodes defined by the sparse matrix 391 392 Collective on Mat 393 394 Input Parameter: 395 . mat - the matrix 396 397 Output Parameters: 398 + nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block) 399 - ghosts - the global indices of the ghost points 400 401 Notes: 402 the nghosts and ghosts are suitable to pass into `VecCreateGhost()` 403 404 Level: advanced 405 406 @*/ 407 PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[]) 408 { 409 PetscFunctionBegin; 410 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 411 PetscValidType(mat,1); 412 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 413 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 414 if (mat->ops->getghosts) PetscUseTypeMethod(mat,getghosts ,nghosts,ghosts); 415 else { 416 if (nghosts) *nghosts = 0; 417 if (ghosts) *ghosts = NULL; 418 } 419 PetscFunctionReturn(0); 420 } 421 422 /*@ 423 MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part 424 425 Logically Collective on Mat 426 427 Input Parameters: 428 . mat - the matrix 429 430 Level: advanced 431 432 .seealso: `MatRealPart()` 433 @*/ 434 PetscErrorCode MatImaginaryPart(Mat mat) 435 { 436 PetscFunctionBegin; 437 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 438 PetscValidType(mat,1); 439 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 440 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 441 MatCheckPreallocated(mat,1); 442 PetscUseTypeMethod(mat,imaginarypart); 443 PetscFunctionReturn(0); 444 } 445 446 /*@ 447 MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices) 448 449 Not Collective 450 451 Input Parameter: 452 . mat - the matrix 453 454 Output Parameters: 455 + missing - is any diagonal missing 456 - dd - first diagonal entry that is missing (optional) on this process 457 458 Level: advanced 459 460 .seealso: `MatRealPart()` 461 @*/ 462 PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd) 463 { 464 PetscFunctionBegin; 465 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 466 PetscValidType(mat,1); 467 PetscValidBoolPointer(missing,2); 468 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix %s",((PetscObject)mat)->type_name); 469 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 470 PetscUseTypeMethod(mat,missingdiagonal ,missing,dd); 471 PetscFunctionReturn(0); 472 } 473 474 /*@C 475 MatGetRow - Gets a row of a matrix. You MUST call `MatRestoreRow()` 476 for each row that you get to ensure that your application does 477 not bleed memory. 478 479 Not Collective 480 481 Input Parameters: 482 + mat - the matrix 483 - row - the row to get 484 485 Output Parameters: 486 + ncols - if not NULL, the number of nonzeros in the row 487 . cols - if not NULL, the column numbers 488 - vals - if not NULL, the values 489 490 Notes: 491 This routine is provided for people who need to have direct access 492 to the structure of a matrix. We hope that we provide enough 493 high-level matrix routines that few users will need it. 494 495 `MatGetRow()` always returns 0-based column indices, regardless of 496 whether the internal representation is 0-based (default) or 1-based. 497 498 For better efficiency, set cols and/or vals to NULL if you do 499 not wish to extract these quantities. 500 501 The user can only examine the values extracted with `MatGetRow()`; 502 the values cannot be altered. To change the matrix entries, one 503 must use `MatSetValues()`. 504 505 You can only have one call to `MatGetRow()` outstanding for a particular 506 matrix at a time, per processor. `MatGetRow()` can only obtain rows 507 associated with the given processor, it cannot get rows from the 508 other processors; for that we suggest using `MatCreateSubMatrices()`, then 509 MatGetRow() on the submatrix. The row index passed to `MatGetRow()` 510 is in the global number of rows. 511 512 Use `MatGetRowIJ()` and `MatRestoreRowIJ()` to access all the local indices of the sparse matrix. 513 514 Use `MatSeqAIJGetArray()` and similar functions to access the numerical values for certain matrix types directly. 515 516 Fortran Notes: 517 The calling sequence from Fortran is 518 .vb 519 MatGetRow(matrix,row,ncols,cols,values,ierr) 520 Mat matrix (input) 521 integer row (input) 522 integer ncols (output) 523 integer cols(maxcols) (output) 524 double precision (or double complex) values(maxcols) output 525 .ve 526 where maxcols >= maximum nonzeros in any row of the matrix. 527 528 Caution: 529 Do not try to change the contents of the output arrays (cols and vals). 530 In some cases, this may corrupt the matrix. 531 532 Level: advanced 533 534 .seealso: `MatRestoreRow()`, `MatSetValues()`, `MatGetValues()`, `MatCreateSubMatrices()`, `MatGetDiagonal()`, `MatGetRowIJ()`, `MatRestoreRowIJ()` 535 @*/ 536 PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 537 { 538 PetscInt incols; 539 540 PetscFunctionBegin; 541 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 542 PetscValidType(mat,1); 543 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 544 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 545 MatCheckPreallocated(mat,1); 546 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); 547 PetscCall(PetscLogEventBegin(MAT_GetRow,mat,0,0,0)); 548 PetscCall((*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals)); 549 if (ncols) *ncols = incols; 550 PetscCall(PetscLogEventEnd(MAT_GetRow,mat,0,0,0)); 551 PetscFunctionReturn(0); 552 } 553 554 /*@ 555 MatConjugate - replaces the matrix values with their complex conjugates 556 557 Logically Collective on Mat 558 559 Input Parameters: 560 . mat - the matrix 561 562 Level: advanced 563 564 .seealso: `VecConjugate()`, `MatTranspose()` 565 @*/ 566 PetscErrorCode MatConjugate(Mat mat) 567 { 568 PetscFunctionBegin; 569 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 570 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 571 if (PetscDefined(USE_COMPLEX) && mat->hermitian != PETSC_BOOL3_TRUE) { 572 PetscUseTypeMethod(mat,conjugate); 573 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 574 } 575 PetscFunctionReturn(0); 576 } 577 578 /*@C 579 MatRestoreRow - Frees any temporary space allocated by `MatGetRow()`. 580 581 Not Collective 582 583 Input Parameters: 584 + mat - the matrix 585 . row - the row to get 586 . ncols, cols - the number of nonzeros and their columns 587 - vals - if nonzero the column values 588 589 Notes: 590 This routine should be called after you have finished examining the entries. 591 592 This routine zeros out ncols, cols, and vals. This is to prevent accidental 593 us of the array after it has been restored. If you pass NULL, it will 594 not zero the pointers. Use of cols or vals after `MatRestoreRow()` is invalid. 595 596 Fortran Notes: 597 The calling sequence from Fortran is 598 .vb 599 MatRestoreRow(matrix,row,ncols,cols,values,ierr) 600 Mat matrix (input) 601 integer row (input) 602 integer ncols (output) 603 integer cols(maxcols) (output) 604 double precision (or double complex) values(maxcols) output 605 .ve 606 Where maxcols >= maximum nonzeros in any row of the matrix. 607 608 In Fortran `MatRestoreRow()` MUST be called after `MatGetRow()` 609 before another call to `MatGetRow()` can be made. 610 611 Level: advanced 612 613 .seealso: `MatGetRow()` 614 @*/ 615 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 616 { 617 PetscFunctionBegin; 618 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 619 if (ncols) PetscValidIntPointer(ncols,3); 620 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 621 if (!mat->ops->restorerow) PetscFunctionReturn(0); 622 PetscCall((*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals)); 623 if (ncols) *ncols = 0; 624 if (cols) *cols = NULL; 625 if (vals) *vals = NULL; 626 PetscFunctionReturn(0); 627 } 628 629 /*@ 630 MatGetRowUpperTriangular - Sets a flag to enable calls to `MatGetRow()` for matrix in `MATSBAIJ` format. 631 You should call `MatRestoreRowUpperTriangular()` after calling` MatGetRow()` and `MatRestoreRow()` to disable the flag. 632 633 Not Collective 634 635 Input Parameters: 636 . mat - the matrix 637 638 Notes: 639 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. 640 641 Level: advanced 642 643 .seealso: `MatRestoreRowUpperTriangular()` 644 @*/ 645 PetscErrorCode MatGetRowUpperTriangular(Mat mat) 646 { 647 PetscFunctionBegin; 648 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 649 PetscValidType(mat,1); 650 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 651 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 652 MatCheckPreallocated(mat,1); 653 if (!mat->ops->getrowuppertriangular) PetscFunctionReturn(0); 654 PetscUseTypeMethod(mat,getrowuppertriangular); 655 PetscFunctionReturn(0); 656 } 657 658 /*@ 659 MatRestoreRowUpperTriangular - Disable calls to `MatGetRow()` for matrix in `MATSBAIJ` format. 660 661 Not Collective 662 663 Input Parameters: 664 . mat - the matrix 665 666 Notes: 667 This routine should be called after you have finished calls to `MatGetRow()` and `MatRestoreRow()`. 668 669 Level: advanced 670 671 .seealso: `MatGetRowUpperTriangular()` 672 @*/ 673 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat) 674 { 675 PetscFunctionBegin; 676 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 677 PetscValidType(mat,1); 678 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 679 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 680 MatCheckPreallocated(mat,1); 681 if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0); 682 PetscUseTypeMethod(mat,restorerowuppertriangular); 683 PetscFunctionReturn(0); 684 } 685 686 /*@C 687 MatSetOptionsPrefix - Sets the prefix used for searching for all 688 Mat options in the database. 689 690 Logically Collective on Mat 691 692 Input Parameters: 693 + A - the Mat context 694 - prefix - the prefix to prepend to all option names 695 696 Notes: 697 A hyphen (-) must NOT be given at the beginning of the prefix name. 698 The first character of all runtime options is AUTOMATICALLY the hyphen. 699 700 This is NOT used for options for the factorization of the matrix. Normally the 701 prefix is automatically passed in from the PC calling the factorization. To set 702 it directly use `MatSetOptionsPrefixFactor()` 703 704 Level: advanced 705 706 .seealso: `MatSetFromOptions()`, `MatSetOptionsPrefixFactor()` 707 @*/ 708 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[]) 709 { 710 PetscFunctionBegin; 711 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 712 PetscCall(PetscObjectSetOptionsPrefix((PetscObject)A,prefix)); 713 PetscFunctionReturn(0); 714 } 715 716 /*@C 717 MatSetOptionsPrefixFactor - Sets the prefix used for searching for all Mat factor options in the database for 718 for matrices created with `MatGetFactor()` 719 720 Logically Collective on Mat 721 722 Input Parameters: 723 + A - the Mat context 724 - prefix - the prefix to prepend to all option names for the factored matrix 725 726 Notes: 727 A hyphen (-) must NOT be given at the beginning of the prefix name. 728 The first character of all runtime options is AUTOMATICALLY the hyphen. 729 730 Normally the prefix is automatically passed in from the PC calling the factorization. To set 731 it directly when not using `KSP`/`PC` use `MatSetOptionsPrefixFactor()` 732 733 Level: developer 734 735 .seealso: `MatSetFromOptions()`, `MatSetOptionsPrefix()`, `MatAppendOptionsPrefixFactor()` 736 @*/ 737 PetscErrorCode MatSetOptionsPrefixFactor(Mat A,const char prefix[]) 738 { 739 PetscFunctionBegin; 740 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 741 if (prefix) { 742 PetscValidCharPointer(prefix,2); 743 PetscCheck(prefix[0] != '-',PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Options prefix should not begin with a hyphen"); 744 if (prefix != A->factorprefix) { 745 PetscCall(PetscFree(A->factorprefix)); 746 PetscCall(PetscStrallocpy(prefix,&A->factorprefix)); 747 } 748 } else PetscCall(PetscFree(A->factorprefix)); 749 PetscFunctionReturn(0); 750 } 751 752 /*@C 753 MatAppendOptionsPrefixFactor - Appends to the prefix used for searching for all Mat factor options in the database for 754 for matrices created with `MatGetFactor()` 755 756 Logically Collective on Mat 757 758 Input Parameters: 759 + A - the Mat context 760 - prefix - the prefix to prepend to all option names for the factored matrix 761 762 Notes: 763 A hyphen (-) must NOT be given at the beginning of the prefix name. 764 The first character of all runtime options is AUTOMATICALLY the hyphen. 765 766 Normally the prefix is automatically passed in from the PC calling the factorization. To set 767 it directly when not using `KSP`/`PC` use `MatAppendOptionsPrefixFactor()` 768 769 Level: developer 770 .seealso: `PetscOptionsCreate()`, `PetscOptionsDestroy()`, `PetscObjectSetOptionsPrefix()`, `PetscObjectPrependOptionsPrefix()`, 771 `PetscObjectGetOptionsPrefix()`, `TSAppendOptionsPrefix()`, `SNESAppendOptionsPrefix()`, `KSPAppendOptionsPrefix()`, `MatSetOptionsPrefixFactor()`, 772 `MatSetOptionsPrefix()` 773 @*/ 774 PetscErrorCode MatAppendOptionsPrefixFactor(Mat A,const char prefix[]) 775 { 776 char *buf = A->factorprefix; 777 size_t len1,len2; 778 779 PetscFunctionBegin; 780 PetscValidHeader(A,1); 781 if (!prefix) PetscFunctionReturn(0); 782 if (!buf) { 783 PetscCall(MatSetOptionsPrefixFactor(A,prefix)); 784 PetscFunctionReturn(0); 785 } 786 PetscCheck(prefix[0] != '-',PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Options prefix should not begin with a hyphen"); 787 788 PetscCall(PetscStrlen(prefix,&len1)); 789 PetscCall(PetscStrlen(buf,&len2)); 790 PetscCall(PetscMalloc1(1+len1+len2,&A->factorprefix)); 791 PetscCall(PetscStrcpy(A->factorprefix,buf)); 792 PetscCall(PetscStrcat(A->factorprefix,prefix)); 793 PetscCall(PetscFree(buf)); 794 PetscFunctionReturn(0); 795 } 796 797 /*@C 798 MatAppendOptionsPrefix - Appends to the prefix used for searching for all 799 Mat options in the database. 800 801 Logically Collective on Mat 802 803 Input Parameters: 804 + A - the Mat context 805 - prefix - the prefix to prepend to all option names 806 807 Notes: 808 A hyphen (-) must NOT be given at the beginning of the prefix name. 809 The first character of all runtime options is AUTOMATICALLY the hyphen. 810 811 Level: advanced 812 813 .seealso: `MatGetOptionsPrefix()` 814 @*/ 815 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[]) 816 { 817 PetscFunctionBegin; 818 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 819 PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)A,prefix)); 820 PetscFunctionReturn(0); 821 } 822 823 /*@C 824 MatGetOptionsPrefix - Gets the prefix used for searching for all 825 Mat options in the database. 826 827 Not Collective 828 829 Input Parameter: 830 . A - the Mat context 831 832 Output Parameter: 833 . prefix - pointer to the prefix string used 834 835 Notes: 836 On the fortran side, the user should pass in a string 'prefix' of 837 sufficient length to hold the prefix. 838 839 Level: advanced 840 841 .seealso: `MatAppendOptionsPrefix()` 842 @*/ 843 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[]) 844 { 845 PetscFunctionBegin; 846 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 847 PetscValidPointer(prefix,2); 848 PetscCall(PetscObjectGetOptionsPrefix((PetscObject)A,prefix)); 849 PetscFunctionReturn(0); 850 } 851 852 /*@ 853 MatResetPreallocation - Reset mat to use the original nonzero pattern provided by users. 854 855 Collective on Mat 856 857 Input Parameters: 858 . A - the Mat context 859 860 Notes: 861 The allocated memory will be shrunk after calling `MatAssemblyBegin()` and `MatAssemblyEnd()` with `MAT_FINAL_ASSEMBLY`. 862 863 Users can reset the preallocation to access the original memory. 864 865 Currently only supported for `MATMPIAIJ` and `MATSEQAIJ` matrices. 866 867 Level: beginner 868 869 .seealso: `MatSeqAIJSetPreallocation()`, `MatMPIAIJSetPreallocation()`, `MatXAIJSetPreallocation()` 870 @*/ 871 PetscErrorCode MatResetPreallocation(Mat A) 872 { 873 PetscFunctionBegin; 874 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 875 PetscValidType(A,1); 876 PetscUseMethod(A,"MatResetPreallocation_C",(Mat),(A)); 877 PetscFunctionReturn(0); 878 } 879 880 /*@ 881 MatSetUp - Sets up the internal matrix data structures for later use. 882 883 Collective on Mat 884 885 Input Parameters: 886 . A - the Mat context 887 888 Notes: 889 If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used. 890 891 If a suitable preallocation routine is used, this function does not need to be called. 892 893 See the Performance chapter of the PETSc users manual for how to preallocate matrices 894 895 Level: beginner 896 897 .seealso: `MatCreate()`, `MatDestroy()` 898 @*/ 899 PetscErrorCode MatSetUp(Mat A) 900 { 901 PetscFunctionBegin; 902 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 903 if (!((PetscObject)A)->type_name) { 904 PetscMPIInt size; 905 906 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)A), &size)); 907 PetscCall(MatSetType(A, size == 1 ? MATSEQAIJ : MATMPIAIJ)); 908 } 909 if (!A->preallocated && A->ops->setup) { 910 PetscCall(PetscInfo(A,"Warning not preallocating matrix storage\n")); 911 PetscUseTypeMethod(A,setup); 912 } 913 PetscCall(PetscLayoutSetUp(A->rmap)); 914 PetscCall(PetscLayoutSetUp(A->cmap)); 915 A->preallocated = PETSC_TRUE; 916 PetscFunctionReturn(0); 917 } 918 919 #if defined(PETSC_HAVE_SAWS) 920 #include <petscviewersaws.h> 921 #endif 922 923 /*@C 924 MatViewFromOptions - View from Options 925 926 Collective on Mat 927 928 Input Parameters: 929 + A - the Mat context 930 . obj - Optional object 931 - name - command line option 932 933 Level: intermediate 934 .seealso: `Mat`, `MatView`, `PetscObjectViewFromOptions()`, `MatCreate()` 935 @*/ 936 PetscErrorCode MatViewFromOptions(Mat A,PetscObject obj,const char name[]) 937 { 938 PetscFunctionBegin; 939 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 940 PetscCall(PetscObjectViewFromOptions((PetscObject)A,obj,name)); 941 PetscFunctionReturn(0); 942 } 943 944 /*@C 945 MatView - Visualizes a matrix object. 946 947 Collective on Mat 948 949 Input Parameters: 950 + mat - the matrix 951 - viewer - visualization context 952 953 Notes: 954 The available visualization contexts include 955 + `PETSC_VIEWER_STDOUT_SELF` - for sequential matrices 956 . `PETSC_VIEWER_STDOUT_WORLD` - for parallel matrices created on `PETSC_COMM_WORLD` 957 . `PETSC_VIEWER_STDOUT_`(comm) - for matrices created on MPI communicator comm 958 - `PETSC_VIEWER_DRAW_WORLD` - graphical display of nonzero structure 959 960 The user can open alternative visualization contexts with 961 + `PetscViewerASCIIOpen()` - Outputs matrix to a specified file 962 . `PetscViewerBinaryOpen()` - Outputs matrix in binary to a 963 specified file; corresponding input uses MatLoad() 964 . `PetscViewerDrawOpen()` - Outputs nonzero matrix structure to 965 an X window display 966 - `PetscViewerSocketOpen()` - Outputs matrix to Socket viewer. 967 Currently only the sequential dense and AIJ 968 matrix types support the Socket viewer. 969 970 The user can call `PetscViewerPushFormat()` to specify the output 971 format of ASCII printed objects (when using `PETSC_VIEWER_STDOUT_SELF`, 972 `PETSC_VIEWER_STDOUT_WORLD` and `PetscViewerASCIIOpen()`). Available formats include 973 + `PETSC_VIEWER_DEFAULT` - default, prints matrix contents 974 . `PETSC_VIEWER_ASCII_MATLAB` - prints matrix contents in Matlab format 975 . `PETSC_VIEWER_ASCII_DENSE` - prints entire matrix including zeros 976 . `PETSC_VIEWER_ASCII_COMMON` - prints matrix contents, using a sparse 977 format common among all matrix types 978 . `PETSC_VIEWER_ASCII_IMPL` - prints matrix contents, using an implementation-specific 979 format (which is in many cases the same as the default) 980 . `PETSC_VIEWER_ASCII_INFO` - prints basic information about the matrix 981 size and structure (not the matrix entries) 982 - `PETSC_VIEWER_ASCII_INFO_DETAIL` - prints more detailed information about 983 the matrix structure 984 985 Options Database Keys: 986 + -mat_view ::ascii_info - Prints info on matrix at conclusion of `MatAssemblyEnd()` 987 . -mat_view ::ascii_info_detail - Prints more detailed info 988 . -mat_view - Prints matrix in ASCII format 989 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 990 . -mat_view draw - PetscDraws nonzero structure of matrix, using `MatView()` and `PetscDrawOpenX()`. 991 . -display <name> - Sets display name (default is host) 992 . -draw_pause <sec> - Sets number of seconds to pause after display 993 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details) 994 . -viewer_socket_machine <machine> - 995 . -viewer_socket_port <port> - 996 . -mat_view binary - save matrix to file in binary format 997 - -viewer_binary_filename <name> - 998 999 Level: beginner 1000 1001 Notes: 1002 The ASCII viewers are only recommended for small matrices on at most a moderate number of processes, 1003 the program will seemingly hang and take hours for larger matrices, for larger matrices one should use the binary format. 1004 1005 In the debugger you can do "call MatView(mat,0)" to display the matrix. (The same holds for any PETSc object viewer). 1006 1007 See the manual page for `MatLoad()` for the exact format of the binary file when the binary 1008 viewer is used. 1009 1010 See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary 1011 viewer is used and lib/petsc/bin/PetscBinaryIO.py for loading them into Python. 1012 1013 One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure, 1014 and then use the following mouse functions. 1015 .vb 1016 left mouse: zoom in 1017 middle mouse: zoom out 1018 right mouse: continue with the simulation 1019 .ve 1020 1021 .seealso: `PetscViewerPushFormat()`, `PetscViewerASCIIOpen()`, `PetscViewerDrawOpen()`, 1022 `PetscViewerSocketOpen()`, `PetscViewerBinaryOpen()`, `MatLoad()` 1023 @*/ 1024 PetscErrorCode MatView(Mat mat,PetscViewer viewer) 1025 { 1026 PetscInt rows,cols,rbs,cbs; 1027 PetscBool isascii,isstring,issaws; 1028 PetscViewerFormat format; 1029 PetscMPIInt size; 1030 1031 PetscFunctionBegin; 1032 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1033 PetscValidType(mat,1); 1034 if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer)); 1035 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1036 PetscCheckSameComm(mat,1,viewer,2); 1037 MatCheckPreallocated(mat,1); 1038 1039 PetscCall(PetscViewerGetFormat(viewer,&format)); 1040 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 1041 if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0); 1042 1043 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring)); 1044 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii)); 1045 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws)); 1046 if ((!isascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) { 1047 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detail"); 1048 } 1049 1050 PetscCall(PetscLogEventBegin(MAT_View,mat,viewer,0,0)); 1051 if (isascii) { 1052 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix"); 1053 PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer)); 1054 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1055 MatNullSpace nullsp,transnullsp; 1056 1057 PetscCall(PetscViewerASCIIPushTab(viewer)); 1058 PetscCall(MatGetSize(mat,&rows,&cols)); 1059 PetscCall(MatGetBlockSizes(mat,&rbs,&cbs)); 1060 if (rbs != 1 || cbs != 1) { 1061 if (rbs != cbs) PetscCall(PetscViewerASCIIPrintf(viewer,"rows=%" PetscInt_FMT ", cols=%" PetscInt_FMT ", rbs=%" PetscInt_FMT ", cbs=%" PetscInt_FMT "\n",rows,cols,rbs,cbs)); 1062 else PetscCall(PetscViewerASCIIPrintf(viewer,"rows=%" PetscInt_FMT ", cols=%" PetscInt_FMT ", bs=%" PetscInt_FMT "\n",rows,cols,rbs)); 1063 } else PetscCall(PetscViewerASCIIPrintf(viewer,"rows=%" PetscInt_FMT ", cols=%" PetscInt_FMT "\n",rows,cols)); 1064 if (mat->factortype) { 1065 MatSolverType solver; 1066 PetscCall(MatFactorGetSolverType(mat,&solver)); 1067 PetscCall(PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver)); 1068 } 1069 if (mat->ops->getinfo) { 1070 MatInfo info; 1071 PetscCall(MatGetInfo(mat,MAT_GLOBAL_SUM,&info)); 1072 PetscCall(PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated)); 1073 if (!mat->factortype) PetscCall(PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls=%" PetscInt_FMT "\n",(PetscInt)info.mallocs)); 1074 } 1075 PetscCall(MatGetNullSpace(mat,&nullsp)); 1076 PetscCall(MatGetTransposeNullSpace(mat,&transnullsp)); 1077 if (nullsp) PetscCall(PetscViewerASCIIPrintf(viewer," has attached null space\n")); 1078 if (transnullsp && transnullsp != nullsp) PetscCall(PetscViewerASCIIPrintf(viewer," has attached transposed null space\n")); 1079 PetscCall(MatGetNearNullSpace(mat,&nullsp)); 1080 if (nullsp) PetscCall(PetscViewerASCIIPrintf(viewer," has attached near null space\n")); 1081 PetscCall(PetscViewerASCIIPushTab(viewer)); 1082 PetscCall(MatProductView(mat,viewer)); 1083 PetscCall(PetscViewerASCIIPopTab(viewer)); 1084 } 1085 } else if (issaws) { 1086 #if defined(PETSC_HAVE_SAWS) 1087 PetscMPIInt rank; 1088 1089 PetscCall(PetscObjectName((PetscObject)mat)); 1090 PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD,&rank)); 1091 if (!((PetscObject)mat)->amsmem && rank == 0) { 1092 PetscCall(PetscObjectViewSAWs((PetscObject)mat,viewer)); 1093 } 1094 #endif 1095 } else if (isstring) { 1096 const char *type; 1097 PetscCall(MatGetType(mat,&type)); 1098 PetscCall(PetscViewerStringSPrintf(viewer," MatType: %-7.7s",type)); 1099 PetscTryTypeMethod(mat,view,viewer); 1100 } 1101 if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) { 1102 PetscCall(PetscViewerASCIIPushTab(viewer)); 1103 PetscUseTypeMethod(mat,viewnative ,viewer); 1104 PetscCall(PetscViewerASCIIPopTab(viewer)); 1105 } else if (mat->ops->view) { 1106 PetscCall(PetscViewerASCIIPushTab(viewer)); 1107 PetscUseTypeMethod(mat,view ,viewer); 1108 PetscCall(PetscViewerASCIIPopTab(viewer)); 1109 } 1110 if (isascii) { 1111 PetscCall(PetscViewerGetFormat(viewer,&format)); 1112 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1113 PetscCall(PetscViewerASCIIPopTab(viewer)); 1114 } 1115 } 1116 PetscCall(PetscLogEventEnd(MAT_View,mat,viewer,0,0)); 1117 PetscFunctionReturn(0); 1118 } 1119 1120 #if defined(PETSC_USE_DEBUG) 1121 #include <../src/sys/totalview/tv_data_display.h> 1122 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat) 1123 { 1124 TV_add_row("Local rows", "int", &mat->rmap->n); 1125 TV_add_row("Local columns", "int", &mat->cmap->n); 1126 TV_add_row("Global rows", "int", &mat->rmap->N); 1127 TV_add_row("Global columns", "int", &mat->cmap->N); 1128 TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name); 1129 return TV_format_OK; 1130 } 1131 #endif 1132 1133 /*@C 1134 MatLoad - Loads a matrix that has been stored in binary/HDF5 format 1135 with `MatView()`. The matrix format is determined from the options database. 1136 Generates a parallel MPI matrix if the communicator has more than one 1137 processor. The default matrix type is AIJ. 1138 1139 Collective on PetscViewer 1140 1141 Input Parameters: 1142 + mat - the newly loaded matrix, this needs to have been created with `MatCreate()` 1143 or some related function before a call to `MatLoad()` 1144 - viewer - binary/HDF5 file viewer 1145 1146 Options Database Keys: 1147 Used with block matrix formats (`MATSEQBAIJ`, ...) to specify 1148 block size 1149 . -matload_block_size <bs> - set block size 1150 1151 Level: beginner 1152 1153 Notes: 1154 If the Mat type has not yet been given then `MATAIJ` is used, call `MatSetFromOptions()` on the 1155 Mat before calling this routine if you wish to set it from the options database. 1156 1157 `MatLoad()` automatically loads into the options database any options 1158 given in the file filename.info where filename is the name of the file 1159 that was passed to the `PetscViewerBinaryOpen()`. The options in the info 1160 file will be ignored if you use the -viewer_binary_skip_info option. 1161 1162 If the type or size of mat is not set before a call to `MatLoad()`, PETSc 1163 sets the default matrix type AIJ and sets the local and global sizes. 1164 If type and/or size is already set, then the same are used. 1165 1166 In parallel, each processor can load a subset of rows (or the 1167 entire matrix). This routine is especially useful when a large 1168 matrix is stored on disk and only part of it is desired on each 1169 processor. For example, a parallel solver may access only some of 1170 the rows from each processor. The algorithm used here reads 1171 relatively small blocks of data rather than reading the entire 1172 matrix and then subsetting it. 1173 1174 Viewer's `PetscViewerType` must be either `PETSCVIEWERBINARY` or `PETSCVIEWERHDF5`. 1175 Such viewer can be created using `PetscViewerBinaryOpen()` or `PetscViewerHDF5Open()`, 1176 or the sequence like 1177 .vb 1178 `PetscViewer` v; 1179 `PetscViewerCreate`(`PETSC_COMM_WORLD`,&v); 1180 `PetscViewerSetType`(v,`PETSCVIEWERBINARY`); 1181 `PetscViewerSetFromOptions`(v); 1182 `PetscViewerFileSetMode`(v,`FILE_MODE_READ`); 1183 `PetscViewerFileSetName`(v,"datafile"); 1184 .ve 1185 The optional `PetscViewerSetFromOptions()` call allows overriding `PetscViewerSetType()` using the option 1186 $ -viewer_type {binary,hdf5} 1187 1188 See the example src/ksp/ksp/tutorials/ex27.c with the first approach, 1189 and src/mat/tutorials/ex10.c with the second approach. 1190 1191 Notes about the PETSc binary format: 1192 In case of `PETSCVIEWERBINARY`, a native PETSc binary format is used. Each of the blocks 1193 is read onto rank 0 and then shipped to its destination rank, one after another. 1194 Multiple objects, both matrices and vectors, can be stored within the same file. 1195 Their PetscObject name is ignored; they are loaded in the order of their storage. 1196 1197 Most users should not need to know the details of the binary storage 1198 format, since `MatLoad()` and `MatView()` completely hide these details. 1199 But for anyone who's interested, the standard binary matrix storage 1200 format is 1201 1202 $ PetscInt MAT_FILE_CLASSID 1203 $ PetscInt number of rows 1204 $ PetscInt number of columns 1205 $ PetscInt total number of nonzeros 1206 $ PetscInt *number nonzeros in each row 1207 $ PetscInt *column indices of all nonzeros (starting index is zero) 1208 $ PetscScalar *values of all nonzeros 1209 1210 PETSc automatically does the byte swapping for 1211 machines that store the bytes reversed, e.g. DEC alpha, freebsd, 1212 Linux, Microsoft Windows and the Intel Paragon; thus if you write your own binary 1213 read/write routines you have to swap the bytes; see `PetscBinaryRead()` 1214 and `PetscBinaryWrite()` to see how this may be done. 1215 1216 Notes about the HDF5 (MATLAB MAT-File Version 7.3) format: 1217 In case of `PETSCVIEWERHDF5`, a parallel HDF5 reader is used. 1218 Each processor's chunk is loaded independently by its owning rank. 1219 Multiple objects, both matrices and vectors, can be stored within the same file. 1220 They are looked up by their PetscObject name. 1221 1222 As the MATLAB MAT-File Version 7.3 format is also a HDF5 flavor, we decided to use 1223 by default the same structure and naming of the AIJ arrays and column count 1224 within the HDF5 file. This means that a MAT file saved with -v7.3 flag, e.g. 1225 $ save example.mat A b -v7.3 1226 can be directly read by this routine (see Reference 1 for details). 1227 Note that depending on your MATLAB version, this format might be a default, 1228 otherwise you can set it as default in Preferences. 1229 1230 Unless -nocompression flag is used to save the file in MATLAB, 1231 PETSc must be configured with ZLIB package. 1232 1233 See also examples src/mat/tutorials/ex10.c and src/ksp/ksp/tutorials/ex27.c 1234 1235 Current HDF5 (MAT-File) limitations: 1236 This reader currently supports only real `MATSEQAIJ`, `MATMPIAIJ`, `MATSEQDENSE` and `MATMPIDENSE` matrices. 1237 1238 Corresponding `MatView()` is not yet implemented. 1239 1240 The loaded matrix is actually a transpose of the original one in MATLAB, 1241 unless you push `PETSC_VIEWER_HDF5_MAT` format (see examples above). 1242 With this format, matrix is automatically transposed by PETSc, 1243 unless the matrix is marked as SPD or symmetric 1244 (see `MatSetOption()`, `MAT_SPD`, `MAT_SYMMETRIC`). 1245 1246 References: 1247 . * - MATLAB(R) Documentation, manual page of save(), https://www.mathworks.com/help/matlab/ref/save.html#btox10b-1-version 1248 1249 .seealso: `PetscViewerBinaryOpen()`, `PetscViewerSetType()`, `MatView()`, `VecLoad()` 1250 1251 @*/ 1252 PetscErrorCode MatLoad(Mat mat,PetscViewer viewer) 1253 { 1254 PetscBool flg; 1255 1256 PetscFunctionBegin; 1257 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1258 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1259 1260 if (!((PetscObject)mat)->type_name) PetscCall(MatSetType(mat,MATAIJ)); 1261 1262 flg = PETSC_FALSE; 1263 PetscCall(PetscOptionsGetBool(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matload_symmetric",&flg,NULL)); 1264 if (flg) { 1265 PetscCall(MatSetOption(mat,MAT_SYMMETRIC,PETSC_TRUE)); 1266 PetscCall(MatSetOption(mat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE)); 1267 } 1268 flg = PETSC_FALSE; 1269 PetscCall(PetscOptionsGetBool(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matload_spd",&flg,NULL)); 1270 if (flg) PetscCall(MatSetOption(mat,MAT_SPD,PETSC_TRUE)); 1271 1272 PetscCall(PetscLogEventBegin(MAT_Load,mat,viewer,0,0)); 1273 PetscUseTypeMethod(mat,load ,viewer); 1274 PetscCall(PetscLogEventEnd(MAT_Load,mat,viewer,0,0)); 1275 PetscFunctionReturn(0); 1276 } 1277 1278 static PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant) 1279 { 1280 Mat_Redundant *redund = *redundant; 1281 1282 PetscFunctionBegin; 1283 if (redund) { 1284 if (redund->matseq) { /* via MatCreateSubMatrices() */ 1285 PetscCall(ISDestroy(&redund->isrow)); 1286 PetscCall(ISDestroy(&redund->iscol)); 1287 PetscCall(MatDestroySubMatrices(1,&redund->matseq)); 1288 } else { 1289 PetscCall(PetscFree2(redund->send_rank,redund->recv_rank)); 1290 PetscCall(PetscFree(redund->sbuf_j)); 1291 PetscCall(PetscFree(redund->sbuf_a)); 1292 for (PetscInt i=0; i<redund->nrecvs; i++) { 1293 PetscCall(PetscFree(redund->rbuf_j[i])); 1294 PetscCall(PetscFree(redund->rbuf_a[i])); 1295 } 1296 PetscCall(PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a)); 1297 } 1298 1299 if (redund->subcomm) PetscCall(PetscCommDestroy(&redund->subcomm)); 1300 PetscCall(PetscFree(redund)); 1301 } 1302 PetscFunctionReturn(0); 1303 } 1304 1305 /*@C 1306 MatDestroy - Frees space taken by a matrix. 1307 1308 Collective on Mat 1309 1310 Input Parameter: 1311 . A - the matrix 1312 1313 Level: beginner 1314 1315 Developer Notes: 1316 Some special arrays of matrices are not destroyed in this routine but instead by the routines called by 1317 `MatDestroySubMatrices()`. Thus one must be sure that any changes here must also be made in those routines. 1318 MatHeaderMerge() and MatHeaderReplace() also manipulate the data in the `Mat` object and likely need changes 1319 if changes are needed here. 1320 @*/ 1321 PetscErrorCode MatDestroy(Mat *A) 1322 { 1323 PetscFunctionBegin; 1324 if (!*A) PetscFunctionReturn(0); 1325 PetscValidHeaderSpecific(*A,MAT_CLASSID,1); 1326 if (--((PetscObject)(*A))->refct > 0) {*A = NULL; PetscFunctionReturn(0);} 1327 1328 /* if memory was published with SAWs then destroy it */ 1329 PetscCall(PetscObjectSAWsViewOff((PetscObject)*A)); 1330 PetscTryTypeMethod((*A),destroy); 1331 1332 PetscCall(PetscFree((*A)->factorprefix)); 1333 PetscCall(PetscFree((*A)->defaultvectype)); 1334 PetscCall(PetscFree((*A)->bsizes)); 1335 PetscCall(PetscFree((*A)->solvertype)); 1336 for (PetscInt i=0; i<MAT_FACTOR_NUM_TYPES; i++) PetscCall(PetscFree((*A)->preferredordering[i])); 1337 if ((*A)->redundant && (*A)->redundant->matseq[0] == *A) (*A)->redundant->matseq[0] = NULL; 1338 PetscCall(MatDestroy_Redundant(&(*A)->redundant)); 1339 PetscCall(MatProductClear(*A)); 1340 PetscCall(MatNullSpaceDestroy(&(*A)->nullsp)); 1341 PetscCall(MatNullSpaceDestroy(&(*A)->transnullsp)); 1342 PetscCall(MatNullSpaceDestroy(&(*A)->nearnullsp)); 1343 PetscCall(MatDestroy(&(*A)->schur)); 1344 PetscCall(PetscLayoutDestroy(&(*A)->rmap)); 1345 PetscCall(PetscLayoutDestroy(&(*A)->cmap)); 1346 PetscCall(PetscHeaderDestroy(A)); 1347 PetscFunctionReturn(0); 1348 } 1349 1350 /*@C 1351 MatSetValues - Inserts or adds a block of values into a matrix. 1352 These values may be cached, so `MatAssemblyBegin()` and `MatAssemblyEnd()` 1353 MUST be called after all calls to `MatSetValues()` have been completed. 1354 1355 Not Collective 1356 1357 Input Parameters: 1358 + mat - the matrix 1359 . v - a logically two-dimensional array of values 1360 . m, idxm - the number of rows and their global indices 1361 . n, idxn - the number of columns and their global indices 1362 - addv - either `ADD_VALUES` or `INSERT_VALUES`, where 1363 `ADD_VALUES` adds values to any existing entries, and 1364 `INSERT_VALUES` replaces existing entries with new values 1365 1366 Notes: 1367 If you create the matrix yourself (that is not with a call to `DMCreateMatrix()`) then you MUST call MatXXXXSetPreallocation() or 1368 `MatSetUp()` before using this routine 1369 1370 By default the values, v, are row-oriented. See `MatSetOption()` for other options. 1371 1372 Calls to `MatSetValues()` with the `INSERT_VALUES` and `ADD_VALUES` 1373 options cannot be mixed without intervening calls to the assembly 1374 routines. 1375 1376 `MatSetValues()` uses 0-based row and column numbers in Fortran 1377 as well as in C. 1378 1379 Negative indices may be passed in idxm and idxn, these rows and columns are 1380 simply ignored. This allows easily inserting element stiffness matrices 1381 with homogeneous Dirchlet boundary conditions that you don't want represented 1382 in the matrix. 1383 1384 Efficiency Alert: 1385 The routine `MatSetValuesBlocked()` may offer much better efficiency 1386 for users of block sparse formats (`MATSEQBAIJ` and `MATMPIBAIJ`). 1387 1388 Level: beginner 1389 1390 Developer Notes: 1391 This is labeled with C so does not automatically generate Fortran stubs and interfaces 1392 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 1393 1394 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 1395 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES` 1396 @*/ 1397 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1398 { 1399 PetscFunctionBeginHot; 1400 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1401 PetscValidType(mat,1); 1402 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1403 PetscValidIntPointer(idxm,3); 1404 PetscValidIntPointer(idxn,5); 1405 MatCheckPreallocated(mat,1); 1406 1407 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 1408 else PetscCheck(mat->insertmode == addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1409 1410 if (PetscDefined(USE_DEBUG)) { 1411 PetscInt i,j; 1412 1413 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1414 for (i=0; i<m; i++) { 1415 for (j=0; j<n; j++) { 1416 if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j])) 1417 #if defined(PETSC_USE_COMPLEX) 1418 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]); 1419 #else 1420 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]); 1421 #endif 1422 } 1423 } 1424 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); 1425 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); 1426 } 1427 1428 if (mat->assembled) { 1429 mat->was_assembled = PETSC_TRUE; 1430 mat->assembled = PETSC_FALSE; 1431 } 1432 PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 1433 PetscUseTypeMethod(mat,setvalues ,m,idxm,n,idxn,v,addv); 1434 PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 1435 PetscFunctionReturn(0); 1436 } 1437 1438 /*@C 1439 MatSetValuesIS - Inserts or adds a block of values into a matrix using IS to indicate the rows and columns 1440 These values may be cached, so `MatAssemblyBegin()` and `MatAssemblyEnd()` 1441 MUST be called after all calls to `MatSetValues()` have been completed. 1442 1443 Not Collective 1444 1445 Input Parameters: 1446 + mat - the matrix 1447 . v - a logically two-dimensional array of values 1448 . ism - the rows to provide 1449 . isn - the columns to provide 1450 - addv - either `ADD_VALUES` or `INSERT_VALUES`, where 1451 `ADD_VALUES` adds values to any existing entries, and 1452 `INSERT_VALUES` replaces existing entries with new values 1453 1454 Notes: 1455 If you create the matrix yourself (that is not with a call to `DMCreateMatrix()`) then you MUST call MatXXXXSetPreallocation() or 1456 `MatSetUp()` before using this routine 1457 1458 By default the values, v, are row-oriented. See `MatSetOption()` for other options. 1459 1460 Calls to `MatSetValues()` with the `INSERT_VALUES` and `ADD_VALUES` 1461 options cannot be mixed without intervening calls to the assembly 1462 routines. 1463 1464 MatSetValues() uses 0-based row and column numbers in Fortran 1465 as well as in C. 1466 1467 Negative indices may be passed in ism and isn, these rows and columns are 1468 simply ignored. This allows easily inserting element stiffness matrices 1469 with homogeneous Dirchlet boundary conditions that you don't want represented 1470 in the matrix. 1471 1472 Efficiency Alert: 1473 The routine `MatSetValuesBlocked()` may offer much better efficiency 1474 for users of block sparse formats (`MATSEQBAIJ` and `MATMPIBAIJ`). 1475 1476 Level: beginner 1477 1478 Developer Notes: 1479 This is labeled with C so does not automatically generate Fortran stubs and interfaces 1480 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 1481 1482 This is currently not optimized for any particular IS type 1483 1484 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 1485 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()` 1486 @*/ 1487 PetscErrorCode MatSetValuesIS(Mat mat,IS ism,IS isn,const PetscScalar v[],InsertMode addv) 1488 { 1489 PetscInt m,n; 1490 const PetscInt *rows,*cols; 1491 1492 PetscFunctionBeginHot; 1493 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1494 PetscCall(ISGetIndices(ism,&rows)); 1495 PetscCall(ISGetIndices(isn,&cols)); 1496 PetscCall(ISGetLocalSize(ism,&m)); 1497 PetscCall(ISGetLocalSize(isn,&n)); 1498 PetscCall(MatSetValues(mat,m,rows,n,cols,v,addv)); 1499 PetscCall(ISRestoreIndices(ism,&rows)); 1500 PetscCall(ISRestoreIndices(isn,&cols)); 1501 PetscFunctionReturn(0); 1502 } 1503 1504 /*@ 1505 MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero 1506 values into a matrix 1507 1508 Not Collective 1509 1510 Input Parameters: 1511 + mat - the matrix 1512 . row - the (block) row to set 1513 - v - a logically two-dimensional array of values 1514 1515 Notes: 1516 By the values, v, are column-oriented (for the block version) and sorted 1517 1518 All the nonzeros in the row must be provided 1519 1520 The matrix must have previously had its column indices set 1521 1522 The row must belong to this process 1523 1524 Level: intermediate 1525 1526 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 1527 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()`, `MatSetValuesRow()`, `MatSetLocalToGlobalMapping()` 1528 @*/ 1529 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[]) 1530 { 1531 PetscInt globalrow; 1532 1533 PetscFunctionBegin; 1534 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1535 PetscValidType(mat,1); 1536 PetscValidScalarPointer(v,3); 1537 PetscCall(ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow)); 1538 PetscCall(MatSetValuesRow(mat,globalrow,v)); 1539 PetscFunctionReturn(0); 1540 } 1541 1542 /*@ 1543 MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero 1544 values into a matrix 1545 1546 Not Collective 1547 1548 Input Parameters: 1549 + mat - the matrix 1550 . row - the (block) row to set 1551 - 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 1552 1553 Notes: 1554 The values, v, are column-oriented for the block version. 1555 1556 All the nonzeros in the row must be provided 1557 1558 THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually `MatSetValues()` is used. 1559 1560 The row must belong to this process 1561 1562 Level: advanced 1563 1564 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 1565 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()` 1566 @*/ 1567 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[]) 1568 { 1569 PetscFunctionBeginHot; 1570 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1571 PetscValidType(mat,1); 1572 MatCheckPreallocated(mat,1); 1573 PetscValidScalarPointer(v,3); 1574 PetscCheck(mat->insertmode != ADD_VALUES,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values"); 1575 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1576 mat->insertmode = INSERT_VALUES; 1577 1578 if (mat->assembled) { 1579 mat->was_assembled = PETSC_TRUE; 1580 mat->assembled = PETSC_FALSE; 1581 } 1582 PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 1583 PetscUseTypeMethod(mat,setvaluesrow ,row,v); 1584 PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 1585 PetscFunctionReturn(0); 1586 } 1587 1588 /*@ 1589 MatSetValuesStencil - Inserts or adds a block of values into a matrix. 1590 Using structured grid indexing 1591 1592 Not Collective 1593 1594 Input Parameters: 1595 + mat - the matrix 1596 . m - number of rows being entered 1597 . idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered 1598 . n - number of columns being entered 1599 . idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered 1600 . v - a logically two-dimensional array of values 1601 - addv - either ADD_VALUES or INSERT_VALUES, where 1602 ADD_VALUES adds values to any existing entries, and 1603 INSERT_VALUES replaces existing entries with new values 1604 1605 Notes: 1606 By default the values, v, are row-oriented. See `MatSetOption()` for other options. 1607 1608 Calls to `MatSetValuesStencil()` with the `INSERT_VALUES` and `ADD_VALUES` 1609 options cannot be mixed without intervening calls to the assembly 1610 routines. 1611 1612 The grid coordinates are across the entire grid, not just the local portion 1613 1614 `MatSetValuesStencil()` uses 0-based row and column numbers in Fortran 1615 as well as in C. 1616 1617 For setting/accessing vector values via array coordinates you can use the `DMDAVecGetArray()` routine 1618 1619 In order to use this routine you must either obtain the matrix with `DMCreateMatrix()` 1620 or call `MatSetLocalToGlobalMapping()` and `MatSetStencil()` first. 1621 1622 The columns and rows in the stencil passed in MUST be contained within the 1623 ghost region of the given process as set with DMDACreateXXX() or `MatSetStencil()`. For example, 1624 if you create a `DMDA` with an overlap of one grid level and on a particular process its first 1625 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1626 first i index you can use in your column and row indices in `MatSetStencil()` is 5. 1627 1628 In Fortran idxm and idxn should be declared as 1629 $ MatStencil idxm(4,m),idxn(4,n) 1630 and the values inserted using 1631 $ idxm(MatStencil_i,1) = i 1632 $ idxm(MatStencil_j,1) = j 1633 $ idxm(MatStencil_k,1) = k 1634 $ idxm(MatStencil_c,1) = c 1635 etc 1636 1637 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 1638 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 1639 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 1640 `DM_BOUNDARY_PERIODIC` boundary type. 1641 1642 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 1643 a single value per point) you can skip filling those indices. 1644 1645 Inspired by the structured grid interface to the HYPRE package 1646 (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods) 1647 1648 Efficiency Alert: 1649 The routine `MatSetValuesBlockedStencil()` may offer much better efficiency 1650 for users of block sparse formats (`MATSEQBAIJ` and `MATMPIBAIJ`). 1651 1652 Level: beginner 1653 1654 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()` 1655 `MatSetValues()`, `MatSetValuesBlockedStencil()`, `MatSetStencil()`, `DMCreateMatrix()`, `DMDAVecGetArray()`, `MatStencil` 1656 @*/ 1657 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1658 { 1659 PetscInt buf[8192],*bufm=NULL,*bufn=NULL,*jdxm,*jdxn; 1660 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1661 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1662 1663 PetscFunctionBegin; 1664 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1665 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1666 PetscValidType(mat,1); 1667 PetscValidPointer(idxm,3); 1668 PetscValidPointer(idxn,5); 1669 1670 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1671 jdxm = buf; jdxn = buf+m; 1672 } else { 1673 PetscCall(PetscMalloc2(m,&bufm,n,&bufn)); 1674 jdxm = bufm; jdxn = bufn; 1675 } 1676 for (i=0; i<m; i++) { 1677 for (j=0; j<3-sdim; j++) dxm++; 1678 tmp = *dxm++ - starts[0]; 1679 for (j=0; j<dim-1; j++) { 1680 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1681 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1682 } 1683 if (mat->stencil.noc) dxm++; 1684 jdxm[i] = tmp; 1685 } 1686 for (i=0; i<n; i++) { 1687 for (j=0; j<3-sdim; j++) dxn++; 1688 tmp = *dxn++ - starts[0]; 1689 for (j=0; j<dim-1; j++) { 1690 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1691 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1692 } 1693 if (mat->stencil.noc) dxn++; 1694 jdxn[i] = tmp; 1695 } 1696 PetscCall(MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv)); 1697 PetscCall(PetscFree2(bufm,bufn)); 1698 PetscFunctionReturn(0); 1699 } 1700 1701 /*@ 1702 MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix. 1703 Using structured grid indexing 1704 1705 Not Collective 1706 1707 Input Parameters: 1708 + mat - the matrix 1709 . m - number of rows being entered 1710 . idxm - grid coordinates for matrix rows being entered 1711 . n - number of columns being entered 1712 . idxn - grid coordinates for matrix columns being entered 1713 . v - a logically two-dimensional array of values 1714 - addv - either ADD_VALUES or INSERT_VALUES, where 1715 ADD_VALUES adds values to any existing entries, and 1716 INSERT_VALUES replaces existing entries with new values 1717 1718 Notes: 1719 By default the values, v, are row-oriented and unsorted. 1720 See MatSetOption() for other options. 1721 1722 Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES 1723 options cannot be mixed without intervening calls to the assembly 1724 routines. 1725 1726 The grid coordinates are across the entire grid, not just the local portion 1727 1728 MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran 1729 as well as in C. 1730 1731 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine 1732 1733 In order to use this routine you must either obtain the matrix with DMCreateMatrix() 1734 or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first. 1735 1736 The columns and rows in the stencil passed in MUST be contained within the 1737 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example, 1738 if you create a DMDA with an overlap of one grid level and on a particular process its first 1739 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1740 first i index you can use in your column and row indices in MatSetStencil() is 5. 1741 1742 In Fortran idxm and idxn should be declared as 1743 $ MatStencil idxm(4,m),idxn(4,n) 1744 and the values inserted using 1745 $ idxm(MatStencil_i,1) = i 1746 $ idxm(MatStencil_j,1) = j 1747 $ idxm(MatStencil_k,1) = k 1748 etc 1749 1750 Negative indices may be passed in idxm and idxn, these rows and columns are 1751 simply ignored. This allows easily inserting element stiffness matrices 1752 with homogeneous Dirchlet boundary conditions that you don't want represented 1753 in the matrix. 1754 1755 Inspired by the structured grid interface to the HYPRE package 1756 (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods) 1757 1758 Level: beginner 1759 1760 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()` 1761 `MatSetValues()`, `MatSetValuesStencil()`, `MatSetStencil()`, `DMCreateMatrix()`, `DMDAVecGetArray()`, `MatStencil`, 1762 `MatSetBlockSize()`, `MatSetLocalToGlobalMapping()` 1763 @*/ 1764 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1765 { 1766 PetscInt buf[8192],*bufm=NULL,*bufn=NULL,*jdxm,*jdxn; 1767 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1768 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1769 1770 PetscFunctionBegin; 1771 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1772 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1773 PetscValidType(mat,1); 1774 PetscValidPointer(idxm,3); 1775 PetscValidPointer(idxn,5); 1776 PetscValidScalarPointer(v,6); 1777 1778 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1779 jdxm = buf; jdxn = buf+m; 1780 } else { 1781 PetscCall(PetscMalloc2(m,&bufm,n,&bufn)); 1782 jdxm = bufm; jdxn = bufn; 1783 } 1784 for (i=0; i<m; i++) { 1785 for (j=0; j<3-sdim; j++) dxm++; 1786 tmp = *dxm++ - starts[0]; 1787 for (j=0; j<sdim-1; j++) { 1788 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1789 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1790 } 1791 dxm++; 1792 jdxm[i] = tmp; 1793 } 1794 for (i=0; i<n; i++) { 1795 for (j=0; j<3-sdim; j++) dxn++; 1796 tmp = *dxn++ - starts[0]; 1797 for (j=0; j<sdim-1; j++) { 1798 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1799 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1800 } 1801 dxn++; 1802 jdxn[i] = tmp; 1803 } 1804 PetscCall(MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv)); 1805 PetscCall(PetscFree2(bufm,bufn)); 1806 PetscFunctionReturn(0); 1807 } 1808 1809 /*@ 1810 MatSetStencil - Sets the grid information for setting values into a matrix via 1811 MatSetValuesStencil() 1812 1813 Not Collective 1814 1815 Input Parameters: 1816 + mat - the matrix 1817 . dim - dimension of the grid 1, 2, or 3 1818 . dims - number of grid points in x, y, and z direction, including ghost points on your processor 1819 . starts - starting point of ghost nodes on your processor in x, y, and z direction 1820 - dof - number of degrees of freedom per node 1821 1822 Inspired by the structured grid interface to the HYPRE package 1823 (www.llnl.gov/CASC/hyper) 1824 1825 For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the 1826 user. 1827 1828 Level: beginner 1829 1830 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()` 1831 `MatSetValues()`, `MatSetValuesBlockedStencil()`, `MatSetValuesStencil()` 1832 @*/ 1833 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof) 1834 { 1835 PetscFunctionBegin; 1836 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1837 PetscValidIntPointer(dims,3); 1838 PetscValidIntPointer(starts,4); 1839 1840 mat->stencil.dim = dim + (dof > 1); 1841 for (PetscInt i=0; i<dim; i++) { 1842 mat->stencil.dims[i] = dims[dim-i-1]; /* copy the values in backwards */ 1843 mat->stencil.starts[i] = starts[dim-i-1]; 1844 } 1845 mat->stencil.dims[dim] = dof; 1846 mat->stencil.starts[dim] = 0; 1847 mat->stencil.noc = (PetscBool)(dof == 1); 1848 PetscFunctionReturn(0); 1849 } 1850 1851 /*@C 1852 MatSetValuesBlocked - Inserts or adds a block of values into a matrix. 1853 1854 Not Collective 1855 1856 Input Parameters: 1857 + mat - the matrix 1858 . v - a logically two-dimensional array of values 1859 . m, idxm - the number of block rows and their global block indices 1860 . n, idxn - the number of block columns and their global block indices 1861 - addv - either ADD_VALUES or INSERT_VALUES, where 1862 ADD_VALUES adds values to any existing entries, and 1863 INSERT_VALUES replaces existing entries with new values 1864 1865 Notes: 1866 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call 1867 MatXXXXSetPreallocation() or MatSetUp() before using this routine. 1868 1869 The m and n count the NUMBER of blocks in the row direction and column direction, 1870 NOT the total number of rows/columns; for example, if the block size is 2 and 1871 you are passing in values for rows 2,3,4,5 then m would be 2 (not 4). 1872 The values in idxm would be 1 2; that is the first index for each block divided by 1873 the block size. 1874 1875 Note that you must call MatSetBlockSize() when constructing this matrix (before 1876 preallocating it). 1877 1878 By default the values, v, are row-oriented, so the layout of 1879 v is the same as for MatSetValues(). See MatSetOption() for other options. 1880 1881 Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES 1882 options cannot be mixed without intervening calls to the assembly 1883 routines. 1884 1885 MatSetValuesBlocked() uses 0-based row and column numbers in Fortran 1886 as well as in C. 1887 1888 Negative indices may be passed in idxm and idxn, these rows and columns are 1889 simply ignored. This allows easily inserting element stiffness matrices 1890 with homogeneous Dirchlet boundary conditions that you don't want represented 1891 in the matrix. 1892 1893 Each time an entry is set within a sparse matrix via MatSetValues(), 1894 internal searching must be done to determine where to place the 1895 data in the matrix storage space. By instead inserting blocks of 1896 entries via MatSetValuesBlocked(), the overhead of matrix assembly is 1897 reduced. 1898 1899 Example: 1900 $ Suppose m=n=2 and block size(bs) = 2 The array is 1901 $ 1902 $ 1 2 | 3 4 1903 $ 5 6 | 7 8 1904 $ - - - | - - - 1905 $ 9 10 | 11 12 1906 $ 13 14 | 15 16 1907 $ 1908 $ v[] should be passed in like 1909 $ v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] 1910 $ 1911 $ If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then 1912 $ v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16] 1913 1914 Level: intermediate 1915 1916 .seealso: `MatSetBlockSize()`, `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetValuesBlockedLocal()` 1917 @*/ 1918 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1919 { 1920 PetscFunctionBeginHot; 1921 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1922 PetscValidType(mat,1); 1923 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1924 PetscValidIntPointer(idxm,3); 1925 PetscValidIntPointer(idxn,5); 1926 MatCheckPreallocated(mat,1); 1927 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 1928 else PetscCheck(mat->insertmode == addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1929 if (PetscDefined(USE_DEBUG)) { 1930 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1931 PetscCheck(mat->ops->setvaluesblocked || mat->ops->setvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1932 } 1933 if (PetscDefined(USE_DEBUG)) { 1934 PetscInt rbs,cbs,M,N,i; 1935 PetscCall(MatGetBlockSizes(mat,&rbs,&cbs)); 1936 PetscCall(MatGetSize(mat,&M,&N)); 1937 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); 1938 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); 1939 } 1940 if (mat->assembled) { 1941 mat->was_assembled = PETSC_TRUE; 1942 mat->assembled = PETSC_FALSE; 1943 } 1944 PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 1945 if (mat->ops->setvaluesblocked) { 1946 PetscUseTypeMethod(mat,setvaluesblocked ,m,idxm,n,idxn,v,addv); 1947 } else { 1948 PetscInt buf[8192],*bufr=NULL,*bufc=NULL,*iidxm,*iidxn; 1949 PetscInt i,j,bs,cbs; 1950 1951 PetscCall(MatGetBlockSizes(mat,&bs,&cbs)); 1952 if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1953 iidxm = buf; 1954 iidxn = buf + m*bs; 1955 } else { 1956 PetscCall(PetscMalloc2(m*bs,&bufr,n*cbs,&bufc)); 1957 iidxm = bufr; 1958 iidxn = bufc; 1959 } 1960 for (i=0; i<m; i++) { 1961 for (j=0; j<bs; j++) { 1962 iidxm[i*bs+j] = bs*idxm[i] + j; 1963 } 1964 } 1965 if (m != n || bs != cbs || idxm != idxn) { 1966 for (i=0; i<n; i++) { 1967 for (j=0; j<cbs; j++) { 1968 iidxn[i*cbs+j] = cbs*idxn[i] + j; 1969 } 1970 } 1971 } else iidxn = iidxm; 1972 PetscCall(MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv)); 1973 PetscCall(PetscFree2(bufr,bufc)); 1974 } 1975 PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 1976 PetscFunctionReturn(0); 1977 } 1978 1979 /*@C 1980 MatGetValues - Gets a block of values from a matrix. 1981 1982 Not Collective; can only return values that are owned by the give process 1983 1984 Input Parameters: 1985 + mat - the matrix 1986 . v - a logically two-dimensional array for storing the values 1987 . m, idxm - the number of rows and their global indices 1988 - n, idxn - the number of columns and their global indices 1989 1990 Notes: 1991 The user must allocate space (m*n PetscScalars) for the values, v. 1992 The values, v, are then returned in a row-oriented format, 1993 analogous to that used by default in MatSetValues(). 1994 1995 MatGetValues() uses 0-based row and column numbers in 1996 Fortran as well as in C. 1997 1998 MatGetValues() requires that the matrix has been assembled 1999 with MatAssemblyBegin()/MatAssemblyEnd(). Thus, calls to 2000 MatSetValues() and MatGetValues() CANNOT be made in succession 2001 without intermediate matrix assembly. 2002 2003 Negative row or column indices will be ignored and those locations in v[] will be 2004 left unchanged. 2005 2006 For the standard row-based matrix formats, idxm[] can only contain rows owned by the requesting MPI rank. 2007 That is, rows with global index greater than or equal to rstart and less than rend where rstart and rend are obtainable 2008 from MatGetOwnershipRange(mat,&rstart,&rend). 2009 2010 Level: advanced 2011 2012 .seealso: `MatGetRow()`, `MatCreateSubMatrices()`, `MatSetValues()`, `MatGetOwnershipRange()`, `MatGetValuesLocal()`, `MatGetValue()` 2013 @*/ 2014 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[]) 2015 { 2016 PetscFunctionBegin; 2017 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2018 PetscValidType(mat,1); 2019 if (!m || !n) PetscFunctionReturn(0); 2020 PetscValidIntPointer(idxm,3); 2021 PetscValidIntPointer(idxn,5); 2022 PetscValidScalarPointer(v,6); 2023 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2024 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2025 MatCheckPreallocated(mat,1); 2026 2027 PetscCall(PetscLogEventBegin(MAT_GetValues,mat,0,0,0)); 2028 PetscUseTypeMethod(mat,getvalues ,m,idxm,n,idxn,v); 2029 PetscCall(PetscLogEventEnd(MAT_GetValues,mat,0,0,0)); 2030 PetscFunctionReturn(0); 2031 } 2032 2033 /*@C 2034 MatGetValuesLocal - retrieves values from certain locations in a matrix using the local numbering of the indices 2035 defined previously by MatSetLocalToGlobalMapping() 2036 2037 Not Collective 2038 2039 Input Parameters: 2040 + mat - the matrix 2041 . nrow, irow - number of rows and their local indices 2042 - ncol, icol - number of columns and their local indices 2043 2044 Output Parameter: 2045 . y - a logically two-dimensional array of values 2046 2047 Notes: 2048 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine. 2049 2050 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, 2051 are greater than or equal to rstart and less than rend where rstart and rend are obtainable from MatGetOwnershipRange(mat,&rstart,&rend). One can 2052 determine if the resulting global row associated with the local row r is owned by the requesting MPI rank by applying the ISLocalToGlobalMapping set 2053 with MatSetLocalToGlobalMapping(). 2054 2055 Developer Notes: 2056 This is labelled with C so does not automatically generate Fortran stubs and interfaces 2057 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2058 2059 Level: advanced 2060 2061 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetLocalToGlobalMapping()`, 2062 `MatSetValuesLocal()`, `MatGetValues()` 2063 @*/ 2064 PetscErrorCode MatGetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],PetscScalar y[]) 2065 { 2066 PetscFunctionBeginHot; 2067 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2068 PetscValidType(mat,1); 2069 MatCheckPreallocated(mat,1); 2070 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to retrieve */ 2071 PetscValidIntPointer(irow,3); 2072 PetscValidIntPointer(icol,5); 2073 if (PetscDefined(USE_DEBUG)) { 2074 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2075 PetscCheck(mat->ops->getvalueslocal || mat->ops->getvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2076 } 2077 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2078 PetscCall(PetscLogEventBegin(MAT_GetValues,mat,0,0,0)); 2079 if (mat->ops->getvalueslocal) PetscUseTypeMethod(mat,getvalueslocal ,nrow,irow,ncol,icol,y); 2080 else { 2081 PetscInt buf[8192],*bufr=NULL,*bufc=NULL,*irowm,*icolm; 2082 if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2083 irowm = buf; icolm = buf+nrow; 2084 } else { 2085 PetscCall(PetscMalloc2(nrow,&bufr,ncol,&bufc)); 2086 irowm = bufr; icolm = bufc; 2087 } 2088 PetscCheck(mat->rmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MatGetValuesLocal() cannot proceed without local-to-global row mapping (See MatSetLocalToGlobalMapping())."); 2089 PetscCheck(mat->cmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MatGetValuesLocal() cannot proceed without local-to-global column mapping (See MatSetLocalToGlobalMapping())."); 2090 PetscCall(ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm)); 2091 PetscCall(ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm)); 2092 PetscCall(MatGetValues(mat,nrow,irowm,ncol,icolm,y)); 2093 PetscCall(PetscFree2(bufr,bufc)); 2094 } 2095 PetscCall(PetscLogEventEnd(MAT_GetValues,mat,0,0,0)); 2096 PetscFunctionReturn(0); 2097 } 2098 2099 /*@ 2100 MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and 2101 the same size. Currently, this can only be called once and creates the given matrix. 2102 2103 Not Collective 2104 2105 Input Parameters: 2106 + mat - the matrix 2107 . nb - the number of blocks 2108 . bs - the number of rows (and columns) in each block 2109 . rows - a concatenation of the rows for each block 2110 - v - a concatenation of logically two-dimensional arrays of values 2111 2112 Notes: 2113 In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix. 2114 2115 Level: advanced 2116 2117 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 2118 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()` 2119 @*/ 2120 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[]) 2121 { 2122 PetscFunctionBegin; 2123 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2124 PetscValidType(mat,1); 2125 PetscValidIntPointer(rows,4); 2126 PetscValidScalarPointer(v,5); 2127 PetscAssert(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2128 2129 PetscCall(PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0)); 2130 if (mat->ops->setvaluesbatch) PetscUseTypeMethod(mat,setvaluesbatch ,nb,bs,rows,v); 2131 else { 2132 for (PetscInt b = 0; b < nb; ++b) PetscCall(MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES)); 2133 } 2134 PetscCall(PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0)); 2135 PetscFunctionReturn(0); 2136 } 2137 2138 /*@ 2139 MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by 2140 the routine MatSetValuesLocal() to allow users to insert matrix entries 2141 using a local (per-processor) numbering. 2142 2143 Not Collective 2144 2145 Input Parameters: 2146 + x - the matrix 2147 . rmapping - row mapping created with ISLocalToGlobalMappingCreate() or ISLocalToGlobalMappingCreateIS() 2148 - cmapping - column mapping 2149 2150 Level: intermediate 2151 2152 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetValuesLocal()`, `MatGetValuesLocal()` 2153 @*/ 2154 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 2155 { 2156 PetscFunctionBegin; 2157 PetscValidHeaderSpecific(x,MAT_CLASSID,1); 2158 PetscValidType(x,1); 2159 if (rmapping) PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2); 2160 if (cmapping) PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3); 2161 if (x->ops->setlocaltoglobalmapping) PetscUseTypeMethod(x,setlocaltoglobalmapping ,rmapping,cmapping); 2162 else { 2163 PetscCall(PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping)); 2164 PetscCall(PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping)); 2165 } 2166 PetscFunctionReturn(0); 2167 } 2168 2169 /*@ 2170 MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping() 2171 2172 Not Collective 2173 2174 Input Parameter: 2175 . A - the matrix 2176 2177 Output Parameters: 2178 + rmapping - row mapping 2179 - cmapping - column mapping 2180 2181 Level: advanced 2182 2183 .seealso: `MatSetValuesLocal()` 2184 @*/ 2185 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping) 2186 { 2187 PetscFunctionBegin; 2188 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2189 PetscValidType(A,1); 2190 if (rmapping) { 2191 PetscValidPointer(rmapping,2); 2192 *rmapping = A->rmap->mapping; 2193 } 2194 if (cmapping) { 2195 PetscValidPointer(cmapping,3); 2196 *cmapping = A->cmap->mapping; 2197 } 2198 PetscFunctionReturn(0); 2199 } 2200 2201 /*@ 2202 MatSetLayouts - Sets the PetscLayout objects for rows and columns of a matrix 2203 2204 Logically Collective on A 2205 2206 Input Parameters: 2207 + A - the matrix 2208 . rmap - row layout 2209 - cmap - column layout 2210 2211 Level: advanced 2212 2213 .seealso: `MatCreateVecs()`, `MatGetLocalToGlobalMapping()`, `MatGetLayouts()` 2214 @*/ 2215 PetscErrorCode MatSetLayouts(Mat A,PetscLayout rmap,PetscLayout cmap) 2216 { 2217 PetscFunctionBegin; 2218 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2219 PetscCall(PetscLayoutReference(rmap,&A->rmap)); 2220 PetscCall(PetscLayoutReference(cmap,&A->cmap)); 2221 PetscFunctionReturn(0); 2222 } 2223 2224 /*@ 2225 MatGetLayouts - Gets the PetscLayout objects for rows and columns 2226 2227 Not Collective 2228 2229 Input Parameter: 2230 . A - the matrix 2231 2232 Output Parameters: 2233 + rmap - row layout 2234 - cmap - column layout 2235 2236 Level: advanced 2237 2238 .seealso: `MatCreateVecs()`, `MatGetLocalToGlobalMapping()`, `MatSetLayouts()` 2239 @*/ 2240 PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap) 2241 { 2242 PetscFunctionBegin; 2243 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2244 PetscValidType(A,1); 2245 if (rmap) { 2246 PetscValidPointer(rmap,2); 2247 *rmap = A->rmap; 2248 } 2249 if (cmap) { 2250 PetscValidPointer(cmap,3); 2251 *cmap = A->cmap; 2252 } 2253 PetscFunctionReturn(0); 2254 } 2255 2256 /*@C 2257 MatSetValuesLocal - Inserts or adds values into certain locations of a matrix, 2258 using a local numbering of the nodes. 2259 2260 Not Collective 2261 2262 Input Parameters: 2263 + mat - the matrix 2264 . nrow, irow - number of rows and their local indices 2265 . ncol, icol - number of columns and their local indices 2266 . y - a logically two-dimensional array of values 2267 - addv - either INSERT_VALUES or ADD_VALUES, where 2268 ADD_VALUES adds values to any existing entries, and 2269 INSERT_VALUES replaces existing entries with new values 2270 2271 Notes: 2272 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2273 MatSetUp() before using this routine 2274 2275 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine 2276 2277 Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES 2278 options cannot be mixed without intervening calls to the assembly 2279 routines. 2280 2281 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2282 MUST be called after all calls to MatSetValuesLocal() have been completed. 2283 2284 Level: intermediate 2285 2286 Developer Notes: 2287 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2288 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2289 2290 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetLocalToGlobalMapping()`, 2291 `MatSetValueLocal()`, `MatGetValuesLocal()` 2292 @*/ 2293 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2294 { 2295 PetscFunctionBeginHot; 2296 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2297 PetscValidType(mat,1); 2298 MatCheckPreallocated(mat,1); 2299 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2300 PetscValidIntPointer(irow,3); 2301 PetscValidIntPointer(icol,5); 2302 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 2303 else PetscCheck(mat->insertmode == addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2304 if (PetscDefined(USE_DEBUG)) { 2305 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2306 PetscCheck(mat->ops->setvalueslocal || mat->ops->setvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2307 } 2308 2309 if (mat->assembled) { 2310 mat->was_assembled = PETSC_TRUE; 2311 mat->assembled = PETSC_FALSE; 2312 } 2313 PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 2314 if (mat->ops->setvalueslocal) PetscUseTypeMethod(mat,setvalueslocal ,nrow,irow,ncol,icol,y,addv); 2315 else { 2316 PetscInt buf[8192],*bufr=NULL,*bufc=NULL; 2317 const PetscInt *irowm,*icolm; 2318 2319 if ((!mat->rmap->mapping && !mat->cmap->mapping) || (nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2320 bufr = buf; 2321 bufc = buf + nrow; 2322 irowm = bufr; 2323 icolm = bufc; 2324 } else { 2325 PetscCall(PetscMalloc2(nrow,&bufr,ncol,&bufc)); 2326 irowm = bufr; 2327 icolm = bufc; 2328 } 2329 if (mat->rmap->mapping) PetscCall(ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,bufr)); 2330 else irowm = irow; 2331 if (mat->cmap->mapping) { 2332 if (mat->cmap->mapping != mat->rmap->mapping || ncol != nrow || icol != irow) { 2333 PetscCall(ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,bufc)); 2334 } else icolm = irowm; 2335 } else icolm = icol; 2336 PetscCall(MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv)); 2337 if (bufr != buf) PetscCall(PetscFree2(bufr,bufc)); 2338 } 2339 PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 2340 PetscFunctionReturn(0); 2341 } 2342 2343 /*@C 2344 MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix, 2345 using a local ordering of the nodes a block at a time. 2346 2347 Not Collective 2348 2349 Input Parameters: 2350 + x - the matrix 2351 . nrow, irow - number of rows and their local indices 2352 . ncol, icol - number of columns and their local indices 2353 . y - a logically two-dimensional array of values 2354 - addv - either INSERT_VALUES or ADD_VALUES, where 2355 ADD_VALUES adds values to any existing entries, and 2356 INSERT_VALUES replaces existing entries with new values 2357 2358 Notes: 2359 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2360 MatSetUp() before using this routine 2361 2362 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping() 2363 before using this routineBefore calling MatSetValuesLocal(), the user must first set the 2364 2365 Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES 2366 options cannot be mixed without intervening calls to the assembly 2367 routines. 2368 2369 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2370 MUST be called after all calls to MatSetValuesBlockedLocal() have been completed. 2371 2372 Level: intermediate 2373 2374 Developer Notes: 2375 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2376 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2377 2378 .seealso: `MatSetBlockSize()`, `MatSetLocalToGlobalMapping()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, 2379 `MatSetValuesLocal()`, `MatSetValuesBlocked()` 2380 @*/ 2381 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2382 { 2383 PetscFunctionBeginHot; 2384 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2385 PetscValidType(mat,1); 2386 MatCheckPreallocated(mat,1); 2387 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2388 PetscValidIntPointer(irow,3); 2389 PetscValidIntPointer(icol,5); 2390 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 2391 else PetscCheck(mat->insertmode == addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2392 if (PetscDefined(USE_DEBUG)) { 2393 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2394 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); 2395 } 2396 2397 if (mat->assembled) { 2398 mat->was_assembled = PETSC_TRUE; 2399 mat->assembled = PETSC_FALSE; 2400 } 2401 if (PetscUnlikelyDebug(mat->rmap->mapping)) { /* Condition on the mapping existing, because MatSetValuesBlockedLocal_IS does not require it to be set. */ 2402 PetscInt irbs, rbs; 2403 PetscCall(MatGetBlockSizes(mat, &rbs, NULL)); 2404 PetscCall(ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&irbs)); 2405 PetscCheck(rbs == irbs,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different row block sizes! mat %" PetscInt_FMT ", row l2g map %" PetscInt_FMT,rbs,irbs); 2406 } 2407 if (PetscUnlikelyDebug(mat->cmap->mapping)) { 2408 PetscInt icbs, cbs; 2409 PetscCall(MatGetBlockSizes(mat,NULL,&cbs)); 2410 PetscCall(ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&icbs)); 2411 PetscCheck(cbs == icbs,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different col block sizes! mat %" PetscInt_FMT ", col l2g map %" PetscInt_FMT,cbs,icbs); 2412 } 2413 PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 2414 if (mat->ops->setvaluesblockedlocal) PetscUseTypeMethod(mat,setvaluesblockedlocal ,nrow,irow,ncol,icol,y,addv); 2415 else { 2416 PetscInt buf[8192],*bufr=NULL,*bufc=NULL; 2417 const PetscInt *irowm,*icolm; 2418 2419 if ((!mat->rmap->mapping && !mat->cmap->mapping) || (nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2420 bufr = buf; 2421 bufc = buf + nrow; 2422 irowm = bufr; 2423 icolm = bufc; 2424 } else { 2425 PetscCall(PetscMalloc2(nrow,&bufr,ncol,&bufc)); 2426 irowm = bufr; 2427 icolm = bufc; 2428 } 2429 if (mat->rmap->mapping) PetscCall(ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,bufr)); 2430 else irowm = irow; 2431 if (mat->cmap->mapping) { 2432 if (mat->cmap->mapping != mat->rmap->mapping || ncol != nrow || icol != irow) { 2433 PetscCall(ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,bufc)); 2434 } else icolm = irowm; 2435 } else icolm = icol; 2436 PetscCall(MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv)); 2437 if (bufr != buf) PetscCall(PetscFree2(bufr,bufc)); 2438 } 2439 PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 2440 PetscFunctionReturn(0); 2441 } 2442 2443 /*@ 2444 MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal 2445 2446 Collective on Mat 2447 2448 Input Parameters: 2449 + mat - the matrix 2450 - x - the vector to be multiplied 2451 2452 Output Parameters: 2453 . y - the result 2454 2455 Notes: 2456 The vectors x and y cannot be the same. I.e., one cannot 2457 call MatMult(A,y,y). 2458 2459 Level: developer 2460 2461 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 2462 @*/ 2463 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y) 2464 { 2465 PetscFunctionBegin; 2466 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2467 PetscValidType(mat,1); 2468 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2469 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2470 2471 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2472 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2473 PetscCheck(x != y,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2474 MatCheckPreallocated(mat,1); 2475 2476 PetscUseTypeMethod(mat,multdiagonalblock ,x,y); 2477 PetscCall(PetscObjectStateIncrease((PetscObject)y)); 2478 PetscFunctionReturn(0); 2479 } 2480 2481 /* --------------------------------------------------------*/ 2482 /*@ 2483 MatMult - Computes the matrix-vector product, y = Ax. 2484 2485 Neighbor-wise Collective on Mat 2486 2487 Input Parameters: 2488 + mat - the matrix 2489 - x - the vector to be multiplied 2490 2491 Output Parameters: 2492 . y - the result 2493 2494 Notes: 2495 The vectors x and y cannot be the same. I.e., one cannot 2496 call MatMult(A,y,y). 2497 2498 Level: beginner 2499 2500 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 2501 @*/ 2502 PetscErrorCode MatMult(Mat mat,Vec x,Vec y) 2503 { 2504 PetscFunctionBegin; 2505 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2506 PetscValidType(mat,1); 2507 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2508 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2509 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2510 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2511 PetscCheck(x != y,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2512 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); 2513 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); 2514 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); 2515 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); 2516 PetscCall(VecSetErrorIfLocked(y,3)); 2517 if (mat->erroriffailure) PetscCall(VecValidValues(x,2,PETSC_TRUE)); 2518 MatCheckPreallocated(mat,1); 2519 2520 PetscCall(VecLockReadPush(x)); 2521 PetscCall(PetscLogEventBegin(MAT_Mult,mat,x,y,0)); 2522 PetscUseTypeMethod(mat,mult,x,y); 2523 PetscCall(PetscLogEventEnd(MAT_Mult,mat,x,y,0)); 2524 if (mat->erroriffailure) PetscCall(VecValidValues(y,3,PETSC_FALSE)); 2525 PetscCall(VecLockReadPop(x)); 2526 PetscFunctionReturn(0); 2527 } 2528 2529 /*@ 2530 MatMultTranspose - Computes matrix transpose times a vector y = A^T * x. 2531 2532 Neighbor-wise Collective on Mat 2533 2534 Input Parameters: 2535 + mat - the matrix 2536 - x - the vector to be multiplied 2537 2538 Output Parameters: 2539 . y - the result 2540 2541 Notes: 2542 The vectors x and y cannot be the same. I.e., one cannot 2543 call MatMultTranspose(A,y,y). 2544 2545 For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple, 2546 use MatMultHermitianTranspose() 2547 2548 Level: beginner 2549 2550 .seealso: `MatMult()`, `MatMultAdd()`, `MatMultTransposeAdd()`, `MatMultHermitianTranspose()`, `MatTranspose()` 2551 @*/ 2552 PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y) 2553 { 2554 PetscErrorCode (*op)(Mat,Vec,Vec) = NULL; 2555 2556 PetscFunctionBegin; 2557 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2558 PetscValidType(mat,1); 2559 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2560 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2561 2562 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2563 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2564 PetscCheck(x != y,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2565 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); 2566 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); 2567 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); 2568 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); 2569 if (mat->erroriffailure) PetscCall(VecValidValues(x,2,PETSC_TRUE)); 2570 MatCheckPreallocated(mat,1); 2571 2572 if (!mat->ops->multtranspose) { 2573 if (mat->symmetric == PETSC_BOOL3_TRUE && mat->ops->mult) op = mat->ops->mult; 2574 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); 2575 } else op = mat->ops->multtranspose; 2576 PetscCall(PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0)); 2577 PetscCall(VecLockReadPush(x)); 2578 PetscCall((*op)(mat,x,y)); 2579 PetscCall(VecLockReadPop(x)); 2580 PetscCall(PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0)); 2581 PetscCall(PetscObjectStateIncrease((PetscObject)y)); 2582 if (mat->erroriffailure) PetscCall(VecValidValues(y,3,PETSC_FALSE)); 2583 PetscFunctionReturn(0); 2584 } 2585 2586 /*@ 2587 MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector. 2588 2589 Neighbor-wise Collective on Mat 2590 2591 Input Parameters: 2592 + mat - the matrix 2593 - x - the vector to be multilplied 2594 2595 Output Parameters: 2596 . y - the result 2597 2598 Notes: 2599 The vectors x and y cannot be the same. I.e., one cannot 2600 call MatMultHermitianTranspose(A,y,y). 2601 2602 Also called the conjugate transpose, complex conjugate transpose, or adjoint. 2603 2604 For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical. 2605 2606 Level: beginner 2607 2608 .seealso: `MatMult()`, `MatMultAdd()`, `MatMultHermitianTransposeAdd()`, `MatMultTranspose()` 2609 @*/ 2610 PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y) 2611 { 2612 PetscFunctionBegin; 2613 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2614 PetscValidType(mat,1); 2615 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2616 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2617 2618 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2619 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2620 PetscCheck(x != y,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2621 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); 2622 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); 2623 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); 2624 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); 2625 MatCheckPreallocated(mat,1); 2626 2627 PetscCall(PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0)); 2628 #if defined(PETSC_USE_COMPLEX) 2629 if (mat->ops->multhermitiantranspose || (mat->hermitian == PETSC_BOOL3_TRUE && mat->ops->mult)) { 2630 PetscCall(VecLockReadPush(x)); 2631 if (mat->ops->multhermitiantranspose) PetscUseTypeMethod(mat,multhermitiantranspose ,x,y); 2632 else PetscUseTypeMethod(mat,mult ,x,y); 2633 PetscCall(VecLockReadPop(x)); 2634 } else { 2635 Vec w; 2636 PetscCall(VecDuplicate(x,&w)); 2637 PetscCall(VecCopy(x,w)); 2638 PetscCall(VecConjugate(w)); 2639 PetscCall(MatMultTranspose(mat,w,y)); 2640 PetscCall(VecDestroy(&w)); 2641 PetscCall(VecConjugate(y)); 2642 } 2643 PetscCall(PetscObjectStateIncrease((PetscObject)y)); 2644 #else 2645 PetscCall(MatMultTranspose(mat,x,y)); 2646 #endif 2647 PetscCall(PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0)); 2648 PetscFunctionReturn(0); 2649 } 2650 2651 /*@ 2652 MatMultAdd - Computes v3 = v2 + A * v1. 2653 2654 Neighbor-wise Collective on Mat 2655 2656 Input Parameters: 2657 + mat - the matrix 2658 - v1, v2 - the vectors 2659 2660 Output Parameters: 2661 . v3 - the result 2662 2663 Notes: 2664 The vectors v1 and v3 cannot be the same. I.e., one cannot 2665 call MatMultAdd(A,v1,v2,v1). 2666 2667 Level: beginner 2668 2669 .seealso: `MatMultTranspose()`, `MatMult()`, `MatMultTransposeAdd()` 2670 @*/ 2671 PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2672 { 2673 PetscFunctionBegin; 2674 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2675 PetscValidType(mat,1); 2676 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2677 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2678 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2679 2680 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2681 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2682 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); 2683 /* 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); 2684 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); */ 2685 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); 2686 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); 2687 PetscCheck(v1 != v3,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2688 MatCheckPreallocated(mat,1); 2689 2690 PetscCall(PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3)); 2691 PetscCall(VecLockReadPush(v1)); 2692 PetscUseTypeMethod(mat,multadd ,v1,v2,v3); 2693 PetscCall(VecLockReadPop(v1)); 2694 PetscCall(PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3)); 2695 PetscCall(PetscObjectStateIncrease((PetscObject)v3)); 2696 PetscFunctionReturn(0); 2697 } 2698 2699 /*@ 2700 MatMultTransposeAdd - Computes v3 = v2 + A' * v1. 2701 2702 Neighbor-wise Collective on Mat 2703 2704 Input Parameters: 2705 + mat - the matrix 2706 - v1, v2 - the vectors 2707 2708 Output Parameters: 2709 . v3 - the result 2710 2711 Notes: 2712 The vectors v1 and v3 cannot be the same. I.e., one cannot 2713 call MatMultTransposeAdd(A,v1,v2,v1). 2714 2715 Level: beginner 2716 2717 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMult()` 2718 @*/ 2719 PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2720 { 2721 PetscErrorCode (*op)(Mat,Vec,Vec,Vec) = (!mat->ops->multtransposeadd && mat->symmetric) ? mat->ops->multadd : mat->ops->multtransposeadd; 2722 2723 PetscFunctionBegin; 2724 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2725 PetscValidType(mat,1); 2726 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2727 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2728 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2729 2730 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2731 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2732 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); 2733 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); 2734 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); 2735 PetscCheck(v1 != v3,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2736 PetscCheck(op,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2737 MatCheckPreallocated(mat,1); 2738 2739 PetscCall(PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3)); 2740 PetscCall(VecLockReadPush(v1)); 2741 PetscCall((*op)(mat,v1,v2,v3)); 2742 PetscCall(VecLockReadPop(v1)); 2743 PetscCall(PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3)); 2744 PetscCall(PetscObjectStateIncrease((PetscObject)v3)); 2745 PetscFunctionReturn(0); 2746 } 2747 2748 /*@ 2749 MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1. 2750 2751 Neighbor-wise Collective on Mat 2752 2753 Input Parameters: 2754 + mat - the matrix 2755 - v1, v2 - the vectors 2756 2757 Output Parameters: 2758 . v3 - the result 2759 2760 Notes: 2761 The vectors v1 and v3 cannot be the same. I.e., one cannot 2762 call MatMultHermitianTransposeAdd(A,v1,v2,v1). 2763 2764 Level: beginner 2765 2766 .seealso: `MatMultHermitianTranspose()`, `MatMultTranspose()`, `MatMultAdd()`, `MatMult()` 2767 @*/ 2768 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2769 { 2770 PetscFunctionBegin; 2771 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2772 PetscValidType(mat,1); 2773 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2774 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2775 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2776 2777 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2778 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2779 PetscCheck(v1 != v3,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2780 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); 2781 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); 2782 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); 2783 MatCheckPreallocated(mat,1); 2784 2785 PetscCall(PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3)); 2786 PetscCall(VecLockReadPush(v1)); 2787 if (mat->ops->multhermitiantransposeadd) PetscUseTypeMethod(mat,multhermitiantransposeadd ,v1,v2,v3); 2788 else { 2789 Vec w,z; 2790 PetscCall(VecDuplicate(v1,&w)); 2791 PetscCall(VecCopy(v1,w)); 2792 PetscCall(VecConjugate(w)); 2793 PetscCall(VecDuplicate(v3,&z)); 2794 PetscCall(MatMultTranspose(mat,w,z)); 2795 PetscCall(VecDestroy(&w)); 2796 PetscCall(VecConjugate(z)); 2797 if (v2 != v3) { 2798 PetscCall(VecWAXPY(v3,1.0,v2,z)); 2799 } else { 2800 PetscCall(VecAXPY(v3,1.0,z)); 2801 } 2802 PetscCall(VecDestroy(&z)); 2803 } 2804 PetscCall(VecLockReadPop(v1)); 2805 PetscCall(PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3)); 2806 PetscCall(PetscObjectStateIncrease((PetscObject)v3)); 2807 PetscFunctionReturn(0); 2808 } 2809 2810 /*@C 2811 MatGetFactorType - gets the type of factorization it is 2812 2813 Not Collective 2814 2815 Input Parameters: 2816 . mat - the matrix 2817 2818 Output Parameters: 2819 . t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT 2820 2821 Level: intermediate 2822 2823 .seealso: `MatFactorType`, `MatGetFactor()`, `MatSetFactorType()` 2824 @*/ 2825 PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t) 2826 { 2827 PetscFunctionBegin; 2828 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2829 PetscValidType(mat,1); 2830 PetscValidPointer(t,2); 2831 *t = mat->factortype; 2832 PetscFunctionReturn(0); 2833 } 2834 2835 /*@C 2836 MatSetFactorType - sets the type of factorization it is 2837 2838 Logically Collective on Mat 2839 2840 Input Parameters: 2841 + mat - the matrix 2842 - t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT 2843 2844 Level: intermediate 2845 2846 .seealso: `MatFactorType`, `MatGetFactor()`, `MatGetFactorType()` 2847 @*/ 2848 PetscErrorCode MatSetFactorType(Mat mat, MatFactorType t) 2849 { 2850 PetscFunctionBegin; 2851 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2852 PetscValidType(mat,1); 2853 mat->factortype = t; 2854 PetscFunctionReturn(0); 2855 } 2856 2857 /* ------------------------------------------------------------*/ 2858 /*@C 2859 MatGetInfo - Returns information about matrix storage (number of 2860 nonzeros, memory, etc.). 2861 2862 Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag 2863 2864 Input Parameter: 2865 . mat - the matrix 2866 2867 Output Parameters: 2868 + flag - flag indicating the type of parameters to be returned 2869 (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors, 2870 MAT_GLOBAL_SUM - sum over all processors) 2871 - info - matrix information context 2872 2873 Notes: 2874 The MatInfo context contains a variety of matrix data, including 2875 number of nonzeros allocated and used, number of mallocs during 2876 matrix assembly, etc. Additional information for factored matrices 2877 is provided (such as the fill ratio, number of mallocs during 2878 factorization, etc.). Much of this info is printed to PETSC_STDOUT 2879 when using the runtime options 2880 $ -info -mat_view ::ascii_info 2881 2882 Example for C/C++ Users: 2883 See the file ${PETSC_DIR}/include/petscmat.h for a complete list of 2884 data within the MatInfo context. For example, 2885 .vb 2886 MatInfo info; 2887 Mat A; 2888 double mal, nz_a, nz_u; 2889 2890 MatGetInfo(A,MAT_LOCAL,&info); 2891 mal = info.mallocs; 2892 nz_a = info.nz_allocated; 2893 .ve 2894 2895 Example for Fortran Users: 2896 Fortran users should declare info as a double precision 2897 array of dimension MAT_INFO_SIZE, and then extract the parameters 2898 of interest. See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h 2899 a complete list of parameter names. 2900 .vb 2901 double precision info(MAT_INFO_SIZE) 2902 double precision mal, nz_a 2903 Mat A 2904 integer ierr 2905 2906 call MatGetInfo(A,MAT_LOCAL,info,ierr) 2907 mal = info(MAT_INFO_MALLOCS) 2908 nz_a = info(MAT_INFO_NZ_ALLOCATED) 2909 .ve 2910 2911 Level: intermediate 2912 2913 Developer Note: fortran interface is not autogenerated as the f90 2914 interface definition cannot be generated correctly [due to MatInfo] 2915 2916 .seealso: `MatStashGetInfo()` 2917 2918 @*/ 2919 PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info) 2920 { 2921 PetscFunctionBegin; 2922 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2923 PetscValidType(mat,1); 2924 PetscValidPointer(info,3); 2925 MatCheckPreallocated(mat,1); 2926 PetscUseTypeMethod(mat,getinfo ,flag,info); 2927 PetscFunctionReturn(0); 2928 } 2929 2930 /* 2931 This is used by external packages where it is not easy to get the info from the actual 2932 matrix factorization. 2933 */ 2934 PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info) 2935 { 2936 PetscFunctionBegin; 2937 PetscCall(PetscMemzero(info,sizeof(MatInfo))); 2938 PetscFunctionReturn(0); 2939 } 2940 2941 /* ----------------------------------------------------------*/ 2942 2943 /*@C 2944 MatLUFactor - Performs in-place LU factorization of matrix. 2945 2946 Collective on Mat 2947 2948 Input Parameters: 2949 + mat - the matrix 2950 . row - row permutation 2951 . col - column permutation 2952 - info - options for factorization, includes 2953 $ fill - expected fill as ratio of original fill. 2954 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 2955 $ Run with the option -info to determine an optimal value to use 2956 2957 Notes: 2958 Most users should employ the simplified KSP interface for linear solvers 2959 instead of working directly with matrix algebra routines such as this. 2960 See, e.g., KSPCreate(). 2961 2962 This changes the state of the matrix to a factored matrix; it cannot be used 2963 for example with MatSetValues() unless one first calls MatSetUnfactored(). 2964 2965 Level: developer 2966 2967 .seealso: `MatLUFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()`, 2968 `MatGetOrdering()`, `MatSetUnfactored()`, `MatFactorInfo`, `MatGetFactor()` 2969 2970 Developer Note: fortran interface is not autogenerated as the f90 2971 interface definition cannot be generated correctly [due to MatFactorInfo] 2972 2973 @*/ 2974 PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 2975 { 2976 MatFactorInfo tinfo; 2977 2978 PetscFunctionBegin; 2979 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2980 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 2981 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 2982 if (info) PetscValidPointer(info,4); 2983 PetscValidType(mat,1); 2984 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2985 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2986 MatCheckPreallocated(mat,1); 2987 if (!info) { 2988 PetscCall(MatFactorInfoInitialize(&tinfo)); 2989 info = &tinfo; 2990 } 2991 2992 PetscCall(PetscLogEventBegin(MAT_LUFactor,mat,row,col,0)); 2993 PetscUseTypeMethod(mat,lufactor ,row,col,info); 2994 PetscCall(PetscLogEventEnd(MAT_LUFactor,mat,row,col,0)); 2995 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 2996 PetscFunctionReturn(0); 2997 } 2998 2999 /*@C 3000 MatILUFactor - Performs in-place ILU factorization of matrix. 3001 3002 Collective on Mat 3003 3004 Input Parameters: 3005 + mat - the matrix 3006 . row - row permutation 3007 . col - column permutation 3008 - info - structure containing 3009 $ levels - number of levels of fill. 3010 $ expected fill - as ratio of original fill. 3011 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 3012 missing diagonal entries) 3013 3014 Notes: 3015 Probably really in-place only when level of fill is zero, otherwise allocates 3016 new space to store factored matrix and deletes previous memory. 3017 3018 Most users should employ the simplified KSP interface for linear solvers 3019 instead of working directly with matrix algebra routines such as this. 3020 See, e.g., KSPCreate(). 3021 3022 Level: developer 3023 3024 .seealso: `MatILUFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()`, `MatFactorInfo` 3025 3026 Developer Note: fortran interface is not autogenerated as the f90 3027 interface definition cannot be generated correctly [due to MatFactorInfo] 3028 3029 @*/ 3030 PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 3031 { 3032 PetscFunctionBegin; 3033 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3034 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 3035 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 3036 PetscValidPointer(info,4); 3037 PetscValidType(mat,1); 3038 PetscCheck(mat->rmap->N == mat->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 3039 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3040 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3041 MatCheckPreallocated(mat,1); 3042 3043 PetscCall(PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0)); 3044 PetscUseTypeMethod(mat,ilufactor ,row,col,info); 3045 PetscCall(PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0)); 3046 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 3047 PetscFunctionReturn(0); 3048 } 3049 3050 /*@C 3051 MatLUFactorSymbolic - Performs symbolic LU factorization of matrix. 3052 Call this routine before calling MatLUFactorNumeric(). 3053 3054 Collective on Mat 3055 3056 Input Parameters: 3057 + fact - the factor matrix obtained with MatGetFactor() 3058 . mat - the matrix 3059 . row, col - row and column permutations 3060 - info - options for factorization, includes 3061 $ fill - expected fill as ratio of original fill. 3062 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3063 $ Run with the option -info to determine an optimal value to use 3064 3065 Notes: 3066 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 3067 3068 Most users should employ the simplified KSP interface for linear solvers 3069 instead of working directly with matrix algebra routines such as this. 3070 See, e.g., KSPCreate(). 3071 3072 Level: developer 3073 3074 .seealso: `MatLUFactor()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()`, `MatFactorInfo`, `MatFactorInfoInitialize()` 3075 3076 Developer Note: fortran interface is not autogenerated as the f90 3077 interface definition cannot be generated correctly [due to MatFactorInfo] 3078 3079 @*/ 3080 PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 3081 { 3082 MatFactorInfo tinfo; 3083 3084 PetscFunctionBegin; 3085 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3086 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,3); 3087 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,4); 3088 if (info) PetscValidPointer(info,5); 3089 PetscValidType(mat,2); 3090 PetscValidPointer(fact,1); 3091 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3092 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3093 if (!(fact)->ops->lufactorsymbolic) { 3094 MatSolverType stype; 3095 PetscCall(MatFactorGetSolverType(fact,&stype)); 3096 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,stype); 3097 } 3098 MatCheckPreallocated(mat,2); 3099 if (!info) { 3100 PetscCall(MatFactorInfoInitialize(&tinfo)); 3101 info = &tinfo; 3102 } 3103 3104 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0)); 3105 PetscCall((fact->ops->lufactorsymbolic)(fact,mat,row,col,info)); 3106 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0)); 3107 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3108 PetscFunctionReturn(0); 3109 } 3110 3111 /*@C 3112 MatLUFactorNumeric - Performs numeric LU factorization of a matrix. 3113 Call this routine after first calling MatLUFactorSymbolic(). 3114 3115 Collective on Mat 3116 3117 Input Parameters: 3118 + fact - the factor matrix obtained with MatGetFactor() 3119 . mat - the matrix 3120 - info - options for factorization 3121 3122 Notes: 3123 See MatLUFactor() for in-place factorization. See 3124 MatCholeskyFactorNumeric() for the symmetric, positive definite case. 3125 3126 Most users should employ the simplified KSP interface for linear solvers 3127 instead of working directly with matrix algebra routines such as this. 3128 See, e.g., KSPCreate(). 3129 3130 Level: developer 3131 3132 .seealso: `MatLUFactorSymbolic()`, `MatLUFactor()`, `MatCholeskyFactor()` 3133 3134 Developer Note: fortran interface is not autogenerated as the f90 3135 interface definition cannot be generated correctly [due to MatFactorInfo] 3136 3137 @*/ 3138 PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3139 { 3140 MatFactorInfo tinfo; 3141 3142 PetscFunctionBegin; 3143 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3144 PetscValidType(mat,2); 3145 PetscValidPointer(fact,1); 3146 PetscValidHeaderSpecific(fact,MAT_CLASSID,1); 3147 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3148 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); 3149 3150 PetscCheck((fact)->ops->lufactornumeric,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name); 3151 MatCheckPreallocated(mat,2); 3152 if (!info) { 3153 PetscCall(MatFactorInfoInitialize(&tinfo)); 3154 info = &tinfo; 3155 } 3156 3157 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0)); 3158 else PetscCall(PetscLogEventBegin(MAT_LUFactor,mat,fact,0,0)); 3159 PetscCall((fact->ops->lufactornumeric)(fact,mat,info)); 3160 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0)); 3161 else PetscCall(PetscLogEventEnd(MAT_LUFactor,mat,fact,0,0)); 3162 PetscCall(MatViewFromOptions(fact,NULL,"-mat_factor_view")); 3163 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3164 PetscFunctionReturn(0); 3165 } 3166 3167 /*@C 3168 MatCholeskyFactor - Performs in-place Cholesky factorization of a 3169 symmetric matrix. 3170 3171 Collective on Mat 3172 3173 Input Parameters: 3174 + mat - the matrix 3175 . perm - row and column permutations 3176 - f - expected fill as ratio of original fill 3177 3178 Notes: 3179 See MatLUFactor() for the nonsymmetric case. See also 3180 MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric(). 3181 3182 Most users should employ the simplified KSP interface for linear solvers 3183 instead of working directly with matrix algebra routines such as this. 3184 See, e.g., KSPCreate(). 3185 3186 Level: developer 3187 3188 .seealso: `MatLUFactor()`, `MatCholeskyFactorSymbolic()`, `MatCholeskyFactorNumeric()` 3189 `MatGetOrdering()` 3190 3191 Developer Note: fortran interface is not autogenerated as the f90 3192 interface definition cannot be generated correctly [due to MatFactorInfo] 3193 3194 @*/ 3195 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info) 3196 { 3197 MatFactorInfo tinfo; 3198 3199 PetscFunctionBegin; 3200 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3201 PetscValidType(mat,1); 3202 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2); 3203 if (info) PetscValidPointer(info,3); 3204 PetscCheck(mat->rmap->N == mat->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square"); 3205 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3206 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3207 MatCheckPreallocated(mat,1); 3208 if (!info) { 3209 PetscCall(MatFactorInfoInitialize(&tinfo)); 3210 info = &tinfo; 3211 } 3212 3213 PetscCall(PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0)); 3214 PetscUseTypeMethod(mat,choleskyfactor ,perm,info); 3215 PetscCall(PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0)); 3216 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 3217 PetscFunctionReturn(0); 3218 } 3219 3220 /*@C 3221 MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization 3222 of a symmetric matrix. 3223 3224 Collective on Mat 3225 3226 Input Parameters: 3227 + fact - the factor matrix obtained with MatGetFactor() 3228 . mat - the matrix 3229 . perm - row and column permutations 3230 - info - options for factorization, includes 3231 $ fill - expected fill as ratio of original fill. 3232 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3233 $ Run with the option -info to determine an optimal value to use 3234 3235 Notes: 3236 See MatLUFactorSymbolic() for the nonsymmetric case. See also 3237 MatCholeskyFactor() and MatCholeskyFactorNumeric(). 3238 3239 Most users should employ the simplified KSP interface for linear solvers 3240 instead of working directly with matrix algebra routines such as this. 3241 See, e.g., KSPCreate(). 3242 3243 Level: developer 3244 3245 .seealso: `MatLUFactorSymbolic()`, `MatCholeskyFactor()`, `MatCholeskyFactorNumeric()` 3246 `MatGetOrdering()` 3247 3248 Developer Note: fortran interface is not autogenerated as the f90 3249 interface definition cannot be generated correctly [due to MatFactorInfo] 3250 3251 @*/ 3252 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 3253 { 3254 MatFactorInfo tinfo; 3255 3256 PetscFunctionBegin; 3257 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3258 PetscValidType(mat,2); 3259 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,3); 3260 if (info) PetscValidPointer(info,4); 3261 PetscValidPointer(fact,1); 3262 PetscCheck(mat->rmap->N == mat->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square"); 3263 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3264 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3265 if (!(fact)->ops->choleskyfactorsymbolic) { 3266 MatSolverType stype; 3267 PetscCall(MatFactorGetSolverType(fact,&stype)); 3268 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,stype); 3269 } 3270 MatCheckPreallocated(mat,2); 3271 if (!info) { 3272 PetscCall(MatFactorInfoInitialize(&tinfo)); 3273 info = &tinfo; 3274 } 3275 3276 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0)); 3277 PetscCall((fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info)); 3278 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0)); 3279 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3280 PetscFunctionReturn(0); 3281 } 3282 3283 /*@C 3284 MatCholeskyFactorNumeric - Performs numeric Cholesky factorization 3285 of a symmetric matrix. Call this routine after first calling 3286 MatCholeskyFactorSymbolic(). 3287 3288 Collective on Mat 3289 3290 Input Parameters: 3291 + fact - the factor matrix obtained with MatGetFactor() 3292 . mat - the initial matrix 3293 . info - options for factorization 3294 - fact - the symbolic factor of mat 3295 3296 Notes: 3297 Most users should employ the simplified KSP interface for linear solvers 3298 instead of working directly with matrix algebra routines such as this. 3299 See, e.g., KSPCreate(). 3300 3301 Level: developer 3302 3303 .seealso: `MatCholeskyFactorSymbolic()`, `MatCholeskyFactor()`, `MatLUFactorNumeric()` 3304 3305 Developer Note: fortran interface is not autogenerated as the f90 3306 interface definition cannot be generated correctly [due to MatFactorInfo] 3307 3308 @*/ 3309 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3310 { 3311 MatFactorInfo tinfo; 3312 3313 PetscFunctionBegin; 3314 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3315 PetscValidType(mat,2); 3316 PetscValidPointer(fact,1); 3317 PetscValidHeaderSpecific(fact,MAT_CLASSID,1); 3318 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3319 PetscCheck((fact)->ops->choleskyfactornumeric,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name); 3320 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); 3321 MatCheckPreallocated(mat,2); 3322 if (!info) { 3323 PetscCall(MatFactorInfoInitialize(&tinfo)); 3324 info = &tinfo; 3325 } 3326 3327 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0)); 3328 else PetscCall(PetscLogEventBegin(MAT_CholeskyFactor,mat,fact,0,0)); 3329 PetscCall((fact->ops->choleskyfactornumeric)(fact,mat,info)); 3330 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0)); 3331 else PetscCall(PetscLogEventEnd(MAT_CholeskyFactor,mat,fact,0,0)); 3332 PetscCall(MatViewFromOptions(fact,NULL,"-mat_factor_view")); 3333 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3334 PetscFunctionReturn(0); 3335 } 3336 3337 /*@ 3338 MatQRFactor - Performs in-place QR factorization of matrix. 3339 3340 Collective on Mat 3341 3342 Input Parameters: 3343 + mat - the matrix 3344 . col - column permutation 3345 - info - options for factorization, includes 3346 $ fill - expected fill as ratio of original fill. 3347 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3348 $ Run with the option -info to determine an optimal value to use 3349 3350 Notes: 3351 Most users should employ the simplified KSP interface for linear solvers 3352 instead of working directly with matrix algebra routines such as this. 3353 See, e.g., KSPCreate(). 3354 3355 This changes the state of the matrix to a factored matrix; it cannot be used 3356 for example with MatSetValues() unless one first calls MatSetUnfactored(). 3357 3358 Level: developer 3359 3360 .seealso: `MatQRFactorSymbolic()`, `MatQRFactorNumeric()`, `MatLUFactor()`, 3361 `MatSetUnfactored()`, `MatFactorInfo`, `MatGetFactor()` 3362 3363 Developer Note: fortran interface is not autogenerated as the f90 3364 interface definition cannot be generated correctly [due to MatFactorInfo] 3365 3366 @*/ 3367 PetscErrorCode MatQRFactor(Mat mat, IS col, const MatFactorInfo *info) 3368 { 3369 PetscFunctionBegin; 3370 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3371 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,2); 3372 if (info) PetscValidPointer(info,3); 3373 PetscValidType(mat,1); 3374 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3375 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3376 MatCheckPreallocated(mat,1); 3377 PetscCall(PetscLogEventBegin(MAT_QRFactor,mat,col,0,0)); 3378 PetscUseMethod(mat,"MatQRFactor_C", (Mat,IS,const MatFactorInfo*), (mat, col, info)); 3379 PetscCall(PetscLogEventEnd(MAT_QRFactor,mat,col,0,0)); 3380 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 3381 PetscFunctionReturn(0); 3382 } 3383 3384 /*@ 3385 MatQRFactorSymbolic - Performs symbolic QR factorization of matrix. 3386 Call this routine before calling MatQRFactorNumeric(). 3387 3388 Collective on Mat 3389 3390 Input Parameters: 3391 + fact - the factor matrix obtained with MatGetFactor() 3392 . mat - the matrix 3393 . col - column permutation 3394 - info - options for factorization, includes 3395 $ fill - expected fill as ratio of original fill. 3396 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3397 $ Run with the option -info to determine an optimal value to use 3398 3399 Most users should employ the simplified KSP interface for linear solvers 3400 instead of working directly with matrix algebra routines such as this. 3401 See, e.g., KSPCreate(). 3402 3403 Level: developer 3404 3405 .seealso: `MatQRFactor()`, `MatQRFactorNumeric()`, `MatLUFactor()`, `MatFactorInfo`, `MatFactorInfoInitialize()` 3406 3407 Developer Note: fortran interface is not autogenerated as the f90 3408 interface definition cannot be generated correctly [due to MatFactorInfo] 3409 3410 @*/ 3411 PetscErrorCode MatQRFactorSymbolic(Mat fact,Mat mat,IS col,const MatFactorInfo *info) 3412 { 3413 MatFactorInfo tinfo; 3414 3415 PetscFunctionBegin; 3416 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3417 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 3418 if (info) PetscValidPointer(info,4); 3419 PetscValidType(mat,2); 3420 PetscValidPointer(fact,1); 3421 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3422 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3423 MatCheckPreallocated(mat,2); 3424 if (!info) { 3425 PetscCall(MatFactorInfoInitialize(&tinfo)); 3426 info = &tinfo; 3427 } 3428 3429 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_QRFactorSymbolic,fact,mat,col,0)); 3430 PetscUseMethod(fact,"MatQRFactorSymbolic_C", (Mat,Mat,IS,const MatFactorInfo*), (fact, mat, col, info)); 3431 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_QRFactorSymbolic,fact,mat,col,0)); 3432 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3433 PetscFunctionReturn(0); 3434 } 3435 3436 /*@ 3437 MatQRFactorNumeric - Performs numeric QR factorization of a matrix. 3438 Call this routine after first calling MatQRFactorSymbolic(). 3439 3440 Collective on Mat 3441 3442 Input Parameters: 3443 + fact - the factor matrix obtained with MatGetFactor() 3444 . mat - the matrix 3445 - info - options for factorization 3446 3447 Notes: 3448 See MatQRFactor() for in-place factorization. 3449 3450 Most users should employ the simplified KSP interface for linear solvers 3451 instead of working directly with matrix algebra routines such as this. 3452 See, e.g., KSPCreate(). 3453 3454 Level: developer 3455 3456 .seealso: `MatQRFactorSymbolic()`, `MatLUFactor()` 3457 3458 Developer Note: fortran interface is not autogenerated as the f90 3459 interface definition cannot be generated correctly [due to MatFactorInfo] 3460 3461 @*/ 3462 PetscErrorCode MatQRFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3463 { 3464 MatFactorInfo tinfo; 3465 3466 PetscFunctionBegin; 3467 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3468 PetscValidType(mat,2); 3469 PetscValidPointer(fact,1); 3470 PetscValidHeaderSpecific(fact,MAT_CLASSID,1); 3471 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3472 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); 3473 3474 MatCheckPreallocated(mat,2); 3475 if (!info) { 3476 PetscCall(MatFactorInfoInitialize(&tinfo)); 3477 info = &tinfo; 3478 } 3479 3480 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_QRFactorNumeric,mat,fact,0,0)); 3481 else PetscCall(PetscLogEventBegin(MAT_QRFactor,mat,fact,0,0)); 3482 PetscUseMethod(fact,"MatQRFactorNumeric_C", (Mat,Mat,const MatFactorInfo*), (fact, mat, info)); 3483 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_QRFactorNumeric,mat,fact,0,0)); 3484 else PetscCall(PetscLogEventEnd(MAT_QRFactor,mat,fact,0,0)); 3485 PetscCall(MatViewFromOptions(fact,NULL,"-mat_factor_view")); 3486 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3487 PetscFunctionReturn(0); 3488 } 3489 3490 /* ----------------------------------------------------------------*/ 3491 /*@ 3492 MatSolve - Solves A x = b, given a factored matrix. 3493 3494 Neighbor-wise Collective on Mat 3495 3496 Input Parameters: 3497 + mat - the factored matrix 3498 - b - the right-hand-side vector 3499 3500 Output Parameter: 3501 . x - the result vector 3502 3503 Notes: 3504 The vectors b and x cannot be the same. I.e., one cannot 3505 call MatSolve(A,x,x). 3506 3507 Notes: 3508 Most users should employ the simplified KSP interface for linear solvers 3509 instead of working directly with matrix algebra routines such as this. 3510 See, e.g., KSPCreate(). 3511 3512 Level: developer 3513 3514 .seealso: `MatSolveAdd()`, `MatSolveTranspose()`, `MatSolveTransposeAdd()` 3515 @*/ 3516 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x) 3517 { 3518 PetscFunctionBegin; 3519 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3520 PetscValidType(mat,1); 3521 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3522 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3523 PetscCheckSameComm(mat,1,b,2); 3524 PetscCheckSameComm(mat,1,x,3); 3525 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3526 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); 3527 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); 3528 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); 3529 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3530 MatCheckPreallocated(mat,1); 3531 3532 PetscCall(PetscLogEventBegin(MAT_Solve,mat,b,x,0)); 3533 if (mat->factorerrortype) { 3534 PetscCall(PetscInfo(mat,"MatFactorError %d\n",mat->factorerrortype)); 3535 PetscCall(VecSetInf(x)); 3536 } else PetscUseTypeMethod(mat,solve ,b,x); 3537 PetscCall(PetscLogEventEnd(MAT_Solve,mat,b,x,0)); 3538 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3539 PetscFunctionReturn(0); 3540 } 3541 3542 static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X,PetscBool trans) 3543 { 3544 Vec b,x; 3545 PetscInt N,i; 3546 PetscErrorCode (*f)(Mat,Vec,Vec); 3547 PetscBool Abound,Bneedconv = PETSC_FALSE,Xneedconv = PETSC_FALSE; 3548 3549 PetscFunctionBegin; 3550 if (A->factorerrortype) { 3551 PetscCall(PetscInfo(A,"MatFactorError %d\n",A->factorerrortype)); 3552 PetscCall(MatSetInf(X)); 3553 PetscFunctionReturn(0); 3554 } 3555 f = (!trans || (!A->ops->solvetranspose && A->symmetric)) ? A->ops->solve : A->ops->solvetranspose; 3556 PetscCheck(f,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 3557 PetscCall(MatBoundToCPU(A,&Abound)); 3558 if (!Abound) { 3559 PetscCall(PetscObjectTypeCompareAny((PetscObject)B,&Bneedconv,MATSEQDENSE,MATMPIDENSE,"")); 3560 PetscCall(PetscObjectTypeCompareAny((PetscObject)X,&Xneedconv,MATSEQDENSE,MATMPIDENSE,"")); 3561 } 3562 if (Bneedconv) { 3563 PetscCall(MatConvert(B,MATDENSECUDA,MAT_INPLACE_MATRIX,&B)); 3564 } 3565 if (Xneedconv) { 3566 PetscCall(MatConvert(X,MATDENSECUDA,MAT_INPLACE_MATRIX,&X)); 3567 } 3568 PetscCall(MatGetSize(B,NULL,&N)); 3569 for (i=0; i<N; i++) { 3570 PetscCall(MatDenseGetColumnVecRead(B,i,&b)); 3571 PetscCall(MatDenseGetColumnVecWrite(X,i,&x)); 3572 PetscCall((*f)(A,b,x)); 3573 PetscCall(MatDenseRestoreColumnVecWrite(X,i,&x)); 3574 PetscCall(MatDenseRestoreColumnVecRead(B,i,&b)); 3575 } 3576 if (Bneedconv) { 3577 PetscCall(MatConvert(B,MATDENSE,MAT_INPLACE_MATRIX,&B)); 3578 } 3579 if (Xneedconv) { 3580 PetscCall(MatConvert(X,MATDENSE,MAT_INPLACE_MATRIX,&X)); 3581 } 3582 PetscFunctionReturn(0); 3583 } 3584 3585 /*@ 3586 MatMatSolve - Solves A X = B, given a factored matrix. 3587 3588 Neighbor-wise Collective on Mat 3589 3590 Input Parameters: 3591 + A - the factored matrix 3592 - B - the right-hand-side matrix MATDENSE (or sparse -- when using MUMPS) 3593 3594 Output Parameter: 3595 . X - the result matrix (dense matrix) 3596 3597 Notes: 3598 If B is a MATDENSE matrix then one can call MatMatSolve(A,B,B) except with MKL_CPARDISO; 3599 otherwise, B and X cannot be the same. 3600 3601 Notes: 3602 Most users should usually employ the simplified KSP interface for linear solvers 3603 instead of working directly with matrix algebra routines such as this. 3604 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3605 at a time. 3606 3607 Level: developer 3608 3609 .seealso: `MatMatSolveTranspose()`, `MatLUFactor()`, `MatCholeskyFactor()` 3610 @*/ 3611 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X) 3612 { 3613 PetscFunctionBegin; 3614 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3615 PetscValidType(A,1); 3616 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3617 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3618 PetscCheckSameComm(A,1,B,2); 3619 PetscCheckSameComm(A,1,X,3); 3620 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); 3621 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); 3622 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"); 3623 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3624 PetscCheck(A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3625 MatCheckPreallocated(A,1); 3626 3627 PetscCall(PetscLogEventBegin(MAT_MatSolve,A,B,X,0)); 3628 if (!A->ops->matsolve) { 3629 PetscCall(PetscInfo(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name)); 3630 PetscCall(MatMatSolve_Basic(A,B,X,PETSC_FALSE)); 3631 } else PetscUseTypeMethod(A,matsolve ,B,X); 3632 PetscCall(PetscLogEventEnd(MAT_MatSolve,A,B,X,0)); 3633 PetscCall(PetscObjectStateIncrease((PetscObject)X)); 3634 PetscFunctionReturn(0); 3635 } 3636 3637 /*@ 3638 MatMatSolveTranspose - Solves A^T X = B, given a factored matrix. 3639 3640 Neighbor-wise Collective on Mat 3641 3642 Input Parameters: 3643 + A - the factored matrix 3644 - B - the right-hand-side matrix (dense matrix) 3645 3646 Output Parameter: 3647 . X - the result matrix (dense matrix) 3648 3649 Notes: 3650 The matrices B and X cannot be the same. I.e., one cannot 3651 call MatMatSolveTranspose(A,X,X). 3652 3653 Notes: 3654 Most users should usually employ the simplified KSP interface for linear solvers 3655 instead of working directly with matrix algebra routines such as this. 3656 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3657 at a time. 3658 3659 When using SuperLU_Dist or MUMPS as a parallel solver, PETSc will use their functionality to solve multiple right hand sides simultaneously. 3660 3661 Level: developer 3662 3663 .seealso: `MatMatSolve()`, `MatLUFactor()`, `MatCholeskyFactor()` 3664 @*/ 3665 PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X) 3666 { 3667 PetscFunctionBegin; 3668 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3669 PetscValidType(A,1); 3670 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3671 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3672 PetscCheckSameComm(A,1,B,2); 3673 PetscCheckSameComm(A,1,X,3); 3674 PetscCheck(X != B,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3675 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); 3676 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); 3677 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); 3678 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"); 3679 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3680 PetscCheck(A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3681 MatCheckPreallocated(A,1); 3682 3683 PetscCall(PetscLogEventBegin(MAT_MatSolve,A,B,X,0)); 3684 if (!A->ops->matsolvetranspose) { 3685 PetscCall(PetscInfo(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name)); 3686 PetscCall(MatMatSolve_Basic(A,B,X,PETSC_TRUE)); 3687 } else PetscUseTypeMethod(A,matsolvetranspose ,B,X); 3688 PetscCall(PetscLogEventEnd(MAT_MatSolve,A,B,X,0)); 3689 PetscCall(PetscObjectStateIncrease((PetscObject)X)); 3690 PetscFunctionReturn(0); 3691 } 3692 3693 /*@ 3694 MatMatTransposeSolve - Solves A X = B^T, given a factored matrix. 3695 3696 Neighbor-wise Collective on Mat 3697 3698 Input Parameters: 3699 + A - the factored matrix 3700 - Bt - the transpose of right-hand-side matrix 3701 3702 Output Parameter: 3703 . X - the result matrix (dense matrix) 3704 3705 Notes: 3706 Most users should usually employ the simplified KSP interface for linear solvers 3707 instead of working directly with matrix algebra routines such as this. 3708 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3709 at a time. 3710 3711 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(). 3712 3713 Level: developer 3714 3715 .seealso: `MatMatSolve()`, `MatMatSolveTranspose()`, `MatLUFactor()`, `MatCholeskyFactor()` 3716 @*/ 3717 PetscErrorCode MatMatTransposeSolve(Mat A,Mat Bt,Mat X) 3718 { 3719 PetscFunctionBegin; 3720 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3721 PetscValidType(A,1); 3722 PetscValidHeaderSpecific(Bt,MAT_CLASSID,2); 3723 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3724 PetscCheckSameComm(A,1,Bt,2); 3725 PetscCheckSameComm(A,1,X,3); 3726 3727 PetscCheck(X != Bt,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3728 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); 3729 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); 3730 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"); 3731 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3732 PetscCheck(A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3733 MatCheckPreallocated(A,1); 3734 3735 PetscCall(PetscLogEventBegin(MAT_MatTrSolve,A,Bt,X,0)); 3736 PetscUseTypeMethod(A,mattransposesolve ,Bt,X); 3737 PetscCall(PetscLogEventEnd(MAT_MatTrSolve,A,Bt,X,0)); 3738 PetscCall(PetscObjectStateIncrease((PetscObject)X)); 3739 PetscFunctionReturn(0); 3740 } 3741 3742 /*@ 3743 MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or 3744 U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U, 3745 3746 Neighbor-wise Collective on Mat 3747 3748 Input Parameters: 3749 + mat - the factored matrix 3750 - b - the right-hand-side vector 3751 3752 Output Parameter: 3753 . x - the result vector 3754 3755 Notes: 3756 MatSolve() should be used for most applications, as it performs 3757 a forward solve followed by a backward solve. 3758 3759 The vectors b and x cannot be the same, i.e., one cannot 3760 call MatForwardSolve(A,x,x). 3761 3762 For matrix in seqsbaij format with block size larger than 1, 3763 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3764 MatForwardSolve() solves U^T*D y = b, and 3765 MatBackwardSolve() solves U x = y. 3766 Thus they do not provide a symmetric preconditioner. 3767 3768 Most users should employ the simplified KSP interface for linear solvers 3769 instead of working directly with matrix algebra routines such as this. 3770 See, e.g., KSPCreate(). 3771 3772 Level: developer 3773 3774 .seealso: `MatSolve()`, `MatBackwardSolve()` 3775 @*/ 3776 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x) 3777 { 3778 PetscFunctionBegin; 3779 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3780 PetscValidType(mat,1); 3781 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3782 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3783 PetscCheckSameComm(mat,1,b,2); 3784 PetscCheckSameComm(mat,1,x,3); 3785 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3786 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); 3787 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); 3788 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); 3789 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3790 MatCheckPreallocated(mat,1); 3791 3792 PetscCall(PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0)); 3793 PetscUseTypeMethod(mat,forwardsolve ,b,x); 3794 PetscCall(PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0)); 3795 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3796 PetscFunctionReturn(0); 3797 } 3798 3799 /*@ 3800 MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU. 3801 D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U, 3802 3803 Neighbor-wise Collective on Mat 3804 3805 Input Parameters: 3806 + mat - the factored matrix 3807 - b - the right-hand-side vector 3808 3809 Output Parameter: 3810 . x - the result vector 3811 3812 Notes: 3813 MatSolve() should be used for most applications, as it performs 3814 a forward solve followed by a backward solve. 3815 3816 The vectors b and x cannot be the same. I.e., one cannot 3817 call MatBackwardSolve(A,x,x). 3818 3819 For matrix in seqsbaij format with block size larger than 1, 3820 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3821 MatForwardSolve() solves U^T*D y = b, and 3822 MatBackwardSolve() solves U x = y. 3823 Thus they do not provide a symmetric preconditioner. 3824 3825 Most users should employ the simplified KSP interface for linear solvers 3826 instead of working directly with matrix algebra routines such as this. 3827 See, e.g., KSPCreate(). 3828 3829 Level: developer 3830 3831 .seealso: `MatSolve()`, `MatForwardSolve()` 3832 @*/ 3833 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x) 3834 { 3835 PetscFunctionBegin; 3836 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3837 PetscValidType(mat,1); 3838 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3839 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3840 PetscCheckSameComm(mat,1,b,2); 3841 PetscCheckSameComm(mat,1,x,3); 3842 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3843 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); 3844 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); 3845 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); 3846 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3847 MatCheckPreallocated(mat,1); 3848 3849 PetscCall(PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0)); 3850 PetscUseTypeMethod(mat,backwardsolve ,b,x); 3851 PetscCall(PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0)); 3852 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3853 PetscFunctionReturn(0); 3854 } 3855 3856 /*@ 3857 MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix. 3858 3859 Neighbor-wise Collective on Mat 3860 3861 Input Parameters: 3862 + mat - the factored matrix 3863 . b - the right-hand-side vector 3864 - y - the vector to be added to 3865 3866 Output Parameter: 3867 . x - the result vector 3868 3869 Notes: 3870 The vectors b and x cannot be the same. I.e., one cannot 3871 call MatSolveAdd(A,x,y,x). 3872 3873 Most users should employ the simplified KSP interface for linear solvers 3874 instead of working directly with matrix algebra routines such as this. 3875 See, e.g., KSPCreate(). 3876 3877 Level: developer 3878 3879 .seealso: `MatSolve()`, `MatSolveTranspose()`, `MatSolveTransposeAdd()` 3880 @*/ 3881 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x) 3882 { 3883 PetscScalar one = 1.0; 3884 Vec tmp; 3885 3886 PetscFunctionBegin; 3887 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3888 PetscValidType(mat,1); 3889 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 3890 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3891 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 3892 PetscCheckSameComm(mat,1,b,2); 3893 PetscCheckSameComm(mat,1,y,3); 3894 PetscCheckSameComm(mat,1,x,4); 3895 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3896 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); 3897 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); 3898 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); 3899 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); 3900 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); 3901 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3902 MatCheckPreallocated(mat,1); 3903 3904 PetscCall(PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y)); 3905 if (mat->factorerrortype) { 3906 3907 PetscCall(PetscInfo(mat,"MatFactorError %d\n",mat->factorerrortype)); 3908 PetscCall(VecSetInf(x)); 3909 } else if (mat->ops->solveadd) { 3910 PetscUseTypeMethod(mat,solveadd ,b,y,x); 3911 } else { 3912 /* do the solve then the add manually */ 3913 if (x != y) { 3914 PetscCall(MatSolve(mat,b,x)); 3915 PetscCall(VecAXPY(x,one,y)); 3916 } else { 3917 PetscCall(VecDuplicate(x,&tmp)); 3918 PetscCall(PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp)); 3919 PetscCall(VecCopy(x,tmp)); 3920 PetscCall(MatSolve(mat,b,x)); 3921 PetscCall(VecAXPY(x,one,tmp)); 3922 PetscCall(VecDestroy(&tmp)); 3923 } 3924 } 3925 PetscCall(PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y)); 3926 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3927 PetscFunctionReturn(0); 3928 } 3929 3930 /*@ 3931 MatSolveTranspose - Solves A' x = b, given a factored matrix. 3932 3933 Neighbor-wise Collective on Mat 3934 3935 Input Parameters: 3936 + mat - the factored matrix 3937 - b - the right-hand-side vector 3938 3939 Output Parameter: 3940 . x - the result vector 3941 3942 Notes: 3943 The vectors b and x cannot be the same. I.e., one cannot 3944 call MatSolveTranspose(A,x,x). 3945 3946 Most users should employ the simplified KSP interface for linear solvers 3947 instead of working directly with matrix algebra routines such as this. 3948 See, e.g., KSPCreate(). 3949 3950 Level: developer 3951 3952 .seealso: `MatSolve()`, `MatSolveAdd()`, `MatSolveTransposeAdd()` 3953 @*/ 3954 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x) 3955 { 3956 PetscErrorCode (*f)(Mat,Vec,Vec) = (!mat->ops->solvetranspose && mat->symmetric) ? mat->ops->solve : mat->ops->solvetranspose; 3957 3958 PetscFunctionBegin; 3959 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3960 PetscValidType(mat,1); 3961 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3962 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3963 PetscCheckSameComm(mat,1,b,2); 3964 PetscCheckSameComm(mat,1,x,3); 3965 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3966 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); 3967 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); 3968 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3969 MatCheckPreallocated(mat,1); 3970 PetscCall(PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0)); 3971 if (mat->factorerrortype) { 3972 PetscCall(PetscInfo(mat,"MatFactorError %d\n",mat->factorerrortype)); 3973 PetscCall(VecSetInf(x)); 3974 } else { 3975 PetscCheck(f,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name); 3976 PetscCall((*f)(mat,b,x)); 3977 } 3978 PetscCall(PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0)); 3979 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3980 PetscFunctionReturn(0); 3981 } 3982 3983 /*@ 3984 MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a 3985 factored matrix. 3986 3987 Neighbor-wise Collective on Mat 3988 3989 Input Parameters: 3990 + mat - the factored matrix 3991 . b - the right-hand-side vector 3992 - y - the vector to be added to 3993 3994 Output Parameter: 3995 . x - the result vector 3996 3997 Notes: 3998 The vectors b and x cannot be the same. I.e., one cannot 3999 call MatSolveTransposeAdd(A,x,y,x). 4000 4001 Most users should employ the simplified KSP interface for linear solvers 4002 instead of working directly with matrix algebra routines such as this. 4003 See, e.g., KSPCreate(). 4004 4005 Level: developer 4006 4007 .seealso: `MatSolve()`, `MatSolveAdd()`, `MatSolveTranspose()` 4008 @*/ 4009 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x) 4010 { 4011 PetscScalar one = 1.0; 4012 Vec tmp; 4013 PetscErrorCode (*f)(Mat,Vec,Vec,Vec) = (!mat->ops->solvetransposeadd && mat->symmetric) ? mat->ops->solveadd : mat->ops->solvetransposeadd; 4014 4015 PetscFunctionBegin; 4016 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4017 PetscValidType(mat,1); 4018 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 4019 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 4020 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 4021 PetscCheckSameComm(mat,1,b,2); 4022 PetscCheckSameComm(mat,1,y,3); 4023 PetscCheckSameComm(mat,1,x,4); 4024 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 4025 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); 4026 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); 4027 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); 4028 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); 4029 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 4030 MatCheckPreallocated(mat,1); 4031 4032 PetscCall(PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y)); 4033 if (mat->factorerrortype) { 4034 PetscCall(PetscInfo(mat,"MatFactorError %d\n",mat->factorerrortype)); 4035 PetscCall(VecSetInf(x)); 4036 } else if (f) { 4037 PetscCall((*f)(mat,b,y,x)); 4038 } else { 4039 /* do the solve then the add manually */ 4040 if (x != y) { 4041 PetscCall(MatSolveTranspose(mat,b,x)); 4042 PetscCall(VecAXPY(x,one,y)); 4043 } else { 4044 PetscCall(VecDuplicate(x,&tmp)); 4045 PetscCall(PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp)); 4046 PetscCall(VecCopy(x,tmp)); 4047 PetscCall(MatSolveTranspose(mat,b,x)); 4048 PetscCall(VecAXPY(x,one,tmp)); 4049 PetscCall(VecDestroy(&tmp)); 4050 } 4051 } 4052 PetscCall(PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y)); 4053 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 4054 PetscFunctionReturn(0); 4055 } 4056 /* ----------------------------------------------------------------*/ 4057 4058 /*@ 4059 MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps. 4060 4061 Neighbor-wise Collective on Mat 4062 4063 Input Parameters: 4064 + mat - the matrix 4065 . b - the right hand side 4066 . omega - the relaxation factor 4067 . flag - flag indicating the type of SOR (see below) 4068 . shift - diagonal shift 4069 . its - the number of iterations 4070 - lits - the number of local iterations 4071 4072 Output Parameter: 4073 . x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess) 4074 4075 SOR Flags: 4076 + SOR_FORWARD_SWEEP - forward SOR 4077 . SOR_BACKWARD_SWEEP - backward SOR 4078 . SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR) 4079 . SOR_LOCAL_FORWARD_SWEEP - local forward SOR 4080 . SOR_LOCAL_BACKWARD_SWEEP - local forward SOR 4081 . SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR 4082 . SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies 4083 upper/lower triangular part of matrix to 4084 vector (with omega) 4085 - SOR_ZERO_INITIAL_GUESS - zero initial guess 4086 4087 Notes: 4088 SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and 4089 SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings 4090 on each processor. 4091 4092 Application programmers will not generally use MatSOR() directly, 4093 but instead will employ the KSP/PC interface. 4094 4095 Notes: 4096 for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing 4097 4098 Notes for Advanced Users: 4099 The flags are implemented as bitwise inclusive or operations. 4100 For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP) 4101 to specify a zero initial guess for SSOR. 4102 4103 Most users should employ the simplified KSP interface for linear solvers 4104 instead of working directly with matrix algebra routines such as this. 4105 See, e.g., KSPCreate(). 4106 4107 Vectors x and b CANNOT be the same 4108 4109 Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes 4110 4111 Level: developer 4112 4113 @*/ 4114 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x) 4115 { 4116 PetscFunctionBegin; 4117 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4118 PetscValidType(mat,1); 4119 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 4120 PetscValidHeaderSpecific(x,VEC_CLASSID,8); 4121 PetscCheckSameComm(mat,1,b,2); 4122 PetscCheckSameComm(mat,1,x,8); 4123 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4124 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4125 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); 4126 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); 4127 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); 4128 PetscCheck(its > 0,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %" PetscInt_FMT " positive",its); 4129 PetscCheck(lits > 0,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %" PetscInt_FMT " positive",lits); 4130 PetscCheck(b != x,PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same"); 4131 4132 MatCheckPreallocated(mat,1); 4133 PetscCall(PetscLogEventBegin(MAT_SOR,mat,b,x,0)); 4134 PetscUseTypeMethod(mat,sor ,b,omega,flag,shift,its,lits,x); 4135 PetscCall(PetscLogEventEnd(MAT_SOR,mat,b,x,0)); 4136 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 4137 PetscFunctionReturn(0); 4138 } 4139 4140 /* 4141 Default matrix copy routine. 4142 */ 4143 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str) 4144 { 4145 PetscInt i,rstart = 0,rend = 0,nz; 4146 const PetscInt *cwork; 4147 const PetscScalar *vwork; 4148 4149 PetscFunctionBegin; 4150 if (B->assembled) PetscCall(MatZeroEntries(B)); 4151 if (str == SAME_NONZERO_PATTERN) { 4152 PetscCall(MatGetOwnershipRange(A,&rstart,&rend)); 4153 for (i=rstart; i<rend; i++) { 4154 PetscCall(MatGetRow(A,i,&nz,&cwork,&vwork)); 4155 PetscCall(MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES)); 4156 PetscCall(MatRestoreRow(A,i,&nz,&cwork,&vwork)); 4157 } 4158 } else { 4159 PetscCall(MatAYPX(B,0.0,A,str)); 4160 } 4161 PetscCall(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY)); 4162 PetscCall(MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY)); 4163 PetscFunctionReturn(0); 4164 } 4165 4166 /*@ 4167 MatCopy - Copies a matrix to another matrix. 4168 4169 Collective on Mat 4170 4171 Input Parameters: 4172 + A - the matrix 4173 - str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN 4174 4175 Output Parameter: 4176 . B - where the copy is put 4177 4178 Notes: 4179 If you use SAME_NONZERO_PATTERN then the two matrices must have the same nonzero pattern or the routine will crash. 4180 4181 MatCopy() copies the matrix entries of a matrix to another existing 4182 matrix (after first zeroing the second matrix). A related routine is 4183 MatConvert(), which first creates a new matrix and then copies the data. 4184 4185 Level: intermediate 4186 4187 .seealso: `MatConvert()`, `MatDuplicate()` 4188 @*/ 4189 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str) 4190 { 4191 PetscInt i; 4192 4193 PetscFunctionBegin; 4194 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4195 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4196 PetscValidType(A,1); 4197 PetscValidType(B,2); 4198 PetscCheckSameComm(A,1,B,2); 4199 MatCheckPreallocated(B,2); 4200 PetscCheck(A->assembled,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4201 PetscCheck(!A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4202 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); 4203 MatCheckPreallocated(A,1); 4204 if (A == B) PetscFunctionReturn(0); 4205 4206 PetscCall(PetscLogEventBegin(MAT_Copy,A,B,0,0)); 4207 if (A->ops->copy) PetscUseTypeMethod(A,copy ,B,str); 4208 else PetscCall(MatCopy_Basic(A,B,str)); 4209 4210 B->stencil.dim = A->stencil.dim; 4211 B->stencil.noc = A->stencil.noc; 4212 for (i=0; i<=A->stencil.dim; i++) { 4213 B->stencil.dims[i] = A->stencil.dims[i]; 4214 B->stencil.starts[i] = A->stencil.starts[i]; 4215 } 4216 4217 PetscCall(PetscLogEventEnd(MAT_Copy,A,B,0,0)); 4218 PetscCall(PetscObjectStateIncrease((PetscObject)B)); 4219 PetscFunctionReturn(0); 4220 } 4221 4222 /*@C 4223 MatConvert - Converts a matrix to another matrix, either of the same 4224 or different type. 4225 4226 Collective on Mat 4227 4228 Input Parameters: 4229 + mat - the matrix 4230 . newtype - new matrix type. Use MATSAME to create a new matrix of the 4231 same type as the original matrix. 4232 - reuse - denotes if the destination matrix is to be created or reused. 4233 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 4234 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). 4235 4236 Output Parameter: 4237 . M - pointer to place new matrix 4238 4239 Notes: 4240 MatConvert() first creates a new matrix and then copies the data from 4241 the first matrix. A related routine is MatCopy(), which copies the matrix 4242 entries of one matrix to another already existing matrix context. 4243 4244 Cannot be used to convert a sequential matrix to parallel or parallel to sequential, 4245 the MPI communicator of the generated matrix is always the same as the communicator 4246 of the input matrix. 4247 4248 Level: intermediate 4249 4250 .seealso: `MatCopy()`, `MatDuplicate()` 4251 @*/ 4252 PetscErrorCode MatConvert(Mat mat,MatType newtype,MatReuse reuse,Mat *M) 4253 { 4254 PetscBool sametype,issame,flg; 4255 PetscBool3 issymmetric,ishermitian; 4256 char convname[256],mtype[256]; 4257 Mat B; 4258 4259 PetscFunctionBegin; 4260 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4261 PetscValidType(mat,1); 4262 PetscValidPointer(M,4); 4263 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4264 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4265 MatCheckPreallocated(mat,1); 4266 4267 PetscCall(PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,sizeof(mtype),&flg)); 4268 if (flg) newtype = mtype; 4269 4270 PetscCall(PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype)); 4271 PetscCall(PetscStrcmp(newtype,"same",&issame)); 4272 PetscCheck(!(reuse == MAT_INPLACE_MATRIX) || !(mat != *M),PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix"); 4273 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"); 4274 4275 if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) { 4276 PetscCall(PetscInfo(mat,"Early return for inplace %s %d %d\n",((PetscObject)mat)->type_name,sametype,issame)); 4277 PetscFunctionReturn(0); 4278 } 4279 4280 /* Cache Mat options because some converters use MatHeaderReplace */ 4281 issymmetric = mat->symmetric; 4282 ishermitian = mat->hermitian; 4283 4284 if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) { 4285 PetscCall(PetscInfo(mat,"Calling duplicate for initial matrix %s %d %d\n",((PetscObject)mat)->type_name,sametype,issame)); 4286 PetscUseTypeMethod(mat,duplicate ,MAT_COPY_VALUES,M); 4287 } else { 4288 PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL; 4289 const char *prefix[3] = {"seq","mpi",""}; 4290 PetscInt i; 4291 /* 4292 Order of precedence: 4293 0) See if newtype is a superclass of the current matrix. 4294 1) See if a specialized converter is known to the current matrix. 4295 2) See if a specialized converter is known to the desired matrix class. 4296 3) See if a good general converter is registered for the desired class 4297 (as of 6/27/03 only MATMPIADJ falls into this category). 4298 4) See if a good general converter is known for the current matrix. 4299 5) Use a really basic converter. 4300 */ 4301 4302 /* 0) See if newtype is a superclass of the current matrix. 4303 i.e mat is mpiaij and newtype is aij */ 4304 for (i=0; i<2; i++) { 4305 PetscCall(PetscStrncpy(convname,prefix[i],sizeof(convname))); 4306 PetscCall(PetscStrlcat(convname,newtype,sizeof(convname))); 4307 PetscCall(PetscStrcmp(convname,((PetscObject)mat)->type_name,&flg)); 4308 PetscCall(PetscInfo(mat,"Check superclass %s %s -> %d\n",convname,((PetscObject)mat)->type_name,flg)); 4309 if (flg) { 4310 if (reuse == MAT_INPLACE_MATRIX) { 4311 PetscCall(PetscInfo(mat,"Early return\n")); 4312 PetscFunctionReturn(0); 4313 } else if (reuse == MAT_INITIAL_MATRIX && mat->ops->duplicate) { 4314 PetscCall(PetscInfo(mat,"Calling MatDuplicate\n")); 4315 PetscUseTypeMethod(mat,duplicate ,MAT_COPY_VALUES,M); 4316 PetscFunctionReturn(0); 4317 } else if (reuse == MAT_REUSE_MATRIX && mat->ops->copy) { 4318 PetscCall(PetscInfo(mat,"Calling MatCopy\n")); 4319 PetscCall(MatCopy(mat,*M,SAME_NONZERO_PATTERN)); 4320 PetscFunctionReturn(0); 4321 } 4322 } 4323 } 4324 /* 1) See if a specialized converter is known to the current matrix and the desired class */ 4325 for (i=0; i<3; i++) { 4326 PetscCall(PetscStrncpy(convname,"MatConvert_",sizeof(convname))); 4327 PetscCall(PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname))); 4328 PetscCall(PetscStrlcat(convname,"_",sizeof(convname))); 4329 PetscCall(PetscStrlcat(convname,prefix[i],sizeof(convname))); 4330 PetscCall(PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname))); 4331 PetscCall(PetscStrlcat(convname,"_C",sizeof(convname))); 4332 PetscCall(PetscObjectQueryFunction((PetscObject)mat,convname,&conv)); 4333 PetscCall(PetscInfo(mat,"Check specialized (1) %s (%s) -> %d\n",convname,((PetscObject)mat)->type_name,!!conv)); 4334 if (conv) goto foundconv; 4335 } 4336 4337 /* 2) See if a specialized converter is known to the desired matrix class. */ 4338 PetscCall(MatCreate(PetscObjectComm((PetscObject)mat),&B)); 4339 PetscCall(MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N)); 4340 PetscCall(MatSetType(B,newtype)); 4341 for (i=0; i<3; i++) { 4342 PetscCall(PetscStrncpy(convname,"MatConvert_",sizeof(convname))); 4343 PetscCall(PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname))); 4344 PetscCall(PetscStrlcat(convname,"_",sizeof(convname))); 4345 PetscCall(PetscStrlcat(convname,prefix[i],sizeof(convname))); 4346 PetscCall(PetscStrlcat(convname,newtype,sizeof(convname))); 4347 PetscCall(PetscStrlcat(convname,"_C",sizeof(convname))); 4348 PetscCall(PetscObjectQueryFunction((PetscObject)B,convname,&conv)); 4349 PetscCall(PetscInfo(mat,"Check specialized (2) %s (%s) -> %d\n",convname,((PetscObject)B)->type_name,!!conv)); 4350 if (conv) { 4351 PetscCall(MatDestroy(&B)); 4352 goto foundconv; 4353 } 4354 } 4355 4356 /* 3) See if a good general converter is registered for the desired class */ 4357 conv = B->ops->convertfrom; 4358 PetscCall(PetscInfo(mat,"Check convertfrom (%s) -> %d\n",((PetscObject)B)->type_name,!!conv)); 4359 PetscCall(MatDestroy(&B)); 4360 if (conv) goto foundconv; 4361 4362 /* 4) See if a good general converter is known for the current matrix */ 4363 if (mat->ops->convert) conv = mat->ops->convert; 4364 PetscCall(PetscInfo(mat,"Check general convert (%s) -> %d\n",((PetscObject)mat)->type_name,!!conv)); 4365 if (conv) goto foundconv; 4366 4367 /* 5) Use a really basic converter. */ 4368 PetscCall(PetscInfo(mat,"Using MatConvert_Basic\n")); 4369 conv = MatConvert_Basic; 4370 4371 foundconv: 4372 PetscCall(PetscLogEventBegin(MAT_Convert,mat,0,0,0)); 4373 PetscCall((*conv)(mat,newtype,reuse,M)); 4374 if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) { 4375 /* the block sizes must be same if the mappings are copied over */ 4376 (*M)->rmap->bs = mat->rmap->bs; 4377 (*M)->cmap->bs = mat->cmap->bs; 4378 PetscCall(PetscObjectReference((PetscObject)mat->rmap->mapping)); 4379 PetscCall(PetscObjectReference((PetscObject)mat->cmap->mapping)); 4380 (*M)->rmap->mapping = mat->rmap->mapping; 4381 (*M)->cmap->mapping = mat->cmap->mapping; 4382 } 4383 (*M)->stencil.dim = mat->stencil.dim; 4384 (*M)->stencil.noc = mat->stencil.noc; 4385 for (i=0; i<=mat->stencil.dim; i++) { 4386 (*M)->stencil.dims[i] = mat->stencil.dims[i]; 4387 (*M)->stencil.starts[i] = mat->stencil.starts[i]; 4388 } 4389 PetscCall(PetscLogEventEnd(MAT_Convert,mat,0,0,0)); 4390 } 4391 PetscCall(PetscObjectStateIncrease((PetscObject)*M)); 4392 4393 /* Copy Mat options */ 4394 if (issymmetric == PETSC_BOOL3_TRUE) PetscCall(MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE)); 4395 else if (issymmetric == PETSC_BOOL3_FALSE) PetscCall(MatSetOption(*M,MAT_SYMMETRIC,PETSC_FALSE)); 4396 if (ishermitian == PETSC_BOOL3_TRUE) PetscCall(MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE)); 4397 else if (ishermitian == PETSC_BOOL3_FALSE) PetscCall(MatSetOption(*M,MAT_HERMITIAN,PETSC_FALSE)); 4398 PetscFunctionReturn(0); 4399 } 4400 4401 /*@C 4402 MatFactorGetSolverType - Returns name of the package providing the factorization routines 4403 4404 Not Collective 4405 4406 Input Parameter: 4407 . mat - the matrix, must be a factored matrix 4408 4409 Output Parameter: 4410 . type - the string name of the package (do not free this string) 4411 4412 Notes: 4413 In Fortran you pass in a empty string and the package name will be copied into it. 4414 (Make sure the string is long enough) 4415 4416 Level: intermediate 4417 4418 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()` 4419 @*/ 4420 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type) 4421 { 4422 PetscErrorCode (*conv)(Mat,MatSolverType*); 4423 4424 PetscFunctionBegin; 4425 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4426 PetscValidType(mat,1); 4427 PetscValidPointer(type,2); 4428 PetscCheck(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 4429 PetscCall(PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv)); 4430 if (conv) PetscCall((*conv)(mat,type)); 4431 else *type = MATSOLVERPETSC; 4432 PetscFunctionReturn(0); 4433 } 4434 4435 typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType; 4436 struct _MatSolverTypeForSpecifcType { 4437 MatType mtype; 4438 /* no entry for MAT_FACTOR_NONE */ 4439 PetscErrorCode (*createfactor[MAT_FACTOR_NUM_TYPES-1])(Mat,MatFactorType,Mat*); 4440 MatSolverTypeForSpecifcType next; 4441 }; 4442 4443 typedef struct _MatSolverTypeHolder* MatSolverTypeHolder; 4444 struct _MatSolverTypeHolder { 4445 char *name; 4446 MatSolverTypeForSpecifcType handlers; 4447 MatSolverTypeHolder next; 4448 }; 4449 4450 static MatSolverTypeHolder MatSolverTypeHolders = NULL; 4451 4452 /*@C 4453 MatSolverTypeRegister - Registers a MatSolverType that works for a particular matrix type 4454 4455 Input Parameters: 4456 + package - name of the package, for example petsc or superlu 4457 . mtype - the matrix type that works with this package 4458 . ftype - the type of factorization supported by the package 4459 - createfactor - routine that will create the factored matrix ready to be used 4460 4461 Level: intermediate 4462 4463 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()` 4464 @*/ 4465 PetscErrorCode MatSolverTypeRegister(MatSolverType package,MatType mtype,MatFactorType ftype,PetscErrorCode (*createfactor)(Mat,MatFactorType,Mat*)) 4466 { 4467 MatSolverTypeHolder next = MatSolverTypeHolders,prev = NULL; 4468 PetscBool flg; 4469 MatSolverTypeForSpecifcType inext,iprev = NULL; 4470 4471 PetscFunctionBegin; 4472 PetscCall(MatInitializePackage()); 4473 if (!next) { 4474 PetscCall(PetscNew(&MatSolverTypeHolders)); 4475 PetscCall(PetscStrallocpy(package,&MatSolverTypeHolders->name)); 4476 PetscCall(PetscNew(&MatSolverTypeHolders->handlers)); 4477 PetscCall(PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype)); 4478 MatSolverTypeHolders->handlers->createfactor[(int)ftype-1] = createfactor; 4479 PetscFunctionReturn(0); 4480 } 4481 while (next) { 4482 PetscCall(PetscStrcasecmp(package,next->name,&flg)); 4483 if (flg) { 4484 PetscCheck(next->handlers,PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers"); 4485 inext = next->handlers; 4486 while (inext) { 4487 PetscCall(PetscStrcasecmp(mtype,inext->mtype,&flg)); 4488 if (flg) { 4489 inext->createfactor[(int)ftype-1] = createfactor; 4490 PetscFunctionReturn(0); 4491 } 4492 iprev = inext; 4493 inext = inext->next; 4494 } 4495 PetscCall(PetscNew(&iprev->next)); 4496 PetscCall(PetscStrallocpy(mtype,(char **)&iprev->next->mtype)); 4497 iprev->next->createfactor[(int)ftype-1] = createfactor; 4498 PetscFunctionReturn(0); 4499 } 4500 prev = next; 4501 next = next->next; 4502 } 4503 PetscCall(PetscNew(&prev->next)); 4504 PetscCall(PetscStrallocpy(package,&prev->next->name)); 4505 PetscCall(PetscNew(&prev->next->handlers)); 4506 PetscCall(PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype)); 4507 prev->next->handlers->createfactor[(int)ftype-1] = createfactor; 4508 PetscFunctionReturn(0); 4509 } 4510 4511 /*@C 4512 MatSolverTypeGet - Gets the function that creates the factor matrix if it exist 4513 4514 Input Parameters: 4515 + type - name of the package, for example petsc or superlu 4516 . ftype - the type of factorization supported by the type 4517 - mtype - the matrix type that works with this type 4518 4519 Output Parameters: 4520 + foundtype - PETSC_TRUE if the type was registered 4521 . foundmtype - PETSC_TRUE if the type supports the requested mtype 4522 - createfactor - routine that will create the factored matrix ready to be used or NULL if not found 4523 4524 Level: intermediate 4525 4526 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatSolverTypeRegister()`, `MatGetFactor()` 4527 @*/ 4528 PetscErrorCode MatSolverTypeGet(MatSolverType type,MatType mtype,MatFactorType ftype,PetscBool *foundtype,PetscBool *foundmtype,PetscErrorCode (**createfactor)(Mat,MatFactorType,Mat*)) 4529 { 4530 MatSolverTypeHolder next = MatSolverTypeHolders; 4531 PetscBool flg; 4532 MatSolverTypeForSpecifcType inext; 4533 4534 PetscFunctionBegin; 4535 if (foundtype) *foundtype = PETSC_FALSE; 4536 if (foundmtype) *foundmtype = PETSC_FALSE; 4537 if (createfactor) *createfactor = NULL; 4538 4539 if (type) { 4540 while (next) { 4541 PetscCall(PetscStrcasecmp(type,next->name,&flg)); 4542 if (flg) { 4543 if (foundtype) *foundtype = PETSC_TRUE; 4544 inext = next->handlers; 4545 while (inext) { 4546 PetscCall(PetscStrbeginswith(mtype,inext->mtype,&flg)); 4547 if (flg) { 4548 if (foundmtype) *foundmtype = PETSC_TRUE; 4549 if (createfactor) *createfactor = inext->createfactor[(int)ftype-1]; 4550 PetscFunctionReturn(0); 4551 } 4552 inext = inext->next; 4553 } 4554 } 4555 next = next->next; 4556 } 4557 } else { 4558 while (next) { 4559 inext = next->handlers; 4560 while (inext) { 4561 PetscCall(PetscStrcmp(mtype,inext->mtype,&flg)); 4562 if (flg && inext->createfactor[(int)ftype-1]) { 4563 if (foundtype) *foundtype = PETSC_TRUE; 4564 if (foundmtype) *foundmtype = PETSC_TRUE; 4565 if (createfactor) *createfactor = inext->createfactor[(int)ftype-1]; 4566 PetscFunctionReturn(0); 4567 } 4568 inext = inext->next; 4569 } 4570 next = next->next; 4571 } 4572 /* try with base classes inext->mtype */ 4573 next = MatSolverTypeHolders; 4574 while (next) { 4575 inext = next->handlers; 4576 while (inext) { 4577 PetscCall(PetscStrbeginswith(mtype,inext->mtype,&flg)); 4578 if (flg && inext->createfactor[(int)ftype-1]) { 4579 if (foundtype) *foundtype = PETSC_TRUE; 4580 if (foundmtype) *foundmtype = PETSC_TRUE; 4581 if (createfactor) *createfactor = inext->createfactor[(int)ftype-1]; 4582 PetscFunctionReturn(0); 4583 } 4584 inext = inext->next; 4585 } 4586 next = next->next; 4587 } 4588 } 4589 PetscFunctionReturn(0); 4590 } 4591 4592 PetscErrorCode MatSolverTypeDestroy(void) 4593 { 4594 MatSolverTypeHolder next = MatSolverTypeHolders,prev; 4595 MatSolverTypeForSpecifcType inext,iprev; 4596 4597 PetscFunctionBegin; 4598 while (next) { 4599 PetscCall(PetscFree(next->name)); 4600 inext = next->handlers; 4601 while (inext) { 4602 PetscCall(PetscFree(inext->mtype)); 4603 iprev = inext; 4604 inext = inext->next; 4605 PetscCall(PetscFree(iprev)); 4606 } 4607 prev = next; 4608 next = next->next; 4609 PetscCall(PetscFree(prev)); 4610 } 4611 MatSolverTypeHolders = NULL; 4612 PetscFunctionReturn(0); 4613 } 4614 4615 /*@C 4616 MatFactorGetCanUseOrdering - Indicates if the factorization can use the ordering provided in MatLUFactorSymbolic(), MatCholeskyFactorSymbolic() 4617 4618 Logically Collective on Mat 4619 4620 Input Parameters: 4621 . mat - the matrix 4622 4623 Output Parameters: 4624 . flg - PETSC_TRUE if uses the ordering 4625 4626 Notes: 4627 Most internal PETSc factorizations use the ordering passed to the factorization routine but external 4628 packages do not, thus we want to skip generating the ordering when it is not needed or used. 4629 4630 Level: developer 4631 4632 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()` 4633 @*/ 4634 PetscErrorCode MatFactorGetCanUseOrdering(Mat mat, PetscBool *flg) 4635 { 4636 PetscFunctionBegin; 4637 *flg = mat->canuseordering; 4638 PetscFunctionReturn(0); 4639 } 4640 4641 /*@C 4642 MatFactorGetPreferredOrdering - The preferred ordering for a particular matrix factor object 4643 4644 Logically Collective on Mat 4645 4646 Input Parameters: 4647 . mat - the matrix 4648 4649 Output Parameters: 4650 . otype - the preferred type 4651 4652 Level: developer 4653 4654 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()` 4655 @*/ 4656 PetscErrorCode MatFactorGetPreferredOrdering(Mat mat, MatFactorType ftype, MatOrderingType *otype) 4657 { 4658 PetscFunctionBegin; 4659 *otype = mat->preferredordering[ftype]; 4660 PetscCheck(*otype,PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatFactor did not have a preferred ordering"); 4661 PetscFunctionReturn(0); 4662 } 4663 4664 /*@C 4665 MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic() 4666 4667 Collective on Mat 4668 4669 Input Parameters: 4670 + mat - the matrix 4671 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4672 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4673 4674 Output Parameters: 4675 . f - the factor matrix used with MatXXFactorSymbolic() calls 4676 4677 Options Database Key: 4678 . -mat_factor_bind_factorization <host, device> - Where to do matrix factorization? Default is device (might consume more device memory. 4679 One can choose host to save device memory). Currently only supported with SEQAIJCUSPARSE matrices. 4680 4681 Notes: 4682 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4683 such as pastix, superlu, mumps etc. 4684 4685 PETSc must have been ./configure to use the external solver, using the option --download-package 4686 4687 Some of the packages have options for controlling the factorization, these are in the form -prefix_mat_packagename_packageoption 4688 where prefix is normally obtained from the calling `KSP`/`PC`. If `MatGetFactor()` is called directly one can set 4689 call `MatSetOptionsPrefixFactor()` on the originating matrix or `MatSetOptionsPrefix()` on the resulting factor matrix. 4690 4691 Developer Notes: 4692 This should actually be called MatCreateFactor() since it creates a new factor object 4693 4694 Level: intermediate 4695 4696 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatFactorGetCanUseOrdering()`, `MatSolverTypeRegister()` 4697 @*/ 4698 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f) 4699 { 4700 PetscBool foundtype,foundmtype; 4701 PetscErrorCode (*conv)(Mat,MatFactorType,Mat*); 4702 4703 PetscFunctionBegin; 4704 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4705 PetscValidType(mat,1); 4706 4707 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4708 MatCheckPreallocated(mat,1); 4709 4710 PetscCall(MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundtype,&foundmtype,&conv)); 4711 if (!foundtype) { 4712 if (type) { 4713 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); 4714 } else { 4715 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); 4716 } 4717 } 4718 PetscCheck(foundmtype,PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name); 4719 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); 4720 4721 PetscCall((*conv)(mat,ftype,f)); 4722 if (mat->factorprefix) PetscCall(MatSetOptionsPrefix(*f,mat->factorprefix)); 4723 PetscFunctionReturn(0); 4724 } 4725 4726 /*@C 4727 MatGetFactorAvailable - Returns a a flag if matrix supports particular type and factor type 4728 4729 Not Collective 4730 4731 Input Parameters: 4732 + mat - the matrix 4733 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4734 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4735 4736 Output Parameter: 4737 . flg - PETSC_TRUE if the factorization is available 4738 4739 Notes: 4740 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4741 such as pastix, superlu, mumps etc. 4742 4743 PETSc must have been ./configure to use the external solver, using the option --download-package 4744 4745 Developer Notes: 4746 This should actually be called MatCreateFactorAvailable() since MatGetFactor() creates a new factor object 4747 4748 Level: intermediate 4749 4750 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactor()`, `MatSolverTypeRegister()` 4751 @*/ 4752 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool *flg) 4753 { 4754 PetscErrorCode (*gconv)(Mat,MatFactorType,Mat*); 4755 4756 PetscFunctionBegin; 4757 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4758 PetscValidType(mat,1); 4759 PetscValidBoolPointer(flg,4); 4760 4761 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4762 MatCheckPreallocated(mat,1); 4763 4764 PetscCall(MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv)); 4765 *flg = gconv ? PETSC_TRUE : PETSC_FALSE; 4766 PetscFunctionReturn(0); 4767 } 4768 4769 /*@ 4770 MatDuplicate - Duplicates a matrix including the non-zero structure. 4771 4772 Collective on Mat 4773 4774 Input Parameters: 4775 + mat - the matrix 4776 - op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN. 4777 See the manual page for MatDuplicateOption for an explanation of these options. 4778 4779 Output Parameter: 4780 . M - pointer to place new matrix 4781 4782 Level: intermediate 4783 4784 Notes: 4785 You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN. 4786 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. 4787 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. 4788 4789 .seealso: `MatCopy()`, `MatConvert()`, `MatDuplicateOption` 4790 @*/ 4791 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M) 4792 { 4793 Mat B; 4794 VecType vtype; 4795 PetscInt i; 4796 PetscObject dm; 4797 void (*viewf)(void); 4798 4799 PetscFunctionBegin; 4800 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4801 PetscValidType(mat,1); 4802 PetscValidPointer(M,3); 4803 PetscCheck(op != MAT_COPY_VALUES || mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix"); 4804 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4805 MatCheckPreallocated(mat,1); 4806 4807 *M = NULL; 4808 PetscCall(PetscLogEventBegin(MAT_Convert,mat,0,0,0)); 4809 PetscUseTypeMethod(mat,duplicate ,op,M); 4810 PetscCall(PetscLogEventEnd(MAT_Convert,mat,0,0,0)); 4811 B = *M; 4812 4813 PetscCall(MatGetOperation(mat,MATOP_VIEW,&viewf)); 4814 if (viewf) PetscCall(MatSetOperation(B,MATOP_VIEW,viewf)); 4815 PetscCall(MatGetVecType(mat,&vtype)); 4816 PetscCall(MatSetVecType(B,vtype)); 4817 4818 B->stencil.dim = mat->stencil.dim; 4819 B->stencil.noc = mat->stencil.noc; 4820 for (i=0; i<=mat->stencil.dim; i++) { 4821 B->stencil.dims[i] = mat->stencil.dims[i]; 4822 B->stencil.starts[i] = mat->stencil.starts[i]; 4823 } 4824 4825 B->nooffproczerorows = mat->nooffproczerorows; 4826 B->nooffprocentries = mat->nooffprocentries; 4827 4828 PetscCall(PetscObjectQuery((PetscObject) mat, "__PETSc_dm", &dm)); 4829 if (dm) { 4830 PetscCall(PetscObjectCompose((PetscObject) B, "__PETSc_dm", dm)); 4831 } 4832 PetscCall(PetscObjectStateIncrease((PetscObject)B)); 4833 PetscFunctionReturn(0); 4834 } 4835 4836 /*@ 4837 MatGetDiagonal - Gets the diagonal of a matrix. 4838 4839 Logically Collective on Mat 4840 4841 Input Parameters: 4842 + mat - the matrix 4843 - v - the vector for storing the diagonal 4844 4845 Output Parameter: 4846 . v - the diagonal of the matrix 4847 4848 Level: intermediate 4849 4850 Note: 4851 Currently only correct in parallel for square matrices. 4852 4853 .seealso: `MatGetRow()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMaxAbs()` 4854 @*/ 4855 PetscErrorCode MatGetDiagonal(Mat mat,Vec v) 4856 { 4857 PetscFunctionBegin; 4858 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4859 PetscValidType(mat,1); 4860 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4861 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4862 MatCheckPreallocated(mat,1); 4863 4864 PetscUseTypeMethod(mat,getdiagonal ,v); 4865 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 4866 PetscFunctionReturn(0); 4867 } 4868 4869 /*@C 4870 MatGetRowMin - Gets the minimum value (of the real part) of each 4871 row of the matrix 4872 4873 Logically Collective on Mat 4874 4875 Input Parameter: 4876 . mat - the matrix 4877 4878 Output Parameters: 4879 + v - the vector for storing the maximums 4880 - idx - the indices of the column found for each row (optional) 4881 4882 Level: intermediate 4883 4884 Notes: 4885 The result of this call are the same as if one converted the matrix to dense format 4886 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4887 4888 This code is only implemented for a couple of matrix formats. 4889 4890 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMaxAbs()`, 4891 `MatGetRowMax()` 4892 @*/ 4893 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[]) 4894 { 4895 PetscFunctionBegin; 4896 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4897 PetscValidType(mat,1); 4898 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4899 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4900 4901 if (!mat->cmap->N) { 4902 PetscCall(VecSet(v,PETSC_MAX_REAL)); 4903 if (idx) { 4904 PetscInt i,m = mat->rmap->n; 4905 for (i=0; i<m; i++) idx[i] = -1; 4906 } 4907 } else { 4908 MatCheckPreallocated(mat,1); 4909 } 4910 PetscUseTypeMethod(mat,getrowmin ,v,idx); 4911 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 4912 PetscFunctionReturn(0); 4913 } 4914 4915 /*@C 4916 MatGetRowMinAbs - Gets the minimum value (in absolute value) of each 4917 row of the matrix 4918 4919 Logically Collective on Mat 4920 4921 Input Parameter: 4922 . mat - the matrix 4923 4924 Output Parameters: 4925 + v - the vector for storing the minimums 4926 - idx - the indices of the column found for each row (or NULL if not needed) 4927 4928 Level: intermediate 4929 4930 Notes: 4931 if a row is completely empty or has only 0.0 values then the idx[] value for that 4932 row is 0 (the first column). 4933 4934 This code is only implemented for a couple of matrix formats. 4935 4936 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMax()`, `MatGetRowMaxAbs()`, `MatGetRowMin()` 4937 @*/ 4938 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[]) 4939 { 4940 PetscFunctionBegin; 4941 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4942 PetscValidType(mat,1); 4943 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4944 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4945 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4946 4947 if (!mat->cmap->N) { 4948 PetscCall(VecSet(v,0.0)); 4949 if (idx) { 4950 PetscInt i,m = mat->rmap->n; 4951 for (i=0; i<m; i++) idx[i] = -1; 4952 } 4953 } else { 4954 MatCheckPreallocated(mat,1); 4955 if (idx) PetscCall(PetscArrayzero(idx,mat->rmap->n)); 4956 PetscUseTypeMethod(mat,getrowminabs ,v,idx); 4957 } 4958 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 4959 PetscFunctionReturn(0); 4960 } 4961 4962 /*@C 4963 MatGetRowMax - Gets the maximum value (of the real part) of each 4964 row of the matrix 4965 4966 Logically Collective on Mat 4967 4968 Input Parameter: 4969 . mat - the matrix 4970 4971 Output Parameters: 4972 + v - the vector for storing the maximums 4973 - idx - the indices of the column found for each row (optional) 4974 4975 Level: intermediate 4976 4977 Notes: 4978 The result of this call are the same as if one converted the matrix to dense format 4979 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4980 4981 This code is only implemented for a couple of matrix formats. 4982 4983 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMaxAbs()`, `MatGetRowMin()` 4984 @*/ 4985 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[]) 4986 { 4987 PetscFunctionBegin; 4988 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4989 PetscValidType(mat,1); 4990 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4991 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4992 4993 if (!mat->cmap->N) { 4994 PetscCall(VecSet(v,PETSC_MIN_REAL)); 4995 if (idx) { 4996 PetscInt i,m = mat->rmap->n; 4997 for (i=0; i<m; i++) idx[i] = -1; 4998 } 4999 } else { 5000 MatCheckPreallocated(mat,1); 5001 PetscUseTypeMethod(mat,getrowmax ,v,idx); 5002 } 5003 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 5004 PetscFunctionReturn(0); 5005 } 5006 5007 /*@C 5008 MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each 5009 row of the matrix 5010 5011 Logically Collective on Mat 5012 5013 Input Parameter: 5014 . mat - the matrix 5015 5016 Output Parameters: 5017 + v - the vector for storing the maximums 5018 - idx - the indices of the column found for each row (or NULL if not needed) 5019 5020 Level: intermediate 5021 5022 Notes: 5023 if a row is completely empty or has only 0.0 values then the idx[] value for that 5024 row is 0 (the first column). 5025 5026 This code is only implemented for a couple of matrix formats. 5027 5028 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMax()`, `MatGetRowMin()` 5029 @*/ 5030 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[]) 5031 { 5032 PetscFunctionBegin; 5033 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5034 PetscValidType(mat,1); 5035 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 5036 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5037 5038 if (!mat->cmap->N) { 5039 PetscCall(VecSet(v,0.0)); 5040 if (idx) { 5041 PetscInt i,m = mat->rmap->n; 5042 for (i=0; i<m; i++) idx[i] = -1; 5043 } 5044 } else { 5045 MatCheckPreallocated(mat,1); 5046 if (idx) PetscCall(PetscArrayzero(idx,mat->rmap->n)); 5047 PetscUseTypeMethod(mat,getrowmaxabs ,v,idx); 5048 } 5049 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 5050 PetscFunctionReturn(0); 5051 } 5052 5053 /*@ 5054 MatGetRowSum - Gets the sum of each row of the matrix 5055 5056 Logically or Neighborhood Collective on Mat 5057 5058 Input Parameters: 5059 . mat - the matrix 5060 5061 Output Parameter: 5062 . v - the vector for storing the sum of rows 5063 5064 Level: intermediate 5065 5066 Notes: 5067 This code is slow since it is not currently specialized for different formats 5068 5069 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMax()`, `MatGetRowMin()` 5070 @*/ 5071 PetscErrorCode MatGetRowSum(Mat mat, Vec v) 5072 { 5073 Vec ones; 5074 5075 PetscFunctionBegin; 5076 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5077 PetscValidType(mat,1); 5078 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 5079 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5080 MatCheckPreallocated(mat,1); 5081 PetscCall(MatCreateVecs(mat,&ones,NULL)); 5082 PetscCall(VecSet(ones,1.)); 5083 PetscCall(MatMult(mat,ones,v)); 5084 PetscCall(VecDestroy(&ones)); 5085 PetscFunctionReturn(0); 5086 } 5087 5088 /*@ 5089 MatTransposeSetPrecursor - Set the matrix from which the second matrix will receive numerical transpose data with a call to `MatTranspose`(A,`MAT_REUSE_MATRIX`,&B) 5090 when B was not obtained with `MatTranspose`(A,`MAT_INITIAL_MATRIX`,&B) 5091 5092 Collective on Mat 5093 5094 Input Parameter: 5095 . mat - the matrix to provide the transpose 5096 5097 Output Parameter: 5098 . mat - the matrix to contain the transpose; it MUST have the nonzero structure of the transpose of A or the code will crash or generate incorrect results 5099 5100 Level: advanced 5101 5102 Note: 5103 Normally he use of `MatTranspose`(A,`MAT_REUSE_MATRIX`,&B) requires that B was obtained with a call to `MatTranspose`(A,`MAT_INITIAL_MATRIX`,&B). This 5104 routine allows bypassing that call. 5105 5106 .seealso: `MatTransposeSymbolic()`, `MatTranspose()`, `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse`, `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, `MAT_INPLACE_MATRIX` 5107 @*/ 5108 PetscErrorCode MatTransposeSetPrecursor(Mat mat,Mat B) 5109 { 5110 PetscContainer rB = NULL; 5111 MatParentState *rb = NULL; 5112 5113 PetscFunctionBegin; 5114 PetscCall(PetscNew(&rb)); 5115 rb->id = ((PetscObject)mat)->id; 5116 rb->state = 0; 5117 PetscCall(MatGetNonzeroState(mat,&rb->nonzerostate)); 5118 PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)B),&rB)); 5119 PetscCall(PetscContainerSetPointer(rB,rb)); 5120 PetscCall(PetscContainerSetUserDestroy(rB,PetscContainerUserDestroyDefault)); 5121 PetscCall(PetscObjectCompose((PetscObject)B,"MatTransposeParent",(PetscObject)rB)); 5122 PetscCall(PetscObjectDereference((PetscObject)rB)); 5123 PetscFunctionReturn(0); 5124 } 5125 5126 /*@ 5127 MatTranspose - Computes an in-place or out-of-place transpose of a matrix. 5128 5129 Collective on Mat 5130 5131 Input Parameters: 5132 + mat - the matrix to transpose 5133 - reuse - either `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, or `MAT_INPLACE_MATRIX` 5134 5135 Output Parameter: 5136 . B - the transpose 5137 5138 Notes: 5139 If you use `MAT_INPLACE_MATRIX` then you must pass in &mat for B 5140 5141 `MAT_REUSE_MATRIX` uses the B matrix obtained from a previous call to this function with `MAT_INITIAL_MATRIX`. If you already have a matrix to contain the 5142 transpose, call `MatTransposeSetPrecursor`(mat,B) before calling this routine. 5143 5144 If the nonzero structure of mat changed from the previous call to this function with the same matrices an error will be generated for some matrix types. 5145 5146 Consider using `MatCreateTranspose()` instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed. 5147 5148 If mat is unchanged from the last call this function returns immediately without recomputing the result 5149 5150 If you only need the symbolic transpose, and not the numerical values, use `MatTransposeSymbolic()` 5151 5152 Level: intermediate 5153 5154 .seealso: `MatTransposeSetPrecursor()`, `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse`, `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, `MAT_INPLACE_MATRIX`, 5155 `MatTransposeSymbolic()` 5156 @*/ 5157 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B) 5158 { 5159 PetscContainer rB = NULL; 5160 MatParentState *rb = NULL; 5161 5162 PetscFunctionBegin; 5163 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5164 PetscValidType(mat,1); 5165 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5166 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5167 PetscCheck(reuse != MAT_INPLACE_MATRIX || mat == *B,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first"); 5168 PetscCheck(reuse != MAT_REUSE_MATRIX || mat != *B,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX"); 5169 MatCheckPreallocated(mat,1); 5170 if (reuse == MAT_REUSE_MATRIX) { 5171 PetscCall(PetscObjectQuery((PetscObject)*B,"MatTransposeParent",(PetscObject*)&rB)); 5172 PetscCheck(rB,PetscObjectComm((PetscObject)*B),PETSC_ERR_ARG_WRONG,"Reuse matrix used was not generated from call to MatTranspose(). Suggest MatTransposeSetPrecursor()."); 5173 PetscCall(PetscContainerGetPointer(rB,(void**)&rb)); 5174 PetscCheck(rb->id == ((PetscObject)mat)->id,PetscObjectComm((PetscObject)*B),PETSC_ERR_ARG_WRONG,"Reuse matrix used was not generated from input matrix"); 5175 if (rb->state == ((PetscObject)mat)->state) PetscFunctionReturn(0); 5176 } 5177 5178 PetscCall(PetscLogEventBegin(MAT_Transpose,mat,0,0,0)); 5179 if (reuse != MAT_INPLACE_MATRIX || mat->symmetric != PETSC_BOOL3_TRUE) { 5180 PetscUseTypeMethod(mat,transpose,reuse,B); 5181 PetscCall(PetscObjectStateIncrease((PetscObject)*B)); 5182 } 5183 PetscCall(PetscLogEventEnd(MAT_Transpose,mat,0,0,0)); 5184 5185 if (reuse == MAT_INITIAL_MATRIX) PetscCall(MatTransposeSetPrecursor(mat,*B)); 5186 if (reuse != MAT_INPLACE_MATRIX) { 5187 PetscCall(PetscObjectQuery((PetscObject)*B,"MatTransposeParent",(PetscObject*)&rB)); 5188 PetscCall(PetscContainerGetPointer(rB,(void**)&rb)); 5189 rb->state = ((PetscObject)mat)->state; 5190 rb->nonzerostate = mat->nonzerostate; 5191 } 5192 PetscFunctionReturn(0); 5193 } 5194 5195 /*@ 5196 MatTransposeSymbolic - Computes the symbolic part of the transpose of a matrix. 5197 5198 Collective on Mat 5199 5200 Input Parameters: 5201 . A - the matrix to transpose 5202 5203 Output Parameter: 5204 . B - the transpose. This is a complete matrix but the numerical portion is invalid. One can call `MatTranspose`(A,MAT_REUSE_MATRIX,&B) to compute the 5205 numerical portion. 5206 5207 Level: intermediate 5208 5209 Note: 5210 This is not supported for many matrix types, use `MatTranspose()` in those cases 5211 5212 .seealso: `MatTransposeSetPrecursor()`, `MatTranspose()`, `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse`, `MAT_INITIAL_MATRIX`, `MAT_REUSE_MATRIX`, `MAT_INPLACE_MATRIX` 5213 @*/ 5214 PetscErrorCode MatTransposeSymbolic(Mat A,Mat *B) 5215 { 5216 PetscFunctionBegin; 5217 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5218 PetscValidType(A,1); 5219 PetscCheck(A->assembled,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5220 PetscCheck(!A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5221 PetscCheck(A->ops->transposesymbolic,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 5222 PetscCall(PetscLogEventBegin(MAT_Transpose,A,0,0,0)); 5223 PetscCall((*A->ops->transposesymbolic)(A,B)); 5224 PetscCall(PetscLogEventEnd(MAT_Transpose,A,0,0,0)); 5225 5226 PetscCall(MatTransposeSetPrecursor(A,*B)); 5227 PetscFunctionReturn(0); 5228 } 5229 5230 PetscErrorCode MatTransposeCheckNonzeroState_Private(Mat A,Mat B) 5231 { 5232 PetscContainer rB; 5233 MatParentState *rb; 5234 5235 PetscFunctionBegin; 5236 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5237 PetscValidType(A,1); 5238 PetscCheck(A->assembled,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5239 PetscCheck(!A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5240 PetscCall(PetscObjectQuery((PetscObject)B,"MatTransposeParent",(PetscObject*)&rB)); 5241 PetscCheck(rB,PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONG,"Reuse matrix used was not generated from call to MatTranspose()"); 5242 PetscCall(PetscContainerGetPointer(rB,(void**)&rb)); 5243 PetscCheck(rb->id == ((PetscObject)A)->id,PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONG,"Reuse matrix used was not generated from input matrix"); 5244 PetscCheck(rb->nonzerostate == A->nonzerostate,PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Reuse matrix has changed nonzero structure"); 5245 PetscFunctionReturn(0); 5246 } 5247 5248 /*@ 5249 MatIsTranspose - Test whether a matrix is another one's transpose, 5250 or its own, in which case it tests symmetry. 5251 5252 Collective on Mat 5253 5254 Input Parameters: 5255 + A - the matrix to test 5256 - B - the matrix to test against, this can equal the first parameter 5257 5258 Output Parameters: 5259 . flg - the result 5260 5261 Notes: 5262 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 5263 has a running time of the order of the number of nonzeros; the parallel 5264 test involves parallel copies of the block-offdiagonal parts of the matrix. 5265 5266 Level: intermediate 5267 5268 .seealso: `MatTranspose()`, `MatIsSymmetric()`, `MatIsHermitian()` 5269 @*/ 5270 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 5271 { 5272 PetscErrorCode (*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 5273 5274 PetscFunctionBegin; 5275 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5276 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5277 PetscValidBoolPointer(flg,4); 5278 PetscCall(PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f)); 5279 PetscCall(PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g)); 5280 *flg = PETSC_FALSE; 5281 if (f && g) { 5282 PetscCheck(f == g,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test"); 5283 PetscCall((*f)(A,B,tol,flg)); 5284 } else { 5285 MatType mattype; 5286 5287 PetscCall(MatGetType(f ? B : A,&mattype)); 5288 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for transpose",mattype); 5289 } 5290 PetscFunctionReturn(0); 5291 } 5292 5293 /*@ 5294 MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate. 5295 5296 Collective on Mat 5297 5298 Input Parameters: 5299 + mat - the matrix to transpose and complex conjugate 5300 - reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX 5301 5302 Output Parameter: 5303 . B - the Hermitian 5304 5305 Level: intermediate 5306 5307 .seealso: `MatTranspose()`, `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse` 5308 @*/ 5309 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B) 5310 { 5311 PetscFunctionBegin; 5312 PetscCall(MatTranspose(mat,reuse,B)); 5313 #if defined(PETSC_USE_COMPLEX) 5314 PetscCall(MatConjugate(*B)); 5315 #endif 5316 PetscFunctionReturn(0); 5317 } 5318 5319 /*@ 5320 MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose, 5321 5322 Collective on Mat 5323 5324 Input Parameters: 5325 + A - the matrix to test 5326 - B - the matrix to test against, this can equal the first parameter 5327 5328 Output Parameters: 5329 . flg - the result 5330 5331 Notes: 5332 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 5333 has a running time of the order of the number of nonzeros; the parallel 5334 test involves parallel copies of the block-offdiagonal parts of the matrix. 5335 5336 Level: intermediate 5337 5338 .seealso: `MatTranspose()`, `MatIsSymmetric()`, `MatIsHermitian()`, `MatIsTranspose()` 5339 @*/ 5340 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 5341 { 5342 PetscErrorCode (*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 5343 5344 PetscFunctionBegin; 5345 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5346 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5347 PetscValidBoolPointer(flg,4); 5348 PetscCall(PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f)); 5349 PetscCall(PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g)); 5350 if (f && g) { 5351 PetscCheck(f != g,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test"); 5352 PetscCall((*f)(A,B,tol,flg)); 5353 } 5354 PetscFunctionReturn(0); 5355 } 5356 5357 /*@ 5358 MatPermute - Creates a new matrix with rows and columns permuted from the 5359 original. 5360 5361 Collective on Mat 5362 5363 Input Parameters: 5364 + mat - the matrix to permute 5365 . row - row permutation, each processor supplies only the permutation for its rows 5366 - col - column permutation, each processor supplies only the permutation for its columns 5367 5368 Output Parameters: 5369 . B - the permuted matrix 5370 5371 Level: advanced 5372 5373 Note: 5374 The index sets map from row/col of permuted matrix to row/col of original matrix. 5375 The index sets should be on the same communicator as Mat and have the same local sizes. 5376 5377 Developer Note: 5378 If you want to implement MatPermute for a matrix type, and your approach doesn't 5379 exploit the fact that row and col are permutations, consider implementing the 5380 more general MatCreateSubMatrix() instead. 5381 5382 .seealso: `MatGetOrdering()`, `ISAllGather()` 5383 5384 @*/ 5385 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B) 5386 { 5387 PetscFunctionBegin; 5388 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5389 PetscValidType(mat,1); 5390 PetscValidHeaderSpecific(row,IS_CLASSID,2); 5391 PetscValidHeaderSpecific(col,IS_CLASSID,3); 5392 PetscValidPointer(B,4); 5393 PetscCheckSameComm(mat,1,row,2); 5394 if (row != col) PetscCheckSameComm(row,2,col,3); 5395 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5396 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5397 PetscCheck(mat->ops->permute || mat->ops->createsubmatrix,PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name); 5398 MatCheckPreallocated(mat,1); 5399 5400 if (mat->ops->permute) { 5401 PetscUseTypeMethod(mat,permute ,row,col,B); 5402 PetscCall(PetscObjectStateIncrease((PetscObject)*B)); 5403 } else { 5404 PetscCall(MatCreateSubMatrix(mat, row, col, MAT_INITIAL_MATRIX, B)); 5405 } 5406 PetscFunctionReturn(0); 5407 } 5408 5409 /*@ 5410 MatEqual - Compares two matrices. 5411 5412 Collective on Mat 5413 5414 Input Parameters: 5415 + A - the first matrix 5416 - B - the second matrix 5417 5418 Output Parameter: 5419 . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise. 5420 5421 Level: intermediate 5422 5423 @*/ 5424 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool *flg) 5425 { 5426 PetscFunctionBegin; 5427 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5428 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5429 PetscValidType(A,1); 5430 PetscValidType(B,2); 5431 PetscValidBoolPointer(flg,3); 5432 PetscCheckSameComm(A,1,B,2); 5433 MatCheckPreallocated(A,1); 5434 MatCheckPreallocated(B,2); 5435 PetscCheck(A->assembled,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5436 PetscCheck(B->assembled,PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5437 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); 5438 if (A->ops->equal && A->ops->equal == B->ops->equal) { 5439 PetscUseTypeMethod(A,equal ,B,flg); 5440 } else { 5441 PetscCall(MatMultEqual(A,B,10,flg)); 5442 } 5443 PetscFunctionReturn(0); 5444 } 5445 5446 /*@ 5447 MatDiagonalScale - Scales a matrix on the left and right by diagonal 5448 matrices that are stored as vectors. Either of the two scaling 5449 matrices can be NULL. 5450 5451 Collective on Mat 5452 5453 Input Parameters: 5454 + mat - the matrix to be scaled 5455 . l - the left scaling vector (or NULL) 5456 - r - the right scaling vector (or NULL) 5457 5458 Notes: 5459 MatDiagonalScale() computes A = LAR, where 5460 L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector) 5461 The L scales the rows of the matrix, the R scales the columns of the matrix. 5462 5463 Level: intermediate 5464 5465 .seealso: `MatScale()`, `MatShift()`, `MatDiagonalSet()` 5466 @*/ 5467 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r) 5468 { 5469 PetscFunctionBegin; 5470 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5471 PetscValidType(mat,1); 5472 if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);} 5473 if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);} 5474 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5475 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5476 MatCheckPreallocated(mat,1); 5477 if (!l && !r) PetscFunctionReturn(0); 5478 5479 PetscCall(PetscLogEventBegin(MAT_Scale,mat,0,0,0)); 5480 PetscUseTypeMethod(mat,diagonalscale ,l,r); 5481 PetscCall(PetscLogEventEnd(MAT_Scale,mat,0,0,0)); 5482 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5483 if (l != r) mat->symmetric = PETSC_BOOL3_FALSE; 5484 PetscFunctionReturn(0); 5485 } 5486 5487 /*@ 5488 MatScale - Scales all elements of a matrix by a given number. 5489 5490 Logically Collective on Mat 5491 5492 Input Parameters: 5493 + mat - the matrix to be scaled 5494 - a - the scaling value 5495 5496 Output Parameter: 5497 . mat - the scaled matrix 5498 5499 Level: intermediate 5500 5501 .seealso: `MatDiagonalScale()` 5502 @*/ 5503 PetscErrorCode MatScale(Mat mat,PetscScalar a) 5504 { 5505 PetscFunctionBegin; 5506 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5507 PetscValidType(mat,1); 5508 PetscCheck(a == (PetscScalar)1.0 || mat->ops->scale,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5509 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5510 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5511 PetscValidLogicalCollectiveScalar(mat,a,2); 5512 MatCheckPreallocated(mat,1); 5513 5514 PetscCall(PetscLogEventBegin(MAT_Scale,mat,0,0,0)); 5515 if (a != (PetscScalar)1.0) { 5516 PetscUseTypeMethod(mat,scale ,a); 5517 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5518 } 5519 PetscCall(PetscLogEventEnd(MAT_Scale,mat,0,0,0)); 5520 PetscFunctionReturn(0); 5521 } 5522 5523 /*@ 5524 MatNorm - Calculates various norms of a matrix. 5525 5526 Collective on Mat 5527 5528 Input Parameters: 5529 + mat - the matrix 5530 - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY 5531 5532 Output Parameter: 5533 . nrm - the resulting norm 5534 5535 Level: intermediate 5536 5537 @*/ 5538 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm) 5539 { 5540 PetscFunctionBegin; 5541 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5542 PetscValidType(mat,1); 5543 PetscValidRealPointer(nrm,3); 5544 5545 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5546 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5547 MatCheckPreallocated(mat,1); 5548 5549 PetscUseTypeMethod(mat,norm ,type,nrm); 5550 PetscFunctionReturn(0); 5551 } 5552 5553 /* 5554 This variable is used to prevent counting of MatAssemblyBegin() that 5555 are called from within a MatAssemblyEnd(). 5556 */ 5557 static PetscInt MatAssemblyEnd_InUse = 0; 5558 /*@ 5559 MatAssemblyBegin - Begins assembling the matrix. This routine should 5560 be called after completing all calls to MatSetValues(). 5561 5562 Collective on Mat 5563 5564 Input Parameters: 5565 + mat - the matrix 5566 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5567 5568 Notes: 5569 MatSetValues() generally caches the values. The matrix is ready to 5570 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5571 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5572 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5573 using the matrix. 5574 5575 ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the 5576 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 5577 a global collective operation requring all processes that share the matrix. 5578 5579 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5580 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5581 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5582 5583 Level: beginner 5584 5585 .seealso: `MatAssemblyEnd()`, `MatSetValues()`, `MatAssembled()` 5586 @*/ 5587 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type) 5588 { 5589 PetscFunctionBegin; 5590 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5591 PetscValidType(mat,1); 5592 MatCheckPreallocated(mat,1); 5593 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?"); 5594 if (mat->assembled) { 5595 mat->was_assembled = PETSC_TRUE; 5596 mat->assembled = PETSC_FALSE; 5597 } 5598 5599 if (!MatAssemblyEnd_InUse) { 5600 PetscCall(PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0)); 5601 PetscTryTypeMethod(mat,assemblybegin,type); 5602 PetscCall(PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0)); 5603 } else PetscTryTypeMethod(mat,assemblybegin,type); 5604 PetscFunctionReturn(0); 5605 } 5606 5607 /*@ 5608 MatAssembled - Indicates if a matrix has been assembled and is ready for 5609 use; for example, in matrix-vector product. 5610 5611 Not Collective 5612 5613 Input Parameter: 5614 . mat - the matrix 5615 5616 Output Parameter: 5617 . assembled - PETSC_TRUE or PETSC_FALSE 5618 5619 Level: advanced 5620 5621 .seealso: `MatAssemblyEnd()`, `MatSetValues()`, `MatAssemblyBegin()` 5622 @*/ 5623 PetscErrorCode MatAssembled(Mat mat,PetscBool *assembled) 5624 { 5625 PetscFunctionBegin; 5626 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5627 PetscValidBoolPointer(assembled,2); 5628 *assembled = mat->assembled; 5629 PetscFunctionReturn(0); 5630 } 5631 5632 /*@ 5633 MatAssemblyEnd - Completes assembling the matrix. This routine should 5634 be called after MatAssemblyBegin(). 5635 5636 Collective on Mat 5637 5638 Input Parameters: 5639 + mat - the matrix 5640 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5641 5642 Options Database Keys: 5643 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly() 5644 . -mat_view ::ascii_info_detail - Prints more detailed info 5645 . -mat_view - Prints matrix in ASCII format 5646 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 5647 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 5648 . -display <name> - Sets display name (default is host) 5649 . -draw_pause <sec> - Sets number of seconds to pause after display 5650 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab) 5651 . -viewer_socket_machine <machine> - Machine to use for socket 5652 . -viewer_socket_port <port> - Port number to use for socket 5653 - -mat_view binary:filename[:append] - Save matrix to file in binary format 5654 5655 Notes: 5656 MatSetValues() generally caches the values. The matrix is ready to 5657 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5658 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5659 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5660 using the matrix. 5661 5662 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5663 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5664 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5665 5666 Level: beginner 5667 5668 .seealso: `MatAssemblyBegin()`, `MatSetValues()`, `PetscDrawOpenX()`, `PetscDrawCreate()`, `MatView()`, `MatAssembled()`, `PetscViewerSocketOpen()` 5669 @*/ 5670 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type) 5671 { 5672 static PetscInt inassm = 0; 5673 PetscBool flg = PETSC_FALSE; 5674 5675 PetscFunctionBegin; 5676 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5677 PetscValidType(mat,1); 5678 5679 inassm++; 5680 MatAssemblyEnd_InUse++; 5681 if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */ 5682 PetscCall(PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0)); 5683 PetscTryTypeMethod(mat,assemblyend,type); 5684 PetscCall(PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0)); 5685 } else PetscTryTypeMethod(mat,assemblyend,type); 5686 5687 /* Flush assembly is not a true assembly */ 5688 if (type != MAT_FLUSH_ASSEMBLY) { 5689 if (mat->num_ass) { 5690 if (!mat->symmetry_eternal) { 5691 mat->symmetric = PETSC_BOOL3_UNKNOWN; 5692 mat->hermitian = PETSC_BOOL3_UNKNOWN; 5693 } 5694 if (!mat->structural_symmetry_eternal && mat->ass_nonzerostate != mat->nonzerostate) { 5695 mat->structurally_symmetric = PETSC_BOOL3_UNKNOWN; 5696 } 5697 if (!mat->spd_eternal) mat->spd = PETSC_BOOL3_UNKNOWN; 5698 } 5699 mat->num_ass++; 5700 mat->assembled = PETSC_TRUE; 5701 mat->ass_nonzerostate = mat->nonzerostate; 5702 } 5703 5704 mat->insertmode = NOT_SET_VALUES; 5705 MatAssemblyEnd_InUse--; 5706 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5707 if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) { 5708 PetscCall(MatViewFromOptions(mat,NULL,"-mat_view")); 5709 5710 if (mat->checksymmetryonassembly) { 5711 PetscCall(MatIsSymmetric(mat,mat->checksymmetrytol,&flg)); 5712 if (flg) { 5713 PetscCall(PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol)); 5714 } else { 5715 PetscCall(PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol)); 5716 } 5717 } 5718 if (mat->nullsp && mat->checknullspaceonassembly) { 5719 PetscCall(MatNullSpaceTest(mat->nullsp,mat,NULL)); 5720 } 5721 } 5722 inassm--; 5723 PetscFunctionReturn(0); 5724 } 5725 5726 /*@ 5727 MatSetOption - Sets a parameter option for a matrix. Some options 5728 may be specific to certain storage formats. Some options 5729 determine how values will be inserted (or added). Sorted, 5730 row-oriented input will generally assemble the fastest. The default 5731 is row-oriented. 5732 5733 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5734 5735 Input Parameters: 5736 + mat - the matrix 5737 . option - the option, one of those listed below (and possibly others), 5738 - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5739 5740 Options Describing Matrix Structure: 5741 + MAT_SPD - symmetric positive definite 5742 . MAT_SYMMETRIC - symmetric in terms of both structure and value 5743 . MAT_HERMITIAN - transpose is the complex conjugation 5744 . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure 5745 . MAT_SYMMETRY_ETERNAL - indicates the symmetry (or Hermitian structure) or its absence will persist through any changes to the matrix 5746 . MAT_STRUCTURAL_SYMMETRY_ETERNAL - indicates the structural symmetry or its absence will persist through any changes to the matrix 5747 - MAT_SPD_ETERNAL - indicates the value of MAT_SPD (true or false) will persist through any changes to the matrix 5748 5749 These are not really options of the matrix, they are knowledge about the structure of the matrix that users may provide so that they 5750 do not need to be computed (usually at a high cost) 5751 5752 Options For Use with MatSetValues(): 5753 Insert a logically dense subblock, which can be 5754 . MAT_ROW_ORIENTED - row-oriented (default) 5755 5756 Note these options reflect the data you pass in with MatSetValues(); it has 5757 nothing to do with how the data is stored internally in the matrix 5758 data structure. 5759 5760 When (re)assembling a matrix, we can restrict the input for 5761 efficiency/debugging purposes. These options include 5762 + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow) 5763 . MAT_FORCE_DIAGONAL_ENTRIES - forces diagonal entries to be allocated 5764 . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries 5765 . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry 5766 . MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly 5767 . MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if 5768 any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves 5769 performance for very large process counts. 5770 - MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset 5771 of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly 5772 functions, instead sending only neighbor messages. 5773 5774 Notes: 5775 Except for MAT_UNUSED_NONZERO_LOCATION_ERR and MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg! 5776 5777 Some options are relevant only for particular matrix types and 5778 are thus ignored by others. Other options are not supported by 5779 certain matrix types and will generate an error message if set. 5780 5781 If using a Fortran 77 module to compute a matrix, one may need to 5782 use the column-oriented option (or convert to the row-oriented 5783 format). 5784 5785 MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion 5786 that would generate a new entry in the nonzero structure is instead 5787 ignored. Thus, if memory has not alredy been allocated for this particular 5788 data, then the insertion is ignored. For dense matrices, in which 5789 the entire array is allocated, no entries are ever ignored. 5790 Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5791 5792 MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5793 that would generate a new entry in the nonzero structure instead produces 5794 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 5795 5796 MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5797 that would generate a new entry that has not been preallocated will 5798 instead produce an error. (Currently supported for AIJ and BAIJ formats 5799 only.) This is a useful flag when debugging matrix memory preallocation. 5800 If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5801 5802 MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for 5803 other processors should be dropped, rather than stashed. 5804 This is useful if you know that the "owning" processor is also 5805 always generating the correct matrix entries, so that PETSc need 5806 not transfer duplicate entries generated on another processor. 5807 5808 MAT_USE_HASH_TABLE indicates that a hash table be used to improve the 5809 searches during matrix assembly. When this flag is set, the hash table 5810 is created during the first Matrix Assembly. This hash table is 5811 used the next time through, during MatSetVaules()/MatSetVaulesBlocked() 5812 to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag 5813 should be used with MAT_USE_HASH_TABLE flag. This option is currently 5814 supported by MATMPIBAIJ format only. 5815 5816 MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries 5817 are kept in the nonzero structure 5818 5819 MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating 5820 a zero location in the matrix 5821 5822 MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types 5823 5824 MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the 5825 zero row routines and thus improves performance for very large process counts. 5826 5827 MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular 5828 part of the matrix (since they should match the upper triangular part). 5829 5830 MAT_SORTED_FULL - each process provides exactly its local rows; all column indices for a given row are passed in a 5831 single call to MatSetValues(), preallocation is perfect, row oriented, INSERT_VALUES is used. Common 5832 with finite difference schemes with non-periodic boundary conditions. 5833 5834 Developer Note: 5835 MAT_SYMMETRY_ETERNAL, MAT_STRUCTURAL_SYMMETRY_ETERNAL, and MAT_SPD_ETERNAL are used by MatAssemblyEnd() and in other 5836 places where otherwise the value of MAT_SYMMETRIC, MAT_STRUCTURAL_SYMMETRIC or MAT_SPD would need to be changed back 5837 to PETSC_BOOL3_UNKNOWN because the matrix values had changed so the code cannot be certain that the related property had 5838 not changed. 5839 5840 Level: intermediate 5841 5842 .seealso: `MatOption`, `Mat`, `MatGetOption()` 5843 5844 @*/ 5845 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg) 5846 { 5847 PetscFunctionBegin; 5848 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5849 if (op > 0) { 5850 PetscValidLogicalCollectiveEnum(mat,op,2); 5851 PetscValidLogicalCollectiveBool(mat,flg,3); 5852 } 5853 5854 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); 5855 5856 switch (op) { 5857 case MAT_FORCE_DIAGONAL_ENTRIES: 5858 mat->force_diagonals = flg; 5859 PetscFunctionReturn(0); 5860 case MAT_NO_OFF_PROC_ENTRIES: 5861 mat->nooffprocentries = flg; 5862 PetscFunctionReturn(0); 5863 case MAT_SUBSET_OFF_PROC_ENTRIES: 5864 mat->assembly_subset = flg; 5865 if (!mat->assembly_subset) { /* See the same logic in VecAssembly wrt VEC_SUBSET_OFF_PROC_ENTRIES */ 5866 #if !defined(PETSC_HAVE_MPIUNI) 5867 PetscCall(MatStashScatterDestroy_BTS(&mat->stash)); 5868 #endif 5869 mat->stash.first_assembly_done = PETSC_FALSE; 5870 } 5871 PetscFunctionReturn(0); 5872 case MAT_NO_OFF_PROC_ZERO_ROWS: 5873 mat->nooffproczerorows = flg; 5874 PetscFunctionReturn(0); 5875 case MAT_SPD: 5876 if (flg) { 5877 mat->spd = PETSC_BOOL3_TRUE; 5878 mat->symmetric = PETSC_BOOL3_TRUE; 5879 mat->structurally_symmetric = PETSC_BOOL3_TRUE; 5880 } else { 5881 mat->spd = PETSC_BOOL3_FALSE; 5882 } 5883 break; 5884 case MAT_SYMMETRIC: 5885 mat->symmetric = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5886 if (flg) mat->structurally_symmetric = PETSC_BOOL3_TRUE; 5887 #if !defined(PETSC_USE_COMPLEX) 5888 mat->hermitian = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5889 #endif 5890 break; 5891 case MAT_HERMITIAN: 5892 mat->hermitian = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5893 if (flg) mat->structurally_symmetric = PETSC_BOOL3_TRUE; 5894 #if !defined(PETSC_USE_COMPLEX) 5895 mat->symmetric = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5896 #endif 5897 break; 5898 case MAT_STRUCTURALLY_SYMMETRIC: 5899 mat->structurally_symmetric = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5900 break; 5901 case MAT_SYMMETRY_ETERNAL: 5902 PetscCheck(mat->symmetric != PETSC_BOOL3_UNKNOWN,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot set MAT_SYMMETRY_ETERNAL without first setting MAT_SYMMETRIC to true or false"); 5903 mat->symmetry_eternal = flg; 5904 if (flg) mat->structural_symmetry_eternal = PETSC_TRUE; 5905 break; 5906 case MAT_STRUCTURAL_SYMMETRY_ETERNAL: 5907 PetscCheck(mat->structurally_symmetric != PETSC_BOOL3_UNKNOWN,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot set MAT_STRUCTURAL_SYMMETRY_ETERNAL without first setting MAT_STRUCTURAL_SYMMETRIC to true or false"); 5908 mat->structural_symmetry_eternal = flg; 5909 break; 5910 case MAT_SPD_ETERNAL: 5911 PetscCheck(mat->spd != PETSC_BOOL3_UNKNOWN,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot set MAT_SPD_ETERNAL without first setting MAT_SPD to true or false"); 5912 mat->spd_eternal = flg; 5913 if (flg) { 5914 mat->structural_symmetry_eternal = PETSC_TRUE; 5915 mat->symmetry_eternal = PETSC_TRUE; 5916 } 5917 break; 5918 case MAT_STRUCTURE_ONLY: 5919 mat->structure_only = flg; 5920 break; 5921 case MAT_SORTED_FULL: 5922 mat->sortedfull = flg; 5923 break; 5924 default: 5925 break; 5926 } 5927 PetscTryTypeMethod(mat,setoption,op,flg); 5928 PetscFunctionReturn(0); 5929 } 5930 5931 /*@ 5932 MatGetOption - Gets a parameter option that has been set for a matrix. 5933 5934 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5935 5936 Input Parameters: 5937 + mat - the matrix 5938 - option - the option, this only responds to certain options, check the code for which ones 5939 5940 Output Parameter: 5941 . flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5942 5943 Notes: 5944 Can only be called after MatSetSizes() and MatSetType() have been set. 5945 5946 Certain option values may be unknown, for those use the routines `MatIsSymmetric()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, or 5947 `MatIsSymmetricKnown()`, `MatIsHermitianKnown()`, `MatIsStructurallySymmetricKnown()` 5948 5949 Level: intermediate 5950 5951 .seealso: `MatOption`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, 5952 `MatIsSymmetricKnown()`, `MatIsHermitianKnown()`, `MatIsStructurallySymmetricKnown()` 5953 5954 @*/ 5955 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg) 5956 { 5957 PetscFunctionBegin; 5958 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5959 PetscValidType(mat,1); 5960 5961 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); 5962 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()"); 5963 5964 switch (op) { 5965 case MAT_NO_OFF_PROC_ENTRIES: 5966 *flg = mat->nooffprocentries; 5967 break; 5968 case MAT_NO_OFF_PROC_ZERO_ROWS: 5969 *flg = mat->nooffproczerorows; 5970 break; 5971 case MAT_SYMMETRIC: 5972 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Use MatIsSymmetric() or MatIsSymmetricKnown()"); 5973 break; 5974 case MAT_HERMITIAN: 5975 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Use MatIsHermitian() or MatIsHermitianKnown()"); 5976 break; 5977 case MAT_STRUCTURALLY_SYMMETRIC: 5978 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Use MatIsStructurallySymmetric() or MatIsStructurallySymmetricKnown()"); 5979 break; 5980 case MAT_SPD: 5981 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Use MatIsSPDKnown()"); 5982 break; 5983 case MAT_SYMMETRY_ETERNAL: 5984 *flg = mat->symmetry_eternal; 5985 break; 5986 case MAT_STRUCTURAL_SYMMETRY_ETERNAL: 5987 *flg = mat->symmetry_eternal; 5988 break; 5989 default: 5990 break; 5991 } 5992 PetscFunctionReturn(0); 5993 } 5994 5995 /*@ 5996 MatZeroEntries - Zeros all entries of a matrix. For sparse matrices 5997 this routine retains the old nonzero structure. 5998 5999 Logically Collective on Mat 6000 6001 Input Parameters: 6002 . mat - the matrix 6003 6004 Level: intermediate 6005 6006 Notes: 6007 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. 6008 See the Performance chapter of the users manual for information on preallocating matrices. 6009 6010 .seealso: `MatZeroRows()` 6011 @*/ 6012 PetscErrorCode MatZeroEntries(Mat mat) 6013 { 6014 PetscFunctionBegin; 6015 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6016 PetscValidType(mat,1); 6017 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6018 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"); 6019 MatCheckPreallocated(mat,1); 6020 6021 PetscCall(PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0)); 6022 PetscUseTypeMethod(mat,zeroentries); 6023 PetscCall(PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0)); 6024 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6025 PetscFunctionReturn(0); 6026 } 6027 6028 /*@ 6029 MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal) 6030 of a set of rows and columns of a matrix. 6031 6032 Collective on Mat 6033 6034 Input Parameters: 6035 + mat - the matrix 6036 . numRows - the number of rows to remove 6037 . rows - the global row indices 6038 . diag - value put in the diagonal of the eliminated rows 6039 . x - optional vector of solutions for zeroed rows (other entries in vector are not used), these must be set before this call 6040 - b - optional vector of right hand side, that will be adjusted by provided solution 6041 6042 Notes: 6043 This routine, along with `MatZeroRows()`, is typically used to eliminate known Dirichlet boundary conditions from a linear system. 6044 6045 For each zeroed row, the value of the corresponding b is set to diag times the value of the corresponding x. 6046 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 6047 6048 If the resulting linear system is to be solved with KSP then one can (but does not have to) call `KSPSetInitialGuessNonzero()` to allow the 6049 Krylov method to take advantage of the known solution on the zeroed rows. 6050 6051 For the parallel case, all processes that share the matrix (i.e., 6052 those in the communicator used for matrix creation) MUST call this 6053 routine, regardless of whether any rows being zeroed are owned by 6054 them. 6055 6056 Unlike `MatZeroRows()` this does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 6057 6058 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6059 list only rows local to itself). 6060 6061 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 6062 6063 Level: intermediate 6064 6065 .seealso: `MatZeroRowsIS()`, `MatZeroRows()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6066 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6067 @*/ 6068 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6069 { 6070 PetscFunctionBegin; 6071 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6072 PetscValidType(mat,1); 6073 if (numRows) PetscValidIntPointer(rows,3); 6074 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6075 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6076 MatCheckPreallocated(mat,1); 6077 6078 PetscUseTypeMethod(mat,zerorowscolumns ,numRows,rows,diag,x,b); 6079 PetscCall(MatViewFromOptions(mat,NULL,"-mat_view")); 6080 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6081 PetscFunctionReturn(0); 6082 } 6083 6084 /*@ 6085 MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal) 6086 of a set of rows and columns of a matrix. 6087 6088 Collective on Mat 6089 6090 Input Parameters: 6091 + mat - the matrix 6092 . is - the rows to zero 6093 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6094 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6095 - b - optional vector of right hand side, that will be adjusted by provided solution 6096 6097 Note: 6098 See `MatZeroRowsColumns()` for details on how this routine operates. 6099 6100 Level: intermediate 6101 6102 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6103 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRows()`, `MatZeroRowsColumnsStencil()` 6104 @*/ 6105 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6106 { 6107 PetscInt numRows; 6108 const PetscInt *rows; 6109 6110 PetscFunctionBegin; 6111 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6112 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6113 PetscValidType(mat,1); 6114 PetscValidType(is,2); 6115 PetscCall(ISGetLocalSize(is,&numRows)); 6116 PetscCall(ISGetIndices(is,&rows)); 6117 PetscCall(MatZeroRowsColumns(mat,numRows,rows,diag,x,b)); 6118 PetscCall(ISRestoreIndices(is,&rows)); 6119 PetscFunctionReturn(0); 6120 } 6121 6122 /*@ 6123 MatZeroRows - Zeros all entries (except possibly the main diagonal) 6124 of a set of rows of a matrix. 6125 6126 Collective on Mat 6127 6128 Input Parameters: 6129 + mat - the matrix 6130 . numRows - the number of rows to remove 6131 . rows - the global row indices 6132 . diag - value put in the diagonal of the eliminated rows 6133 . x - optional vector of solutions for zeroed rows (other entries in vector are not used), these must be set before this call 6134 - b - optional vector of right hand side, that will be adjusted by provided solution 6135 6136 Notes: 6137 This routine, along with `MatZeroRowsColumns()`, is typically used to eliminate known Dirichlet boundary conditions from a linear system. 6138 6139 For each zeroed row, the value of the corresponding b is set to diag times the value of the corresponding x. 6140 6141 If the resulting linear system is to be solved with KSP then one can (but does not have to) call `KSPSetInitialGuessNonzero()` to allow the 6142 Krylov method to take advantage of the known solution on the zeroed rows. 6143 6144 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) 6145 from the matrix. 6146 6147 Unlike `MatZeroRowsColumns()` for the AIJ and BAIJ matrix formats this removes the old nonzero structure, from the eliminated rows of the matrix 6148 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 6149 formats this does not alter the nonzero structure. 6150 6151 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6152 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6153 merely zeroed. 6154 6155 The user can set a value in the diagonal entry (or for the AIJ and 6156 row formats can optionally remove the main diagonal entry from the 6157 nonzero structure as well, by passing 0.0 as the final argument). 6158 6159 For the parallel case, all processes that share the matrix (i.e., 6160 those in the communicator used for matrix creation) MUST call this 6161 routine, regardless of whether any rows being zeroed are owned by 6162 them. 6163 6164 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6165 list only rows local to itself). 6166 6167 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6168 owns that are to be zeroed. This saves a global synchronization in the implementation. 6169 6170 Level: intermediate 6171 6172 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6173 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()`, `PCREDISTRIBUTE` 6174 @*/ 6175 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6176 { 6177 PetscFunctionBegin; 6178 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6179 PetscValidType(mat,1); 6180 if (numRows) PetscValidIntPointer(rows,3); 6181 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6182 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6183 MatCheckPreallocated(mat,1); 6184 6185 PetscUseTypeMethod(mat,zerorows ,numRows,rows,diag,x,b); 6186 PetscCall(MatViewFromOptions(mat,NULL,"-mat_view")); 6187 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6188 PetscFunctionReturn(0); 6189 } 6190 6191 /*@ 6192 MatZeroRowsIS - Zeros all entries (except possibly the main diagonal) 6193 of a set of rows of a matrix. 6194 6195 Collective on Mat 6196 6197 Input Parameters: 6198 + mat - the matrix 6199 . is - index set of rows to remove (if NULL then no row is removed) 6200 . diag - value put in all diagonals of eliminated rows 6201 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6202 - b - optional vector of right hand side, that will be adjusted by provided solution 6203 6204 Note: 6205 See `MatZeroRows()` for details on how this routine operates. 6206 6207 Level: intermediate 6208 6209 .seealso: `MatZeroRows()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6210 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6211 @*/ 6212 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6213 { 6214 PetscInt numRows = 0; 6215 const PetscInt *rows = NULL; 6216 6217 PetscFunctionBegin; 6218 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6219 PetscValidType(mat,1); 6220 if (is) { 6221 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6222 PetscCall(ISGetLocalSize(is,&numRows)); 6223 PetscCall(ISGetIndices(is,&rows)); 6224 } 6225 PetscCall(MatZeroRows(mat,numRows,rows,diag,x,b)); 6226 if (is) { 6227 PetscCall(ISRestoreIndices(is,&rows)); 6228 } 6229 PetscFunctionReturn(0); 6230 } 6231 6232 /*@ 6233 MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal) 6234 of a set of rows of a matrix. These rows must be local to the process. 6235 6236 Collective on Mat 6237 6238 Input Parameters: 6239 + mat - the matrix 6240 . numRows - the number of rows to remove 6241 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 6242 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6243 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6244 - b - optional vector of right hand side, that will be adjusted by provided solution 6245 6246 Notes: 6247 See `MatZeroRows()` for details on how this routine operates. 6248 6249 The grid coordinates are across the entire grid, not just the local portion 6250 6251 In Fortran idxm and idxn should be declared as 6252 $ MatStencil idxm(4,m) 6253 and the values inserted using 6254 $ idxm(MatStencil_i,1) = i 6255 $ idxm(MatStencil_j,1) = j 6256 $ idxm(MatStencil_k,1) = k 6257 $ idxm(MatStencil_c,1) = c 6258 etc 6259 6260 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6261 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6262 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6263 DM_BOUNDARY_PERIODIC boundary type. 6264 6265 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 6266 a single value per point) you can skip filling those indices. 6267 6268 Level: intermediate 6269 6270 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsl()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6271 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6272 @*/ 6273 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 6274 { 6275 PetscInt dim = mat->stencil.dim; 6276 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 6277 PetscInt *dims = mat->stencil.dims+1; 6278 PetscInt *starts = mat->stencil.starts; 6279 PetscInt *dxm = (PetscInt*) rows; 6280 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6281 6282 PetscFunctionBegin; 6283 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6284 PetscValidType(mat,1); 6285 if (numRows) PetscValidPointer(rows,3); 6286 6287 PetscCall(PetscMalloc1(numRows, &jdxm)); 6288 for (i = 0; i < numRows; ++i) { 6289 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6290 for (j = 0; j < 3-sdim; ++j) dxm++; 6291 /* Local index in X dir */ 6292 tmp = *dxm++ - starts[0]; 6293 /* Loop over remaining dimensions */ 6294 for (j = 0; j < dim-1; ++j) { 6295 /* If nonlocal, set index to be negative */ 6296 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6297 /* Update local index */ 6298 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6299 } 6300 /* Skip component slot if necessary */ 6301 if (mat->stencil.noc) dxm++; 6302 /* Local row number */ 6303 if (tmp >= 0) { 6304 jdxm[numNewRows++] = tmp; 6305 } 6306 } 6307 PetscCall(MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b)); 6308 PetscCall(PetscFree(jdxm)); 6309 PetscFunctionReturn(0); 6310 } 6311 6312 /*@ 6313 MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal) 6314 of a set of rows and columns of a matrix. 6315 6316 Collective on Mat 6317 6318 Input Parameters: 6319 + mat - the matrix 6320 . numRows - the number of rows/columns to remove 6321 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 6322 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6323 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6324 - b - optional vector of right hand side, that will be adjusted by provided solution 6325 6326 Notes: 6327 See `MatZeroRowsColumns()` for details on how this routine operates. 6328 6329 The grid coordinates are across the entire grid, not just the local portion 6330 6331 In Fortran idxm and idxn should be declared as 6332 $ MatStencil idxm(4,m) 6333 and the values inserted using 6334 $ idxm(MatStencil_i,1) = i 6335 $ idxm(MatStencil_j,1) = j 6336 $ idxm(MatStencil_k,1) = k 6337 $ idxm(MatStencil_c,1) = c 6338 etc 6339 6340 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6341 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6342 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6343 DM_BOUNDARY_PERIODIC boundary type. 6344 6345 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 6346 a single value per point) you can skip filling those indices. 6347 6348 Level: intermediate 6349 6350 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6351 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRows()` 6352 @*/ 6353 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 6354 { 6355 PetscInt dim = mat->stencil.dim; 6356 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 6357 PetscInt *dims = mat->stencil.dims+1; 6358 PetscInt *starts = mat->stencil.starts; 6359 PetscInt *dxm = (PetscInt*) rows; 6360 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6361 6362 PetscFunctionBegin; 6363 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6364 PetscValidType(mat,1); 6365 if (numRows) PetscValidPointer(rows,3); 6366 6367 PetscCall(PetscMalloc1(numRows, &jdxm)); 6368 for (i = 0; i < numRows; ++i) { 6369 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6370 for (j = 0; j < 3-sdim; ++j) dxm++; 6371 /* Local index in X dir */ 6372 tmp = *dxm++ - starts[0]; 6373 /* Loop over remaining dimensions */ 6374 for (j = 0; j < dim-1; ++j) { 6375 /* If nonlocal, set index to be negative */ 6376 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6377 /* Update local index */ 6378 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6379 } 6380 /* Skip component slot if necessary */ 6381 if (mat->stencil.noc) dxm++; 6382 /* Local row number */ 6383 if (tmp >= 0) { 6384 jdxm[numNewRows++] = tmp; 6385 } 6386 } 6387 PetscCall(MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b)); 6388 PetscCall(PetscFree(jdxm)); 6389 PetscFunctionReturn(0); 6390 } 6391 6392 /*@C 6393 MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal) 6394 of a set of rows of a matrix; using local numbering of rows. 6395 6396 Collective on Mat 6397 6398 Input Parameters: 6399 + mat - the matrix 6400 . numRows - the number of rows to remove 6401 . rows - the local row indices 6402 . diag - value put in all diagonals of eliminated rows 6403 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6404 - b - optional vector of right hand side, that will be adjusted by provided solution 6405 6406 Notes: 6407 Before calling `MatZeroRowsLocal()`, the user must first set the 6408 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6409 6410 See `MatZeroRows()` for details on how this routine operates. 6411 6412 Level: intermediate 6413 6414 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRows()`, `MatSetOption()`, 6415 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6416 @*/ 6417 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6418 { 6419 PetscFunctionBegin; 6420 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6421 PetscValidType(mat,1); 6422 if (numRows) PetscValidIntPointer(rows,3); 6423 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6424 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6425 MatCheckPreallocated(mat,1); 6426 6427 if (mat->ops->zerorowslocal) { 6428 PetscUseTypeMethod(mat,zerorowslocal ,numRows,rows,diag,x,b); 6429 } else { 6430 IS is, newis; 6431 const PetscInt *newRows; 6432 6433 PetscCheck(mat->rmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6434 PetscCall(ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is)); 6435 PetscCall(ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis)); 6436 PetscCall(ISGetIndices(newis,&newRows)); 6437 PetscUseTypeMethod(mat,zerorows ,numRows,newRows,diag,x,b); 6438 PetscCall(ISRestoreIndices(newis,&newRows)); 6439 PetscCall(ISDestroy(&newis)); 6440 PetscCall(ISDestroy(&is)); 6441 } 6442 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6443 PetscFunctionReturn(0); 6444 } 6445 6446 /*@ 6447 MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal) 6448 of a set of rows of a matrix; using local numbering of rows. 6449 6450 Collective on Mat 6451 6452 Input Parameters: 6453 + mat - the matrix 6454 . is - index set of rows to remove 6455 . diag - value put in all diagonals of eliminated rows 6456 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6457 - b - optional vector of right hand side, that will be adjusted by provided solution 6458 6459 Notes: 6460 Before calling `MatZeroRowsLocalIS()`, the user must first set the 6461 local-to-global mapping by calling `MatSetLocalToGlobalMapping()`. 6462 6463 See `MatZeroRows()` for details on how this routine operates. 6464 6465 Level: intermediate 6466 6467 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRows()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6468 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6469 @*/ 6470 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6471 { 6472 PetscInt numRows; 6473 const PetscInt *rows; 6474 6475 PetscFunctionBegin; 6476 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6477 PetscValidType(mat,1); 6478 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6479 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6480 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6481 MatCheckPreallocated(mat,1); 6482 6483 PetscCall(ISGetLocalSize(is,&numRows)); 6484 PetscCall(ISGetIndices(is,&rows)); 6485 PetscCall(MatZeroRowsLocal(mat,numRows,rows,diag,x,b)); 6486 PetscCall(ISRestoreIndices(is,&rows)); 6487 PetscFunctionReturn(0); 6488 } 6489 6490 /*@ 6491 MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal) 6492 of a set of rows and columns of a matrix; using local numbering of rows. 6493 6494 Collective on Mat 6495 6496 Input Parameters: 6497 + mat - the matrix 6498 . numRows - the number of rows to remove 6499 . rows - the global row indices 6500 . diag - value put in all diagonals of eliminated rows 6501 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6502 - b - optional vector of right hand side, that will be adjusted by provided solution 6503 6504 Notes: 6505 Before calling MatZeroRowsColumnsLocal(), the user must first set the 6506 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6507 6508 See `MatZeroRowsColumns()` for details on how this routine operates. 6509 6510 Level: intermediate 6511 6512 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6513 `MatZeroRows()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6514 @*/ 6515 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6516 { 6517 IS is, newis; 6518 const PetscInt *newRows; 6519 6520 PetscFunctionBegin; 6521 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6522 PetscValidType(mat,1); 6523 if (numRows) PetscValidIntPointer(rows,3); 6524 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6525 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6526 MatCheckPreallocated(mat,1); 6527 6528 PetscCheck(mat->cmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6529 PetscCall(ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is)); 6530 PetscCall(ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis)); 6531 PetscCall(ISGetIndices(newis,&newRows)); 6532 PetscUseTypeMethod(mat,zerorowscolumns ,numRows,newRows,diag,x,b); 6533 PetscCall(ISRestoreIndices(newis,&newRows)); 6534 PetscCall(ISDestroy(&newis)); 6535 PetscCall(ISDestroy(&is)); 6536 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6537 PetscFunctionReturn(0); 6538 } 6539 6540 /*@ 6541 MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal) 6542 of a set of rows and columns of a matrix; using local numbering of rows. 6543 6544 Collective on Mat 6545 6546 Input Parameters: 6547 + mat - the matrix 6548 . is - index set of rows to remove 6549 . diag - value put in all diagonals of eliminated rows 6550 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6551 - b - optional vector of right hand side, that will be adjusted by provided solution 6552 6553 Notes: 6554 Before calling `MatZeroRowsColumnsLocalIS()`, the user must first set the 6555 local-to-global mapping by calling `MatSetLocalToGlobalMapping()`. 6556 6557 See `MatZeroRowsColumns()` for details on how this routine operates. 6558 6559 Level: intermediate 6560 6561 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6562 `MatZeroRowsColumnsLocal()`, `MatZeroRows()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6563 @*/ 6564 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6565 { 6566 PetscInt numRows; 6567 const PetscInt *rows; 6568 6569 PetscFunctionBegin; 6570 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6571 PetscValidType(mat,1); 6572 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6573 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6574 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6575 MatCheckPreallocated(mat,1); 6576 6577 PetscCall(ISGetLocalSize(is,&numRows)); 6578 PetscCall(ISGetIndices(is,&rows)); 6579 PetscCall(MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b)); 6580 PetscCall(ISRestoreIndices(is,&rows)); 6581 PetscFunctionReturn(0); 6582 } 6583 6584 /*@C 6585 MatGetSize - Returns the numbers of rows and columns in a matrix. 6586 6587 Not Collective 6588 6589 Input Parameter: 6590 . mat - the matrix 6591 6592 Output Parameters: 6593 + m - the number of global rows 6594 - n - the number of global columns 6595 6596 Note: both output parameters can be NULL on input. 6597 6598 Level: beginner 6599 6600 .seealso: `MatGetLocalSize()` 6601 @*/ 6602 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n) 6603 { 6604 PetscFunctionBegin; 6605 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6606 if (m) *m = mat->rmap->N; 6607 if (n) *n = mat->cmap->N; 6608 PetscFunctionReturn(0); 6609 } 6610 6611 /*@C 6612 MatGetLocalSize - For most matrix formats, excluding `MATELEMENTAL` and `MATSCALAPACK`, Returns the number of local rows and local columns 6613 of a matrix. For all matrices this is the local size of the left and right vectors as returned by MatCreateVecs(). 6614 6615 Not Collective 6616 6617 Input Parameter: 6618 . mat - the matrix 6619 6620 Output Parameters: 6621 + m - the number of local rows, use `NULL` to not obtain this value 6622 - n - the number of local columns, use `NULL` to not obtain this value 6623 6624 Level: beginner 6625 6626 .seealso: `MatGetSize()` 6627 @*/ 6628 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n) 6629 { 6630 PetscFunctionBegin; 6631 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6632 if (m) PetscValidIntPointer(m,2); 6633 if (n) PetscValidIntPointer(n,3); 6634 if (m) *m = mat->rmap->n; 6635 if (n) *n = mat->cmap->n; 6636 PetscFunctionReturn(0); 6637 } 6638 6639 /*@C 6640 MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies this matrix by that are owned by 6641 this processor. (The columns of the "diagonal block" for most sparse matrix formats). See :any:`<sec_matlayout>` for details on matrix layouts. 6642 6643 Not Collective, unless matrix has not been allocated, then collective on Mat 6644 6645 Input Parameter: 6646 . mat - the matrix 6647 6648 Output Parameters: 6649 + m - the global index of the first local column, use `NULL` to not obtain this value 6650 - n - one more than the global index of the last local column, use `NULL` to not obtain this value 6651 6652 Level: developer 6653 6654 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRanges()`, `MatGetOwnershipRangesColumn()`, `PetscLayout` 6655 6656 @*/ 6657 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n) 6658 { 6659 PetscFunctionBegin; 6660 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6661 PetscValidType(mat,1); 6662 if (m) PetscValidIntPointer(m,2); 6663 if (n) PetscValidIntPointer(n,3); 6664 MatCheckPreallocated(mat,1); 6665 if (m) *m = mat->cmap->rstart; 6666 if (n) *n = mat->cmap->rend; 6667 PetscFunctionReturn(0); 6668 } 6669 6670 /*@C 6671 MatGetOwnershipRange - For matrices that own values by row, excludes `MATELEMENTAL` and `MATSCALAPACK`, returns the range of matrix rows owned by 6672 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 6673 vector product with this matrix. See :any:`<sec_matlayout>` for details on matrix layouts 6674 6675 Not Collective 6676 6677 Input Parameter: 6678 . mat - the matrix 6679 6680 Output Parameters: 6681 + m - the global index of the first local row, use `NULL` to not obtain this value 6682 - n - one more than the global index of the last local row, use `NULL` to not obtain this value 6683 6684 Note: 6685 This function requires that the matrix be preallocated. If you have not preallocated, consider using 6686 `PetscSplitOwnership`(`MPI_Comm` comm, `PetscInt` *n, `PetscInt` *N) 6687 and then `MPI_Scan()` to calculate prefix sums of the local sizes. 6688 6689 Level: beginner 6690 6691 .seealso: `MatGetOwnershipRanges()`, `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRangesColumn()`, `PetscSplitOwnership()`, `PetscSplitOwnershipBlock()`, 6692 `PetscLayout` 6693 6694 @*/ 6695 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n) 6696 { 6697 PetscFunctionBegin; 6698 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6699 PetscValidType(mat,1); 6700 if (m) PetscValidIntPointer(m,2); 6701 if (n) PetscValidIntPointer(n,3); 6702 MatCheckPreallocated(mat,1); 6703 if (m) *m = mat->rmap->rstart; 6704 if (n) *n = mat->rmap->rend; 6705 PetscFunctionReturn(0); 6706 } 6707 6708 /*@C 6709 MatGetOwnershipRanges - For matrices that own values by row, excludes `MATELEMENTAL` and `MATSCALAPACK`, returns the range of matrix rows owned by 6710 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 6711 vector product with this matrix. See :any:`<sec_matlayout>` for details on matrix layouts 6712 6713 Not Collective, unless matrix has not been allocated, then collective on Mat 6714 6715 Input Parameters: 6716 . mat - the matrix 6717 6718 Output Parameters: 6719 . ranges - start of each processors portion plus one more than the total length at the end 6720 6721 Level: beginner 6722 6723 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRangesColumn()`, `PetscLayout` 6724 6725 @*/ 6726 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges) 6727 { 6728 PetscFunctionBegin; 6729 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6730 PetscValidType(mat,1); 6731 MatCheckPreallocated(mat,1); 6732 PetscCall(PetscLayoutGetRanges(mat->rmap,ranges)); 6733 PetscFunctionReturn(0); 6734 } 6735 6736 /*@C 6737 MatGetOwnershipRangesColumn - Returns the ranges of matrix columns associated with rows of a vector one multiplies this vector by that are owned by 6738 each processor. (The columns of the "diagonal blocks", for most sparse matrix formats). See :any:`<sec_matlayout>` for details on matrix layouts. 6739 6740 Not Collective, unless matrix has not been allocated, then collective on Mat 6741 6742 Input Parameters: 6743 . mat - the matrix 6744 6745 Output Parameters: 6746 . ranges - start of each processors portion plus one more then the total length at the end 6747 6748 Level: beginner 6749 6750 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRanges()` 6751 6752 @*/ 6753 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges) 6754 { 6755 PetscFunctionBegin; 6756 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6757 PetscValidType(mat,1); 6758 MatCheckPreallocated(mat,1); 6759 PetscCall(PetscLayoutGetRanges(mat->cmap,ranges)); 6760 PetscFunctionReturn(0); 6761 } 6762 6763 /*@C 6764 MatGetOwnershipIS - Get row and column ownership of a matrices' values as index sets. For most matrices, excluding `MATELEMENTAL` and `MATSCALAPACK`, this 6765 corresponds to values returned by `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`. For `MATELEMENTAL` and `MATSCALAPACK` the ownership 6766 is more complicated. See :any:`<sec_matlayout>` for details on matrix layouts. 6767 6768 Not Collective 6769 6770 Input Parameter: 6771 . A - matrix 6772 6773 Output Parameters: 6774 + rows - rows in which this process owns elements, , use `NULL` to not obtain this value 6775 - cols - columns in which this process owns elements, use `NULL` to not obtain this value 6776 6777 Level: intermediate 6778 6779 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`, `MatSetValues()`, ``MATELEMENTAL``, ``MATSCALAPACK`` 6780 @*/ 6781 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols) 6782 { 6783 PetscErrorCode (*f)(Mat,IS*,IS*); 6784 6785 PetscFunctionBegin; 6786 MatCheckPreallocated(A,1); 6787 PetscCall(PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f)); 6788 if (f) { 6789 PetscCall((*f)(A,rows,cols)); 6790 } else { /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */ 6791 if (rows) PetscCall(ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows)); 6792 if (cols) PetscCall(ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols)); 6793 } 6794 PetscFunctionReturn(0); 6795 } 6796 6797 /*@C 6798 MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix. 6799 Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric() 6800 to complete the factorization. 6801 6802 Collective on Mat 6803 6804 Input Parameters: 6805 + mat - the matrix 6806 . row - row permutation 6807 . column - column permutation 6808 - info - structure containing 6809 $ levels - number of levels of fill. 6810 $ expected fill - as ratio of original fill. 6811 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 6812 missing diagonal entries) 6813 6814 Output Parameters: 6815 . fact - new matrix that has been symbolically factored 6816 6817 Notes: 6818 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 6819 6820 Most users should employ the simplified KSP interface for linear solvers 6821 instead of working directly with matrix algebra routines such as this. 6822 See, e.g., KSPCreate(). 6823 6824 Level: developer 6825 6826 .seealso: `MatLUFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()` 6827 `MatGetOrdering()`, `MatFactorInfo` 6828 6829 Note: this uses the definition of level of fill as in Y. Saad, 2003 6830 6831 Developer Note: fortran interface is not autogenerated as the f90 6832 interface definition cannot be generated correctly [due to MatFactorInfo] 6833 6834 References: 6835 . * - Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6836 @*/ 6837 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 6838 { 6839 PetscFunctionBegin; 6840 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 6841 PetscValidType(mat,2); 6842 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,3); 6843 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,4); 6844 PetscValidPointer(info,5); 6845 PetscValidPointer(fact,1); 6846 PetscCheck(info->levels >= 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %" PetscInt_FMT,(PetscInt)info->levels); 6847 PetscCheck(info->fill >= 1.0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6848 if (!fact->ops->ilufactorsymbolic) { 6849 MatSolverType stype; 6850 PetscCall(MatFactorGetSolverType(fact,&stype)); 6851 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver type %s",((PetscObject)mat)->type_name,stype); 6852 } 6853 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6854 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6855 MatCheckPreallocated(mat,2); 6856 6857 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0)); 6858 PetscCall((fact->ops->ilufactorsymbolic)(fact,mat,row,col,info)); 6859 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0)); 6860 PetscFunctionReturn(0); 6861 } 6862 6863 /*@C 6864 MatICCFactorSymbolic - Performs symbolic incomplete 6865 Cholesky factorization for a symmetric matrix. Use 6866 MatCholeskyFactorNumeric() to complete the factorization. 6867 6868 Collective on Mat 6869 6870 Input Parameters: 6871 + mat - the matrix 6872 . perm - row and column permutation 6873 - info - structure containing 6874 $ levels - number of levels of fill. 6875 $ expected fill - as ratio of original fill. 6876 6877 Output Parameter: 6878 . fact - the factored matrix 6879 6880 Notes: 6881 Most users should employ the KSP interface for linear solvers 6882 instead of working directly with matrix algebra routines such as this. 6883 See, e.g., KSPCreate(). 6884 6885 Level: developer 6886 6887 .seealso: `MatCholeskyFactorNumeric()`, `MatCholeskyFactor()`, `MatFactorInfo` 6888 6889 Note: this uses the definition of level of fill as in Y. Saad, 2003 6890 6891 Developer Note: fortran interface is not autogenerated as the f90 6892 interface definition cannot be generated correctly [due to MatFactorInfo] 6893 6894 References: 6895 . * - Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6896 @*/ 6897 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 6898 { 6899 PetscFunctionBegin; 6900 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 6901 PetscValidType(mat,2); 6902 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,3); 6903 PetscValidPointer(info,4); 6904 PetscValidPointer(fact,1); 6905 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6906 PetscCheck(info->levels >= 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %" PetscInt_FMT,(PetscInt) info->levels); 6907 PetscCheck(info->fill >= 1.0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6908 if (!(fact)->ops->iccfactorsymbolic) { 6909 MatSolverType stype; 6910 PetscCall(MatFactorGetSolverType(fact,&stype)); 6911 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver type %s",((PetscObject)mat)->type_name,stype); 6912 } 6913 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6914 MatCheckPreallocated(mat,2); 6915 6916 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0)); 6917 PetscCall((fact->ops->iccfactorsymbolic)(fact,mat,perm,info)); 6918 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0)); 6919 PetscFunctionReturn(0); 6920 } 6921 6922 /*@C 6923 MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat 6924 points to an array of valid matrices, they may be reused to store the new 6925 submatrices. 6926 6927 Collective on Mat 6928 6929 Input Parameters: 6930 + mat - the matrix 6931 . n - the number of submatrixes to be extracted (on this processor, may be zero) 6932 . irow, icol - index sets of rows and columns to extract 6933 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6934 6935 Output Parameter: 6936 . submat - the array of submatrices 6937 6938 Notes: 6939 MatCreateSubMatrices() can extract ONLY sequential submatrices 6940 (from both sequential and parallel matrices). Use MatCreateSubMatrix() 6941 to extract a parallel submatrix. 6942 6943 Some matrix types place restrictions on the row and column 6944 indices, such as that they be sorted or that they be equal to each other. 6945 6946 The index sets may not have duplicate entries. 6947 6948 When extracting submatrices from a parallel matrix, each processor can 6949 form a different submatrix by setting the rows and columns of its 6950 individual index sets according to the local submatrix desired. 6951 6952 When finished using the submatrices, the user should destroy 6953 them with MatDestroySubMatrices(). 6954 6955 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 6956 original matrix has not changed from that last call to MatCreateSubMatrices(). 6957 6958 This routine creates the matrices in submat; you should NOT create them before 6959 calling it. It also allocates the array of matrix pointers submat. 6960 6961 For BAIJ matrices the index sets must respect the block structure, that is if they 6962 request one row/column in a block, they must request all rows/columns that are in 6963 that block. For example, if the block size is 2 you cannot request just row 0 and 6964 column 0. 6965 6966 Fortran Note: 6967 The Fortran interface is slightly different from that given below; it 6968 requires one to pass in as submat a Mat (integer) array of size at least n+1. 6969 6970 Level: advanced 6971 6972 .seealso: `MatDestroySubMatrices()`, `MatCreateSubMatrix()`, `MatGetRow()`, `MatGetDiagonal()`, `MatReuse` 6973 @*/ 6974 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 6975 { 6976 PetscInt i; 6977 PetscBool eq; 6978 6979 PetscFunctionBegin; 6980 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6981 PetscValidType(mat,1); 6982 if (n) { 6983 PetscValidPointer(irow,3); 6984 for (i=0; i<n; i++) PetscValidHeaderSpecific(irow[i],IS_CLASSID,3); 6985 PetscValidPointer(icol,4); 6986 for (i=0; i<n; i++) PetscValidHeaderSpecific(icol[i],IS_CLASSID,4); 6987 } 6988 PetscValidPointer(submat,6); 6989 if (n && scall == MAT_REUSE_MATRIX) { 6990 PetscValidPointer(*submat,6); 6991 for (i=0; i<n; i++) PetscValidHeaderSpecific((*submat)[i],MAT_CLASSID,6); 6992 } 6993 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6994 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6995 MatCheckPreallocated(mat,1); 6996 PetscCall(PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0)); 6997 PetscUseTypeMethod(mat,createsubmatrices ,n,irow,icol,scall,submat); 6998 PetscCall(PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0)); 6999 for (i=0; i<n; i++) { 7000 (*submat)[i]->factortype = MAT_FACTOR_NONE; /* in case in place factorization was previously done on submatrix */ 7001 PetscCall(ISEqualUnsorted(irow[i],icol[i],&eq)); 7002 if (eq) { 7003 PetscCall(MatPropagateSymmetryOptions(mat,(*submat)[i])); 7004 } 7005 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 7006 if (mat->boundtocpu && mat->bindingpropagates) { 7007 PetscCall(MatBindToCPU((*submat)[i],PETSC_TRUE)); 7008 PetscCall(MatSetBindingPropagates((*submat)[i],PETSC_TRUE)); 7009 } 7010 #endif 7011 } 7012 PetscFunctionReturn(0); 7013 } 7014 7015 /*@C 7016 MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms). 7017 7018 Collective on Mat 7019 7020 Input Parameters: 7021 + mat - the matrix 7022 . n - the number of submatrixes to be extracted 7023 . irow, icol - index sets of rows and columns to extract 7024 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 7025 7026 Output Parameter: 7027 . submat - the array of submatrices 7028 7029 Level: advanced 7030 7031 .seealso: `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRow()`, `MatGetDiagonal()`, `MatReuse` 7032 @*/ 7033 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 7034 { 7035 PetscInt i; 7036 PetscBool eq; 7037 7038 PetscFunctionBegin; 7039 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7040 PetscValidType(mat,1); 7041 if (n) { 7042 PetscValidPointer(irow,3); 7043 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 7044 PetscValidPointer(icol,4); 7045 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 7046 } 7047 PetscValidPointer(submat,6); 7048 if (n && scall == MAT_REUSE_MATRIX) { 7049 PetscValidPointer(*submat,6); 7050 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 7051 } 7052 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7053 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7054 MatCheckPreallocated(mat,1); 7055 7056 PetscCall(PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0)); 7057 PetscUseTypeMethod(mat,createsubmatricesmpi ,n,irow,icol,scall,submat); 7058 PetscCall(PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0)); 7059 for (i=0; i<n; i++) { 7060 PetscCall(ISEqualUnsorted(irow[i],icol[i],&eq)); 7061 if (eq) { 7062 PetscCall(MatPropagateSymmetryOptions(mat,(*submat)[i])); 7063 } 7064 } 7065 PetscFunctionReturn(0); 7066 } 7067 7068 /*@C 7069 MatDestroyMatrices - Destroys an array of matrices. 7070 7071 Collective on Mat 7072 7073 Input Parameters: 7074 + n - the number of local matrices 7075 - mat - the matrices (note that this is a pointer to the array of matrices) 7076 7077 Level: advanced 7078 7079 Notes: 7080 Frees not only the matrices, but also the array that contains the matrices 7081 In Fortran will not free the array. 7082 7083 .seealso: `MatCreateSubMatrices()` `MatDestroySubMatrices()` 7084 @*/ 7085 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[]) 7086 { 7087 PetscInt i; 7088 7089 PetscFunctionBegin; 7090 if (!*mat) PetscFunctionReturn(0); 7091 PetscCheck(n >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %" PetscInt_FMT,n); 7092 PetscValidPointer(mat,2); 7093 7094 for (i=0; i<n; i++) { 7095 PetscCall(MatDestroy(&(*mat)[i])); 7096 } 7097 7098 /* memory is allocated even if n = 0 */ 7099 PetscCall(PetscFree(*mat)); 7100 PetscFunctionReturn(0); 7101 } 7102 7103 /*@C 7104 MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices(). 7105 7106 Collective on Mat 7107 7108 Input Parameters: 7109 + n - the number of local matrices 7110 - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling 7111 sequence of MatCreateSubMatrices()) 7112 7113 Level: advanced 7114 7115 Notes: 7116 Frees not only the matrices, but also the array that contains the matrices 7117 In Fortran will not free the array. 7118 7119 .seealso: `MatCreateSubMatrices()` 7120 @*/ 7121 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[]) 7122 { 7123 Mat mat0; 7124 7125 PetscFunctionBegin; 7126 if (!*mat) PetscFunctionReturn(0); 7127 /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */ 7128 PetscCheck(n >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %" PetscInt_FMT,n); 7129 PetscValidPointer(mat,2); 7130 7131 mat0 = (*mat)[0]; 7132 if (mat0 && mat0->ops->destroysubmatrices) { 7133 PetscCall((mat0->ops->destroysubmatrices)(n,mat)); 7134 } else { 7135 PetscCall(MatDestroyMatrices(n,mat)); 7136 } 7137 PetscFunctionReturn(0); 7138 } 7139 7140 /*@C 7141 MatGetSeqNonzeroStructure - Extracts the nonzero structure from a matrix and stores it, in its entirety, on each process 7142 7143 Collective on Mat 7144 7145 Input Parameters: 7146 . mat - the matrix 7147 7148 Output Parameter: 7149 . matstruct - the sequential matrix with the nonzero structure of mat 7150 7151 Level: intermediate 7152 7153 .seealso: `MatDestroySeqNonzeroStructure()`, `MatCreateSubMatrices()`, `MatDestroyMatrices()` 7154 @*/ 7155 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct) 7156 { 7157 PetscFunctionBegin; 7158 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7159 PetscValidPointer(matstruct,2); 7160 7161 PetscValidType(mat,1); 7162 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7163 MatCheckPreallocated(mat,1); 7164 7165 PetscCall(PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0)); 7166 PetscUseTypeMethod(mat,getseqnonzerostructure ,matstruct); 7167 PetscCall(PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0)); 7168 PetscFunctionReturn(0); 7169 } 7170 7171 /*@C 7172 MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure(). 7173 7174 Collective on Mat 7175 7176 Input Parameters: 7177 . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling 7178 sequence of MatGetSequentialNonzeroStructure()) 7179 7180 Level: advanced 7181 7182 Notes: 7183 Frees not only the matrices, but also the array that contains the matrices 7184 7185 .seealso: `MatGetSeqNonzeroStructure()` 7186 @*/ 7187 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat) 7188 { 7189 PetscFunctionBegin; 7190 PetscValidPointer(mat,1); 7191 PetscCall(MatDestroy(mat)); 7192 PetscFunctionReturn(0); 7193 } 7194 7195 /*@ 7196 MatIncreaseOverlap - Given a set of submatrices indicated by index sets, 7197 replaces the index sets by larger ones that represent submatrices with 7198 additional overlap. 7199 7200 Collective on Mat 7201 7202 Input Parameters: 7203 + mat - the matrix 7204 . n - the number of index sets 7205 . is - the array of index sets (these index sets will changed during the call) 7206 - ov - the additional overlap requested 7207 7208 Options Database: 7209 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7210 7211 Level: developer 7212 7213 Developer Note: 7214 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. 7215 7216 .seealso: `MatCreateSubMatrices()` 7217 @*/ 7218 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov) 7219 { 7220 PetscInt i,bs,cbs; 7221 7222 PetscFunctionBegin; 7223 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7224 PetscValidType(mat,1); 7225 PetscValidLogicalCollectiveInt(mat,n,2); 7226 PetscCheck(n >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %" PetscInt_FMT,n); 7227 if (n) { 7228 PetscValidPointer(is,3); 7229 for (i = 0; i < n; i++) PetscValidHeaderSpecific(is[i],IS_CLASSID,3); 7230 } 7231 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7232 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7233 MatCheckPreallocated(mat,1); 7234 7235 if (!ov || !n) PetscFunctionReturn(0); 7236 PetscCall(PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0)); 7237 PetscUseTypeMethod(mat,increaseoverlap ,n,is,ov); 7238 PetscCall(PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0)); 7239 PetscCall(MatGetBlockSizes(mat,&bs,&cbs)); 7240 if (bs == cbs) { 7241 for (i=0; i<n; i++) { 7242 PetscCall(ISSetBlockSize(is[i],bs)); 7243 } 7244 } 7245 PetscFunctionReturn(0); 7246 } 7247 7248 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt); 7249 7250 /*@ 7251 MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across 7252 a sub communicator, replaces the index sets by larger ones that represent submatrices with 7253 additional overlap. 7254 7255 Collective on Mat 7256 7257 Input Parameters: 7258 + mat - the matrix 7259 . n - the number of index sets 7260 . is - the array of index sets (these index sets will changed during the call) 7261 - ov - the additional overlap requested 7262 7263 Options Database: 7264 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7265 7266 Level: developer 7267 7268 .seealso: `MatCreateSubMatrices()` 7269 @*/ 7270 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov) 7271 { 7272 PetscInt i; 7273 7274 PetscFunctionBegin; 7275 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7276 PetscValidType(mat,1); 7277 PetscCheck(n >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %" PetscInt_FMT,n); 7278 if (n) { 7279 PetscValidPointer(is,3); 7280 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 7281 } 7282 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7283 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7284 MatCheckPreallocated(mat,1); 7285 if (!ov) PetscFunctionReturn(0); 7286 PetscCall(PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0)); 7287 for (i=0; i<n; i++) { 7288 PetscCall(MatIncreaseOverlapSplit_Single(mat,&is[i],ov)); 7289 } 7290 PetscCall(PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0)); 7291 PetscFunctionReturn(0); 7292 } 7293 7294 /*@ 7295 MatGetBlockSize - Returns the matrix block size. 7296 7297 Not Collective 7298 7299 Input Parameter: 7300 . mat - the matrix 7301 7302 Output Parameter: 7303 . bs - block size 7304 7305 Notes: 7306 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7307 7308 If the block size has not been set yet this routine returns 1. 7309 7310 Level: intermediate 7311 7312 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSizes()` 7313 @*/ 7314 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs) 7315 { 7316 PetscFunctionBegin; 7317 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7318 PetscValidIntPointer(bs,2); 7319 *bs = PetscAbs(mat->rmap->bs); 7320 PetscFunctionReturn(0); 7321 } 7322 7323 /*@ 7324 MatGetBlockSizes - Returns the matrix block row and column sizes. 7325 7326 Not Collective 7327 7328 Input Parameter: 7329 . mat - the matrix 7330 7331 Output Parameters: 7332 + rbs - row block size 7333 - cbs - column block size 7334 7335 Notes: 7336 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7337 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7338 7339 If a block size has not been set yet this routine returns 1. 7340 7341 Level: intermediate 7342 7343 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSize()`, `MatSetBlockSizes()` 7344 @*/ 7345 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs) 7346 { 7347 PetscFunctionBegin; 7348 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7349 if (rbs) PetscValidIntPointer(rbs,2); 7350 if (cbs) PetscValidIntPointer(cbs,3); 7351 if (rbs) *rbs = PetscAbs(mat->rmap->bs); 7352 if (cbs) *cbs = PetscAbs(mat->cmap->bs); 7353 PetscFunctionReturn(0); 7354 } 7355 7356 /*@ 7357 MatSetBlockSize - Sets the matrix block size. 7358 7359 Logically Collective on Mat 7360 7361 Input Parameters: 7362 + mat - the matrix 7363 - bs - block size 7364 7365 Notes: 7366 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7367 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7368 7369 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size 7370 is compatible with the matrix local sizes. 7371 7372 Level: intermediate 7373 7374 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`, `MatGetBlockSizes()` 7375 @*/ 7376 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs) 7377 { 7378 PetscFunctionBegin; 7379 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7380 PetscValidLogicalCollectiveInt(mat,bs,2); 7381 PetscCall(MatSetBlockSizes(mat,bs,bs)); 7382 PetscFunctionReturn(0); 7383 } 7384 7385 typedef struct { 7386 PetscInt n; 7387 IS *is; 7388 Mat *mat; 7389 PetscObjectState nonzerostate; 7390 Mat C; 7391 } EnvelopeData; 7392 7393 static PetscErrorCode EnvelopeDataDestroy(EnvelopeData *edata) 7394 { 7395 for (PetscInt i=0; i<edata->n; i++) { 7396 PetscCall(ISDestroy(&edata->is[i])); 7397 } 7398 PetscCall(PetscFree(edata->is)); 7399 PetscCall(PetscFree(edata)); 7400 return 0; 7401 } 7402 7403 /* 7404 MatComputeVariableBlockEnvelope - Given a matrix whose nonzeros are in blocks along the diagonal this computes and stores 7405 the sizes of these blocks in the matrix. An individual block may lie over several processes. 7406 7407 Collective on mat 7408 7409 Input Parameter: 7410 . mat - the matrix 7411 7412 Notes: 7413 There can be zeros within the blocks 7414 7415 The blocks can overlap between processes, including laying on more than two processes 7416 7417 */ 7418 static PetscErrorCode MatComputeVariableBlockEnvelope(Mat mat) 7419 { 7420 PetscInt n,*sizes,*starts,i = 0,env = 0, tbs = 0, lblocks = 0,rstart,II,ln = 0,cnt = 0,cstart,cend; 7421 PetscInt *diag,*odiag,sc; 7422 VecScatter scatter; 7423 PetscScalar *seqv; 7424 const PetscScalar *parv; 7425 const PetscInt *ia,*ja; 7426 PetscBool set,flag,done; 7427 Mat AA = mat,A; 7428 MPI_Comm comm; 7429 PetscMPIInt rank,size,tag; 7430 MPI_Status status; 7431 PetscContainer container; 7432 EnvelopeData *edata; 7433 Vec seq,par; 7434 IS isglobal; 7435 7436 PetscFunctionBegin; 7437 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7438 PetscCall(MatIsSymmetricKnown(mat,&set,&flag)); 7439 if (!set || !flag) { 7440 /* TOO: only needs nonzero structure of transpose */ 7441 PetscCall(MatTranspose(mat,MAT_INITIAL_MATRIX,&AA)); 7442 PetscCall(MatAXPY(AA,1.0,mat,DIFFERENT_NONZERO_PATTERN)); 7443 } 7444 PetscCall(MatAIJGetLocalMat(AA,&A)); 7445 PetscCall(MatGetRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ia,&ja,&done)); 7446 PetscCheck(done,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Unable to get IJ structure from matrix"); 7447 7448 PetscCall(MatGetLocalSize(mat,&n,NULL)); 7449 PetscCall(PetscObjectGetNewTag((PetscObject)mat,&tag)); 7450 PetscCall(PetscObjectGetComm((PetscObject)mat,&comm)); 7451 PetscCallMPI(MPI_Comm_size(comm,&size)); 7452 PetscCallMPI(MPI_Comm_rank(comm,&rank)); 7453 7454 PetscCall(PetscMalloc2(n,&sizes,n,&starts)); 7455 7456 if (rank > 0) { 7457 PetscCallMPI(MPI_Recv(&env,1,MPIU_INT,rank-1,tag,comm,&status)); 7458 PetscCallMPI(MPI_Recv(&tbs,1,MPIU_INT,rank-1,tag,comm,&status)); 7459 } 7460 PetscCall(MatGetOwnershipRange(mat,&rstart,NULL)); 7461 for (i=0; i<n; i++) { 7462 env = PetscMax(env,ja[ia[i+1]-1]); 7463 II = rstart + i; 7464 if (env == II) { 7465 starts[lblocks] = tbs; 7466 sizes[lblocks++] = 1 + II - tbs; 7467 tbs = 1 + II; 7468 } 7469 } 7470 if (rank < size-1) { 7471 PetscCallMPI(MPI_Send(&env,1,MPIU_INT,rank+1,tag,comm)); 7472 PetscCallMPI(MPI_Send(&tbs,1,MPIU_INT,rank+1,tag,comm)); 7473 } 7474 7475 PetscCall(MatRestoreRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ia,&ja,&done)); 7476 if (!set || !flag) { 7477 PetscCall(MatDestroy(&AA)); 7478 } 7479 PetscCall(MatDestroy(&A)); 7480 7481 PetscCall(PetscNew(&edata)); 7482 PetscCall(MatGetNonzeroState(mat,&edata->nonzerostate)); 7483 edata->n = lblocks; 7484 /* create IS needed for extracting blocks from the original matrix */ 7485 PetscCall(PetscMalloc1(lblocks,&edata->is)); 7486 for (PetscInt i=0; i<lblocks; i++) { 7487 PetscCall(ISCreateStride(PETSC_COMM_SELF,sizes[i],starts[i],1,&edata->is[i])); 7488 } 7489 7490 /* Create the resulting inverse matrix structure with preallocation information */ 7491 PetscCall(MatCreate(PetscObjectComm((PetscObject)mat),&edata->C)); 7492 PetscCall(MatSetSizes(edata->C,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N)); 7493 PetscCall(MatSetBlockSizesFromMats(edata->C,mat,mat)); 7494 PetscCall(MatSetType(edata->C,MATAIJ)); 7495 7496 /* Communicate the start and end of each row, from each block to the correct rank */ 7497 /* TODO: Use PetscSF instead of VecScatter */ 7498 for (PetscInt i=0; i<lblocks; i++) ln += sizes[i]; 7499 PetscCall(VecCreateSeq(PETSC_COMM_SELF,2*ln,&seq)); 7500 PetscCall(VecGetArrayWrite(seq,&seqv)); 7501 for (PetscInt i=0; i<lblocks; i++) { 7502 for (PetscInt j=0; j<sizes[i]; j++) { 7503 seqv[cnt] = starts[i]; 7504 seqv[cnt+1] = starts[i] + sizes[i]; 7505 cnt += 2; 7506 } 7507 } 7508 PetscCall(VecRestoreArrayWrite(seq,&seqv)); 7509 PetscCallMPI(MPI_Scan(&cnt,&sc,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat))); 7510 sc -= cnt; 7511 PetscCall(VecCreateMPI(PetscObjectComm((PetscObject)mat),2*mat->rmap->n,2*mat->rmap->N,&par)); 7512 PetscCall(ISCreateStride(PETSC_COMM_SELF,cnt,sc,1,&isglobal)); 7513 PetscCall(VecScatterCreate(seq, NULL ,par, isglobal,&scatter)); 7514 PetscCall(ISDestroy(&isglobal)); 7515 PetscCall(VecScatterBegin(scatter,seq,par,INSERT_VALUES,SCATTER_FORWARD)); 7516 PetscCall(VecScatterEnd(scatter,seq,par,INSERT_VALUES,SCATTER_FORWARD)); 7517 PetscCall(VecScatterDestroy(&scatter)); 7518 PetscCall(VecDestroy(&seq)); 7519 PetscCall(MatGetOwnershipRangeColumn(mat,&cstart,&cend)); 7520 PetscCall(PetscMalloc2(mat->rmap->n,&diag,mat->rmap->n,&odiag)); 7521 PetscCall(VecGetArrayRead(par,&parv)); 7522 cnt = 0; 7523 PetscCall(MatGetSize(mat,NULL,&n)); 7524 for (PetscInt i=0; i<mat->rmap->n; i++) { 7525 PetscInt start,end,d = 0,od = 0; 7526 7527 start = (PetscInt)PetscRealPart(parv[cnt]); 7528 end = (PetscInt)PetscRealPart(parv[cnt+1]); 7529 cnt += 2; 7530 7531 if (start < cstart) {od += cstart - start + n - cend; d += cend - cstart;} 7532 else if (start < cend) {od += n - cend; d += cend - start;} 7533 else od += n - start; 7534 if (end <= cstart) {od -= cstart - end + n - cend; d -= cend - cstart;} 7535 else if (end < cend) {od -= n - cend; d -= cend - end;} 7536 else od -= n - end; 7537 7538 odiag[i] = od; 7539 diag[i] = d; 7540 } 7541 PetscCall(VecRestoreArrayRead(par,&parv)); 7542 PetscCall(VecDestroy(&par)); 7543 PetscCall(MatXAIJSetPreallocation(edata->C,mat->rmap->bs,diag,odiag,NULL,NULL)); 7544 PetscCall(PetscFree2(diag,odiag)); 7545 PetscCall(PetscFree2(sizes,starts)); 7546 7547 PetscCall(PetscContainerCreate(PETSC_COMM_SELF,&container)); 7548 PetscCall(PetscContainerSetPointer(container,edata)); 7549 PetscCall(PetscContainerSetUserDestroy(container,(PetscErrorCode (*)(void*))EnvelopeDataDestroy)); 7550 PetscCall(PetscObjectCompose((PetscObject)mat,"EnvelopeData",(PetscObject)container)); 7551 PetscCall(PetscObjectDereference((PetscObject)container)); 7552 PetscFunctionReturn(0); 7553 } 7554 7555 /*@ 7556 MatInvertVariableBlockEnvelope - set matrix C to be the inverted block diagonal of matrix A 7557 7558 Collective on Mat 7559 7560 Input Parameters: 7561 . A - the matrix 7562 7563 Output Parameters: 7564 . C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set. 7565 7566 Notes: 7567 For efficiency the matrix A should have all the nonzero entries clustered in smallish blocks along the diagonal. 7568 7569 Level: advanced 7570 7571 .seealso: MatInvertBlockDiagonal(), MatComputeBlockDiagonal() 7572 @*/ 7573 PetscErrorCode MatInvertVariableBlockEnvelope(Mat A,MatReuse reuse, Mat *C) 7574 { 7575 PetscContainer container; 7576 EnvelopeData *edata; 7577 PetscObjectState nonzerostate; 7578 7579 PetscFunctionBegin; 7580 PetscCall(PetscObjectQuery((PetscObject)A,"EnvelopeData",(PetscObject*)&container)); 7581 if (!container) { 7582 PetscCall(MatComputeVariableBlockEnvelope(A)); 7583 PetscCall(PetscObjectQuery((PetscObject)A,"EnvelopeData",(PetscObject*)&container)); 7584 } 7585 PetscCall(PetscContainerGetPointer(container,(void**)&edata)); 7586 PetscCall(MatGetNonzeroState(A,&nonzerostate)); 7587 PetscCheck(nonzerostate <= edata->nonzerostate,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Cannot handle changes to matrix nonzero structure"); 7588 PetscCheck(reuse != MAT_REUSE_MATRIX || *C == edata->C,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C matrix must be the same as previously output"); 7589 7590 PetscCall(MatCreateSubMatrices(A,edata->n,edata->is,edata->is,MAT_INITIAL_MATRIX,&edata->mat)); 7591 *C = edata->C; 7592 7593 for (PetscInt i=0; i<edata->n; i++) { 7594 Mat D; 7595 PetscScalar *dvalues; 7596 7597 PetscCall(MatConvert(edata->mat[i], MATSEQDENSE,MAT_INITIAL_MATRIX,&D)); 7598 PetscCall(MatSetOption(*C,MAT_ROW_ORIENTED,PETSC_FALSE)); 7599 PetscCall(MatSeqDenseInvert(D)); 7600 PetscCall(MatDenseGetArray(D,&dvalues)); 7601 PetscCall(MatSetValuesIS(*C,edata->is[i],edata->is[i],dvalues,INSERT_VALUES)); 7602 PetscCall(MatDestroy(&D)); 7603 } 7604 PetscCall(MatDestroySubMatrices(edata->n,&edata->mat)); 7605 PetscCall(MatAssemblyBegin(*C,MAT_FINAL_ASSEMBLY)); 7606 PetscCall(MatAssemblyEnd(*C,MAT_FINAL_ASSEMBLY)); 7607 PetscFunctionReturn(0); 7608 } 7609 7610 /*@ 7611 MatSetVariableBlockSizes - Sets diagonal point-blocks of the matrix that need not be of the same size 7612 7613 Logically Collective on Mat 7614 7615 Input Parameters: 7616 + mat - the matrix 7617 . nblocks - the number of blocks on this process, each block can only exist on a single process 7618 - bsizes - the block sizes 7619 7620 Notes: 7621 Currently used by PCVPBJACOBI for AIJ matrices 7622 7623 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. 7624 7625 Level: intermediate 7626 7627 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`, `MatGetBlockSizes()`, `MatGetVariableBlockSizes()`, `MatComputeVariableBlockEnvelope()`, `PCVPBJACOBI` 7628 @*/ 7629 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes) 7630 { 7631 PetscInt i,ncnt = 0, nlocal; 7632 7633 PetscFunctionBegin; 7634 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7635 PetscCheck(nblocks >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero"); 7636 PetscCall(MatGetLocalSize(mat,&nlocal,NULL)); 7637 for (i=0; i<nblocks; i++) ncnt += bsizes[i]; 7638 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); 7639 PetscCall(PetscFree(mat->bsizes)); 7640 mat->nblocks = nblocks; 7641 PetscCall(PetscMalloc1(nblocks,&mat->bsizes)); 7642 PetscCall(PetscArraycpy(mat->bsizes,bsizes,nblocks)); 7643 PetscFunctionReturn(0); 7644 } 7645 7646 /*@C 7647 MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size 7648 7649 Logically Collective on Mat 7650 7651 Input Parameter: 7652 . mat - the matrix 7653 7654 Output Parameters: 7655 + nblocks - the number of blocks on this process 7656 - bsizes - the block sizes 7657 7658 Notes: Currently not supported from Fortran 7659 7660 Level: intermediate 7661 7662 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`, `MatGetBlockSizes()`, `MatSetVariableBlockSizes()`, `MatComputeVariableBlockEnvelope()` 7663 @*/ 7664 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes) 7665 { 7666 PetscFunctionBegin; 7667 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7668 *nblocks = mat->nblocks; 7669 *bsizes = mat->bsizes; 7670 PetscFunctionReturn(0); 7671 } 7672 7673 /*@ 7674 MatSetBlockSizes - Sets the matrix block row and column sizes. 7675 7676 Logically Collective on Mat 7677 7678 Input Parameters: 7679 + mat - the matrix 7680 . rbs - row block size 7681 - cbs - column block size 7682 7683 Notes: 7684 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7685 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7686 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7687 7688 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes 7689 are compatible with the matrix local sizes. 7690 7691 The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs(). 7692 7693 Level: intermediate 7694 7695 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSize()`, `MatGetBlockSizes()` 7696 @*/ 7697 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs) 7698 { 7699 PetscFunctionBegin; 7700 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7701 PetscValidLogicalCollectiveInt(mat,rbs,2); 7702 PetscValidLogicalCollectiveInt(mat,cbs,3); 7703 PetscTryTypeMethod(mat,setblocksizes,rbs,cbs); 7704 if (mat->rmap->refcnt) { 7705 ISLocalToGlobalMapping l2g = NULL; 7706 PetscLayout nmap = NULL; 7707 7708 PetscCall(PetscLayoutDuplicate(mat->rmap,&nmap)); 7709 if (mat->rmap->mapping) { 7710 PetscCall(ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g)); 7711 } 7712 PetscCall(PetscLayoutDestroy(&mat->rmap)); 7713 mat->rmap = nmap; 7714 mat->rmap->mapping = l2g; 7715 } 7716 if (mat->cmap->refcnt) { 7717 ISLocalToGlobalMapping l2g = NULL; 7718 PetscLayout nmap = NULL; 7719 7720 PetscCall(PetscLayoutDuplicate(mat->cmap,&nmap)); 7721 if (mat->cmap->mapping) { 7722 PetscCall(ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g)); 7723 } 7724 PetscCall(PetscLayoutDestroy(&mat->cmap)); 7725 mat->cmap = nmap; 7726 mat->cmap->mapping = l2g; 7727 } 7728 PetscCall(PetscLayoutSetBlockSize(mat->rmap,rbs)); 7729 PetscCall(PetscLayoutSetBlockSize(mat->cmap,cbs)); 7730 PetscFunctionReturn(0); 7731 } 7732 7733 /*@ 7734 MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices 7735 7736 Logically Collective on Mat 7737 7738 Input Parameters: 7739 + mat - the matrix 7740 . fromRow - matrix from which to copy row block size 7741 - fromCol - matrix from which to copy column block size (can be same as fromRow) 7742 7743 Level: developer 7744 7745 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()` 7746 @*/ 7747 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol) 7748 { 7749 PetscFunctionBegin; 7750 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7751 PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2); 7752 PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3); 7753 if (fromRow->rmap->bs > 0) PetscCall(PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs)); 7754 if (fromCol->cmap->bs > 0) PetscCall(PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs)); 7755 PetscFunctionReturn(0); 7756 } 7757 7758 /*@ 7759 MatResidual - Default routine to calculate the residual. 7760 7761 Collective on Mat 7762 7763 Input Parameters: 7764 + mat - the matrix 7765 . b - the right-hand-side 7766 - x - the approximate solution 7767 7768 Output Parameter: 7769 . r - location to store the residual 7770 7771 Level: developer 7772 7773 .seealso: `PCMGSetResidual()` 7774 @*/ 7775 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r) 7776 { 7777 PetscFunctionBegin; 7778 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7779 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 7780 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 7781 PetscValidHeaderSpecific(r,VEC_CLASSID,4); 7782 PetscValidType(mat,1); 7783 MatCheckPreallocated(mat,1); 7784 PetscCall(PetscLogEventBegin(MAT_Residual,mat,0,0,0)); 7785 if (!mat->ops->residual) { 7786 PetscCall(MatMult(mat,x,r)); 7787 PetscCall(VecAYPX(r,-1.0,b)); 7788 } else { 7789 PetscUseTypeMethod(mat,residual ,b,x,r); 7790 } 7791 PetscCall(PetscLogEventEnd(MAT_Residual,mat,0,0,0)); 7792 PetscFunctionReturn(0); 7793 } 7794 7795 /*@C 7796 MatGetRowIJ - Returns the compressed row storage i and j indices for the local rows of a sparse matrix 7797 7798 Collective on Mat 7799 7800 Input Parameters: 7801 + mat - the matrix 7802 . shift - 0 or 1 indicating we want the indices starting at 0 or 1 7803 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 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 7808 Output Parameters: 7809 + n - number of local rows in the (possibly compressed) matrix 7810 . ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix 7811 . ja - the column indices 7812 - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers 7813 are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set 7814 7815 Level: developer 7816 7817 Notes: 7818 You CANNOT change any of the ia[] or ja[] values. 7819 7820 Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values. 7821 7822 Fortran Notes: 7823 In Fortran use 7824 $ 7825 $ PetscInt ia(1), ja(1) 7826 $ PetscOffset iia, jja 7827 $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr) 7828 $ ! Access the ith and jth entries via ia(iia + i) and ja(jja + j) 7829 7830 or 7831 $ 7832 $ PetscInt, pointer :: ia(:),ja(:) 7833 $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr) 7834 $ ! Access the ith and jth entries via ia(i) and ja(j) 7835 7836 .seealso: `MatGetColumnIJ()`, `MatRestoreRowIJ()`, `MatSeqAIJGetArray()` 7837 @*/ 7838 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7839 { 7840 PetscFunctionBegin; 7841 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7842 PetscValidType(mat,1); 7843 if (n) PetscValidIntPointer(n,5); 7844 if (ia) PetscValidPointer(ia,6); 7845 if (ja) PetscValidPointer(ja,7); 7846 if (done) PetscValidBoolPointer(done,8); 7847 MatCheckPreallocated(mat,1); 7848 if (!mat->ops->getrowij && done) *done = PETSC_FALSE; 7849 else { 7850 if (done) *done = PETSC_TRUE; 7851 PetscCall(PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0)); 7852 PetscUseTypeMethod(mat,getrowij ,shift,symmetric,inodecompressed,n,ia,ja,done); 7853 PetscCall(PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0)); 7854 } 7855 PetscFunctionReturn(0); 7856 } 7857 7858 /*@C 7859 MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices. 7860 7861 Collective on Mat 7862 7863 Input Parameters: 7864 + mat - the matrix 7865 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7866 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7867 symmetrized 7868 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7869 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7870 always used. 7871 . n - number of columns in the (possibly compressed) matrix 7872 . ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix 7873 - ja - the row indices 7874 7875 Output Parameters: 7876 . done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned 7877 7878 Level: developer 7879 7880 .seealso: `MatGetRowIJ()`, `MatRestoreColumnIJ()` 7881 @*/ 7882 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7883 { 7884 PetscFunctionBegin; 7885 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7886 PetscValidType(mat,1); 7887 PetscValidIntPointer(n,5); 7888 if (ia) PetscValidPointer(ia,6); 7889 if (ja) PetscValidPointer(ja,7); 7890 PetscValidBoolPointer(done,8); 7891 MatCheckPreallocated(mat,1); 7892 if (!mat->ops->getcolumnij) *done = PETSC_FALSE; 7893 else { 7894 *done = PETSC_TRUE; 7895 PetscUseTypeMethod(mat,getcolumnij ,shift,symmetric,inodecompressed,n,ia,ja,done); 7896 } 7897 PetscFunctionReturn(0); 7898 } 7899 7900 /*@C 7901 MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with 7902 MatGetRowIJ(). 7903 7904 Collective on Mat 7905 7906 Input Parameters: 7907 + mat - the matrix 7908 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7909 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7910 symmetrized 7911 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7912 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7913 always used. 7914 . n - size of (possibly compressed) matrix 7915 . ia - the row pointers 7916 - ja - the column indices 7917 7918 Output Parameters: 7919 . done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7920 7921 Note: 7922 This routine zeros out n, ia, and ja. This is to prevent accidental 7923 us of the array after it has been restored. If you pass NULL, it will 7924 not zero the pointers. Use of ia or ja after MatRestoreRowIJ() is invalid. 7925 7926 Level: developer 7927 7928 .seealso: `MatGetRowIJ()`, `MatRestoreColumnIJ()` 7929 @*/ 7930 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7931 { 7932 PetscFunctionBegin; 7933 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7934 PetscValidType(mat,1); 7935 if (ia) PetscValidPointer(ia,6); 7936 if (ja) PetscValidPointer(ja,7); 7937 if (done) PetscValidBoolPointer(done,8); 7938 MatCheckPreallocated(mat,1); 7939 7940 if (!mat->ops->restorerowij && done) *done = PETSC_FALSE; 7941 else { 7942 if (done) *done = PETSC_TRUE; 7943 PetscUseTypeMethod(mat,restorerowij ,shift,symmetric,inodecompressed,n,ia,ja,done); 7944 if (n) *n = 0; 7945 if (ia) *ia = NULL; 7946 if (ja) *ja = NULL; 7947 } 7948 PetscFunctionReturn(0); 7949 } 7950 7951 /*@C 7952 MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with 7953 MatGetColumnIJ(). 7954 7955 Collective on Mat 7956 7957 Input Parameters: 7958 + mat - the matrix 7959 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7960 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7961 symmetrized 7962 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7963 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7964 always used. 7965 7966 Output Parameters: 7967 + n - size of (possibly compressed) matrix 7968 . ia - the column pointers 7969 . ja - the row indices 7970 - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7971 7972 Level: developer 7973 7974 .seealso: `MatGetColumnIJ()`, `MatRestoreRowIJ()` 7975 @*/ 7976 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7977 { 7978 PetscFunctionBegin; 7979 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7980 PetscValidType(mat,1); 7981 if (ia) PetscValidPointer(ia,6); 7982 if (ja) PetscValidPointer(ja,7); 7983 PetscValidBoolPointer(done,8); 7984 MatCheckPreallocated(mat,1); 7985 7986 if (!mat->ops->restorecolumnij) *done = PETSC_FALSE; 7987 else { 7988 *done = PETSC_TRUE; 7989 PetscUseTypeMethod(mat,restorecolumnij ,shift,symmetric,inodecompressed,n,ia,ja,done); 7990 if (n) *n = 0; 7991 if (ia) *ia = NULL; 7992 if (ja) *ja = NULL; 7993 } 7994 PetscFunctionReturn(0); 7995 } 7996 7997 /*@C 7998 MatColoringPatch -Used inside matrix coloring routines that 7999 use MatGetRowIJ() and/or MatGetColumnIJ(). 8000 8001 Collective on Mat 8002 8003 Input Parameters: 8004 + mat - the matrix 8005 . ncolors - max color value 8006 . n - number of entries in colorarray 8007 - colorarray - array indicating color for each column 8008 8009 Output Parameters: 8010 . iscoloring - coloring generated using colorarray information 8011 8012 Level: developer 8013 8014 .seealso: `MatGetRowIJ()`, `MatGetColumnIJ()` 8015 8016 @*/ 8017 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring) 8018 { 8019 PetscFunctionBegin; 8020 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8021 PetscValidType(mat,1); 8022 PetscValidIntPointer(colorarray,4); 8023 PetscValidPointer(iscoloring,5); 8024 MatCheckPreallocated(mat,1); 8025 8026 if (!mat->ops->coloringpatch) { 8027 PetscCall(ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring)); 8028 } else { 8029 PetscUseTypeMethod(mat,coloringpatch ,ncolors,n,colorarray,iscoloring); 8030 } 8031 PetscFunctionReturn(0); 8032 } 8033 8034 /*@ 8035 MatSetUnfactored - Resets a factored matrix to be treated as unfactored. 8036 8037 Logically Collective on Mat 8038 8039 Input Parameter: 8040 . mat - the factored matrix to be reset 8041 8042 Notes: 8043 This routine should be used only with factored matrices formed by in-place 8044 factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE 8045 format). This option can save memory, for example, when solving nonlinear 8046 systems with a matrix-free Newton-Krylov method and a matrix-based, in-place 8047 ILU(0) preconditioner. 8048 8049 Note that one can specify in-place ILU(0) factorization by calling 8050 .vb 8051 PCType(pc,PCILU); 8052 PCFactorSeUseInPlace(pc); 8053 .ve 8054 or by using the options -pc_type ilu -pc_factor_in_place 8055 8056 In-place factorization ILU(0) can also be used as a local 8057 solver for the blocks within the block Jacobi or additive Schwarz 8058 methods (runtime option: -sub_pc_factor_in_place). See Users-Manual: ch_pc 8059 for details on setting local solver options. 8060 8061 Most users should employ the simplified KSP interface for linear solvers 8062 instead of working directly with matrix algebra routines such as this. 8063 See, e.g., KSPCreate(). 8064 8065 Level: developer 8066 8067 .seealso: `PCFactorSetUseInPlace()`, `PCFactorGetUseInPlace()` 8068 8069 @*/ 8070 PetscErrorCode MatSetUnfactored(Mat mat) 8071 { 8072 PetscFunctionBegin; 8073 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8074 PetscValidType(mat,1); 8075 MatCheckPreallocated(mat,1); 8076 mat->factortype = MAT_FACTOR_NONE; 8077 if (!mat->ops->setunfactored) PetscFunctionReturn(0); 8078 PetscUseTypeMethod(mat,setunfactored); 8079 PetscFunctionReturn(0); 8080 } 8081 8082 /*MC 8083 MatDenseGetArrayF90 - Accesses a matrix array from Fortran90. 8084 8085 Synopsis: 8086 MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 8087 8088 Not collective 8089 8090 Input Parameter: 8091 . x - matrix 8092 8093 Output Parameters: 8094 + xx_v - the Fortran90 pointer to the array 8095 - ierr - error code 8096 8097 Example of Usage: 8098 .vb 8099 PetscScalar, pointer xx_v(:,:) 8100 .... 8101 call MatDenseGetArrayF90(x,xx_v,ierr) 8102 a = xx_v(3) 8103 call MatDenseRestoreArrayF90(x,xx_v,ierr) 8104 .ve 8105 8106 Level: advanced 8107 8108 .seealso: `MatDenseRestoreArrayF90()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatSeqAIJGetArrayF90()` 8109 8110 M*/ 8111 8112 /*MC 8113 MatDenseRestoreArrayF90 - Restores a matrix array that has been 8114 accessed with MatDenseGetArrayF90(). 8115 8116 Synopsis: 8117 MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 8118 8119 Not collective 8120 8121 Input Parameters: 8122 + x - matrix 8123 - xx_v - the Fortran90 pointer to the array 8124 8125 Output Parameter: 8126 . ierr - error code 8127 8128 Example of Usage: 8129 .vb 8130 PetscScalar, pointer xx_v(:,:) 8131 .... 8132 call MatDenseGetArrayF90(x,xx_v,ierr) 8133 a = xx_v(3) 8134 call MatDenseRestoreArrayF90(x,xx_v,ierr) 8135 .ve 8136 8137 Level: advanced 8138 8139 .seealso: `MatDenseGetArrayF90()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatSeqAIJRestoreArrayF90()` 8140 8141 M*/ 8142 8143 /*MC 8144 MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90. 8145 8146 Synopsis: 8147 MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 8148 8149 Not collective 8150 8151 Input Parameter: 8152 . x - matrix 8153 8154 Output Parameters: 8155 + xx_v - the Fortran90 pointer to the array 8156 - ierr - error code 8157 8158 Example of Usage: 8159 .vb 8160 PetscScalar, pointer xx_v(:) 8161 .... 8162 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 8163 a = xx_v(3) 8164 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 8165 .ve 8166 8167 Level: advanced 8168 8169 .seealso: `MatSeqAIJRestoreArrayF90()`, `MatSeqAIJGetArray()`, `MatSeqAIJRestoreArray()`, `MatDenseGetArrayF90()` 8170 8171 M*/ 8172 8173 /*MC 8174 MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been 8175 accessed with MatSeqAIJGetArrayF90(). 8176 8177 Synopsis: 8178 MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 8179 8180 Not collective 8181 8182 Input Parameters: 8183 + x - matrix 8184 - xx_v - the Fortran90 pointer to the array 8185 8186 Output Parameter: 8187 . ierr - error code 8188 8189 Example of Usage: 8190 .vb 8191 PetscScalar, pointer xx_v(:) 8192 .... 8193 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 8194 a = xx_v(3) 8195 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 8196 .ve 8197 8198 Level: advanced 8199 8200 .seealso: `MatSeqAIJGetArrayF90()`, `MatSeqAIJGetArray()`, `MatSeqAIJRestoreArray()`, `MatDenseRestoreArrayF90()` 8201 8202 M*/ 8203 8204 /*@ 8205 MatCreateSubMatrix - Gets a single submatrix on the same number of processors 8206 as the original matrix. 8207 8208 Collective on Mat 8209 8210 Input Parameters: 8211 + mat - the original matrix 8212 . isrow - parallel IS containing the rows this processor should obtain 8213 . 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. 8214 - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 8215 8216 Output Parameter: 8217 . newmat - the new submatrix, of the same type as the old 8218 8219 Level: advanced 8220 8221 Notes: 8222 The submatrix will be able to be multiplied with vectors using the same layout as iscol. 8223 8224 Some matrix types place restrictions on the row and column indices, such 8225 as that they be sorted or that they be equal to each other. 8226 8227 The index sets may not have duplicate entries. 8228 8229 The first time this is called you should use a cll of MAT_INITIAL_MATRIX, 8230 the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls 8231 to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX 8232 will reuse the matrix generated the first time. You should call MatDestroy() on newmat when 8233 you are finished using it. 8234 8235 The communicator of the newly obtained matrix is ALWAYS the same as the communicator of 8236 the input matrix. 8237 8238 If iscol is NULL then all columns are obtained (not supported in Fortran). 8239 8240 Example usage: 8241 Consider the following 8x8 matrix with 34 non-zero values, that is 8242 assembled across 3 processors. Let's assume that proc0 owns 3 rows, 8243 proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown 8244 as follows: 8245 8246 .vb 8247 1 2 0 | 0 3 0 | 0 4 8248 Proc0 0 5 6 | 7 0 0 | 8 0 8249 9 0 10 | 11 0 0 | 12 0 8250 ------------------------------------- 8251 13 0 14 | 15 16 17 | 0 0 8252 Proc1 0 18 0 | 19 20 21 | 0 0 8253 0 0 0 | 22 23 0 | 24 0 8254 ------------------------------------- 8255 Proc2 25 26 27 | 0 0 28 | 29 0 8256 30 0 0 | 31 32 33 | 0 34 8257 .ve 8258 8259 Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is 8260 8261 .vb 8262 2 0 | 0 3 0 | 0 8263 Proc0 5 6 | 7 0 0 | 8 8264 ------------------------------- 8265 Proc1 18 0 | 19 20 21 | 0 8266 ------------------------------- 8267 Proc2 26 27 | 0 0 28 | 29 8268 0 0 | 31 32 33 | 0 8269 .ve 8270 8271 .seealso: `MatCreateSubMatrices()`, `MatCreateSubMatricesMPI()`, `MatCreateSubMatrixVirtual()`, `MatSubMatrixVirtualUpdate()` 8272 @*/ 8273 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat) 8274 { 8275 PetscMPIInt size; 8276 Mat *local; 8277 IS iscoltmp; 8278 PetscBool flg; 8279 8280 PetscFunctionBegin; 8281 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8282 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 8283 if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 8284 PetscValidPointer(newmat,5); 8285 if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5); 8286 PetscValidType(mat,1); 8287 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8288 PetscCheck(cll != MAT_IGNORE_MATRIX,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX"); 8289 8290 MatCheckPreallocated(mat,1); 8291 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 8292 8293 if (!iscol || isrow == iscol) { 8294 PetscBool stride; 8295 PetscMPIInt grabentirematrix = 0,grab; 8296 PetscCall(PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride)); 8297 if (stride) { 8298 PetscInt first,step,n,rstart,rend; 8299 PetscCall(ISStrideGetInfo(isrow,&first,&step)); 8300 if (step == 1) { 8301 PetscCall(MatGetOwnershipRange(mat,&rstart,&rend)); 8302 if (rstart == first) { 8303 PetscCall(ISGetLocalSize(isrow,&n)); 8304 if (n == rend-rstart) { 8305 grabentirematrix = 1; 8306 } 8307 } 8308 } 8309 } 8310 PetscCall(MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat))); 8311 if (grab) { 8312 PetscCall(PetscInfo(mat,"Getting entire matrix as submatrix\n")); 8313 if (cll == MAT_INITIAL_MATRIX) { 8314 *newmat = mat; 8315 PetscCall(PetscObjectReference((PetscObject)mat)); 8316 } 8317 PetscFunctionReturn(0); 8318 } 8319 } 8320 8321 if (!iscol) { 8322 PetscCall(ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp)); 8323 } else { 8324 iscoltmp = iscol; 8325 } 8326 8327 /* if original matrix is on just one processor then use submatrix generated */ 8328 if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) { 8329 PetscCall(MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat)); 8330 goto setproperties; 8331 } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) { 8332 PetscCall(MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local)); 8333 *newmat = *local; 8334 PetscCall(PetscFree(local)); 8335 goto setproperties; 8336 } else if (!mat->ops->createsubmatrix) { 8337 /* Create a new matrix type that implements the operation using the full matrix */ 8338 PetscCall(PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0)); 8339 switch (cll) { 8340 case MAT_INITIAL_MATRIX: 8341 PetscCall(MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat)); 8342 break; 8343 case MAT_REUSE_MATRIX: 8344 PetscCall(MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp)); 8345 break; 8346 default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX"); 8347 } 8348 PetscCall(PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0)); 8349 goto setproperties; 8350 } 8351 8352 PetscCall(PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0)); 8353 PetscUseTypeMethod(mat,createsubmatrix ,isrow,iscoltmp,cll,newmat); 8354 PetscCall(PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0)); 8355 8356 setproperties: 8357 PetscCall(ISEqualUnsorted(isrow,iscoltmp,&flg)); 8358 if (flg) PetscCall(MatPropagateSymmetryOptions(mat,*newmat)); 8359 if (!iscol) PetscCall(ISDestroy(&iscoltmp)); 8360 if (*newmat && cll == MAT_INITIAL_MATRIX) PetscCall(PetscObjectStateIncrease((PetscObject)*newmat)); 8361 PetscFunctionReturn(0); 8362 } 8363 8364 /*@ 8365 MatPropagateSymmetryOptions - Propagates symmetry options set on a matrix to another matrix 8366 8367 Not Collective 8368 8369 Input Parameters: 8370 + A - the matrix we wish to propagate options from 8371 - B - the matrix we wish to propagate options to 8372 8373 Level: beginner 8374 8375 Notes: 8376 Propagates the options associated to `MAT_SYMMETRY_ETERNAL`, `MAT_STRUCTURALLY_SYMMETRIC`, `MAT_HERMITIAN`, `MAT_SPD`, `MAT_SYMMETRIC`, and `MAT_STRUCTURAL_SYMMETRY_ETERNAL` 8377 8378 .seealso: `MatSetOption()`, `MatIsSymmetricKnown()`, `MatIsSPDKnown()`, `MatIsHermitianKnown()`, MatIsStructurallySymmetricKnown()` 8379 @*/ 8380 PetscErrorCode MatPropagateSymmetryOptions(Mat A, Mat B) 8381 { 8382 PetscFunctionBegin; 8383 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8384 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 8385 B->symmetry_eternal = A->symmetry_eternal; 8386 B->structural_symmetry_eternal = A->structural_symmetry_eternal; 8387 B->symmetric = A->symmetric; 8388 B->structurally_symmetric = A->structurally_symmetric; 8389 B->spd = A->spd; 8390 B->hermitian = A->hermitian; 8391 PetscFunctionReturn(0); 8392 } 8393 8394 /*@ 8395 MatStashSetInitialSize - sets the sizes of the matrix stash, that is 8396 used during the assembly process to store values that belong to 8397 other processors. 8398 8399 Not Collective 8400 8401 Input Parameters: 8402 + mat - the matrix 8403 . size - the initial size of the stash. 8404 - bsize - the initial size of the block-stash(if used). 8405 8406 Options Database Keys: 8407 + -matstash_initial_size <size> or <size0,size1,...sizep-1> 8408 - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1> 8409 8410 Level: intermediate 8411 8412 Notes: 8413 The block-stash is used for values set with MatSetValuesBlocked() while 8414 the stash is used for values set with MatSetValues() 8415 8416 Run with the option -info and look for output of the form 8417 MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs. 8418 to determine the appropriate value, MM, to use for size and 8419 MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs. 8420 to determine the value, BMM to use for bsize 8421 8422 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `Mat`, `MatStashGetInfo()` 8423 8424 @*/ 8425 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize) 8426 { 8427 PetscFunctionBegin; 8428 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8429 PetscValidType(mat,1); 8430 PetscCall(MatStashSetInitialSize_Private(&mat->stash,size)); 8431 PetscCall(MatStashSetInitialSize_Private(&mat->bstash,bsize)); 8432 PetscFunctionReturn(0); 8433 } 8434 8435 /*@ 8436 MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 8437 the matrix 8438 8439 Neighbor-wise Collective on Mat 8440 8441 Input Parameters: 8442 + mat - the matrix 8443 . x,y - the vectors 8444 - w - where the result is stored 8445 8446 Level: intermediate 8447 8448 Notes: 8449 w may be the same vector as y. 8450 8451 This allows one to use either the restriction or interpolation (its transpose) 8452 matrix to do the interpolation 8453 8454 .seealso: `MatMultAdd()`, `MatMultTransposeAdd()`, `MatRestrict()` 8455 8456 @*/ 8457 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w) 8458 { 8459 PetscInt M,N,Ny; 8460 8461 PetscFunctionBegin; 8462 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8463 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8464 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8465 PetscValidHeaderSpecific(w,VEC_CLASSID,4); 8466 PetscCall(MatGetSize(A,&M,&N)); 8467 PetscCall(VecGetSize(y,&Ny)); 8468 if (M == Ny) { 8469 PetscCall(MatMultAdd(A,x,y,w)); 8470 } else { 8471 PetscCall(MatMultTransposeAdd(A,x,y,w)); 8472 } 8473 PetscFunctionReturn(0); 8474 } 8475 8476 /*@ 8477 MatInterpolate - y = A*x or A'*x depending on the shape of 8478 the matrix 8479 8480 Neighbor-wise Collective on Mat 8481 8482 Input Parameters: 8483 + mat - the matrix 8484 - x,y - the vectors 8485 8486 Level: intermediate 8487 8488 Notes: 8489 This allows one to use either the restriction or interpolation (its transpose) 8490 matrix to do the interpolation 8491 8492 .seealso: `MatMultAdd()`, `MatMultTransposeAdd()`, `MatRestrict()` 8493 8494 @*/ 8495 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y) 8496 { 8497 PetscInt M,N,Ny; 8498 8499 PetscFunctionBegin; 8500 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8501 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8502 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8503 PetscCall(MatGetSize(A,&M,&N)); 8504 PetscCall(VecGetSize(y,&Ny)); 8505 if (M == Ny) { 8506 PetscCall(MatMult(A,x,y)); 8507 } else { 8508 PetscCall(MatMultTranspose(A,x,y)); 8509 } 8510 PetscFunctionReturn(0); 8511 } 8512 8513 /*@ 8514 MatRestrict - y = A*x or A'*x 8515 8516 Neighbor-wise Collective on Mat 8517 8518 Input Parameters: 8519 + mat - the matrix 8520 - x,y - the vectors 8521 8522 Level: intermediate 8523 8524 Notes: 8525 This allows one to use either the restriction or interpolation (its transpose) 8526 matrix to do the restriction 8527 8528 .seealso: `MatMultAdd()`, `MatMultTransposeAdd()`, `MatInterpolate()` 8529 8530 @*/ 8531 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y) 8532 { 8533 PetscInt M,N,Ny; 8534 8535 PetscFunctionBegin; 8536 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8537 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8538 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8539 PetscCall(MatGetSize(A,&M,&N)); 8540 PetscCall(VecGetSize(y,&Ny)); 8541 if (M == Ny) { 8542 PetscCall(MatMult(A,x,y)); 8543 } else { 8544 PetscCall(MatMultTranspose(A,x,y)); 8545 } 8546 PetscFunctionReturn(0); 8547 } 8548 8549 /*@ 8550 MatMatInterpolateAdd - Y = W + A*X or W + A'*X 8551 8552 Neighbor-wise Collective on Mat 8553 8554 Input Parameters: 8555 + mat - the matrix 8556 - w, x - the input dense matrices 8557 8558 Output Parameters: 8559 . y - the output dense matrix 8560 8561 Level: intermediate 8562 8563 Notes: 8564 This allows one to use either the restriction or interpolation (its transpose) 8565 matrix to do the interpolation. y matrix can be reused if already created with the proper sizes, 8566 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8567 8568 .seealso: `MatInterpolateAdd()`, `MatMatInterpolate()`, `MatMatRestrict()` 8569 8570 @*/ 8571 PetscErrorCode MatMatInterpolateAdd(Mat A,Mat x,Mat w,Mat *y) 8572 { 8573 PetscInt M,N,Mx,Nx,Mo,My = 0,Ny = 0; 8574 PetscBool trans = PETSC_TRUE; 8575 MatReuse reuse = MAT_INITIAL_MATRIX; 8576 8577 PetscFunctionBegin; 8578 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8579 PetscValidHeaderSpecific(x,MAT_CLASSID,2); 8580 PetscValidType(x,2); 8581 if (w) PetscValidHeaderSpecific(w,MAT_CLASSID,3); 8582 if (*y) PetscValidHeaderSpecific(*y,MAT_CLASSID,4); 8583 PetscCall(MatGetSize(A,&M,&N)); 8584 PetscCall(MatGetSize(x,&Mx,&Nx)); 8585 if (N == Mx) trans = PETSC_FALSE; 8586 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); 8587 Mo = trans ? N : M; 8588 if (*y) { 8589 PetscCall(MatGetSize(*y,&My,&Ny)); 8590 if (Mo == My && Nx == Ny) { reuse = MAT_REUSE_MATRIX; } 8591 else { 8592 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); 8593 PetscCall(MatDestroy(y)); 8594 } 8595 } 8596 8597 if (w && *y == w) { /* this is to minimize changes in PCMG */ 8598 PetscBool flg; 8599 8600 PetscCall(PetscObjectQuery((PetscObject)*y,"__MatMatIntAdd_w",(PetscObject*)&w)); 8601 if (w) { 8602 PetscInt My,Ny,Mw,Nw; 8603 8604 PetscCall(PetscObjectTypeCompare((PetscObject)*y,((PetscObject)w)->type_name,&flg)); 8605 PetscCall(MatGetSize(*y,&My,&Ny)); 8606 PetscCall(MatGetSize(w,&Mw,&Nw)); 8607 if (!flg || My != Mw || Ny != Nw) w = NULL; 8608 } 8609 if (!w) { 8610 PetscCall(MatDuplicate(*y,MAT_COPY_VALUES,&w)); 8611 PetscCall(PetscObjectCompose((PetscObject)*y,"__MatMatIntAdd_w",(PetscObject)w)); 8612 PetscCall(PetscLogObjectParent((PetscObject)*y,(PetscObject)w)); 8613 PetscCall(PetscObjectDereference((PetscObject)w)); 8614 } else { 8615 PetscCall(MatCopy(*y,w,UNKNOWN_NONZERO_PATTERN)); 8616 } 8617 } 8618 if (!trans) { 8619 PetscCall(MatMatMult(A,x,reuse,PETSC_DEFAULT,y)); 8620 } else { 8621 PetscCall(MatTransposeMatMult(A,x,reuse,PETSC_DEFAULT,y)); 8622 } 8623 if (w) PetscCall(MatAXPY(*y,1.0,w,UNKNOWN_NONZERO_PATTERN)); 8624 PetscFunctionReturn(0); 8625 } 8626 8627 /*@ 8628 MatMatInterpolate - Y = A*X or A'*X 8629 8630 Neighbor-wise Collective on Mat 8631 8632 Input Parameters: 8633 + mat - the matrix 8634 - x - the input dense matrix 8635 8636 Output Parameters: 8637 . y - the output dense matrix 8638 8639 Level: intermediate 8640 8641 Notes: 8642 This allows one to use either the restriction or interpolation (its transpose) 8643 matrix to do the interpolation. y matrix can be reused if already created with the proper sizes, 8644 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8645 8646 .seealso: `MatInterpolate()`, `MatRestrict()`, `MatMatRestrict()` 8647 8648 @*/ 8649 PetscErrorCode MatMatInterpolate(Mat A,Mat x,Mat *y) 8650 { 8651 PetscFunctionBegin; 8652 PetscCall(MatMatInterpolateAdd(A,x,NULL,y)); 8653 PetscFunctionReturn(0); 8654 } 8655 8656 /*@ 8657 MatMatRestrict - Y = A*X or A'*X 8658 8659 Neighbor-wise Collective on Mat 8660 8661 Input Parameters: 8662 + mat - the matrix 8663 - x - the input dense matrix 8664 8665 Output Parameters: 8666 . y - the output dense matrix 8667 8668 Level: intermediate 8669 8670 Notes: 8671 This allows one to use either the restriction or interpolation (its transpose) 8672 matrix to do the restriction. y matrix can be reused if already created with the proper sizes, 8673 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8674 8675 .seealso: `MatRestrict()`, `MatInterpolate()`, `MatMatInterpolate()` 8676 @*/ 8677 PetscErrorCode MatMatRestrict(Mat A,Mat x,Mat *y) 8678 { 8679 PetscFunctionBegin; 8680 PetscCall(MatMatInterpolateAdd(A,x,NULL,y)); 8681 PetscFunctionReturn(0); 8682 } 8683 8684 /*@ 8685 MatGetNullSpace - retrieves the null space of a matrix. 8686 8687 Logically Collective on Mat 8688 8689 Input Parameters: 8690 + mat - the matrix 8691 - nullsp - the null space object 8692 8693 Level: developer 8694 8695 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatSetNullSpace()` 8696 @*/ 8697 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp) 8698 { 8699 PetscFunctionBegin; 8700 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8701 PetscValidPointer(nullsp,2); 8702 *nullsp = (mat->symmetric == PETSC_BOOL3_TRUE && !mat->nullsp) ? mat->transnullsp : mat->nullsp; 8703 PetscFunctionReturn(0); 8704 } 8705 8706 /*@ 8707 MatSetNullSpace - attaches a null space to a matrix. 8708 8709 Logically Collective on Mat 8710 8711 Input Parameters: 8712 + mat - the matrix 8713 - nullsp - the null space object 8714 8715 Level: advanced 8716 8717 Notes: 8718 This null space is used by the KSP linear solvers to solve singular systems. 8719 8720 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 8721 8722 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 8723 to zero but the linear system will still be solved in a least squares sense. 8724 8725 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8726 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). 8727 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 8728 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 8729 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). 8730 This \hat{b} can be obtained by calling MatNullSpaceRemove() with the null space of the transpose of the matrix. 8731 8732 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 8733 routine also automatically calls MatSetTransposeNullSpace(). 8734 8735 The user should call `MatNullSpaceDestroy()`. 8736 8737 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatGetNullSpace()`, `MatSetTransposeNullSpace()`, `MatGetTransposeNullSpace()`, `MatNullSpaceRemove()`, 8738 `KSPSetPCSide()` 8739 @*/ 8740 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp) 8741 { 8742 PetscFunctionBegin; 8743 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8744 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8745 if (nullsp) PetscCall(PetscObjectReference((PetscObject)nullsp)); 8746 PetscCall(MatNullSpaceDestroy(&mat->nullsp)); 8747 mat->nullsp = nullsp; 8748 if (mat->symmetric == PETSC_BOOL3_TRUE) { 8749 PetscCall(MatSetTransposeNullSpace(mat,nullsp)); 8750 } 8751 PetscFunctionReturn(0); 8752 } 8753 8754 /*@ 8755 MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix. 8756 8757 Logically Collective on Mat 8758 8759 Input Parameters: 8760 + mat - the matrix 8761 - nullsp - the null space object 8762 8763 Level: developer 8764 8765 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatSetTransposeNullSpace()`, `MatSetNullSpace()`, `MatGetNullSpace()` 8766 @*/ 8767 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp) 8768 { 8769 PetscFunctionBegin; 8770 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8771 PetscValidType(mat,1); 8772 PetscValidPointer(nullsp,2); 8773 *nullsp = (mat->symmetric == PETSC_BOOL3_TRUE && !mat->transnullsp) ? mat->nullsp : mat->transnullsp; 8774 PetscFunctionReturn(0); 8775 } 8776 8777 /*@ 8778 MatSetTransposeNullSpace - attaches the null space of a transpose of a matrix to the matrix 8779 8780 Logically Collective on Mat 8781 8782 Input Parameters: 8783 + mat - the matrix 8784 - nullsp - the null space object 8785 8786 Level: advanced 8787 8788 Notes: 8789 This allows solving singular linear systems defined by the transpose of the matrix using KSP solvers with left preconditioning. 8790 8791 See MatSetNullSpace() 8792 8793 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatGetNullSpace()`, `MatSetNullSpace()`, `MatGetTransposeNullSpace()`, `MatNullSpaceRemove()`, `KSPSetPCSide()` 8794 @*/ 8795 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp) 8796 { 8797 PetscFunctionBegin; 8798 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8799 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8800 if (nullsp) PetscCall(PetscObjectReference((PetscObject)nullsp)); 8801 PetscCall(MatNullSpaceDestroy(&mat->transnullsp)); 8802 mat->transnullsp = nullsp; 8803 PetscFunctionReturn(0); 8804 } 8805 8806 /*@ 8807 MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions 8808 This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix. 8809 8810 Logically Collective on Mat 8811 8812 Input Parameters: 8813 + mat - the matrix 8814 - nullsp - the null space object 8815 8816 Level: advanced 8817 8818 Notes: 8819 Overwrites any previous near null space that may have been attached 8820 8821 You can remove the null space by calling this routine with an nullsp of NULL 8822 8823 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNullSpace()`, `MatNullSpaceCreateRigidBody()`, `MatGetNearNullSpace()` 8824 @*/ 8825 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp) 8826 { 8827 PetscFunctionBegin; 8828 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8829 PetscValidType(mat,1); 8830 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8831 MatCheckPreallocated(mat,1); 8832 if (nullsp) PetscCall(PetscObjectReference((PetscObject)nullsp)); 8833 PetscCall(MatNullSpaceDestroy(&mat->nearnullsp)); 8834 mat->nearnullsp = nullsp; 8835 PetscFunctionReturn(0); 8836 } 8837 8838 /*@ 8839 MatGetNearNullSpace - Get null space attached with MatSetNearNullSpace() 8840 8841 Not Collective 8842 8843 Input Parameter: 8844 . mat - the matrix 8845 8846 Output Parameter: 8847 . nullsp - the null space object, NULL if not set 8848 8849 Level: developer 8850 8851 .seealso: `MatSetNearNullSpace()`, `MatGetNullSpace()`, `MatNullSpaceCreate()` 8852 @*/ 8853 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp) 8854 { 8855 PetscFunctionBegin; 8856 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8857 PetscValidType(mat,1); 8858 PetscValidPointer(nullsp,2); 8859 MatCheckPreallocated(mat,1); 8860 *nullsp = mat->nearnullsp; 8861 PetscFunctionReturn(0); 8862 } 8863 8864 /*@C 8865 MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix. 8866 8867 Collective on Mat 8868 8869 Input Parameters: 8870 + mat - the matrix 8871 . row - row/column permutation 8872 . fill - expected fill factor >= 1.0 8873 - level - level of fill, for ICC(k) 8874 8875 Notes: 8876 Probably really in-place only when level of fill is zero, otherwise allocates 8877 new space to store factored matrix and deletes previous memory. 8878 8879 Most users should employ the simplified KSP interface for linear solvers 8880 instead of working directly with matrix algebra routines such as this. 8881 See, e.g., KSPCreate(). 8882 8883 Level: developer 8884 8885 .seealso: `MatICCFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()` 8886 8887 Developer Note: fortran interface is not autogenerated as the f90 8888 interface definition cannot be generated correctly [due to MatFactorInfo] 8889 8890 @*/ 8891 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info) 8892 { 8893 PetscFunctionBegin; 8894 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8895 PetscValidType(mat,1); 8896 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 8897 PetscValidPointer(info,3); 8898 PetscCheck(mat->rmap->N == mat->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 8899 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8900 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8901 MatCheckPreallocated(mat,1); 8902 PetscUseTypeMethod(mat,iccfactor ,row,info); 8903 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 8904 PetscFunctionReturn(0); 8905 } 8906 8907 /*@ 8908 MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 8909 ghosted ones. 8910 8911 Not Collective 8912 8913 Input Parameters: 8914 + mat - the matrix 8915 - diag - the diagonal values, including ghost ones 8916 8917 Level: developer 8918 8919 Notes: 8920 Works only for MPIAIJ and MPIBAIJ matrices 8921 8922 .seealso: `MatDiagonalScale()` 8923 @*/ 8924 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag) 8925 { 8926 PetscMPIInt size; 8927 8928 PetscFunctionBegin; 8929 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8930 PetscValidHeaderSpecific(diag,VEC_CLASSID,2); 8931 PetscValidType(mat,1); 8932 8933 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled"); 8934 PetscCall(PetscLogEventBegin(MAT_Scale,mat,0,0,0)); 8935 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 8936 if (size == 1) { 8937 PetscInt n,m; 8938 PetscCall(VecGetSize(diag,&n)); 8939 PetscCall(MatGetSize(mat,NULL,&m)); 8940 if (m == n) { 8941 PetscCall(MatDiagonalScale(mat,NULL,diag)); 8942 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions"); 8943 } else { 8944 PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag)); 8945 } 8946 PetscCall(PetscLogEventEnd(MAT_Scale,mat,0,0,0)); 8947 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 8948 PetscFunctionReturn(0); 8949 } 8950 8951 /*@ 8952 MatGetInertia - Gets the inertia from a factored matrix 8953 8954 Collective on Mat 8955 8956 Input Parameter: 8957 . mat - the matrix 8958 8959 Output Parameters: 8960 + nneg - number of negative eigenvalues 8961 . nzero - number of zero eigenvalues 8962 - npos - number of positive eigenvalues 8963 8964 Level: advanced 8965 8966 Notes: 8967 Matrix must have been factored by MatCholeskyFactor() 8968 8969 @*/ 8970 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos) 8971 { 8972 PetscFunctionBegin; 8973 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8974 PetscValidType(mat,1); 8975 PetscCheck(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8976 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled"); 8977 PetscUseTypeMethod(mat,getinertia ,nneg,nzero,npos); 8978 PetscFunctionReturn(0); 8979 } 8980 8981 /* ----------------------------------------------------------------*/ 8982 /*@C 8983 MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors 8984 8985 Neighbor-wise Collective on Mats 8986 8987 Input Parameters: 8988 + mat - the factored matrix 8989 - b - the right-hand-side vectors 8990 8991 Output Parameter: 8992 . x - the result vectors 8993 8994 Notes: 8995 The vectors b and x cannot be the same. I.e., one cannot 8996 call MatSolves(A,x,x). 8997 8998 Notes: 8999 Most users should employ the simplified KSP interface for linear solvers 9000 instead of working directly with matrix algebra routines such as this. 9001 See, e.g., KSPCreate(). 9002 9003 Level: developer 9004 9005 .seealso: `MatSolveAdd()`, `MatSolveTranspose()`, `MatSolveTransposeAdd()`, `MatSolve()` 9006 @*/ 9007 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x) 9008 { 9009 PetscFunctionBegin; 9010 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9011 PetscValidType(mat,1); 9012 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 9013 PetscCheck(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 9014 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 9015 9016 MatCheckPreallocated(mat,1); 9017 PetscCall(PetscLogEventBegin(MAT_Solves,mat,0,0,0)); 9018 PetscUseTypeMethod(mat,solves ,b,x); 9019 PetscCall(PetscLogEventEnd(MAT_Solves,mat,0,0,0)); 9020 PetscFunctionReturn(0); 9021 } 9022 9023 /*@ 9024 MatIsSymmetric - Test whether a matrix is symmetric 9025 9026 Collective on Mat 9027 9028 Input Parameters: 9029 + A - the matrix to test 9030 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose) 9031 9032 Output Parameters: 9033 . flg - the result 9034 9035 Notes: 9036 For real numbers MatIsSymmetric() and MatIsHermitian() return identical results 9037 9038 If the matrix does not yet know if it is symmetric or not this can be an expensive operation, also available `MatIsSymmetricKnown()` 9039 9040 Level: intermediate 9041 9042 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetricKnown()` 9043 @*/ 9044 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg) 9045 { 9046 PetscFunctionBegin; 9047 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9048 PetscValidBoolPointer(flg,3); 9049 9050 if (A->symmetric == PETSC_BOOL3_TRUE) *flg = PETSC_TRUE; 9051 else if (A->symmetric == PETSC_BOOL3_FALSE) *flg = PETSC_FALSE; 9052 else { 9053 if (!A->ops->issymmetric) { 9054 MatType mattype; 9055 PetscCall(MatGetType(A,&mattype)); 9056 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for symmetric",mattype); 9057 } 9058 PetscUseTypeMethod(A,issymmetric ,tol,flg); 9059 if (!tol) PetscCall(MatSetOption(A,MAT_SYMMETRIC,*flg)); 9060 } 9061 PetscFunctionReturn(0); 9062 } 9063 9064 /*@ 9065 MatIsHermitian - Test whether a matrix is Hermitian 9066 9067 Collective on Mat 9068 9069 Input Parameters: 9070 + A - the matrix to test 9071 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian) 9072 9073 Output Parameters: 9074 . flg - the result 9075 9076 Level: intermediate 9077 9078 Notes: 9079 For real numbers MatIsSymmetric() and MatIsHermitian() return identical results 9080 9081 If the matrix does not yet know if it is hermitian or not this can be an expensive operation, also available `MatIsHermitianKnown()` 9082 9083 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitianKnown()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, 9084 `MatIsSymmetricKnown()`, `MatIsSymmetric()` 9085 @*/ 9086 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg) 9087 { 9088 PetscFunctionBegin; 9089 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9090 PetscValidBoolPointer(flg,3); 9091 9092 if (A->hermitian == PETSC_BOOL3_TRUE) *flg = PETSC_TRUE; 9093 else if (A->hermitian == PETSC_BOOL3_FALSE) *flg = PETSC_FALSE; 9094 else { 9095 if (!A->ops->ishermitian) { 9096 MatType mattype; 9097 PetscCall(MatGetType(A,&mattype)); 9098 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for hermitian",mattype); 9099 } 9100 PetscUseTypeMethod(A,ishermitian ,tol,flg); 9101 if (!tol) PetscCall(MatSetOption(A,MAT_HERMITIAN,*flg)); 9102 } 9103 PetscFunctionReturn(0); 9104 } 9105 9106 /*@ 9107 MatIsSymmetricKnown - Checks if a matrix knows if it is symmetric or not and its symmetric state 9108 9109 Not Collective 9110 9111 Input Parameter: 9112 . A - the matrix to check 9113 9114 Output Parameters: 9115 + set - PETSC_TRUE if the matrix knows its symmetry state (this tells you if the next flag is valid) 9116 - flg - the result (only valid if set is PETSC_TRUE) 9117 9118 Level: advanced 9119 9120 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric() 9121 if you want it explicitly checked 9122 9123 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitianKnown()` 9124 @*/ 9125 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg) 9126 { 9127 PetscFunctionBegin; 9128 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9129 PetscValidBoolPointer(set,2); 9130 PetscValidBoolPointer(flg,3); 9131 if (A->symmetric != PETSC_BOOL3_UNKNOWN) { 9132 *set = PETSC_TRUE; 9133 *flg = PetscBool3ToBool(A->symmetric); 9134 } else { 9135 *set = PETSC_FALSE; 9136 } 9137 PetscFunctionReturn(0); 9138 } 9139 9140 /*@ 9141 MatIsSPDKnown - Checks if a matrix knows if it is symmetric positive definite or not and its symmetric positive definite state 9142 9143 Not Collective 9144 9145 Input Parameter: 9146 . A - the matrix to check 9147 9148 Output Parameters: 9149 + set - PETSC_TRUE if the matrix knows its symmetric positive definite state (this tells you if the next flag is valid) 9150 - flg - the result (only valid if set is PETSC_TRUE) 9151 9152 Level: advanced 9153 9154 Note: 9155 Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). 9156 9157 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitianKnown()` 9158 @*/ 9159 PetscErrorCode MatIsSPDKnown(Mat A,PetscBool *set,PetscBool *flg) 9160 { 9161 PetscFunctionBegin; 9162 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9163 PetscValidBoolPointer(set,2); 9164 PetscValidBoolPointer(flg,3); 9165 if (A->spd != PETSC_BOOL3_UNKNOWN) { 9166 *set = PETSC_TRUE; 9167 *flg = PetscBool3ToBool(A->spd); 9168 } else { 9169 *set = PETSC_FALSE; 9170 } 9171 PetscFunctionReturn(0); 9172 } 9173 9174 /*@ 9175 MatIsHermitianKnown - Checks if a matrix knows if it is Hermitian or not and its Hermitian state 9176 9177 Not Collective 9178 9179 Input Parameter: 9180 . A - the matrix to check 9181 9182 Output Parameters: 9183 + set - PETSC_TRUE if the matrix knows its Hermitian state (this tells you if the next flag is valid) 9184 - flg - the result (only valid if set is PETSC_TRUE) 9185 9186 Level: advanced 9187 9188 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian() 9189 if you want it explicitly checked 9190 9191 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()` 9192 @*/ 9193 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg) 9194 { 9195 PetscFunctionBegin; 9196 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9197 PetscValidBoolPointer(set,2); 9198 PetscValidBoolPointer(flg,3); 9199 if (A->hermitian != PETSC_BOOL3_UNKNOWN) { 9200 *set = PETSC_TRUE; 9201 *flg = PetscBool3ToBool(A->hermitian); 9202 } else { 9203 *set = PETSC_FALSE; 9204 } 9205 PetscFunctionReturn(0); 9206 } 9207 9208 /*@ 9209 MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric 9210 9211 Collective on Mat 9212 9213 Input Parameter: 9214 . A - the matrix to test 9215 9216 Output Parameters: 9217 . flg - the result 9218 9219 Notes: 9220 If the matrix does yet know it is structurally symmetric this can be an expensive operation, also available `MatIsStructurallySymmetricKnown()` 9221 9222 Level: intermediate 9223 9224 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsSymmetric()`, `MatSetOption()`, `MatIsStructurallySymmetricKnown()` 9225 @*/ 9226 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg) 9227 { 9228 PetscFunctionBegin; 9229 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9230 PetscValidBoolPointer(flg,2); 9231 if (A->structurally_symmetric != PETSC_BOOL3_UNKNOWN) { 9232 *flg = PetscBool3ToBool(A->structurally_symmetric); 9233 } else { 9234 PetscUseTypeMethod(A,isstructurallysymmetric ,flg); 9235 PetscCall(MatSetOption(A,MAT_STRUCTURALLY_SYMMETRIC,*flg)); 9236 } 9237 PetscFunctionReturn(0); 9238 } 9239 9240 /*@ 9241 MatIsStructurallySymmetricKnown - Checks if a matrix knows if it is structurally symmetric or not and its structurally symmetric state 9242 9243 Not Collective 9244 9245 Input Parameter: 9246 . A - the matrix to check 9247 9248 Output Parameters: 9249 + set - PETSC_TRUE if the matrix knows its structurally symmetric state (this tells you if the next flag is valid) 9250 - flg - the result (only valid if set is PETSC_TRUE) 9251 9252 Level: advanced 9253 9254 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitianKnown()` 9255 @*/ 9256 PetscErrorCode MatIsStructurallySymmetricKnown(Mat A,PetscBool *set,PetscBool *flg) 9257 { 9258 PetscFunctionBegin; 9259 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9260 PetscValidBoolPointer(set,2); 9261 PetscValidBoolPointer(flg,3); 9262 if (A->structurally_symmetric != PETSC_BOOL3_UNKNOWN) { 9263 *set = PETSC_TRUE; 9264 *flg = PetscBool3ToBool(A->structurally_symmetric); 9265 } else { 9266 *set = PETSC_FALSE; 9267 } 9268 PetscFunctionReturn(0); 9269 } 9270 9271 /*@ 9272 MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need 9273 to be communicated to other processors during the MatAssemblyBegin/End() process 9274 9275 Not collective 9276 9277 Input Parameter: 9278 . vec - the vector 9279 9280 Output Parameters: 9281 + nstash - the size of the stash 9282 . reallocs - the number of additional mallocs incurred. 9283 . bnstash - the size of the block stash 9284 - breallocs - the number of additional mallocs incurred.in the block stash 9285 9286 Level: advanced 9287 9288 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `Mat`, `MatStashSetInitialSize()` 9289 9290 @*/ 9291 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs) 9292 { 9293 PetscFunctionBegin; 9294 PetscCall(MatStashGetInfo_Private(&mat->stash,nstash,reallocs)); 9295 PetscCall(MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs)); 9296 PetscFunctionReturn(0); 9297 } 9298 9299 /*@C 9300 MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same 9301 parallel layout 9302 9303 Collective on Mat 9304 9305 Input Parameter: 9306 . mat - the matrix 9307 9308 Output Parameters: 9309 + right - (optional) vector that the matrix can be multiplied against 9310 - left - (optional) vector that the matrix vector product can be stored in 9311 9312 Notes: 9313 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(). 9314 9315 Notes: 9316 These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed 9317 9318 Level: advanced 9319 9320 .seealso: `MatCreate()`, `VecDestroy()` 9321 @*/ 9322 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left) 9323 { 9324 PetscFunctionBegin; 9325 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9326 PetscValidType(mat,1); 9327 if (mat->ops->getvecs) { 9328 PetscUseTypeMethod(mat,getvecs ,right,left); 9329 } else { 9330 PetscInt rbs,cbs; 9331 PetscCall(MatGetBlockSizes(mat,&rbs,&cbs)); 9332 if (right) { 9333 PetscCheck(mat->cmap->n >= 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup"); 9334 PetscCall(VecCreate(PetscObjectComm((PetscObject)mat),right)); 9335 PetscCall(VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE)); 9336 PetscCall(VecSetBlockSize(*right,cbs)); 9337 PetscCall(VecSetType(*right,mat->defaultvectype)); 9338 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 9339 if (mat->boundtocpu && mat->bindingpropagates) { 9340 PetscCall(VecSetBindingPropagates(*right,PETSC_TRUE)); 9341 PetscCall(VecBindToCPU(*right,PETSC_TRUE)); 9342 } 9343 #endif 9344 PetscCall(PetscLayoutReference(mat->cmap,&(*right)->map)); 9345 } 9346 if (left) { 9347 PetscCheck(mat->rmap->n >= 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup"); 9348 PetscCall(VecCreate(PetscObjectComm((PetscObject)mat),left)); 9349 PetscCall(VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE)); 9350 PetscCall(VecSetBlockSize(*left,rbs)); 9351 PetscCall(VecSetType(*left,mat->defaultvectype)); 9352 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 9353 if (mat->boundtocpu && mat->bindingpropagates) { 9354 PetscCall(VecSetBindingPropagates(*left,PETSC_TRUE)); 9355 PetscCall(VecBindToCPU(*left,PETSC_TRUE)); 9356 } 9357 #endif 9358 PetscCall(PetscLayoutReference(mat->rmap,&(*left)->map)); 9359 } 9360 } 9361 PetscFunctionReturn(0); 9362 } 9363 9364 /*@C 9365 MatFactorInfoInitialize - Initializes a MatFactorInfo data structure 9366 with default values. 9367 9368 Not Collective 9369 9370 Input Parameters: 9371 . info - the MatFactorInfo data structure 9372 9373 Notes: 9374 The solvers are generally used through the KSP and PC objects, for example 9375 PCLU, PCILU, PCCHOLESKY, PCICC 9376 9377 Level: developer 9378 9379 .seealso: `MatFactorInfo` 9380 9381 Developer Note: fortran interface is not autogenerated as the f90 9382 interface definition cannot be generated correctly [due to MatFactorInfo] 9383 9384 @*/ 9385 9386 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info) 9387 { 9388 PetscFunctionBegin; 9389 PetscCall(PetscMemzero(info,sizeof(MatFactorInfo))); 9390 PetscFunctionReturn(0); 9391 } 9392 9393 /*@ 9394 MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed 9395 9396 Collective on Mat 9397 9398 Input Parameters: 9399 + mat - the factored matrix 9400 - is - the index set defining the Schur indices (0-based) 9401 9402 Notes: 9403 Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system. 9404 9405 You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call. 9406 9407 Level: developer 9408 9409 .seealso: `MatGetFactor()`, `MatFactorGetSchurComplement()`, `MatFactorRestoreSchurComplement()`, `MatFactorCreateSchurComplement()`, `MatFactorSolveSchurComplement()`, 9410 `MatFactorSolveSchurComplementTranspose()`, `MatFactorSolveSchurComplement()` 9411 9412 @*/ 9413 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is) 9414 { 9415 PetscErrorCode (*f)(Mat,IS); 9416 9417 PetscFunctionBegin; 9418 PetscValidType(mat,1); 9419 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9420 PetscValidType(is,2); 9421 PetscValidHeaderSpecific(is,IS_CLASSID,2); 9422 PetscCheckSameComm(mat,1,is,2); 9423 PetscCheck(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 9424 PetscCall(PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f)); 9425 PetscCheck(f,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"The selected MatSolverType does not support Schur complement computation. You should use MATSOLVERMUMPS or MATSOLVERMKL_PARDISO"); 9426 PetscCall(MatDestroy(&mat->schur)); 9427 PetscCall((*f)(mat,is)); 9428 PetscCheck(mat->schur,PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created"); 9429 PetscFunctionReturn(0); 9430 } 9431 9432 /*@ 9433 MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step 9434 9435 Logically Collective on Mat 9436 9437 Input Parameters: 9438 + F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface 9439 . S - location where to return the Schur complement, can be NULL 9440 - status - the status of the Schur complement matrix, can be NULL 9441 9442 Notes: 9443 You must call MatFactorSetSchurIS() before calling this routine. 9444 9445 The routine provides a copy of the Schur matrix stored within the solver data structures. 9446 The caller must destroy the object when it is no longer needed. 9447 If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse. 9448 9449 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) 9450 9451 Developer Notes: 9452 The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc 9453 matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix. 9454 9455 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 9456 9457 Level: advanced 9458 9459 References: 9460 9461 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorGetSchurComplement()`, `MatFactorSchurStatus` 9462 @*/ 9463 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 9464 { 9465 PetscFunctionBegin; 9466 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9467 if (S) PetscValidPointer(S,2); 9468 if (status) PetscValidPointer(status,3); 9469 if (S) { 9470 PetscErrorCode (*f)(Mat,Mat*); 9471 9472 PetscCall(PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f)); 9473 if (f) { 9474 PetscCall((*f)(F,S)); 9475 } else { 9476 PetscCall(MatDuplicate(F->schur,MAT_COPY_VALUES,S)); 9477 } 9478 } 9479 if (status) *status = F->schur_status; 9480 PetscFunctionReturn(0); 9481 } 9482 9483 /*@ 9484 MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix 9485 9486 Logically Collective on Mat 9487 9488 Input Parameters: 9489 + F - the factored matrix obtained by calling MatGetFactor() 9490 . *S - location where to return the Schur complement, can be NULL 9491 - status - the status of the Schur complement matrix, can be NULL 9492 9493 Notes: 9494 You must call MatFactorSetSchurIS() before calling this routine. 9495 9496 Schur complement mode is currently implemented for sequential matrices. 9497 The routine returns a the Schur Complement stored within the data strutures of the solver. 9498 If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement. 9499 The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed. 9500 9501 Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix 9502 9503 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 9504 9505 Level: advanced 9506 9507 References: 9508 9509 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorRestoreSchurComplement()`, `MatFactorCreateSchurComplement()`, `MatFactorSchurStatus` 9510 @*/ 9511 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 9512 { 9513 PetscFunctionBegin; 9514 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9515 if (S) PetscValidPointer(S,2); 9516 if (status) PetscValidPointer(status,3); 9517 if (S) *S = F->schur; 9518 if (status) *status = F->schur_status; 9519 PetscFunctionReturn(0); 9520 } 9521 9522 /*@ 9523 MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement 9524 9525 Logically Collective on Mat 9526 9527 Input Parameters: 9528 + F - the factored matrix obtained by calling MatGetFactor() 9529 . *S - location where the Schur complement is stored 9530 - status - the status of the Schur complement matrix (see MatFactorSchurStatus) 9531 9532 Notes: 9533 9534 Level: advanced 9535 9536 References: 9537 9538 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorRestoreSchurComplement()`, `MatFactorCreateSchurComplement()`, `MatFactorSchurStatus` 9539 @*/ 9540 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status) 9541 { 9542 PetscFunctionBegin; 9543 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9544 if (S) { 9545 PetscValidHeaderSpecific(*S,MAT_CLASSID,2); 9546 *S = NULL; 9547 } 9548 F->schur_status = status; 9549 PetscCall(MatFactorUpdateSchurStatus_Private(F)); 9550 PetscFunctionReturn(0); 9551 } 9552 9553 /*@ 9554 MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step 9555 9556 Logically Collective on Mat 9557 9558 Input Parameters: 9559 + F - the factored matrix obtained by calling MatGetFactor() 9560 . rhs - location where the right hand side of the Schur complement system is stored 9561 - sol - location where the solution of the Schur complement system has to be returned 9562 9563 Notes: 9564 The sizes of the vectors should match the size of the Schur complement 9565 9566 Must be called after MatFactorSetSchurIS() 9567 9568 Level: advanced 9569 9570 References: 9571 9572 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorSolveSchurComplement()` 9573 @*/ 9574 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol) 9575 { 9576 PetscFunctionBegin; 9577 PetscValidType(F,1); 9578 PetscValidType(rhs,2); 9579 PetscValidType(sol,3); 9580 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9581 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9582 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9583 PetscCheckSameComm(F,1,rhs,2); 9584 PetscCheckSameComm(F,1,sol,3); 9585 PetscCall(MatFactorFactorizeSchurComplement(F)); 9586 switch (F->schur_status) { 9587 case MAT_FACTOR_SCHUR_FACTORED: 9588 PetscCall(MatSolveTranspose(F->schur,rhs,sol)); 9589 break; 9590 case MAT_FACTOR_SCHUR_INVERTED: 9591 PetscCall(MatMultTranspose(F->schur,rhs,sol)); 9592 break; 9593 default: 9594 SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %d",F->schur_status); 9595 } 9596 PetscFunctionReturn(0); 9597 } 9598 9599 /*@ 9600 MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step 9601 9602 Logically Collective on Mat 9603 9604 Input Parameters: 9605 + F - the factored matrix obtained by calling MatGetFactor() 9606 . rhs - location where the right hand side of the Schur complement system is stored 9607 - sol - location where the solution of the Schur complement system has to be returned 9608 9609 Notes: 9610 The sizes of the vectors should match the size of the Schur complement 9611 9612 Must be called after MatFactorSetSchurIS() 9613 9614 Level: advanced 9615 9616 References: 9617 9618 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorSolveSchurComplementTranspose()` 9619 @*/ 9620 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol) 9621 { 9622 PetscFunctionBegin; 9623 PetscValidType(F,1); 9624 PetscValidType(rhs,2); 9625 PetscValidType(sol,3); 9626 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9627 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9628 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9629 PetscCheckSameComm(F,1,rhs,2); 9630 PetscCheckSameComm(F,1,sol,3); 9631 PetscCall(MatFactorFactorizeSchurComplement(F)); 9632 switch (F->schur_status) { 9633 case MAT_FACTOR_SCHUR_FACTORED: 9634 PetscCall(MatSolve(F->schur,rhs,sol)); 9635 break; 9636 case MAT_FACTOR_SCHUR_INVERTED: 9637 PetscCall(MatMult(F->schur,rhs,sol)); 9638 break; 9639 default: 9640 SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %d",F->schur_status); 9641 } 9642 PetscFunctionReturn(0); 9643 } 9644 9645 /*@ 9646 MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step 9647 9648 Logically Collective on Mat 9649 9650 Input Parameters: 9651 . F - the factored matrix obtained by calling MatGetFactor() 9652 9653 Notes: 9654 Must be called after MatFactorSetSchurIS(). 9655 9656 Call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it. 9657 9658 Level: advanced 9659 9660 References: 9661 9662 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorGetSchurComplement()`, `MatFactorCreateSchurComplement()` 9663 @*/ 9664 PetscErrorCode MatFactorInvertSchurComplement(Mat F) 9665 { 9666 PetscFunctionBegin; 9667 PetscValidType(F,1); 9668 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9669 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0); 9670 PetscCall(MatFactorFactorizeSchurComplement(F)); 9671 PetscCall(MatFactorInvertSchurComplement_Private(F)); 9672 F->schur_status = MAT_FACTOR_SCHUR_INVERTED; 9673 PetscFunctionReturn(0); 9674 } 9675 9676 /*@ 9677 MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step 9678 9679 Logically Collective on Mat 9680 9681 Input Parameters: 9682 . F - the factored matrix obtained by calling MatGetFactor() 9683 9684 Notes: 9685 Must be called after MatFactorSetSchurIS(). 9686 9687 Level: advanced 9688 9689 References: 9690 9691 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorInvertSchurComplement()` 9692 @*/ 9693 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F) 9694 { 9695 PetscFunctionBegin; 9696 PetscValidType(F,1); 9697 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9698 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0); 9699 PetscCall(MatFactorFactorizeSchurComplement_Private(F)); 9700 F->schur_status = MAT_FACTOR_SCHUR_FACTORED; 9701 PetscFunctionReturn(0); 9702 } 9703 9704 /*@ 9705 MatPtAP - Creates the matrix product C = P^T * A * P 9706 9707 Neighbor-wise Collective on Mat 9708 9709 Input Parameters: 9710 + A - the matrix 9711 . P - the projection matrix 9712 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9713 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate 9714 if the result is a dense matrix this is irrelevant 9715 9716 Output Parameters: 9717 . C - the product matrix 9718 9719 Notes: 9720 C will be created and must be destroyed by the user with MatDestroy(). 9721 9722 For matrix types without special implementation the function fallbacks to MatMatMult() followed by MatTransposeMatMult(). 9723 9724 Level: intermediate 9725 9726 .seealso: `MatMatMult()`, `MatRARt()` 9727 @*/ 9728 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 9729 { 9730 PetscFunctionBegin; 9731 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*C,5); 9732 PetscCheck(scall != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9733 9734 if (scall == MAT_INITIAL_MATRIX) { 9735 PetscCall(MatProductCreate(A,P,NULL,C)); 9736 PetscCall(MatProductSetType(*C,MATPRODUCT_PtAP)); 9737 PetscCall(MatProductSetAlgorithm(*C,"default")); 9738 PetscCall(MatProductSetFill(*C,fill)); 9739 9740 (*C)->product->api_user = PETSC_TRUE; 9741 PetscCall(MatProductSetFromOptions(*C)); 9742 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); 9743 PetscCall(MatProductSymbolic(*C)); 9744 } else { /* scall == MAT_REUSE_MATRIX */ 9745 PetscCall(MatProductReplaceMats(A,P,NULL,*C)); 9746 } 9747 9748 PetscCall(MatProductNumeric(*C)); 9749 (*C)->symmetric = A->symmetric; 9750 (*C)->spd = A->spd; 9751 PetscFunctionReturn(0); 9752 } 9753 9754 /*@ 9755 MatRARt - Creates the matrix product C = R * A * R^T 9756 9757 Neighbor-wise Collective on Mat 9758 9759 Input Parameters: 9760 + A - the matrix 9761 . R - the projection matrix 9762 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9763 - fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate 9764 if the result is a dense matrix this is irrelevant 9765 9766 Output Parameters: 9767 . C - the product matrix 9768 9769 Notes: 9770 C will be created and must be destroyed by the user with MatDestroy(). 9771 9772 This routine is currently only implemented for pairs of AIJ matrices and classes 9773 which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes, 9774 parallel MatRARt is implemented via explicit transpose of R, which could be very expensive. 9775 We recommend using MatPtAP(). 9776 9777 Level: intermediate 9778 9779 .seealso: `MatMatMult()`, `MatPtAP()` 9780 @*/ 9781 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C) 9782 { 9783 PetscFunctionBegin; 9784 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*C,5); 9785 PetscCheck(scall != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9786 9787 if (scall == MAT_INITIAL_MATRIX) { 9788 PetscCall(MatProductCreate(A,R,NULL,C)); 9789 PetscCall(MatProductSetType(*C,MATPRODUCT_RARt)); 9790 PetscCall(MatProductSetAlgorithm(*C,"default")); 9791 PetscCall(MatProductSetFill(*C,fill)); 9792 9793 (*C)->product->api_user = PETSC_TRUE; 9794 PetscCall(MatProductSetFromOptions(*C)); 9795 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); 9796 PetscCall(MatProductSymbolic(*C)); 9797 } else { /* scall == MAT_REUSE_MATRIX */ 9798 PetscCall(MatProductReplaceMats(A,R,NULL,*C)); 9799 } 9800 9801 PetscCall(MatProductNumeric(*C)); 9802 if (A->symmetric == PETSC_BOOL3_TRUE) { 9803 PetscCall(MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE)); 9804 } 9805 PetscFunctionReturn(0); 9806 } 9807 9808 static PetscErrorCode MatProduct_Private(Mat A,Mat B,MatReuse scall,PetscReal fill,MatProductType ptype, Mat *C) 9809 { 9810 PetscFunctionBegin; 9811 PetscCheck(scall != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9812 9813 if (scall == MAT_INITIAL_MATRIX) { 9814 PetscCall(PetscInfo(A,"Calling MatProduct API with MAT_INITIAL_MATRIX and product type %s\n",MatProductTypes[ptype])); 9815 PetscCall(MatProductCreate(A,B,NULL,C)); 9816 PetscCall(MatProductSetType(*C,ptype)); 9817 PetscCall(MatProductSetAlgorithm(*C,MATPRODUCTALGORITHMDEFAULT)); 9818 PetscCall(MatProductSetFill(*C,fill)); 9819 9820 (*C)->product->api_user = PETSC_TRUE; 9821 PetscCall(MatProductSetFromOptions(*C)); 9822 PetscCall(MatProductSymbolic(*C)); 9823 } else { /* scall == MAT_REUSE_MATRIX */ 9824 Mat_Product *product = (*C)->product; 9825 PetscBool isdense; 9826 9827 PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)(*C),&isdense,MATSEQDENSE,MATMPIDENSE,"")); 9828 if (isdense && product && product->type != ptype) { 9829 PetscCall(MatProductClear(*C)); 9830 product = NULL; 9831 } 9832 PetscCall(PetscInfo(A,"Calling MatProduct API with MAT_REUSE_MATRIX %s product present and product type %s\n",product ? "with" : "without",MatProductTypes[ptype])); 9833 if (!product) { /* user provide the dense matrix *C without calling MatProductCreate() or reusing it from previous calls */ 9834 if (isdense) { 9835 PetscCall(MatProductCreate_Private(A,B,NULL,*C)); 9836 product = (*C)->product; 9837 product->fill = fill; 9838 product->api_user = PETSC_TRUE; 9839 product->clear = PETSC_TRUE; 9840 9841 PetscCall(MatProductSetType(*C,ptype)); 9842 PetscCall(MatProductSetFromOptions(*C)); 9843 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); 9844 PetscCall(MatProductSymbolic(*C)); 9845 } else SETERRQ(PetscObjectComm((PetscObject)(*C)),PETSC_ERR_SUP,"Call MatProductCreate() first"); 9846 } else { /* user may change input matrices A or B when REUSE */ 9847 PetscCall(MatProductReplaceMats(A,B,NULL,*C)); 9848 } 9849 } 9850 PetscCall(MatProductNumeric(*C)); 9851 PetscFunctionReturn(0); 9852 } 9853 9854 /*@ 9855 MatMatMult - Performs Matrix-Matrix Multiplication C=A*B. 9856 9857 Neighbor-wise Collective on Mat 9858 9859 Input Parameters: 9860 + A - the left matrix 9861 . B - the right matrix 9862 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9863 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate 9864 if the result is a dense matrix this is irrelevant 9865 9866 Output Parameters: 9867 . C - the product matrix 9868 9869 Notes: 9870 Unless scall is MAT_REUSE_MATRIX C will be created. 9871 9872 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 9873 call to this function with MAT_INITIAL_MATRIX. 9874 9875 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value actually needed. 9876 9877 If you have many matrices with the same non-zero structure to multiply, you should use MatProductCreate()/MatProductSymbolic()/MatProductReplaceMats(), and call MatProductNumeric() repeatedly. 9878 9879 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. 9880 9881 Example of Usage: 9882 .vb 9883 MatProductCreate(A,B,NULL,&C); 9884 MatProductSetType(C,MATPRODUCT_AB); 9885 MatProductSymbolic(C); 9886 MatProductNumeric(C); // compute C=A * B 9887 MatProductReplaceMats(A1,B1,NULL,C); // compute C=A1 * B1 9888 MatProductNumeric(C); 9889 MatProductReplaceMats(A2,NULL,NULL,C); // compute C=A2 * B1 9890 MatProductNumeric(C); 9891 .ve 9892 9893 Level: intermediate 9894 9895 .seealso: `MatTransposeMatMult()`, `MatMatTransposeMult()`, `MatPtAP()`, `MatProductCreate()`, `MatProductSymbolic()`, `MatProductReplaceMats()`, `MatProductNumeric()` 9896 @*/ 9897 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9898 { 9899 PetscFunctionBegin; 9900 PetscCall(MatProduct_Private(A,B,scall,fill,MATPRODUCT_AB,C)); 9901 PetscFunctionReturn(0); 9902 } 9903 9904 /*@ 9905 MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T. 9906 9907 Neighbor-wise Collective on Mat 9908 9909 Input Parameters: 9910 + A - the left matrix 9911 . B - the right matrix 9912 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9913 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9914 9915 Output Parameters: 9916 . C - the product matrix 9917 9918 Notes: 9919 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9920 9921 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9922 9923 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9924 actually needed. 9925 9926 This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class, 9927 and for pairs of MPIDense matrices. 9928 9929 Options Database Keys: 9930 . -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorithms for MPIDense matrices: the 9931 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity; 9932 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity. 9933 9934 Level: intermediate 9935 9936 .seealso: `MatMatMult()`, `MatTransposeMatMult()` `MatPtAP()` 9937 @*/ 9938 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9939 { 9940 PetscFunctionBegin; 9941 PetscCall(MatProduct_Private(A,B,scall,fill,MATPRODUCT_ABt,C)); 9942 if (A == B) { 9943 PetscCall(MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE)); 9944 } 9945 PetscFunctionReturn(0); 9946 } 9947 9948 /*@ 9949 MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B. 9950 9951 Neighbor-wise Collective on Mat 9952 9953 Input Parameters: 9954 + A - the left matrix 9955 . B - the right matrix 9956 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9957 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9958 9959 Output Parameters: 9960 . C - the product matrix 9961 9962 Notes: 9963 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9964 9965 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call. 9966 9967 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9968 actually needed. 9969 9970 This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes 9971 which inherit from SeqAIJ. C will be of the same type as the input matrices. 9972 9973 Level: intermediate 9974 9975 .seealso: `MatMatMult()`, `MatMatTransposeMult()`, `MatPtAP()` 9976 @*/ 9977 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9978 { 9979 PetscFunctionBegin; 9980 PetscCall(MatProduct_Private(A,B,scall,fill,MATPRODUCT_AtB,C)); 9981 PetscFunctionReturn(0); 9982 } 9983 9984 /*@ 9985 MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C. 9986 9987 Neighbor-wise Collective on Mat 9988 9989 Input Parameters: 9990 + A - the left matrix 9991 . B - the middle matrix 9992 . C - the right matrix 9993 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9994 - 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 9995 if the result is a dense matrix this is irrelevant 9996 9997 Output Parameters: 9998 . D - the product matrix 9999 10000 Notes: 10001 Unless scall is MAT_REUSE_MATRIX D will be created. 10002 10003 MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call 10004 10005 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 10006 actually needed. 10007 10008 If you have many matrices with the same non-zero structure to multiply, you 10009 should use MAT_REUSE_MATRIX in all calls but the first 10010 10011 Level: intermediate 10012 10013 .seealso: `MatMatMult`, `MatPtAP()`, `MatMatTransposeMult()`, `MatTransposeMatMult()` 10014 @*/ 10015 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D) 10016 { 10017 PetscFunctionBegin; 10018 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*D,6); 10019 PetscCheck(scall != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 10020 10021 if (scall == MAT_INITIAL_MATRIX) { 10022 PetscCall(MatProductCreate(A,B,C,D)); 10023 PetscCall(MatProductSetType(*D,MATPRODUCT_ABC)); 10024 PetscCall(MatProductSetAlgorithm(*D,"default")); 10025 PetscCall(MatProductSetFill(*D,fill)); 10026 10027 (*D)->product->api_user = PETSC_TRUE; 10028 PetscCall(MatProductSetFromOptions(*D)); 10029 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); 10030 PetscCall(MatProductSymbolic(*D)); 10031 } else { /* user may change input matrices when REUSE */ 10032 PetscCall(MatProductReplaceMats(A,B,C,*D)); 10033 } 10034 PetscCall(MatProductNumeric(*D)); 10035 PetscFunctionReturn(0); 10036 } 10037 10038 /*@ 10039 MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators. 10040 10041 Collective on Mat 10042 10043 Input Parameters: 10044 + mat - the matrix 10045 . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices) 10046 . subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used) 10047 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10048 10049 Output Parameter: 10050 . matredundant - redundant matrix 10051 10052 Notes: 10053 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 10054 original matrix has not changed from that last call to MatCreateRedundantMatrix(). 10055 10056 This routine creates the duplicated matrices in the subcommunicators; you should NOT create them before 10057 calling it. 10058 10059 Level: advanced 10060 10061 .seealso: `MatDestroy()` 10062 @*/ 10063 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant) 10064 { 10065 MPI_Comm comm; 10066 PetscMPIInt size; 10067 PetscInt mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs; 10068 Mat_Redundant *redund=NULL; 10069 PetscSubcomm psubcomm=NULL; 10070 MPI_Comm subcomm_in=subcomm; 10071 Mat *matseq; 10072 IS isrow,iscol; 10073 PetscBool newsubcomm=PETSC_FALSE; 10074 10075 PetscFunctionBegin; 10076 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10077 if (nsubcomm && reuse == MAT_REUSE_MATRIX) { 10078 PetscValidPointer(*matredundant,5); 10079 PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5); 10080 } 10081 10082 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 10083 if (size == 1 || nsubcomm == 1) { 10084 if (reuse == MAT_INITIAL_MATRIX) { 10085 PetscCall(MatDuplicate(mat,MAT_COPY_VALUES,matredundant)); 10086 } else { 10087 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"); 10088 PetscCall(MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN)); 10089 } 10090 PetscFunctionReturn(0); 10091 } 10092 10093 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10094 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10095 MatCheckPreallocated(mat,1); 10096 10097 PetscCall(PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0)); 10098 if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */ 10099 /* create psubcomm, then get subcomm */ 10100 PetscCall(PetscObjectGetComm((PetscObject)mat,&comm)); 10101 PetscCallMPI(MPI_Comm_size(comm,&size)); 10102 PetscCheck(nsubcomm >= 1 && nsubcomm <= size,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %d",size); 10103 10104 PetscCall(PetscSubcommCreate(comm,&psubcomm)); 10105 PetscCall(PetscSubcommSetNumber(psubcomm,nsubcomm)); 10106 PetscCall(PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS)); 10107 PetscCall(PetscSubcommSetFromOptions(psubcomm)); 10108 PetscCall(PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL)); 10109 newsubcomm = PETSC_TRUE; 10110 PetscCall(PetscSubcommDestroy(&psubcomm)); 10111 } 10112 10113 /* get isrow, iscol and a local sequential matrix matseq[0] */ 10114 if (reuse == MAT_INITIAL_MATRIX) { 10115 mloc_sub = PETSC_DECIDE; 10116 nloc_sub = PETSC_DECIDE; 10117 if (bs < 1) { 10118 PetscCall(PetscSplitOwnership(subcomm,&mloc_sub,&M)); 10119 PetscCall(PetscSplitOwnership(subcomm,&nloc_sub,&N)); 10120 } else { 10121 PetscCall(PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M)); 10122 PetscCall(PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N)); 10123 } 10124 PetscCallMPI(MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm)); 10125 rstart = rend - mloc_sub; 10126 PetscCall(ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow)); 10127 PetscCall(ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol)); 10128 } else { /* reuse == MAT_REUSE_MATRIX */ 10129 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"); 10130 /* retrieve subcomm */ 10131 PetscCall(PetscObjectGetComm((PetscObject)(*matredundant),&subcomm)); 10132 redund = (*matredundant)->redundant; 10133 isrow = redund->isrow; 10134 iscol = redund->iscol; 10135 matseq = redund->matseq; 10136 } 10137 PetscCall(MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq)); 10138 10139 /* get matredundant over subcomm */ 10140 if (reuse == MAT_INITIAL_MATRIX) { 10141 PetscCall(MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant)); 10142 10143 /* create a supporting struct and attach it to C for reuse */ 10144 PetscCall(PetscNewLog(*matredundant,&redund)); 10145 (*matredundant)->redundant = redund; 10146 redund->isrow = isrow; 10147 redund->iscol = iscol; 10148 redund->matseq = matseq; 10149 if (newsubcomm) { 10150 redund->subcomm = subcomm; 10151 } else { 10152 redund->subcomm = MPI_COMM_NULL; 10153 } 10154 } else { 10155 PetscCall(MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant)); 10156 } 10157 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 10158 if (matseq[0]->boundtocpu && matseq[0]->bindingpropagates) { 10159 PetscCall(MatBindToCPU(*matredundant,PETSC_TRUE)); 10160 PetscCall(MatSetBindingPropagates(*matredundant,PETSC_TRUE)); 10161 } 10162 #endif 10163 PetscCall(PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0)); 10164 PetscFunctionReturn(0); 10165 } 10166 10167 /*@C 10168 MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from 10169 a given 'mat' object. Each submatrix can span multiple procs. 10170 10171 Collective on Mat 10172 10173 Input Parameters: 10174 + mat - the matrix 10175 . subcomm - the subcommunicator obtained by com_split(comm) 10176 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10177 10178 Output Parameter: 10179 . subMat - 'parallel submatrices each spans a given subcomm 10180 10181 Notes: 10182 The submatrix partition across processors is dictated by 'subComm' a 10183 communicator obtained by MPI_comm_split(). The subComm 10184 is not restriced to be grouped with consecutive original ranks. 10185 10186 Due the MPI_Comm_split() usage, the parallel layout of the submatrices 10187 map directly to the layout of the original matrix [wrt the local 10188 row,col partitioning]. So the original 'DiagonalMat' naturally maps 10189 into the 'DiagonalMat' of the subMat, hence it is used directly from 10190 the subMat. However the offDiagMat looses some columns - and this is 10191 reconstructed with MatSetValues() 10192 10193 Level: advanced 10194 10195 .seealso: `MatCreateSubMatrices()` 10196 @*/ 10197 PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat) 10198 { 10199 PetscMPIInt commsize,subCommSize; 10200 10201 PetscFunctionBegin; 10202 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize)); 10203 PetscCallMPI(MPI_Comm_size(subComm,&subCommSize)); 10204 PetscCheck(subCommSize <= commsize,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %d < SubCommZize %d",commsize,subCommSize); 10205 10206 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"); 10207 PetscCall(PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0)); 10208 PetscUseTypeMethod(mat,getmultiprocblock ,subComm,scall,subMat); 10209 PetscCall(PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0)); 10210 PetscFunctionReturn(0); 10211 } 10212 10213 /*@ 10214 MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering 10215 10216 Not Collective 10217 10218 Input Parameters: 10219 + mat - matrix to extract local submatrix from 10220 . isrow - local row indices for submatrix 10221 - iscol - local column indices for submatrix 10222 10223 Output Parameter: 10224 . submat - the submatrix 10225 10226 Level: intermediate 10227 10228 Notes: 10229 The submat should be returned with MatRestoreLocalSubMatrix(). 10230 10231 Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be 10232 the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's. 10233 10234 The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then 10235 MatSetValuesBlockedLocal() will also be implemented. 10236 10237 The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that 10238 matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided. 10239 10240 .seealso: `MatRestoreLocalSubMatrix()`, `MatCreateLocalRef()`, `MatSetLocalToGlobalMapping()` 10241 @*/ 10242 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10243 { 10244 PetscFunctionBegin; 10245 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10246 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10247 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10248 PetscCheckSameComm(isrow,2,iscol,3); 10249 PetscValidPointer(submat,4); 10250 PetscCheck(mat->rmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call"); 10251 10252 if (mat->ops->getlocalsubmatrix) { 10253 PetscUseTypeMethod(mat,getlocalsubmatrix ,isrow,iscol,submat); 10254 } else { 10255 PetscCall(MatCreateLocalRef(mat,isrow,iscol,submat)); 10256 } 10257 PetscFunctionReturn(0); 10258 } 10259 10260 /*@ 10261 MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering 10262 10263 Not Collective 10264 10265 Input Parameters: 10266 + mat - matrix to extract local submatrix from 10267 . isrow - local row indices for submatrix 10268 . iscol - local column indices for submatrix 10269 - submat - the submatrix 10270 10271 Level: intermediate 10272 10273 .seealso: `MatGetLocalSubMatrix()` 10274 @*/ 10275 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10276 { 10277 PetscFunctionBegin; 10278 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10279 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10280 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10281 PetscCheckSameComm(isrow,2,iscol,3); 10282 PetscValidPointer(submat,4); 10283 if (*submat) { 10284 PetscValidHeaderSpecific(*submat,MAT_CLASSID,4); 10285 } 10286 10287 if (mat->ops->restorelocalsubmatrix) { 10288 PetscUseTypeMethod(mat,restorelocalsubmatrix ,isrow,iscol,submat); 10289 } else { 10290 PetscCall(MatDestroy(submat)); 10291 } 10292 *submat = NULL; 10293 PetscFunctionReturn(0); 10294 } 10295 10296 /* --------------------------------------------------------*/ 10297 /*@ 10298 MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix 10299 10300 Collective on Mat 10301 10302 Input Parameter: 10303 . mat - the matrix 10304 10305 Output Parameter: 10306 . is - if any rows have zero diagonals this contains the list of them 10307 10308 Level: developer 10309 10310 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 10311 @*/ 10312 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is) 10313 { 10314 PetscFunctionBegin; 10315 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10316 PetscValidType(mat,1); 10317 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10318 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10319 10320 if (!mat->ops->findzerodiagonals) { 10321 Vec diag; 10322 const PetscScalar *a; 10323 PetscInt *rows; 10324 PetscInt rStart, rEnd, r, nrow = 0; 10325 10326 PetscCall(MatCreateVecs(mat, &diag, NULL)); 10327 PetscCall(MatGetDiagonal(mat, diag)); 10328 PetscCall(MatGetOwnershipRange(mat, &rStart, &rEnd)); 10329 PetscCall(VecGetArrayRead(diag, &a)); 10330 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow; 10331 PetscCall(PetscMalloc1(nrow, &rows)); 10332 nrow = 0; 10333 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart; 10334 PetscCall(VecRestoreArrayRead(diag, &a)); 10335 PetscCall(VecDestroy(&diag)); 10336 PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is)); 10337 } else { 10338 PetscUseTypeMethod(mat,findzerodiagonals , is); 10339 } 10340 PetscFunctionReturn(0); 10341 } 10342 10343 /*@ 10344 MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size) 10345 10346 Collective on Mat 10347 10348 Input Parameter: 10349 . mat - the matrix 10350 10351 Output Parameter: 10352 . is - contains the list of rows with off block diagonal entries 10353 10354 Level: developer 10355 10356 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 10357 @*/ 10358 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is) 10359 { 10360 PetscFunctionBegin; 10361 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10362 PetscValidType(mat,1); 10363 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10364 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10365 10366 PetscUseTypeMethod(mat,findoffblockdiagonalentries ,is); 10367 PetscFunctionReturn(0); 10368 } 10369 10370 /*@C 10371 MatInvertBlockDiagonal - Inverts the block diagonal entries. 10372 10373 Collective on Mat 10374 10375 Input Parameters: 10376 . mat - the matrix 10377 10378 Output Parameters: 10379 . values - the block inverses in column major order (FORTRAN-like) 10380 10381 Note: 10382 The size of the blocks is determined by the block size of the matrix. 10383 10384 Fortran Note: 10385 This routine is not available from Fortran. 10386 10387 Level: advanced 10388 10389 .seealso: `MatInvertVariableBlockEnvelope()`, `MatInvertBlockDiagonalMat()` 10390 @*/ 10391 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values) 10392 { 10393 PetscFunctionBegin; 10394 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10395 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10396 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10397 PetscUseTypeMethod(mat,invertblockdiagonal ,values); 10398 PetscFunctionReturn(0); 10399 } 10400 10401 /*@C 10402 MatInvertVariableBlockDiagonal - Inverts the point block diagonal entries. 10403 10404 Collective on Mat 10405 10406 Input Parameters: 10407 + mat - the matrix 10408 . nblocks - the number of blocks on the process, set with MatSetVariableBlockSizes() 10409 - bsizes - the size of each block on the process, set with MatSetVariableBlockSizes() 10410 10411 Output Parameters: 10412 . values - the block inverses in column major order (FORTRAN-like) 10413 10414 Note: 10415 This routine is not available from Fortran. 10416 10417 Level: advanced 10418 10419 .seealso: `MatInvertBlockDiagonal()`, `MatSetVariableBlockSizes()`, `MatInvertVariableBlockEnvelope()` 10420 @*/ 10421 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values) 10422 { 10423 PetscFunctionBegin; 10424 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10425 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10426 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10427 PetscUseTypeMethod(mat,invertvariableblockdiagonal ,nblocks,bsizes,values); 10428 PetscFunctionReturn(0); 10429 } 10430 10431 /*@ 10432 MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A 10433 10434 Collective on Mat 10435 10436 Input Parameters: 10437 . A - the matrix 10438 10439 Output Parameters: 10440 . C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set. 10441 10442 Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C 10443 10444 Level: advanced 10445 10446 .seealso: `MatInvertBlockDiagonal()` 10447 @*/ 10448 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C) 10449 { 10450 const PetscScalar *vals; 10451 PetscInt *dnnz; 10452 PetscInt m,rstart,rend,bs,i,j; 10453 10454 PetscFunctionBegin; 10455 PetscCall(MatInvertBlockDiagonal(A,&vals)); 10456 PetscCall(MatGetBlockSize(A,&bs)); 10457 PetscCall(MatGetLocalSize(A,&m,NULL)); 10458 PetscCall(MatSetLayouts(C,A->rmap,A->cmap)); 10459 PetscCall(PetscMalloc1(m/bs,&dnnz)); 10460 for (j = 0; j < m/bs; j++) dnnz[j] = 1; 10461 PetscCall(MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL)); 10462 PetscCall(PetscFree(dnnz)); 10463 PetscCall(MatGetOwnershipRange(C,&rstart,&rend)); 10464 PetscCall(MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE)); 10465 for (i = rstart/bs; i < rend/bs; i++) { 10466 PetscCall(MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES)); 10467 } 10468 PetscCall(MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY)); 10469 PetscCall(MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY)); 10470 PetscCall(MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE)); 10471 PetscFunctionReturn(0); 10472 } 10473 10474 /*@C 10475 MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created 10476 via MatTransposeColoringCreate(). 10477 10478 Collective on MatTransposeColoring 10479 10480 Input Parameter: 10481 . c - coloring context 10482 10483 Level: intermediate 10484 10485 .seealso: `MatTransposeColoringCreate()` 10486 @*/ 10487 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c) 10488 { 10489 MatTransposeColoring matcolor=*c; 10490 10491 PetscFunctionBegin; 10492 if (!matcolor) PetscFunctionReturn(0); 10493 if (--((PetscObject)matcolor)->refct > 0) {matcolor = NULL; PetscFunctionReturn(0);} 10494 10495 PetscCall(PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow)); 10496 PetscCall(PetscFree(matcolor->rows)); 10497 PetscCall(PetscFree(matcolor->den2sp)); 10498 PetscCall(PetscFree(matcolor->colorforcol)); 10499 PetscCall(PetscFree(matcolor->columns)); 10500 if (matcolor->brows>0) PetscCall(PetscFree(matcolor->lstart)); 10501 PetscCall(PetscHeaderDestroy(c)); 10502 PetscFunctionReturn(0); 10503 } 10504 10505 /*@C 10506 MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which 10507 a MatTransposeColoring context has been created, computes a dense B^T by Apply 10508 MatTransposeColoring to sparse B. 10509 10510 Collective on MatTransposeColoring 10511 10512 Input Parameters: 10513 + B - sparse matrix B 10514 . Btdense - symbolic dense matrix B^T 10515 - coloring - coloring context created with MatTransposeColoringCreate() 10516 10517 Output Parameter: 10518 . Btdense - dense matrix B^T 10519 10520 Level: advanced 10521 10522 Notes: 10523 These are used internally for some implementations of MatRARt() 10524 10525 .seealso: `MatTransposeColoringCreate()`, `MatTransposeColoringDestroy()`, `MatTransColoringApplyDenToSp()` 10526 10527 @*/ 10528 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense) 10529 { 10530 PetscFunctionBegin; 10531 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 10532 PetscValidHeaderSpecific(Btdense,MAT_CLASSID,3); 10533 PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,1); 10534 10535 PetscCall((B->ops->transcoloringapplysptoden)(coloring,B,Btdense)); 10536 PetscFunctionReturn(0); 10537 } 10538 10539 /*@C 10540 MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which 10541 a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense 10542 in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix 10543 Csp from Cden. 10544 10545 Collective on MatTransposeColoring 10546 10547 Input Parameters: 10548 + coloring - coloring context created with MatTransposeColoringCreate() 10549 - Cden - matrix product of a sparse matrix and a dense matrix Btdense 10550 10551 Output Parameter: 10552 . Csp - sparse matrix 10553 10554 Level: advanced 10555 10556 Notes: 10557 These are used internally for some implementations of MatRARt() 10558 10559 .seealso: `MatTransposeColoringCreate()`, `MatTransposeColoringDestroy()`, `MatTransColoringApplySpToDen()` 10560 10561 @*/ 10562 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp) 10563 { 10564 PetscFunctionBegin; 10565 PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1); 10566 PetscValidHeaderSpecific(Cden,MAT_CLASSID,2); 10567 PetscValidHeaderSpecific(Csp,MAT_CLASSID,3); 10568 10569 PetscCall((Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp)); 10570 PetscCall(MatAssemblyBegin(Csp,MAT_FINAL_ASSEMBLY)); 10571 PetscCall(MatAssemblyEnd(Csp,MAT_FINAL_ASSEMBLY)); 10572 PetscFunctionReturn(0); 10573 } 10574 10575 /*@C 10576 MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T. 10577 10578 Collective on Mat 10579 10580 Input Parameters: 10581 + mat - the matrix product C 10582 - iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring() 10583 10584 Output Parameter: 10585 . color - the new coloring context 10586 10587 Level: intermediate 10588 10589 .seealso: `MatTransposeColoringDestroy()`, `MatTransColoringApplySpToDen()`, 10590 `MatTransColoringApplyDenToSp()` 10591 @*/ 10592 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color) 10593 { 10594 MatTransposeColoring c; 10595 MPI_Comm comm; 10596 10597 PetscFunctionBegin; 10598 PetscCall(PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0)); 10599 PetscCall(PetscObjectGetComm((PetscObject)mat,&comm)); 10600 PetscCall(PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL)); 10601 10602 c->ctype = iscoloring->ctype; 10603 if (mat->ops->transposecoloringcreate) { 10604 PetscUseTypeMethod(mat,transposecoloringcreate ,iscoloring,c); 10605 } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for matrix type %s",((PetscObject)mat)->type_name); 10606 10607 *color = c; 10608 PetscCall(PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0)); 10609 PetscFunctionReturn(0); 10610 } 10611 10612 /*@ 10613 MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the 10614 matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the 10615 same, otherwise it will be larger 10616 10617 Not Collective 10618 10619 Input Parameter: 10620 . A - the matrix 10621 10622 Output Parameter: 10623 . state - the current state 10624 10625 Notes: 10626 You can only compare states from two different calls to the SAME matrix, you cannot compare calls between 10627 different matrices 10628 10629 Level: intermediate 10630 10631 .seealso: `PetscObjectStateGet()` 10632 @*/ 10633 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state) 10634 { 10635 PetscFunctionBegin; 10636 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10637 *state = mat->nonzerostate; 10638 PetscFunctionReturn(0); 10639 } 10640 10641 /*@ 10642 MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential 10643 matrices from each processor 10644 10645 Collective 10646 10647 Input Parameters: 10648 + comm - the communicators the parallel matrix will live on 10649 . seqmat - the input sequential matrices 10650 . n - number of local columns (or PETSC_DECIDE) 10651 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10652 10653 Output Parameter: 10654 . mpimat - the parallel matrix generated 10655 10656 Level: advanced 10657 10658 Notes: 10659 The number of columns of the matrix in EACH processor MUST be the same. 10660 10661 @*/ 10662 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat) 10663 { 10664 PetscMPIInt size; 10665 10666 PetscFunctionBegin; 10667 PetscCallMPI(MPI_Comm_size(comm,&size)); 10668 if (size == 1) { 10669 if (reuse == MAT_INITIAL_MATRIX) { 10670 PetscCall(MatDuplicate(seqmat,MAT_COPY_VALUES,mpimat)); 10671 } else { 10672 PetscCall(MatCopy(seqmat,*mpimat,SAME_NONZERO_PATTERN)); 10673 } 10674 PetscFunctionReturn(0); 10675 } 10676 10677 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"); 10678 10679 PetscCall(PetscLogEventBegin(MAT_Merge,seqmat,0,0,0)); 10680 PetscCall((*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat)); 10681 PetscCall(PetscLogEventEnd(MAT_Merge,seqmat,0,0,0)); 10682 PetscFunctionReturn(0); 10683 } 10684 10685 /*@ 10686 MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent 10687 ranks' ownership ranges. 10688 10689 Collective on A 10690 10691 Input Parameters: 10692 + A - the matrix to create subdomains from 10693 - N - requested number of subdomains 10694 10695 Output Parameters: 10696 + n - number of subdomains resulting on this rank 10697 - iss - IS list with indices of subdomains on this rank 10698 10699 Level: advanced 10700 10701 Notes: 10702 number of subdomains must be smaller than the communicator size 10703 @*/ 10704 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[]) 10705 { 10706 MPI_Comm comm,subcomm; 10707 PetscMPIInt size,rank,color; 10708 PetscInt rstart,rend,k; 10709 10710 PetscFunctionBegin; 10711 PetscCall(PetscObjectGetComm((PetscObject)A,&comm)); 10712 PetscCallMPI(MPI_Comm_size(comm,&size)); 10713 PetscCallMPI(MPI_Comm_rank(comm,&rank)); 10714 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); 10715 *n = 1; 10716 k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */ 10717 color = rank/k; 10718 PetscCallMPI(MPI_Comm_split(comm,color,rank,&subcomm)); 10719 PetscCall(PetscMalloc1(1,iss)); 10720 PetscCall(MatGetOwnershipRange(A,&rstart,&rend)); 10721 PetscCall(ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0])); 10722 PetscCallMPI(MPI_Comm_free(&subcomm)); 10723 PetscFunctionReturn(0); 10724 } 10725 10726 /*@ 10727 MatGalerkin - Constructs the coarse grid problem via Galerkin projection. 10728 10729 If the interpolation and restriction operators are the same, uses MatPtAP. 10730 If they are not the same, use MatMatMatMult. 10731 10732 Once the coarse grid problem is constructed, correct for interpolation operators 10733 that are not of full rank, which can legitimately happen in the case of non-nested 10734 geometric multigrid. 10735 10736 Input Parameters: 10737 + restrct - restriction operator 10738 . dA - fine grid matrix 10739 . interpolate - interpolation operator 10740 . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10741 - fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate 10742 10743 Output Parameters: 10744 . A - the Galerkin coarse matrix 10745 10746 Options Database Key: 10747 . -pc_mg_galerkin <both,pmat,mat,none> - for what matrices the Galerkin process should be used 10748 10749 Level: developer 10750 10751 .seealso: `MatPtAP()`, `MatMatMatMult()` 10752 @*/ 10753 PetscErrorCode MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A) 10754 { 10755 IS zerorows; 10756 Vec diag; 10757 10758 PetscFunctionBegin; 10759 PetscCheck(reuse != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 10760 /* Construct the coarse grid matrix */ 10761 if (interpolate == restrct) { 10762 PetscCall(MatPtAP(dA,interpolate,reuse,fill,A)); 10763 } else { 10764 PetscCall(MatMatMatMult(restrct,dA,interpolate,reuse,fill,A)); 10765 } 10766 10767 /* If the interpolation matrix is not of full rank, A will have zero rows. 10768 This can legitimately happen in the case of non-nested geometric multigrid. 10769 In that event, we set the rows of the matrix to the rows of the identity, 10770 ignoring the equations (as the RHS will also be zero). */ 10771 10772 PetscCall(MatFindZeroRows(*A, &zerorows)); 10773 10774 if (zerorows != NULL) { /* if there are any zero rows */ 10775 PetscCall(MatCreateVecs(*A, &diag, NULL)); 10776 PetscCall(MatGetDiagonal(*A, diag)); 10777 PetscCall(VecISSet(diag, zerorows, 1.0)); 10778 PetscCall(MatDiagonalSet(*A, diag, INSERT_VALUES)); 10779 PetscCall(VecDestroy(&diag)); 10780 PetscCall(ISDestroy(&zerorows)); 10781 } 10782 PetscFunctionReturn(0); 10783 } 10784 10785 /*@C 10786 MatSetOperation - Allows user to set a matrix operation for any matrix type 10787 10788 Logically Collective on Mat 10789 10790 Input Parameters: 10791 + mat - the matrix 10792 . op - the name of the operation 10793 - f - the function that provides the operation 10794 10795 Level: developer 10796 10797 Usage: 10798 $ extern PetscErrorCode usermult(Mat,Vec,Vec); 10799 $ PetscCall(MatCreateXXX(comm,...&A); 10800 $ PetscCall(MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult); 10801 10802 Notes: 10803 See the file include/petscmat.h for a complete list of matrix 10804 operations, which all have the form MATOP_<OPERATION>, where 10805 <OPERATION> is the name (in all capital letters) of the 10806 user interface routine (e.g., MatMult() -> MATOP_MULT). 10807 10808 All user-provided functions (except for MATOP_DESTROY) should have the same calling 10809 sequence as the usual matrix interface routines, since they 10810 are intended to be accessed via the usual matrix interface 10811 routines, e.g., 10812 $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 10813 10814 In particular each function MUST return an error code of 0 on success and 10815 nonzero on failure. 10816 10817 This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type. 10818 10819 .seealso: `MatGetOperation()`, `MatCreateShell()`, `MatShellSetContext()`, `MatShellSetOperation()` 10820 @*/ 10821 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void)) 10822 { 10823 PetscFunctionBegin; 10824 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10825 if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) { 10826 mat->ops->viewnative = mat->ops->view; 10827 } 10828 (((void(**)(void))mat->ops)[op]) = f; 10829 PetscFunctionReturn(0); 10830 } 10831 10832 /*@C 10833 MatGetOperation - Gets a matrix operation for any matrix type. 10834 10835 Not Collective 10836 10837 Input Parameters: 10838 + mat - the matrix 10839 - op - the name of the operation 10840 10841 Output Parameter: 10842 . f - the function that provides the operation 10843 10844 Level: developer 10845 10846 Usage: 10847 $ PetscErrorCode (*usermult)(Mat,Vec,Vec); 10848 $ MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult); 10849 10850 Notes: 10851 See the file include/petscmat.h for a complete list of matrix 10852 operations, which all have the form MATOP_<OPERATION>, where 10853 <OPERATION> is the name (in all capital letters) of the 10854 user interface routine (e.g., MatMult() -> MATOP_MULT). 10855 10856 This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type. 10857 10858 .seealso: `MatSetOperation()`, `MatCreateShell()`, `MatShellGetContext()`, `MatShellGetOperation()` 10859 @*/ 10860 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void)) 10861 { 10862 PetscFunctionBegin; 10863 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10864 *f = (((void (**)(void))mat->ops)[op]); 10865 PetscFunctionReturn(0); 10866 } 10867 10868 /*@ 10869 MatHasOperation - Determines whether the given matrix supports the particular 10870 operation. 10871 10872 Not Collective 10873 10874 Input Parameters: 10875 + mat - the matrix 10876 - op - the operation, for example, MATOP_GET_DIAGONAL 10877 10878 Output Parameter: 10879 . has - either PETSC_TRUE or PETSC_FALSE 10880 10881 Level: advanced 10882 10883 Notes: 10884 See the file include/petscmat.h for a complete list of matrix 10885 operations, which all have the form MATOP_<OPERATION>, where 10886 <OPERATION> is the name (in all capital letters) of the 10887 user-level routine. E.g., MatNorm() -> MATOP_NORM. 10888 10889 .seealso: `MatCreateShell()` 10890 @*/ 10891 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has) 10892 { 10893 PetscFunctionBegin; 10894 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10895 PetscValidBoolPointer(has,3); 10896 if (mat->ops->hasoperation) { 10897 PetscUseTypeMethod(mat,hasoperation ,op,has); 10898 } else { 10899 if (((void**)mat->ops)[op]) *has = PETSC_TRUE; 10900 else { 10901 *has = PETSC_FALSE; 10902 if (op == MATOP_CREATE_SUBMATRIX) { 10903 PetscMPIInt size; 10904 10905 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 10906 if (size == 1) { 10907 PetscCall(MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has)); 10908 } 10909 } 10910 } 10911 } 10912 PetscFunctionReturn(0); 10913 } 10914 10915 /*@ 10916 MatHasCongruentLayouts - Determines whether the rows and columns layouts 10917 of the matrix are congruent 10918 10919 Collective on mat 10920 10921 Input Parameters: 10922 . mat - the matrix 10923 10924 Output Parameter: 10925 . cong - either PETSC_TRUE or PETSC_FALSE 10926 10927 Level: beginner 10928 10929 Notes: 10930 10931 .seealso: `MatCreate()`, `MatSetSizes()` 10932 @*/ 10933 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong) 10934 { 10935 PetscFunctionBegin; 10936 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10937 PetscValidType(mat,1); 10938 PetscValidBoolPointer(cong,2); 10939 if (!mat->rmap || !mat->cmap) { 10940 *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE; 10941 PetscFunctionReturn(0); 10942 } 10943 if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */ 10944 PetscCall(PetscLayoutSetUp(mat->rmap)); 10945 PetscCall(PetscLayoutSetUp(mat->cmap)); 10946 PetscCall(PetscLayoutCompare(mat->rmap,mat->cmap,cong)); 10947 if (*cong) mat->congruentlayouts = 1; 10948 else mat->congruentlayouts = 0; 10949 } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE; 10950 PetscFunctionReturn(0); 10951 } 10952 10953 PetscErrorCode MatSetInf(Mat A) 10954 { 10955 PetscFunctionBegin; 10956 PetscUseTypeMethod(A,setinf); 10957 PetscFunctionReturn(0); 10958 } 10959 10960 /*C 10961 MatCreateGraph - create a scalar matrix, for use in graph algorithms 10962 10963 Collective on mat 10964 10965 Input Parameters: 10966 + A - the matrix 10967 - sym - PETSC_TRUE indicates that the graph will be symmetrized 10968 . scale - PETSC_TRUE indicates that the graph will be scaled with the diagonal 10969 10970 Output Parameter: 10971 . graph - the resulting graph 10972 10973 Level: advanced 10974 10975 Notes: 10976 10977 .seealso: `MatCreate()`, `MatFilter()` 10978 */ 10979 PETSC_EXTERN PetscErrorCode MatCreateGraph(Mat A, PetscBool sym, PetscBool scale, Mat *graph) 10980 { 10981 PetscFunctionBegin; 10982 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 10983 PetscValidType(A,1); 10984 PetscValidPointer(graph,3); 10985 PetscUseTypeMethod(A,creategraph ,sym,scale,graph); 10986 PetscFunctionReturn(0); 10987 } 10988 10989 /*C 10990 MatFilter - filters a Mat values with an absolut value equal to or below a give threshold 10991 10992 Collective on mat 10993 10994 Input Parameter: 10995 . value - filter value - < 0: does nothing; == 0: removes only 0.0 entries; otherwise: removes entries <= value 10996 10997 Input/Output Parameter: 10998 . A - the Mat to filter in place 10999 11000 Level: developer 11001 11002 Note: 11003 This is called before graph coarsers are called in GAMG 11004 11005 .seealso: `MatCreate()`, `MatCreateGraph()` 11006 */ 11007 PETSC_EXTERN PetscErrorCode MatFilter(Mat G,PetscReal value,Mat *F) 11008 { 11009 PetscFunctionBegin; 11010 PetscValidHeaderSpecific(G,MAT_CLASSID,1); 11011 PetscValidType(G,1); 11012 PetscValidPointer(F,3); 11013 if (value >= 0.0) { 11014 PetscCall((G->ops->filter)(G,value,F)); 11015 } 11016 PetscFunctionReturn(0); 11017 } 11018