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