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