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